@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { HttpRequest request = (HttpRequest) e.getMessage(); if (request.getContent().readableBytes() == 0) { BaseTransport.respond(e.getChannel(), INTERNAL_SERVER_ERROR, "Payload expected."); return; } transportMetrics.messagesReceived.mark(); transportMetrics.messagesReceivedSize.update(request.getContent().readableBytes()); // logger.debug("Received {}", request.getContent().toString(CharsetUtil.UTF_8)); String contentTypeHeader = request.getHeader(CONTENT_TYPE); if (contentTypeHeader == null) { contentTypeHeader = BaseTransport.CONTENT_TYPE_PLAIN; } String decodedContent; if (BaseTransport.CONTENT_TYPE_FORM.equals(contentTypeHeader)) { QueryStringDecoder decoder = new QueryStringDecoder("?" + request.getContent().toString(CharsetUtil.UTF_8)); List<String> d = decoder.getParameters().get("d"); if (d == null) { BaseTransport.respond(e.getChannel(), INTERNAL_SERVER_ERROR, "Payload expected."); return; } decodedContent = d.get(0); } else { decodedContent = request.getContent().toString(CharsetUtil.UTF_8); } if (decodedContent.length() == 0) { BaseTransport.respond(e.getChannel(), INTERNAL_SERVER_ERROR, "Payload expected."); return; } String[] messages = MAPPER.readValue(decodedContent, String[].class); for (String message : messages) { SockJsMessage jsMessage = new SockJsMessage(message); ctx.sendUpstream(new UpstreamMessageEvent(e.getChannel(), jsMessage, e.getRemoteAddress())); } if (isJsonpEnabled) { BaseTransport.respond(e.getChannel(), OK, "ok"); } else { BaseTransport.respond(e.getChannel(), NO_CONTENT, ""); } }
@Override public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent e) throws Exception { Logger.trace("messageReceived: begin"); final Object msg = e.getMessage(); // Http request if (msg instanceof HttpRequest) { final HttpRequest nettyRequest = (HttpRequest) msg; // Websocket upgrade if (HttpHeaders.Values.UPGRADE.equalsIgnoreCase(nettyRequest.getHeader(CONNECTION)) && HttpHeaders.Values.WEBSOCKET.equalsIgnoreCase( nettyRequest.getHeader(HttpHeaders.Names.UPGRADE))) { websocketHandshake(ctx, nettyRequest, e); return; } // Plain old HttpRequest try { final Request request = parseRequest(ctx, nettyRequest); final Response response = new Response(); Http.Response.current.set(response); // Buffered in memory output response.out = new ByteArrayOutputStream(); // Direct output (will be set later) response.direct = null; // Streamed output (using response.writeChunk) response.onWriteChunk( new Action<Object>() { public void invoke(Object result) { writeChunk(request, response, ctx, nettyRequest, result); } }); // Raw invocation boolean raw = false; for (PlayPlugin plugin : Play.plugins) { if (plugin.rawInvocation(request, response)) { raw = true; break; } } if (raw) { copyResponse(ctx, request, response, nettyRequest); } else { // Deleguate to Play framework Invoker.invoke(new NettyInvocation(request, response, ctx, nettyRequest, e)); } } catch (Exception ex) { serve500(ex, ctx, nettyRequest); } } // Websocket frame if (msg instanceof WebSocketFrame) { WebSocketFrame frame = (WebSocketFrame) msg; websocketFrameReceived(ctx, frame); } Logger.trace("messageReceived: end"); }
public void serveStatic( RenderStatic renderStatic, ChannelHandlerContext ctx, Request request, Response response, HttpRequest nettyRequest, MessageEvent e) { Logger.trace("serveStatic: begin"); HttpResponse nettyResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(response.status)); if (exposePlayServer) { nettyResponse.setHeader(SERVER, signature); } try { VirtualFile file = Play.getVirtualFile(renderStatic.file); if (file != null && file.exists() && file.isDirectory()) { file = file.child("index.html"); if (file != null) { renderStatic.file = file.relativePath(); } } if ((file == null || !file.exists())) { serve404( new NotFound("The file " + renderStatic.file + " does not exist"), ctx, request, nettyRequest); } else { boolean raw = false; for (PlayPlugin plugin : Play.plugins) { if (plugin.serveStatic(file, Request.current(), Response.current())) { raw = true; break; } } if (raw) { copyResponse(ctx, request, response, nettyRequest); } else { final File localFile = file.getRealFile(); final boolean keepAlive = isKeepAlive(nettyRequest); nettyResponse = addEtag(nettyRequest, nettyResponse, localFile); if (nettyResponse.getStatus().equals(HttpResponseStatus.NOT_MODIFIED)) { Channel ch = e.getChannel(); // Write the initial line and the header. ChannelFuture writeFuture = ch.write(nettyResponse); if (!keepAlive) { // Write the content. writeFuture.addListener(ChannelFutureListener.CLOSE); } } else { final RandomAccessFile raf = new RandomAccessFile(localFile, "r"); try { long fileLength = raf.length(); Logger.trace("keep alive " + keepAlive); Logger.trace( "content type " + (MimeTypes.getContentType(localFile.getName(), "text/plain"))); if (keepAlive && !nettyResponse.getStatus().equals(HttpResponseStatus.NOT_MODIFIED)) { // Add 'Content-Length' header only for a keep-alive connection. Logger.trace("file length " + fileLength); setContentLength(nettyResponse, fileLength); } nettyResponse.setHeader( CONTENT_TYPE, (MimeTypes.getContentType(localFile.getName(), "text/plain"))); Channel ch = e.getChannel(); // Write the initial line and the header. ChannelFuture writeFuture = ch.write(nettyResponse); // Write the content. if (!nettyRequest.getMethod().equals(HttpMethod.HEAD)) { writeFuture = ch.write(new ChunkedFile(raf, 0, fileLength, 8192)); } else { raf.close(); } if (!keepAlive) { // Close the connection when the whole content is written out. writeFuture.addListener(ChannelFutureListener.CLOSE); } } catch (Throwable exx) { try { raf.close(); } catch (Throwable ex) { /* Left empty */ } try { ctx.getChannel().close(); } catch (Throwable ex) { /* Left empty */ } } } } } } catch (Throwable ez) { Logger.error(ez, "serveStatic for request %s", request.method + " " + request.url); try { HttpResponse errorResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR); ChannelBuffer buf = ChannelBuffers.copiedBuffer("Internal Error (check logs)".getBytes("utf-8")); errorResponse.setContent(buf); ChannelFuture future = ctx.getChannel().write(errorResponse); future.addListener(ChannelFutureListener.CLOSE); } catch (Exception ex) { Logger.error(ez, "serveStatic for request %s", request.method + " " + request.url); } } Logger.trace("serveStatic: end"); }