io.netty.handler.codec.http.HttpObject Java Examples

The following examples show how to use io.netty.handler.codec.http.HttpObject. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ServerResponseCaptureFilter.java    From Dream-Catcher with MIT License 6 votes vote down vote up
@Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
    if (httpObject instanceof HttpResponse) {
        httpResponse = (HttpResponse) httpObject;
        captureContentEncoding(httpResponse);
    }

    if (httpObject instanceof HttpContent) {
        HttpContent httpContent = (HttpContent) httpObject;

        storeResponseContent(httpContent);

        if (httpContent instanceof LastHttpContent) {
            LastHttpContent lastContent = (LastHttpContent) httpContent;
            captureTrailingHeaders(lastContent);

            captureFullResponseContents();
        }
    }

    return super.serverToProxyResponse(httpObject);
}
 
Example #2
Source File: BrowserMobHttpFilterChain.java    From Dream-Catcher with MIT License 6 votes vote down vote up
@Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
    HttpObject processedHttpObject = httpObject;

    for (HttpFilters filter : filters) {
        try {
            processedHttpObject = filter.serverToProxyResponse(processedHttpObject);
            if (processedHttpObject == null) {
                return null;
            }
        } catch (RuntimeException e) {
            log.warn("Filter in filter chain threw exception. Filter method may have been aborted.", e);
        }
    }

    return processedHttpObject;
}
 
Example #3
Source File: RequestFilterAdapter.java    From browserup-proxy with Apache License 2.0 6 votes vote down vote up
@Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
    // only filter when the original HttpRequest comes through. the RequestFilterAdapter is not designed to filter
    // any subsequent HttpContents.
    if (httpObject instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) httpObject;

        HttpMessageContents contents;
        if (httpObject instanceof FullHttpMessage) {
            FullHttpMessage httpContent = (FullHttpMessage) httpObject;
            contents = new HttpMessageContents(httpContent);
        } else {
            // the HTTP object is not a FullHttpMessage, which means that message contents are not available on this request and cannot be modified.
            contents = null;
        }

        HttpMessageInfo messageInfo = new HttpMessageInfo(originalRequest, ctx, isHttps(), getFullUrl(httpRequest), getOriginalUrl());

        HttpResponse response = requestFilter.filterRequest(httpRequest, contents, messageInfo);
        if (response != null) {
            return response;
        }
    }

    return null;
}
 
Example #4
Source File: ClientChannelHandler.java    From flashback with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject)
    throws Exception {
  // initial request
  if (LOG.isDebugEnabled()) {
    LOG.debug(String.format("%s: Reading from client %s", System.currentTimeMillis(), httpObject));
  }
  if (httpObject instanceof HttpRequest) {
    HttpRequest initialRequest = (HttpRequest) httpObject;
    if (_channelHandlerDelegate == null) {
      _channelHandlerDelegate =
          HandlerDelegateFactory.create(initialRequest, _channelMediator, _connectionFlowRegistry);
      _channelHandlerDelegate.onCreate();
    }
  }
  _channelHandlerDelegate.onRead(httpObject);
}
 
Example #5
Source File: BlacklistFilter.java    From browserup-proxy with Apache License 2.0 6 votes vote down vote up
@Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
    if (httpObject instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) httpObject;

        String url = getFullUrl(httpRequest);

        for (BlacklistEntry entry : blacklistedUrls) {
            if (HttpMethod.CONNECT.equals(httpRequest.getMethod()) && entry.getHttpMethodPattern() == null) {
                // do not allow CONNECTs to be blacklisted unless a method pattern is explicitly specified
                continue;
            }

            if (entry.matches(url, httpRequest.getMethod().name())) {
                HttpResponseStatus status = HttpResponseStatus.valueOf(entry.getStatusCode());
                HttpResponse resp = new DefaultFullHttpResponse(httpRequest.getProtocolVersion(), status);
                HttpHeaders.setContentLength(resp, 0L);

                return resp;
            }
        }
    }

    return null;
}
 
Example #6
Source File: ApiRequestParser.java    From netty.book.kor with MIT License 6 votes vote down vote up
private boolean writeResponse(HttpObject currentObj, ChannelHandlerContext ctx) {
    // Decide whether to close the connection or not.
    boolean keepAlive = HttpHeaders.isKeepAlive(request);
    // Build the response object.
    FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1,
            currentObj.getDecoderResult().isSuccess() ? OK : BAD_REQUEST, Unpooled.copiedBuffer(
                    apiResult.toString(), CharsetUtil.UTF_8));

    response.headers().set(CONTENT_TYPE, "application/json; charset=UTF-8");

    if (keepAlive) {
        // Add 'Content-Length' header only for a keep-alive connection.
        response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
        // Add keep alive header as per:
        // -
        // http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection
        response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
    }

    // Write the response.
    ctx.write(response);

    return keepAlive;
}
 
