コード例 #1
0
 private void prepareResponseChannel(ClientResponse response, ClientExchange exchange) {
   String encoding = response.getResponseHeaders().getLast(TRANSFER_ENCODING);
   boolean chunked = encoding != null && Headers.CHUNKED.equals(new HttpString(encoding));
   String length = response.getResponseHeaders().getFirst(CONTENT_LENGTH);
   if (exchange.getRequest().getMethod().equals(Methods.HEAD)) {
     connection
         .getSourceChannel()
         .setConduit(
             new FixedLengthStreamSourceConduit(
                 connection.getSourceChannel().getConduit(), 0, responseFinishedListener));
   } else if (chunked) {
     connection
         .getSourceChannel()
         .setConduit(
             new ChunkedStreamSourceConduit(
                 connection.getSourceChannel().getConduit(),
                 pushBackStreamSourceConduit,
                 bufferPool,
                 responseFinishedListener,
                 exchange));
   } else if (length != null) {
     try {
       long contentLength = Long.parseLong(length);
       connection
           .getSourceChannel()
           .setConduit(
               new FixedLengthStreamSourceConduit(
                   connection.getSourceChannel().getConduit(),
                   contentLength,
                   responseFinishedListener));
     } catch (NumberFormatException e) {
       handleError(new IOException(e));
       throw e;
     }
   } else if (response.getProtocol().equals(Protocols.HTTP_1_1)) {
     connection
         .getSourceChannel()
         .setConduit(
             new FixedLengthStreamSourceConduit(
                 connection.getSourceChannel().getConduit(), 0, responseFinishedListener));
   } else {
     state |= CLOSE_REQ;
   }
 }
コード例 #2
0
  private void initiateRequest(HttpClientExchange httpClientExchange) {
    currentRequest = httpClientExchange;
    pendingResponse = new HttpResponseBuilder();
    ClientRequest request = httpClientExchange.getRequest();

    String connectionString = request.getRequestHeaders().getFirst(CONNECTION);
    if (connectionString != null) {
      HttpString connectionHttpString = new HttpString(connectionString);
      if (connectionHttpString.equals(CLOSE)) {
        state |= CLOSE_REQ;
      } else if (connectionHttpString.equals(UPGRADE)) {
        state |= UPGRADE_REQUESTED;
      }
    } else if (request.getProtocol() != Protocols.HTTP_1_1) {
      state |= CLOSE_REQ;
    }
    if (request.getRequestHeaders().contains(UPGRADE)) {
      state |= UPGRADE_REQUESTED;
    }

    // setup the client request conduits
    final ConduitStreamSourceChannel sourceChannel = connection.getSourceChannel();
    sourceChannel.setReadListener(clientReadListener);
    sourceChannel.resumeReads();

    ConduitStreamSinkChannel sinkChannel = connection.getSinkChannel();
    StreamSinkConduit conduit = originalSinkConduit;
    conduit = new HttpRequestConduit(conduit, bufferPool, request);

    String fixedLengthString = request.getRequestHeaders().getFirst(CONTENT_LENGTH);
    String transferEncodingString = request.getRequestHeaders().getLast(TRANSFER_ENCODING);

    boolean hasContent = true;

    if (fixedLengthString != null) {
      try {
        long length = Long.parseLong(fixedLengthString);
        conduit =
            new ClientFixedLengthStreamSinkConduit(conduit, length, false, false, currentRequest);
        hasContent = length != 0;
      } catch (NumberFormatException e) {
        handleError(new IOException(e));
        return;
      }
    } else if (transferEncodingString != null) {
      if (!transferEncodingString
          .toLowerCase(Locale.ENGLISH)
          .contains(Headers.CHUNKED.toString())) {
        handleError(
            UndertowClientMessages.MESSAGES.unknownTransferEncoding(transferEncodingString));
        return;
      }
      conduit =
          new ChunkedStreamSinkConduit(
              conduit,
              httpClientExchange.getConnection().getBufferPool(),
              false,
              false,
              httpClientExchange.getRequest().getRequestHeaders(),
              requestFinishListener,
              httpClientExchange);
    } else {
      conduit = new ClientFixedLengthStreamSinkConduit(conduit, 0, false, false, currentRequest);
      hasContent = false;
    }
    sinkChannel.setConduit(conduit);

    httpClientExchange.invokeReadReadyCallback(httpClientExchange);
    if (!hasContent) {
      // if there is no content we flush the response channel.
      // otherwise it is up to the user
      try {
        sinkChannel.shutdownWrites();
        if (!sinkChannel.flush()) {
          sinkChannel.setWriteListener(
              ChannelListeners.flushingChannelListener(
                  null,
                  new ChannelExceptionHandler<ConduitStreamSinkChannel>() {
                    @Override
                    public void handleException(
                        ConduitStreamSinkChannel channel, IOException exception) {
                      handleError(exception);
                    }
                  }));
        }
      } catch (IOException e) {
        handleError(e);
      }
    } else if (!sinkChannel.isWriteResumed()) {
      try {
        // TODO: this needs some more thought
        if (!sinkChannel.flush()) {
          sinkChannel.setWriteListener(
              new ChannelListener<ConduitStreamSinkChannel>() {
                @Override
                public void handleEvent(ConduitStreamSinkChannel channel) {
                  try {
                    if (channel.flush()) {
                      channel.suspendWrites();
                    }
                  } catch (IOException e) {
                    handleError(e);
                  }
                }
              });
          sinkChannel.resumeWrites();
        }
      } catch (IOException e) {
        handleError(e);
      }
    }
  }