private void encodeChunkedContent(
      ChannelHandlerContext ctx, Object msg, int contentLength, List<Object> out) {
    if (contentLength > 0) {
      byte[] length = Integer.toHexString(contentLength).getBytes(CharsetUtil.US_ASCII);
      ByteBuf buf = ctx.alloc().buffer(length.length + 2);
      buf.writeBytes(length);
      buf.writeBytes(CRLF);
      out.add(buf);
      out.add(encodeAndRetain(msg));
      out.add(CRLF_BUF.duplicate());
    }

    if (msg instanceof LastHttpContent) {
      HttpHeaders headers = ((LastHttpContent) msg).trailingHeaders();
      if (headers.isEmpty()) {
        out.add(ZERO_CRLF_CRLF_BUF.duplicate());
      } else {
        ByteBuf buf = ctx.alloc().buffer();
        buf.writeBytes(ZERO_CRLF);
        HttpHeaders.encode(headers, buf);
        buf.writeBytes(CRLF);
        out.add(buf);
      }

      state = ST_INIT;
    } else {
      if (contentLength == 0) {
        // Need to produce some output otherwise an
        // IllegalstateException will be thrown
        out.add(EMPTY_BUFFER);
      }
    }
  }
  private void handleChunk(
      HttpContent chunk, //
      final Channel channel, //
      final NettyResponseFuture<?> future, //
      AsyncHandler<?> handler)
      throws IOException, Exception {

    boolean interrupt = false;
    boolean last = chunk instanceof LastHttpContent;

    // Netty 4: the last chunk is not empty
    if (last) {
      LastHttpContent lastChunk = (LastHttpContent) chunk;
      HttpHeaders trailingHeaders = lastChunk.trailingHeaders();
      if (!trailingHeaders.isEmpty()) {
        interrupt =
            handler.onHeadersReceived(new HttpResponseHeaders(trailingHeaders, true))
                != State.CONTINUE;
      }
    }

    ByteBuf buf = chunk.content();
    if (!interrupt
        && !(handler instanceof StreamedAsyncHandler)
        && (buf.readableBytes() > 0 || last)) {
      HttpResponseBodyPart part =
          config.getResponseBodyPartFactory().newResponseBodyPart(buf, last);
      interrupt = updateBodyAndInterrupt(future, handler, part);
    }

    if (interrupt || last) finishUpdate(future, channel, !last);
  }
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder(getUrl());

    sb.append("\t");
    sb.append(method);
    sb.append("\theaders:");
    if (!headers.isEmpty()) {
      for (Map.Entry<String, String> header : headers) {
        sb.append("\t");
        sb.append(header.getKey());
        sb.append(":");
        sb.append(header.getValue());
      }
    }
    if (isNonEmpty(formParams)) {
      sb.append("\tformParams:");
      for (Param param : formParams) {
        sb.append("\t");
        sb.append(param.getName());
        sb.append(":");
        sb.append(param.getValue());
      }
    }

    return sb.toString();
  }
  @Override
  protected void channelRead0(ChannelHandlerContext ctx, FullHttpMessage msg)
      throws Exception { // 1
    // Request header 처리
    if (msg instanceof HttpRequest) { // 2
      this.request = (HttpRequest) msg; // 3

      if (HttpHeaders.is100ContinueExpected(request)) {
        send100Continue(ctx);
      }

      HttpHeaders headers = request.headers(); // 4
      if (!headers.isEmpty()) {
        for (Map.Entry<String, String> h : headers) {
          String key = h.getKey();
          if (usingHeader.contains(key)) { // 5
            reqData.put(key, h.getValue()); // 6
          }
        }
      }

      reqData.put("REQUEST_URI", request.getUri()); // 7
      reqData.put("REQUEST_METHOD", request.getMethod().name()); // 8
    }

    if (msg instanceof HttpContent) { // 9
      HttpContent httpContent = (HttpContent) msg; // 10

      ByteBuf content = httpContent.content(); // 11

      if (msg instanceof LastHttpContent) { // 12
        System.out.println("LastHttpContent message received!!" + request.getUri());

        LastHttpContent trailer = (LastHttpContent) msg;

        readPostData(); // 13

        ApiRequest service = ServiceDispatcher.dispatch(reqData); // 14

        try {
          service.executeService(); // 15

          apiResult = service.getApiResult(); // 16
        } finally {
          reqData.clear();
        }

        if (!writeResponse(trailer, ctx)) { // 17
          ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
        }
        reset();
      }
    }
  }
  @Override
  public void handle(final Channel channel, final NettyResponseFuture<?> future, final Object e)
      throws Exception {
    future.touch();

    // The connect timeout occurred.
    if (future.isCancelled() || future.isDone()) {
      channels.finishChannel(channel);
      return;
    }

    NettyRequest nettyRequest = future.getNettyRequest();
    AsyncHandler<?> handler = future.getAsyncHandler();
    ProxyServer proxyServer = future.getProxyServer();
    try {
      if (e instanceof HttpResponse) {
        HttpResponse response = (HttpResponse) e;
        LOGGER.debug("\n\nRequest {}\n\nResponse {}\n", nettyRequest.getHttpRequest(), response);
        future.setPendingResponse(response);
        return;
      }

      if (e instanceof HttpContent) {
        HttpResponse response = future.getPendingResponse();
        future.setPendingResponse(null);
        if (handler != null) {
          if (response != null
              && handleResponseAndExit(
                  channel, future, handler, nettyRequest.getHttpRequest(), proxyServer, response)) {
            return;
          }

          HttpContent chunk = (HttpContent) e;

          boolean interrupt = false;
          boolean last = chunk instanceof LastHttpContent;

          if (last) {
            LastHttpContent lastChunk = (LastHttpContent) chunk;
            HttpHeaders trailingHeaders = lastChunk.trailingHeaders();
            if (!trailingHeaders.isEmpty()) {
              interrupt =
                  handler.onHeadersReceived(
                          new ResponseHeaders(
                              future.getURI(), future.getHttpHeaders(), trailingHeaders))
                      != STATE.CONTINUE;
            }
          }

          ByteBuf buf = chunk.content();
          try {
            if (!interrupt && (buf.readableBytes() > 0 || last)) {
              interrupt =
                  updateBodyAndInterrupt(
                      future,
                      handler,
                      nettyConfig.getBodyPartFactory().newResponseBodyPart(buf, last));
            }
          } finally {
            // FIXME we shouldn't need this, should we? But a leak was reported there without it?!
            buf.release();
          }

          if (interrupt || last) {
            finishUpdate(future, channel, !last);
          }
        }
      }
    } catch (Exception t) {
      if (hasIOExceptionFilters
          && t instanceof IOException
          && requestSender.applyIoExceptionFiltersAndReplayRequest(
              future, IOException.class.cast(t), channel)) {
        return;
      }

      try {
        channels.abort(future, t);
      } finally {
        finishUpdate(future, channel, false);
        throw t;
      }
    }
  }