Example #7
Source File: ServerResponseCaptureFilter.java    From AndroidHttpCapture with MIT License 6 votes vote down vote up
@Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
    if (httpObject instanceof HttpResponse) {
        httpResponse = (HttpResponse) httpObject;
        captureContentEncoding(httpResponse);
    }

    if (httpObject instanceof HttpContent) {
        HttpContent httpContent = (HttpContent) httpObject;

        storeResponseContent(httpContent);

        if (httpContent instanceof LastHttpContent) {
            LastHttpContent lastContent = (LastHttpContent) httpContent;
            captureTrailingHeaders(lastContent);

            captureFullResponseContents();
        }
    }

    return super.serverToProxyResponse(httpObject);
}
 
Example #8
Source File: HttpsHostCaptureFilter.java    From AndroidHttpCapture with MIT License 6 votes vote down vote up
@Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
    if (httpObject instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) httpObject;

        if (ProxyUtils.isCONNECT(httpRequest)) {
            Attribute<String> hostname = ctx.attr(AttributeKey.<String>valueOf(HttpsAwareFiltersAdapter.HOST_ATTRIBUTE_NAME));
            String hostAndPort = httpRequest.getUri();

            // CONNECT requests contain the port, even when using the default port. a sensible default is to remove the
            // default port, since in most cases it is not explicitly specified and its presence (in a HAR file, for example)
            // would be unexpected.
            String hostNoDefaultPort = BrowserMobHttpUtil.removeMatchingPort(hostAndPort, 443);
            hostname.set(hostNoDefaultPort);
        }
    }

    return null;
}
 
Example #9
Source File: ClientToProxyConnection.java    From g4proxy with Apache License 2.0 6 votes vote down vote up
/**
 * This method takes care of closing client to proxy and/or proxy to server
 * connections after finishing a write.
 */
private void closeConnectionsAfterWriteIfNecessary(
        ProxyToServerConnection serverConnection,
        HttpRequest currentHttpRequest, HttpResponse currentHttpResponse,
        HttpObject httpObject) {
    boolean closeServerConnection = shouldCloseServerConnection(
            currentHttpRequest, currentHttpResponse, httpObject);
    boolean closeClientConnection = shouldCloseClientConnection(
            currentHttpRequest, currentHttpResponse, httpObject);

    if (closeServerConnection) {
        LOG.debug("Closing remote connection after writing to client");
        serverConnection.disconnect();
    }

    if (closeClientConnection) {
        LOG.debug("Closing connection to client after writes");
        disconnect();
    }
}
 
Example #10
Source File: RecordController.java    From flashback with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public void handleReadFromClient(ChannelMediator channelMediator, HttpObject httpObject) {
  if (channelMediator == null) {
    throw new IllegalStateException("HRFC: ChannelMediator can't be null");
  }

  try {
    if (httpObject instanceof HttpRequest) {
      HttpRequest httpRequest = (HttpRequest) httpObject;
      _clientRequestBuilder.interpretHttpRequest(httpRequest);
      _clientRequestBuilder.addHeaders(httpRequest);
    }

    if (httpObject instanceof HttpContent) {
      _clientRequestBuilder.appendHttpContent((HttpContent) httpObject);
    }
  } catch (IOException e) {
    throw new RuntimeException("HRFC: Failed to record HttpContent", e);
  }

  channelMediator.writeToServer(httpObject);
}
 
Example #11
Source File: BrowserUpHttpFilterChain.java    From browserup-proxy with Apache License 2.0 6 votes vote down vote up
@Override
public HttpObject proxyToClientResponse(HttpObject httpObject) {
    HttpObject processedHttpObject = httpObject;
    for (HttpFilters filter : filters) {
        try {
            processedHttpObject = filter.proxyToClientResponse(processedHttpObject);
            if (processedHttpObject == null) {
                return null;
            }
        } catch (RuntimeException e) {
            log.warn("Filter in filter chain threw exception. Filter method may have been aborted.", e);
        }
    }

    return processedHttpObject;
}
 
