@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof Http2Settings) { // Expected } else if (msg instanceof FullHttpResponse) { FullHttpResponse response = (FullHttpResponse) msg; final Invocation invocation = waitsHolder.poll(response); if (invocation != null) { final ServiceInvocationContext iCtx = invocation.invocationContext(); final SerializationFormat serializationFormat = iCtx.scheme().serializationFormat(); try { final Promise<FullHttpResponse> resultPromise = invocation.resultPromise(); if (HttpStatusClass.SUCCESS == response.status().codeClass() // No serialization indicates a raw HTTP protocol which should // have error responses returned. || serializationFormat == SerializationFormat.NONE) { iCtx.resolvePromise(resultPromise, response.retain()); } else { iCtx.rejectPromise( resultPromise, new InvalidResponseException("HTTP Response code: " + response.status())); } } finally { ReferenceCountUtil.release(msg); } } else { // if invocation not found, we just bypass message to next ctx.fireChannelRead(msg); } if (!isMultiplex && HttpHeaderValues.CLOSE.contentEqualsIgnoreCase( response.headers().get(HttpHeaderNames.CONNECTION))) { ctx.close(); } } else { try { throw new IllegalStateException("unexpected message type: " + msg); } finally { ReferenceCountUtil.release(msg); } } }
/** Write the response */ private void writeResponse(ChannelHandlerContext ctx) { // Convert the response content to a ByteBuf. ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(), WaarpStringUtils.UTF8); responseContent.setLength(0); // Decide whether to close the connection or not. boolean keepAlive = HttpUtil.isKeepAlive(request); boolean close = HttpHeaderValues.CLOSE.contentEqualsIgnoreCase( request.headers().get(HttpHeaderNames.CONNECTION)) || (!keepAlive) || forceClose; // Build the response object. FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf); response.headers().add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html"); if (keepAlive) { response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); } if (!close) { // There's no need to add 'Content-Length' header // if this is the last response. response.headers().set(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(buf.readableBytes())); } handleCookies(response); // Write the response. ChannelFuture future = ctx.writeAndFlush(response); // Close the connection after the write operation is done if necessary. if (close) { future.addListener(WaarpSslUtility.SSLCLOSE); } if (shutdown) { ChannelUtils.startShutdown(); } }