Esempio n. 1
0
  @Override
  public void sendRequest(ClientRequest request, ClientCallback<ClientExchange> clientCallback) {
    request.getRequestHeaders().put(PATH, request.getPath());
    request.getRequestHeaders().put(SCHEME, "https");
    request.getRequestHeaders().put(VERSION, request.getProtocol().toString());
    request.getRequestHeaders().put(METHOD, request.getMethod().toString());
    request.getRequestHeaders().put(HOST, request.getRequestHeaders().getFirst(Headers.HOST));
    request.getRequestHeaders().remove(Headers.HOST);

    SpdySynStreamStreamSinkChannel sinkChannel;
    try {
      sinkChannel = spdyChannel.createStream(request.getRequestHeaders());
    } catch (IOException e) {
      clientCallback.failed(e);
      return;
    }
    SpdyClientExchange exchange = new SpdyClientExchange(this, sinkChannel, request);
    currentExchanges.put(sinkChannel.getStreamId(), exchange);

    boolean hasContent = true;

    String fixedLengthString = request.getRequestHeaders().getFirst(CONTENT_LENGTH);
    String transferEncodingString = request.getRequestHeaders().getLast(TRANSFER_ENCODING);
    if (fixedLengthString != null) {
      try {
        long length = Long.parseLong(fixedLengthString);
        hasContent = length != 0;
      } catch (NumberFormatException e) {
        handleError(new IOException(e));
        return;
      }
    } else if (transferEncodingString == null) {
      hasContent = false;
    }
    if (clientCallback != null) {
      clientCallback.completed(exchange);
    }
    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
              .getWriteSetter()
              .set(
                  ChannelListeners.flushingChannelListener(
                      null,
                      new ChannelExceptionHandler<StreamSinkChannel>() {
                        @Override
                        public void handleException(
                            StreamSinkChannel channel, IOException exception) {
                          handleError(exception);
                        }
                      }));
          sinkChannel.resumeWrites();
        }
      } catch (IOException e) {
        handleError(e);
      }
    } else if (!sinkChannel.isWriteResumed()) {
      try {
        // TODO: this needs some more thought
        if (!sinkChannel.flush()) {
          sinkChannel
              .getWriteSetter()
              .set(
                  new ChannelListener<StreamSinkChannel>() {
                    @Override
                    public void handleEvent(StreamSinkChannel channel) {
                      try {
                        if (channel.flush()) {
                          channel.suspendWrites();
                        }
                      } catch (IOException e) {
                        handleError(e);
                      }
                    }
                  });
          sinkChannel.resumeWrites();
        }
      } catch (IOException e) {
        handleError(e);
      }
    }
  }