Example #12
Source File: ServerResponseCaptureFilter.java    From CapturePacket with MIT License 6 votes vote down vote up
@Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
    if (httpObject instanceof HttpResponse) {
        httpResponse = (HttpResponse) httpObject;
        captureContentEncoding(httpResponse);
    }

    if (httpObject instanceof HttpContent) {
        HttpContent httpContent = (HttpContent) httpObject;

        storeResponseContent(httpContent);

        if (httpContent instanceof LastHttpContent) {
            LastHttpContent lastContent = (LastHttpContent) httpContent;
            captureTrailingHeaders(lastContent);

            captureFullResponseContents();
        }
    }

    return super.serverToProxyResponse(httpObject);
}
 
Example #13
Source File: BrowserMobHttpFilterChain.java    From CapturePacket with MIT License 6 votes vote down vote up
@Override
public HttpObject proxyToClientResponse(HttpObject httpObject) {
    HttpObject processedHttpObject = httpObject;
    for (HttpFilters filter : filters) {
        try {
            processedHttpObject = filter.proxyToClientResponse(processedHttpObject);
            if (processedHttpObject == null) {
                return null;
            }
        } catch (RuntimeException e) {
            log.warn("Filter in filter chain threw exception. Filter method may have been aborted.", e);
        }
    }

    return processedHttpObject;
}
 
Example #14
Source File: BlacklistFilter.java    From AndroidHttpCapture with MIT License 6 votes vote down vote up
@Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
    if (httpObject instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) httpObject;

        String url = getFullUrl(httpRequest);

        for (BlacklistEntry entry : blacklistedUrls) {
            if (HttpMethod.CONNECT.equals(httpRequest.getMethod()) && entry.getHttpMethodPattern() == null) {
                // do not allow CONNECTs to be blacklisted unless a method pattern is explicitly specified
                continue;
            }

            if (entry.matches(url, httpRequest.getMethod().name())) {
                HttpResponseStatus status = HttpResponseStatus.valueOf(entry.getStatusCode());
                HttpResponse resp = new DefaultFullHttpResponse(httpRequest.getProtocolVersion(), status);
                HttpHeaders.setContentLength(resp, 0L);

                return resp;
            }
        }
    }

    return null;
}
 
Example #15
Source File: HttpsHostCaptureFilter.java    From CapturePacket with MIT License 6 votes vote down vote up
@Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
    if (httpObject instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) httpObject;

        if (ProxyUtils.isCONNECT(httpRequest)) {
            Attribute<String> hostname = ctx.attr(AttributeKey.<String>valueOf(HttpsAwareFiltersAdapter.HOST_ATTRIBUTE_NAME));
            String hostAndPort = httpRequest.getUri();

            // CONNECT requests contain the port, even when using the default port. a sensible default is to remove the
            // default port, since in most cases it is not explicitly specified and its presence (in a HAR file, for example)
            // would be unexpected.
            String hostNoDefaultPort = BrowserMobHttpUtil.removeMatchingPort(hostAndPort, 443);
            hostname.set(hostNoDefaultPort);
        }
    }

    return null;
}
 
Example #16
Source File: LatencyFilter.java    From CapturePacket with MIT License 6 votes vote down vote up
@Override
public HttpObject proxyToClientResponse(HttpObject httpObject) {
    if (httpObject instanceof HttpResponse) {
        if (latencyMs > 0) {
            try {
                TimeUnit.MILLISECONDS.sleep(latencyMs);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();

                log.warn("Interrupted while adding latency to response", e);
            }
        }
    }

    return super.proxyToClientResponse(httpObject);
}
 
Example #17
Source File: BrowserMobHttpFilterChain.java    From AndroidHttpCapture with MIT License 6 votes vote down vote up
@Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
    HttpObject processedHttpObject = httpObject;

    for (HttpFilters filter : filters) {
        try {
            processedHttpObject = filter.serverToProxyResponse(processedHttpObject);
            if (processedHttpObject == null) {
                return null;
            }
        } catch (RuntimeException e) {
            log.warn("Filter in filter chain threw exception. Filter method may have been aborted.", e);
        }
    }

    return processedHttpObject;
}
 
