private static HttpResponse addEtag( HttpRequest nettyRequest, HttpResponse httpResponse, File file) { if (Play.mode == Play.Mode.DEV) { httpResponse.setHeader(CACHE_CONTROL, "no-cache"); } else { String maxAge = Play.configuration.getProperty("http.cacheControl", "3600"); if (maxAge.equals("0")) { httpResponse.setHeader(CACHE_CONTROL, "no-cache"); } else { httpResponse.setHeader(CACHE_CONTROL, "max-age=" + maxAge); } } boolean useEtag = Play.configuration.getProperty("http.useETag", "true").equals("true"); long last = file.lastModified(); final String etag = "\"" + last + "-" + file.hashCode() + "\""; if (!isModified(etag, last, nettyRequest)) { if (nettyRequest.getMethod().equals(HttpMethod.GET)) { httpResponse.setStatus(HttpResponseStatus.NOT_MODIFIED); } if (useEtag) { httpResponse.setHeader(ETAG, etag); } } else { httpResponse.setHeader(LAST_MODIFIED, Utils.getHttpDateFormatter().format(new Date(last))); if (useEtag) { httpResponse.setHeader(ETAG, etag); } } return httpResponse; }
protected static void addToResponse(Response response, HttpResponse nettyResponse) { Map<String, Http.Header> headers = response.headers; for (Map.Entry<String, Http.Header> entry : headers.entrySet()) { Http.Header hd = entry.getValue(); for (String value : hd.values) { nettyResponse.setHeader(entry.getKey(), value); } } Map<String, Http.Cookie> cookies = response.cookies; for (Http.Cookie cookie : cookies.values()) { CookieEncoder encoder = new CookieEncoder(true); Cookie c = new DefaultCookie(cookie.name, cookie.value); c.setSecure(cookie.secure); c.setPath(cookie.path); if (cookie.domain != null) { c.setDomain(cookie.domain); } if (cookie.maxAge != null) { c.setMaxAge(cookie.maxAge); } c.setHttpOnly(cookie.httpOnly); encoder.addCookie(c); nettyResponse.addHeader(SET_COOKIE, encoder.encode()); } if (!response.headers.containsKey(CACHE_CONTROL)) { nettyResponse.setHeader(CACHE_CONTROL, "no-cache"); } }
public static void serve404( NotFound e, ChannelHandlerContext ctx, Request request, HttpRequest nettyRequest) { Logger.trace("serve404: begin"); HttpResponse nettyResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND); nettyResponse.setHeader(SERVER, signature); nettyResponse.setHeader(CONTENT_TYPE, "text/html"); Map<String, Object> binding = getBindingForErrors(e, false); String format = Request.current().format; if (format == null) { format = "txt"; } nettyResponse.setHeader( CONTENT_TYPE, (MimeTypes.getContentType("404." + format, "text/plain"))); String errorHtml = TemplateLoader.load("errors/404." + format).render(binding); try { ChannelBuffer buf = ChannelBuffers.copiedBuffer(errorHtml.getBytes("utf-8")); nettyResponse.setContent(buf); ChannelFuture writeFuture = ctx.getChannel().write(nettyResponse); writeFuture.addListener(ChannelFutureListener.CLOSE); } catch (UnsupportedEncodingException fex) { Logger.error(fex, "(utf-8 ?)"); } Logger.trace("serve404: end"); }
public static void sendOptionsResponse( String allowHeaders, HttpRequest request, ChannelHandlerContext context) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*"); response.setHeader(ACCESS_CONTROL_ALLOW_METHODS, allowHeaders); response.setHeader(ALLOW, allowHeaders); send(response, request, context); }
private static void sendStatus( HttpResponse response, @Nullable HttpRequest request, Channel channel, @Nullable String description) { response.setHeader(CONTENT_TYPE, "text/html"); if (request == null || request.getMethod() != HttpMethod.HEAD) { String message = response.getStatus().toString(); StringBuilder builder = new StringBuilder(); builder .append("<!doctype html><title>") .append(message) .append("</title>") .append("<h1 style=\"text-align: center\">") .append(message) .append("</h1>"); if (description != null) { builder.append("<p>").append(description).append("</p>"); } builder .append("<hr/><p style=\"text-align: center\">") .append(StringUtil.notNullize(getServerHeaderValue(), "")) .append("</p>"); response.setContent(ChannelBuffers.copiedBuffer(builder, CharsetUtil.UTF_8)); } send(response, channel, request); }
public static boolean addKeepAliveIfNeed(HttpResponse response, HttpRequest request) { if (isKeepAlive(request)) { response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); return true; } return false; }
private void sendError(ChannelHandlerContext ctx, String message, HttpResponseStatus status) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status); response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8"); response.setContent(ChannelBuffers.copiedBuffer(message, CharsetUtil.UTF_8)); // Close the connection as soon as the error message is sent. ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE); }
@Test public void decodeUtf16EncodedResponse() { HttpResponse httpResponse = new HttpResponse(); httpResponse.setStatus(200); httpResponse.setHeader(CONTENT_TYPE, JSON_UTF_8.withCharset(UTF_16).toString()); httpResponse.setContent("{\"status\":0,\"value\":\"水\"}".getBytes(UTF_16)); Response response = codec.decode(httpResponse); assertEquals("水", response.getValue()); }
private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8"); response.setContent( ChannelBuffers.copiedBuffer( "Failure: " + status.toString() + "\r\n", Charset.forName("UTF-8"))); // Close the connection as soon as the error message is sent. ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE); }
@Override public void messageReceived(ChannelHandlerContext context, MessageEvent e) throws Exception { if (e.getMessage() instanceof HttpRequest) { HttpRequest message = (HttpRequest) e.getMessage(); HttpResponse response; if (new QueryStringDecoder(message.getUri()).getPath().equals(START_TIME_PATH)) { response = new DefaultHttpResponse(HTTP_1_1, OK); response.setHeader("Access-Control-Allow-Origin", "*"); response.setContent( ChannelBuffers.copiedBuffer(getApplicationStartTime(), CharsetUtil.US_ASCII)); } else { response = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND); } context.getChannel().write(response).addListener(ChannelFutureListener.CLOSE); } }
public void process(Socket socket) { SocketInputStream input = null; OutputStream output = null; try { input = new SocketInputStream(socket.getInputStream(), 2048); output = socket.getOutputStream(); // create HttpRequest object and parse request = new HttpRequest(input); // create HttpResponse object response = new HttpResponse(output); response.setRequest(request); response.setHeader("Server", "Pyrmont Servlet Container"); parseRequest(input, output); parseHeaders(input); // check if this is a request for a servlet or a static resource // a request for a servlet begins with "/servlet/" if (request.getRequestURI().startsWith("/servlet/")) { ServletProcessor processor = new ServletProcessor(); processor.process(request, response); } else { StaticResourceProcessor processor = new StaticResourceProcessor(); processor.process(request, response); } // Close the socket socket.close(); // no shutdown for this application } catch (Exception e) { e.printStackTrace(); } }
public static void addServer(HttpResponse response) { if (getServerHeaderValue() != null) { response.setHeader(SERVER, getServerHeaderValue()); } }
public static void addDate(HttpResponse response, Date date) { response.setHeader(DATE, DATE_FORMAT.get().format(date)); }
public static void addAllowAnyOrigin(HttpResponse response) { response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*"); }
public void copyResponse( ChannelHandlerContext ctx, Request request, Response response, HttpRequest nettyRequest) throws Exception { Logger.trace("copyResponse: begin"); // response.out.flush(); // Decide whether to close the connection or not. HttpResponse nettyResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(response.status)); if (exposePlayServer) { nettyResponse.setHeader(SERVER, signature); } if (response.contentType != null) { nettyResponse.setHeader( CONTENT_TYPE, response.contentType + (response.contentType.startsWith("text/") && !response.contentType.contains("charset") ? "; charset=utf-8" : "")); } else { nettyResponse.setHeader(CONTENT_TYPE, "text/plain; charset=utf-8"); } addToResponse(response, nettyResponse); final Object obj = response.direct; File file = null; ChunkedInput stream = null; InputStream is = null; if (obj instanceof File) { file = (File) obj; } else if (obj instanceof InputStream) { is = (InputStream) obj; } else if (obj instanceof ChunkedInput) { stream = (ChunkedInput) obj; } final boolean keepAlive = isKeepAlive(nettyRequest); if (file != null && file.isFile()) { try { nettyResponse = addEtag(nettyRequest, nettyResponse, file); if (nettyResponse.getStatus().equals(HttpResponseStatus.NOT_MODIFIED)) { Channel ch = ctx.getChannel(); // Write the initial line and the header. ChannelFuture writeFuture = ch.write(nettyResponse); if (!keepAlive) { // Close the connection when the whole content is written out. writeFuture.addListener(ChannelFutureListener.CLOSE); } } else { nettyResponse.setHeader( CONTENT_TYPE, MimeTypes.getContentType(file.getName(), "text/plain")); final RandomAccessFile raf = new RandomAccessFile(file, "r"); try { long fileLength = raf.length(); if (keepAlive) { // Add 'Content-Length' header only for a keep-alive connection. Logger.trace("file length is [" + fileLength + "]"); setContentLength(nettyResponse, fileLength); } Channel ch = ctx.getChannel(); // Write the initial line and the header. ChannelFuture writeFuture = ch.write(nettyResponse); // Write the content. // If it is not a HEAD 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 (Exception e) { throw e; } } else if (is != null) { ChannelFuture writeFuture = ctx.getChannel().write(nettyResponse); if (!nettyRequest.getMethod().equals(HttpMethod.HEAD) && !nettyResponse.getStatus().equals(HttpResponseStatus.NOT_MODIFIED)) { writeFuture = ctx.getChannel().write(new ChunkedStream(is)); } else { is.close(); } if (!keepAlive) { writeFuture.addListener(ChannelFutureListener.CLOSE); } } else if (stream != null) { ChannelFuture writeFuture = ctx.getChannel().write(nettyResponse); if (!nettyRequest.getMethod().equals(HttpMethod.HEAD) && !nettyResponse.getStatus().equals(HttpResponseStatus.NOT_MODIFIED)) { writeFuture = ctx.getChannel().write(stream); } else { stream.close(); } if (!keepAlive) { writeFuture.addListener(ChannelFutureListener.CLOSE); } } else { writeResponse(ctx, response, nettyResponse, nettyRequest); } Logger.trace("copyResponse: end"); }
// TODO: add request and response as parameter public static void serve500(Exception e, ChannelHandlerContext ctx, HttpRequest nettyRequest) { Logger.trace("serve500: begin"); HttpResponse nettyResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR); if (exposePlayServer) { nettyResponse.setHeader(SERVER, signature); } Request request = Request.current(); Response response = Response.current(); try { if (!(e instanceof PlayException)) { e = new play.exceptions.UnexpectedException(e); } // Flush some cookies try { Map<String, Http.Cookie> cookies = response.cookies; for (Http.Cookie cookie : cookies.values()) { CookieEncoder encoder = new CookieEncoder(true); Cookie c = new DefaultCookie(cookie.name, cookie.value); c.setSecure(cookie.secure); c.setPath(cookie.path); if (cookie.domain != null) { c.setDomain(cookie.domain); } if (cookie.maxAge != null) { c.setMaxAge(cookie.maxAge); } c.setHttpOnly(cookie.httpOnly); encoder.addCookie(c); nettyResponse.addHeader(SET_COOKIE, encoder.encode()); } } catch (Exception exx) { Logger.error(e, "Trying to flush cookies"); // humm ? } Map<String, Object> binding = getBindingForErrors(e, true); String format = request.format; if (format == null) { format = "txt"; } nettyResponse.setHeader( "Content-Type", (MimeTypes.getContentType("500." + format, "text/plain"))); try { String errorHtml = TemplateLoader.load("errors/500." + format).render(binding); ChannelBuffer buf = ChannelBuffers.copiedBuffer(errorHtml.getBytes("utf-8")); nettyResponse.setContent(buf); ChannelFuture writeFuture = ctx.getChannel().write(nettyResponse); writeFuture.addListener(ChannelFutureListener.CLOSE); Logger.error( e, "Internal Server Error (500) for request %s", request.method + " " + request.url); } catch (Throwable ex) { Logger.error( e, "Internal Server Error (500) for request %s", request.method + " " + request.url); Logger.error(ex, "Error during the 500 response generation"); try { ChannelBuffer buf = ChannelBuffers.copiedBuffer("Internal Error (check logs)".getBytes("utf-8")); nettyResponse.setContent(buf); ChannelFuture writeFuture = ctx.getChannel().write(nettyResponse); writeFuture.addListener(ChannelFutureListener.CLOSE); } catch (UnsupportedEncodingException fex) { Logger.error(fex, "(utf-8 ?)"); } } } catch (Throwable exxx) { try { ChannelBuffer buf = ChannelBuffers.copiedBuffer("Internal Error (check logs)".getBytes("utf-8")); nettyResponse.setContent(buf); ChannelFuture writeFuture = ctx.getChannel().write(nettyResponse); writeFuture.addListener(ChannelFutureListener.CLOSE); } catch (Exception fex) { Logger.error(fex, "(utf-8 ?)"); } if (exxx instanceof RuntimeException) { throw (RuntimeException) exxx; } throw new RuntimeException(exxx); } Logger.trace("serve500: 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"); }
public static HttpResponse create(String contentType) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); response.setHeader(CONTENT_TYPE, contentType); return response; }
protected HttpResponse doRequest(HttpRequest request, RequestLine requestLine) throws IOException, MuleException { Map headers = parseHeaders(request); // TODO Mule 2.0 generic way to set stream message adapter MessageAdapter adapter = buildStandardAdapter(request, headers); MuleMessage message = new DefaultMuleMessage(adapter, connector.getMuleContext()); String path = (String) message.getProperty(HttpConnector.HTTP_REQUEST_PROPERTY); int i = path.indexOf('?'); if (i > -1) { path = path.substring(0, i); } message.setProperty(HttpConnector.HTTP_REQUEST_PATH_PROPERTY, path); if (logger.isDebugEnabled()) { logger.debug(message.getProperty(HttpConnector.HTTP_REQUEST_PROPERTY)); } // determine if the request path on this request denotes a different receiver MessageReceiver receiver = getTargetReceiver(message, endpoint); HttpResponse response; // the response only needs to be transformed explicitly if // A) the request was not served or B) a null result was returned if (receiver != null) { message.setProperty( HttpConnector.HTTP_CONTEXT_PATH_PROPERTY, HttpConnector.normalizeUrl(receiver.getEndpointURI().getPath())); preRouteMessage(message); MuleMessage returnMessage = receiver.routeMessage(message, endpoint.isSynchronous(), null); Object tempResponse; if (returnMessage != null) { tempResponse = returnMessage.getPayload(); } else { tempResponse = NullPayload.getInstance(); } // This removes the need for users to explicitly adding the response transformer // ObjectToHttpResponse in their config if (tempResponse instanceof HttpResponse) { response = (HttpResponse) tempResponse; } else { response = transformResponse(returnMessage); } response.setupKeepAliveFromRequestVersion(request.getRequestLine().getHttpVersion()); HttpConnector httpConnector = (HttpConnector) connector; response.disableKeepAlive(!httpConnector.isKeepAlive()); Header connectionHeader = request.getFirstHeader("Connection"); if (connectionHeader != null) { String value = connectionHeader.getValue(); boolean endpointOverride = getEndpointKeepAliveValue(endpoint); if ("keep-alive".equalsIgnoreCase(value) && endpointOverride) { response.setKeepAlive(true); Header header = new Header( HttpConstants.HEADER_KEEP_ALIVE, "timeout=" + httpConnector.getKeepAliveTimeout()); response.addHeader(header); if (response.getHttpVersion().equals(HttpVersion.HTTP_1_0)) { connectionHeader = new Header(HttpConstants.HEADER_CONNECTION, "Keep-Alive"); response.setHeader(connectionHeader); } } else if ("close".equalsIgnoreCase(value)) { response.setKeepAlive(false); } } } else { response = buildFailureResponse(requestLine, message); } return response; }