示例#1
1
  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;
  }
示例#2
0
  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");
    }
  }
示例#3
0
  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");
  }
示例#4
0
 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);
 }
示例#5
0
  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);
  }
示例#6
0
 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);
  }
示例#10
0
 @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();
    }
  }
示例#12
0
 public static void addServer(HttpResponse response) {
   if (getServerHeaderValue() != null) {
     response.setHeader(SERVER, getServerHeaderValue());
   }
 }
示例#13
0
 public static void addDate(HttpResponse response, Date date) {
   response.setHeader(DATE, DATE_FORMAT.get().format(date));
 }
示例#14
0
 public static void addAllowAnyOrigin(HttpResponse response) {
   response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
 }
示例#15
0
  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");
  }
示例#16
0
  // 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");
  }
示例#17
0
  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");
  }
示例#18
0
 public static HttpResponse create(String contentType) {
   HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
   response.setHeader(CONTENT_TYPE, contentType);
   return response;
 }
示例#19
0
    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;
    }