Example #18
Source File: CustomHttpServerHandler.java    From tutorials with MIT License 6 votes vote down vote up
private void writeResponse(ChannelHandlerContext ctx, LastHttpContent trailer, StringBuilder responseData) {
    boolean keepAlive = HttpUtil.isKeepAlive(request);

    FullHttpResponse httpResponse = new DefaultFullHttpResponse(HTTP_1_1, ((HttpObject) trailer).decoderResult()
        .isSuccess() ? OK : BAD_REQUEST, Unpooled.copiedBuffer(responseData.toString(), CharsetUtil.UTF_8));

    httpResponse.headers()
        .set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");

    if (keepAlive) {
        httpResponse.headers()
            .setInt(HttpHeaderNames.CONTENT_LENGTH, httpResponse.content()
                .readableBytes());
        httpResponse.headers()
            .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
    }

    ctx.write(httpResponse);

    if (!keepAlive) {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
            .addListener(ChannelFutureListener.CLOSE);
    }
}
 
Example #19
Source File: HttpServerLiveTest.java    From tutorials with MIT License 6 votes vote down vote up
@Before
public void setup() throws Exception {
    Bootstrap b = new Bootstrap();
    b.group(group)
        .channel(NioSocketChannel.class)
        .handler(new ChannelInitializer<SocketChannel>() {

            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline p = ch.pipeline();
                p.addLast(new HttpClientCodec());
                p.addLast(new HttpContentDecompressor());
                p.addLast(new SimpleChannelInboundHandler<HttpObject>() {
                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
                        response = prepareResponse(ctx, msg, response);
                    }
                });
            }
        });

    channel = b.connect(HOST, PORT)
        .sync()
        .channel();
}
 
Example #20
Source File: RequestInfoSetterHandlerTest.java    From riposte with Apache License 2.0 6 votes vote down vote up
@Test
public void doChannelRead_checks_for_fully_send_responses_but_does_nothing_else_if_msg_is_not_HttpRequest_or_HttpContent() {
    // given
    HttpObject msgMock = mock(HttpObject.class);

    // when
    PipelineContinuationBehavior result = handler.doChannelRead(ctxMock, msgMock);

    // then
    verify(ctxMock, times(2)).channel();
    verifyNoMoreInteractions(ctxMock);
    verify(stateMock).isResponseSendingLastChunkSent();
    verifyNoMoreInteractions(stateMock);
    verifyNoMoreInteractions(msgMock);
    assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE);
}
 
Example #21
Source File: HttpDownloader.java    From netty-cookbook with Apache License 2.0 6 votes vote down vote up
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
	try {
		if (msg instanceof HttpRequest) {
			initFileChannel();
		} else if (msg instanceof HttpContent) {
			if (fileChnl == null) {
				initFileChannel();
			}
			ByteBuf byteBuf = ((HttpContent) msg).content();
			writeBytesToFile(byteBuf);
		} else if (msg instanceof LastHttpContent) {
			if (fileChnl != null && outStream != null) {
				fileChnl.close();
				outStream.close();
			}
			ctx.close();
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}
 
Example #22
Source File: RiposteHandlerInternalUtil.java    From riposte with Apache License 2.0 6 votes vote down vote up
Throwable getDecoderFailure(HttpObject httpObject) {
    if (httpObject == null) {
        return null;
    }

    DecoderResult decoderResult = httpObject.decoderResult();
    if (decoderResult == null) {
        return null;
    }

    if (!decoderResult.isFailure()) {
        return null;
    }

    return decoderResult.cause();
}
 
Example #23
Source File: ComponentTestUtils.java    From riposte with Apache License 2.0 6 votes vote down vote up
public static Bootstrap createNettyHttpClientBootstrap() {
    Bootstrap bootstrap = new Bootstrap();
    bootstrap.group(new NioEventLoopGroup())
             .channel(NioSocketChannel.class)
             .handler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 protected void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                     p.addLast(new HttpClientCodec());
                     p.addLast(new HttpObjectAggregator(Integer.MAX_VALUE));
                     p.addLast("clientResponseHandler", new SimpleChannelInboundHandler<HttpObject>() {
                         @Override
                         protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
                             throw new RuntimeException("Client response handler was not setup before the call");
                         }
                     });
                 }
             });

    return bootstrap;
}
 
Example #24
Source File: HttpsChannelHandlerDelegate.java    From flashback with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
public void onRead(HttpObject httpObject) {
  // Drop initial Connection request.
  // Basically,CONNECT request will be sliced to two parts: HttpRequest and LastContent(empty content to indicate end of
  // this request). This HttpRequest is only used to indicates that it's time to build tunnel between client and server.
  // It invokes Connection flow to build two tunnels: between client to proxy and proxy to server.
  // After that, both HttpRequest and HttpLastContent is useless, that's why they are get dropped.
  // Only after connection flow is complete, we start reading and processing incoming request from client
  if (_connectionFlowProcessor.isComplete()) {
    _channelMediator.readFromClientChannel(httpObject);
  }
}
 
