@Converter public static String toString(FullHttpResponse response, Exchange exchange) { String contentType = response.headers().get(Exchange.CONTENT_TYPE); String charset = NettyHttpHelper.getCharsetFromContentType(contentType); if (charset == null && exchange != null) { charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class); } if (charset != null) { return response.content().toString(Charset.forName(charset)); } else { return response.content().toString(Charset.defaultCharset()); } }
private static void sendListing(ChannelHandlerContext ctx, File dir) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK); response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); StringBuilder buf = new StringBuilder(); String dirPath = dir.getPath(); buf.append("<!DOCTYPE html>\r\n"); buf.append("<html><head><title>"); buf.append(dirPath); buf.append(" 目录:"); buf.append("</title></head><body>\r\n"); buf.append("<h3>"); buf.append(dirPath).append(" 目录:"); buf.append("</h3>\r\n"); buf.append("<ul>"); buf.append("<li>链接:<a href=\"../\">..</a></li>\r\n"); for (File f : dir.listFiles()) { if (f.isHidden() || !f.canRead()) { continue; } String name = f.getName(); if (!ALLOWED_FILE_NAME.matcher(name).matches()) { continue; } buf.append("<li>链接:<a href=\""); buf.append(name); buf.append("\">"); buf.append(name); buf.append("</a></li>\r\n"); } buf.append("</ul></body></html>\r\n"); ByteBuf buffer = Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8); response.content().writeBytes(buffer); buffer.release(); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); }
@SuppressWarnings("argument.type.incompatible") private void sendFullResponse( ChannelHandlerContext ctx, FullHttpRequest request, FullHttpResponse response) throws Exception { boolean keepAlive = HttpUtil.isKeepAlive(request); if (httpSessionManager.getSessionId(request) != null && httpSessionManager.getAuthenticatedUser(request) == null && !response.headers().contains("Set-Cookie")) { httpSessionManager.deleteSessionCookie(response); } response.headers().add("Glowroot-Layout-Version", layoutService.getLayoutVersion()); if (response.headers().contains("Glowroot-Port-Changed")) { // current connection is the only open channel on the old port, keepAlive=false will add // the listener below to close the channel after the response completes // // remove the hacky header, no need to send it back to client response.headers().remove("Glowroot-Port-Changed"); response.headers().add("Connection", "close"); keepAlive = false; } response.headers().add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); if (keepAlive && !request.protocolVersion().isKeepAliveDefault()) { response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); } ChannelFuture f = ctx.write(response); if (!keepAlive) { f.addListener(ChannelFutureListener.CLOSE); } }
private static void sendHttpResponse( ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) { // Generate an error page if response getStatus code is not OK (200). if (res.getStatus().code() != 200) { ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8); res.content().writeBytes(buf); buf.release(); HttpHeaders.setContentLength(res, res.content().readableBytes()); } // Send the response and close the connection if necessary. ChannelFuture f = ctx.channel().writeAndFlush(res); if (!HttpHeaders.isKeepAlive(req) || res.getStatus().code() != 200) { f.addListener(ChannelFutureListener.CLOSE); } }
@Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { Integer streamId = msg.headers().getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text()); if (streamId == null) { logger.error("HttpResponseHandler unexpected message received: " + msg); return; } onResponseReceived(ctx, streamIdUrlMap.get(streamId)); Map.Entry<ChannelFuture, ChannelPromise> entry = streamIdPromiseMap.get(streamId); if (entry == null) { logger.error("Message received for unknown stream id " + streamId); } else { // Do stuff with the message (for now just print it) ByteBuf content = msg.content(); ContentType contentType = ContentType.parse(msg.headers().get(HttpHeaderNames.CONTENT_TYPE)); if (content.isReadable()) { int contentLength = content.readableBytes(); byte[] arr = new byte[contentLength]; content.readBytes(arr); handleContent(arr, ctx, contentType); } entry.getValue().setSuccess(); } }
private void sendServerError(final ChannelHandlerContext ctx, final ServerException cause) throws Exception { if (ctx.channel().isActive()) { final ByteBuf content = Unpooled.buffer(); content.writeBytes( (cause.getStatus().code() + " " + cause.getStatus().reasonPhrase() + " - " + cause.getMessage()) .getBytes()); final FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, cause.getStatus()); response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, content.readableBytes()); response.content().writeBytes(content); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }
@Override public void failover(FullHttpRequest request, FullHttpResponse response) { Response dumpedResponse = failoverResponse(request); response.setProtocolVersion(HttpVersion.valueOf(dumpedResponse.getVersion())); response.setStatus(HttpResponseStatus.valueOf(dumpedResponse.getStatusCode())); for (Map.Entry<String, String> entry : dumpedResponse.getHeaders().entrySet()) { response.headers().add(entry.getKey(), entry.getValue()); } response.content().writeBytes(dumpedResponse.getContent().getBytes()); }
protected void setContent(FullHttpResponse response, int messageId) { response .headers() .set( HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8; " + "MessageId".toLowerCase() + "=" + messageId); response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes()); if (isKeepAlive) { response.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE); } }
@Override public void channelRead0(final ChannelHandlerContext c, Object msg) throws Exception { Channel ch = ctx.channel(); if (response == null) { if (msg instanceof FullHttpResponse) { response = (FullHttpResponse) msg; } else { response = new WSResponse((DefaultHttpResponse) msg, ctx.alloc().buffer()); } if (completeHandshake(ctx)) { return; } } if (msg instanceof LastHttpContent) { return; } if (!(msg instanceof WebSocketFrame)) { throw new Exception( "Unexpected FullHttpResponse (getStatus=" + response.getStatus() + ", " + "content=" + response.content().toString(CharsetUtil.UTF_8) + ')'); } final WebSocketFrame frame = (WebSocketFrame) msg; if (frame instanceof TextWebSocketFrame) { for (WebSocketEventListener l : listensers) { l.onMessage(c, new WebSocketMessage(((TextWebSocketFrame) frame).text())); } } else if (frame instanceof PingWebSocketFrame) { if (autoPong) { ctx.writeAndFlush(new PongWebSocketFrame(frame.content().copy())); } for (WebSocketEventListener l : listensers) { l.onPing(c, (PingWebSocketFrame) frame.copy()); } } else if (frame instanceof PongWebSocketFrame) { Logger.getLogger(getClass()) .warn( String.format( "WebSocketClient received a PongWebSocketFrame, that shouldn't happen! Data : %s", frame.content().toString(CharsetUtil.UTF_8))); } else if (frame instanceof CloseWebSocketFrame) { ch.close(); for (WebSocketEventListener l : listensers) { l.onClose(c, (CloseWebSocketFrame) frame.copy()); } } }
@Override protected void encode(ChannelHandlerContext ctx, Query msg, List<Object> out) throws Exception { FullHttpResponse response = null; if (msg.isSuccessfull()) { switch (msg.getType()) { case WRITE: case DELETE: response = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(CONTENT)); response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "octet-stream"); response .headers() .set(HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes()); break; case READ: response = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(msg.getValue())); response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "octet-stream"); response .headers() .set(HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes()); break; default: break; } } else { response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NO_CONTENT); } _LOG.debug("Query encoded"); out.add(response); }
@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { logger.info("StringEncoder response to client."); String serverMsg = (String) msg; FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(serverMsg.getBytes())); response.headers().set(CONTENT_TYPE, "text/plain"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); response.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.write(response); ctx.flush(); }
/** * Send an error and close * * @param ctx * @param status */ private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { responseContent.setLength(0); responseContent.append(error(status.toString())); FullHttpResponse response = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer(responseContent.toString(), WaarpStringUtils.UTF8)); response.headers().add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html"); responseContent.setLength(0); clearSession(); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(WaarpSslUtility.SSLCLOSE); }
@Override protected HttpResponse createResponseObject() { boolean keepAlive = HttpHeaders.isKeepAlive(request); FullHttpResponse response = new DefaultFullHttpResponse( HTTP_1_1, OK, Unpooled.copiedBuffer(MESSAGE, CharsetUtil.UTF_8)); response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); if (keepAlive) { response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } return response; }
private void sendResponse( ChannelHandlerContext channel, FullHttpRequest request, String messageBody, HttpResponseStatus status) { FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status); if (messageBody != null && !messageBody.isEmpty()) { response.content().writeBytes(Unpooled.copiedBuffer(messageBody, Constants.DEFAULT_CHARSET)); } HttpResponder.respond(channel, request, response); Tracker.getInstance().trackResponse(request, response); }
@Override public void messageReceived(ChannelHandlerContext ctx, HttpRequest req) throws Exception { if (is100ContinueExpected(req)) { ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); } boolean keepAlive = isKeepAlive(req); ByteBuf content = ctx.alloc().buffer(); content.writeBytes(HelloWorldHttp2Handler.RESPONSE_BYTES); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); if (!keepAlive) { ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.writeAndFlush(response); } }
@Override protected void decode(ChannelHandlerContext ctx, FullHttpResponse response, List<Object> out) throws Exception { String protostuffJavaMessageType = response.headers().get(HttpProtostuffConstants.PROTOSTUFF_HEADER_NAME); // All of these may throw exceptions, use netty default handling Class<?> protostuffClass = Class.forName(protostuffJavaMessageType); Schema<Message<?>> protostuffSchemaInstance = (Schema<Message<?>>) protostuffClass.newInstance(); Message<?> resultingMessage = protostuffSchemaInstance.newMessage(); // TODO do we do anything with HTTP status? ByteBuffer content = response.content().nioBuffer(); ByteBufferInput protostuffDecoder = new ByteBufferInput(content, false); protostuffSchemaInstance.mergeFrom(protostuffDecoder, resultingMessage); out.add(resultingMessage); }
/** 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(); } }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if (msg instanceof HttpRequest) { HttpRequest req = (HttpRequest) msg; if (HttpHeaders.is100ContinueExpected(req)) { ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); } boolean keepAlive = HttpHeaders.isKeepAlive(req); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT)); response.headers().set(CONTENT_TYPE, "text/plain"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.write(response); } } }
@Override public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof HttpRequest) { HttpRequest req = (HttpRequest) msg; if (is100ContinueExpected(req)) { ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); } boolean keepAlive = isKeepAlive(req); ByteBuf content = RESPONSE_BYTES.duplicate(); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content); response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.write(response); } } }
@Override protected ByteBuf extractResponse(Object message) throws XioException { if (!(message instanceof HttpObject)) { return null; } FullHttpResponse httpResponse = null; // HttpContent httpContent = null; // ByteBuf content = null; // XioClientChannel xioClientChannel; if (message instanceof FullHttpResponse) { httpResponse = (FullHttpResponse) message; // content = httpResponse.content(); // if (message instanceof LastHttpContent) { // LastHttpContent lastHttpContent = (LastHttpContent) message; // if (lastHttpContent.toString().equals("EmptyLastHttpContent")) { // ((LastHttpContent) message).release(); // } // } // if (message instanceof HttpContent) { // httpContent = (HttpContent) message; // // if (httpContent.getDecoderResult() == DecoderResult.SUCCESS) { // content = httpContent.content(); // } // // if (content != null) { // if (!content.isReadable()) { // log.error("Message Delivered with Unreadable Content"); // } // } // } // TODO(JR): Leave out for testing, ADD BACK BEFORE DEPLOYMENT!!!!! // switch (httpResponse.getStatus().reasonPhrase()) { // case("Unknown Status"): // throw wrapException(new XioTransportException("HTTP response had non-OK status: " // + httpResponse // .getStatus().toString())); // case("Informational"): // break; // case("Successful"): // break; // case("Redirection"): // break; // case("Client Error"): // throw wrapException(new XioTransportException("HTTP response had non-OK status: " // + httpResponse // .getStatus().toString())); // } // HttpContent httpContent = (HttpContent) httpResponse; String CRLF = "\r\n"; StringBuilder responseHeader = new StringBuilder(); responseHeader .append(httpResponse.getProtocolVersion()) .append(' ') .append(httpResponse.getStatus()) .append(CRLF); httpResponse .headers() .entries() .forEach( xs -> { responseHeader.append(xs.getKey()).append(": ").append(xs.getValue()).append(CRLF); }); responseHeader.append(CRLF); ByteBuf headerAndBody = getCtx().alloc().buffer(); headerAndBody.writeBytes(responseHeader.toString().getBytes(Charset.defaultCharset())); if (httpResponse.content() != null) { headerAndBody.writeBytes(httpResponse.content()); headerAndBody.writeBytes("\r\n".getBytes()); } return headerAndBody; } else { return null; } }
@Converter public static InputStream toInputStream(FullHttpResponse response, Exchange exchange) { return NettyConverter.toInputStream(response.content(), exchange); }
@Converter public static byte[] toBytes(FullHttpResponse response, Exchange exchange) { return NettyConverter.toByteArray(response.content(), exchange); }