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; } } }
@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); } }