Example #25
Source File: Http1ClientCodec.java    From xio with Apache License 2.0 5 votes vote down vote up
Response wrapResponse(ChannelHandlerContext ctx, HttpObject msg) {
  log.debug("wrapResponse msg={}", msg);
  final Response response;
  if (msg instanceof FullHttpResponse) {
    response = new FullHttp1Response((FullHttpResponse) msg);
  } else if (msg instanceof HttpResponse) {
    response = new SegmentedHttp1Response((HttpResponse) msg);
  } else if (msg instanceof HttpContent) {
    response =
        getProxyRequestQueue(ctx)
            .currentResponse()
            .map(r -> new SegmentedResponseData(r, new Http1SegmentedData((HttpContent) msg)))
            .orElse(null);
  } else {
    // TODO(CK): throw an exception if response is null?
    response = null;
  }

  return getProxyRequestQueue(ctx)
      .currentProxiedH2StreamId()
      .<Response>map(
          streamId -> {
            if (response instanceof SegmentedResponseData) {
              return new ProxySegmentedResponseData((SegmentedResponseData) response, streamId);
            } else {
              return new ProxyResponse(response, streamId);
            }
          })
      .orElse(response);
}
 
Example #26
Source File: UnregisterRequestFilter.java    From Dream-Catcher with MIT License 5 votes vote down vote up
@Override
public HttpObject proxyToClientResponse(HttpObject httpObject) {
    if (httpObject instanceof LastHttpContent) {
        activityMonitor.requestFinished();
    }

    return super.proxyToClientResponse(httpObject);
}
 
Example #27
Source File: HttpSnoopServerHandler.java    From tools-journey with Apache License 2.0 5 votes vote down vote up
private boolean writeResponse(HttpObject currentObj, ChannelHandlerContext ctx) {
    // Decide whether to close the connection or not.
    boolean keepAlive = HttpUtil.isKeepAlive(request);
    // Build the response object.
    FullHttpResponse response = new DefaultFullHttpResponse(
            HTTP_1_1, currentObj.decoderResult().isSuccess()? OK : BAD_REQUEST,
            Unpooled.copiedBuffer(buf.toString(), CharsetUtil.UTF_8));

    response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");

    if (keepAlive) {
        // Add 'Content-Length' header only for a keep-alive connection.
        response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
        // Add keep alive header as per:
        // - http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection
        response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
    }

    // Encode the cookie.
    String cookieString = request.headers().get(HttpHeaderNames.COOKIE);
    if (cookieString != null) {
        Set<Cookie> cookies = ServerCookieDecoder.STRICT.decode(cookieString);
        if (!cookies.isEmpty()) {
            // Reset the cookies if necessary.
            for (Cookie cookie: cookies) {
                response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));
            }
        }
    } else {
        // Browser sent no cookie.  Add some.
        response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode("key1", "value1"));
        response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode("key2", "value2"));
    }

    // Write the response.
    ctx.write(response);

    return keepAlive;
}
 
Example #28
Source File: RiposteHandlerInternalUtil.java    From riposte with Apache License 2.0 5 votes vote down vote up
void throwExceptionIfNotSuccessfullyDecoded(HttpObject httpObject) {
    Throwable decoderFailure = getDecoderFailure(httpObject);
    if (decoderFailure == null) {
        return;
    }

    throw new InvalidHttpRequestException(
        "Detected HttpObject that was not successfully decoded.", decoderFailure
    );
}
 
Example #29
Source File: HttpSnoopServerHandler.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
private static void appendDecoderResult(StringBuilder buf, HttpObject o) {
    DecoderResult result = o.getDecoderResult();
    if (result.isSuccess()) {
        return;
    }

    buf.append(".. WITH DECODER FAILURE: ");
    buf.append(result.cause());
    buf.append("\r\n");
}
 
Example #30
Source File: ServerChannelHandler.java    From flashback with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject)
    throws Exception {
  _channelMediator.readFromServerChannel(httpObject);
  if (httpObject instanceof DefaultLastHttpContent) {
    _channelMediator.writeToClientAndDisconnect(httpObject);
  } else {
    _channelMediator.writeToClient(httpObject);
  }
}