Beispiel #6
0
  @Override
  protected void encode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out)
      throws Exception {

    boolean valid = false;
    boolean last = false;

    if (msg instanceof HttpRequest) {

      HttpRequest httpRequest = (HttpRequest) msg;
      SpdySynStreamFrame spdySynStreamFrame = createSynStreamFrame(httpRequest);
      out.add(spdySynStreamFrame);

      last = spdySynStreamFrame.isLast();
      valid = true;
    }
    if (msg instanceof HttpResponse) {

      HttpResponse httpResponse = (HttpResponse) msg;
      if (httpResponse.headers().contains(SpdyHttpHeaders.Names.ASSOCIATED_TO_STREAM_ID)) {
        SpdySynStreamFrame spdySynStreamFrame = createSynStreamFrame(httpResponse);
        last = spdySynStreamFrame.isLast();
        out.add(spdySynStreamFrame);
      } else {
        SpdySynReplyFrame spdySynReplyFrame = createSynReplyFrame(httpResponse);
        last = spdySynReplyFrame.isLast();
        out.add(spdySynReplyFrame);
      }

      valid = true;
    }
    if (msg instanceof HttpContent && !last) {

      HttpContent chunk = (HttpContent) msg;

      chunk.content().retain();
      SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(currentStreamId, chunk.content());
      spdyDataFrame.setLast(chunk instanceof LastHttpContent);
      if (chunk instanceof LastHttpContent) {
        LastHttpContent trailer = (LastHttpContent) chunk;
        HttpHeaders trailers = trailer.trailingHeaders();
        if (trailers.isEmpty()) {
          out.add(spdyDataFrame);
        } else {
          // Create SPDY HEADERS frame out of trailers
          SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(currentStreamId);
          for (Map.Entry<String, String> entry : trailers) {
            spdyHeadersFrame.headers().add(entry.getKey(), entry.getValue());
          }

          // Write HEADERS frame and append Data Frame
          out.add(spdyHeadersFrame);
          out.add(spdyDataFrame);
        }
      } else {
        out.add(spdyDataFrame);
      }

      valid = true;
    }

    if (!valid) {
      throw new UnsupportedMessageTypeException(msg);
    }
  }