示例#1
0
  public static HttpResponse buildHttpServletResponse(HttpResponseExchange forwardResponse)
      throws IOException {

    if (null == forwardResponse) {
      return new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.REQUEST_TIMEOUT);
    }
    HttpResponse response =
        new DefaultHttpResponse(
            HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(forwardResponse.getResponseCode()));

    List<String[]> headers = forwardResponse.getHeaders();
    for (String[] header : headers) {
      if (header[0].equalsIgnoreCase(HttpHeaders.Names.SET_COOKIE)
          || header[0].equalsIgnoreCase(HttpHeaders.Names.SET_COOKIE2)) {
        List<SetCookieHeaderValue> cookies = SetCookieHeaderValue.parse(header[1]);
        for (SetCookieHeaderValue cookie : cookies) {
          response.addHeader(header[0], cookie.toString());
        }
      } else {
        response.addHeader(header[0], header[1]);
      }
    }
    byte[] content = forwardResponse.getBody();
    if (null != content) {
      ChannelBuffer bufer = ChannelBuffers.wrappedBuffer(content);
      response.setContent(bufer);
    }

    return response;
  }
示例#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");
    }
  }
 @Override
 public void addHeader(String name, String value) {
   if (name.equalsIgnoreCase("content-type") && response.containsHeader("Content-Type")) {
     setHeader(name, value);
   } else {
     response.addHeader(name, value);
   }
 }
示例#4
0
 public NettyHttpResponse header(String name, String value) {
   if (value == null) {
     response.removeHeader(name);
   } else {
     response.addHeader(name, value);
   }
   return this;
 }
示例#5
0
 @Override
 public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
   if (e.getMessage() instanceof HttpRequest
       && HttpMethod.GET.equals(((HttpRequest) e.getMessage()).getMethod())) {
     HttpRequest request = (HttpRequest) e.getMessage();
     HttpResponse response =
         new DefaultHttpResponse(request.getProtocolVersion(), HttpResponseStatus.OK);
     String resp = "";
     for (Component c : Component.values()) {
       resp +=
           String.format(
               "name=%-20.20s enabled=%-10.10s local=%-10.10s initialized=%-10.10s\n",
               c.name(), c.isEnabled(), c.isLocal(), c.isInitialized());
     }
     ChannelBuffer buf = ChannelBuffers.copiedBuffer(resp.getBytes());
     response.setContent(buf);
     response.addHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(buf.readableBytes()));
     response.addHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8");
     ChannelFuture writeFuture = ctx.getChannel().write(response);
     writeFuture.addListener(ChannelFutureListener.CLOSE);
   } else {
     ctx.sendUpstream(e);
   }
 }
示例#6
0
  @Override
  public void service(ChannelHandlerContext context, HttpRequest request, HttpResponse response) {
    String path = request.getUri();

    path = path.substring(getPrefix().length()).toLowerCase();

    HashMap<String, String> params = getParams(request);

    String data = getData(path, params);

    ChannelBuffer buffer = ChannelBuffers.copiedBuffer(ChannelBuffers.BIG_ENDIAN, data, UTF8);

    response.addHeader(HttpHeaders.Names.CONTENT_TYPE, CONTENT_TYPE);
    response.addHeader(HttpHeaders.Names.CONTENT_ENCODING, ENCODING);

    response.setContent(buffer);
  }
示例#7
0
  public HttpResponse generateResponse(HttpRequest request, String serverOrigin) throws Exception {

    HttpResponse response =
        new DefaultHttpResponse(
            HttpVersion.HTTP_1_1,
            new HttpResponseStatus(101, "Web Socket Protocol Handshake - IETF-00"));
    response.addHeader(HttpHeaders.Names.CONNECTION, "Upgrade");
    response.addHeader(HttpHeaders.Names.UPGRADE, "WebSocket");
    String origin = request.getHeader(Names.ORIGIN);
    if (origin == null) {
      origin = serverOrigin;
    }
    response.addHeader(Names.SEC_WEBSOCKET_ORIGIN, origin);
    response.addHeader(Names.SEC_WEBSOCKET_LOCATION, getWebSocketLocation(request));

    String protocol = request.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);

    if (protocol != null) {
      response.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol);
    }

    // Calculate the answer of the challenge.
    String key1 = request.getHeader(Names.SEC_WEBSOCKET_KEY1);
    String key2 = request.getHeader(Names.SEC_WEBSOCKET_KEY2);
    byte[] key3 = new byte[8];

    request.getContent().readBytes(key3);

    byte[] solution = WebSocketChallenge00.solve(key1, key2, key3);

    ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(solution.length + 2);
    buffer.writeBytes(solution);

    response.addHeader("Content-Length", buffer.readableBytes());

    response.setContent(buffer);
    response.setChunked(false);

    return response;
  }
示例#8
0
 @Override
 public NettyHttpResponse header(String name, long value) {
   response.addHeader(name, value);
   return this;
 }
示例#9
0
 @Override
 public NettyHttpResponse header(String name, Date value) {
   response.addHeader(name, DateHelper.rfc1123Format(value));
   return this;
 }
 @Override
 public void addIntHeader(String name, int value) {
   response.addHeader(name, String.valueOf(value));
 }
示例#11
0
  private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
    // Allow only GET methods.
    if (req.getMethod() != GET) {
      sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));
      return;
    }

    // Send the demo page.
    if (req.getUri().equals("/")) {
      HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);

      ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req));

      res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");
      setContentLength(res, content.readableBytes());

      res.setContent(content);
      sendHttpResponse(ctx, req, res);
      return;
    }

    // Serve the WebSocket handshake request.
    if (req.getUri().equals(WEBSOCKET_PATH)
        && Values.UPGRADE.equalsIgnoreCase(req.getHeader(CONNECTION))
        && WEBSOCKET.equalsIgnoreCase(req.getHeader(Names.UPGRADE))) {

      // Create the WebSocket handshake response.
      HttpResponse res =
          new DefaultHttpResponse(
              HTTP_1_1, new HttpResponseStatus(101, "Web Socket Protocol Handshake"));
      res.addHeader(Names.UPGRADE, WEBSOCKET);
      res.addHeader(CONNECTION, Values.UPGRADE);

      // Fill in the headers and contents depending on handshake method.
      if (req.containsHeader(SEC_WEBSOCKET_KEY1) && req.containsHeader(SEC_WEBSOCKET_KEY2)) {
        // New handshake method with a challenge:
        res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
        res.addHeader(SEC_WEBSOCKET_LOCATION, getWebSocketLocation(req));
        String protocol = req.getHeader(SEC_WEBSOCKET_PROTOCOL);
        if (protocol != null) {
          res.addHeader(SEC_WEBSOCKET_PROTOCOL, protocol);
        }

        // Calculate the answer of the challenge.
        String key1 = req.getHeader(SEC_WEBSOCKET_KEY1);
        String key2 = req.getHeader(SEC_WEBSOCKET_KEY2);
        int a =
            (int)
                (Long.parseLong(key1.replaceAll("[^0-9]", ""))
                    / key1.replaceAll("[^ ]", "").length());
        int b =
            (int)
                (Long.parseLong(key2.replaceAll("[^0-9]", ""))
                    / key2.replaceAll("[^ ]", "").length());
        long c = req.getContent().readLong();
        ChannelBuffer input = ChannelBuffers.buffer(16);
        input.writeInt(a);
        input.writeInt(b);
        input.writeLong(c);
        ChannelBuffer output =
            ChannelBuffers.wrappedBuffer(MessageDigest.getInstance("MD5").digest(input.array()));
        res.setContent(output);
      } else {
        // Old handshake method with no challenge:
        res.addHeader(WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
        res.addHeader(WEBSOCKET_LOCATION, getWebSocketLocation(req));
        String protocol = req.getHeader(WEBSOCKET_PROTOCOL);
        if (protocol != null) {
          res.addHeader(WEBSOCKET_PROTOCOL, protocol);
        }
      }

      // Upgrade the connection and send the handshake response.
      ChannelPipeline p = ctx.getChannel().getPipeline();
      p.remove("aggregator");
      p.replace("decoder", "wsdecoder", new WebSocketFrameDecoder());

      ctx.getChannel().write(res);

      p.replace("encoder", "wsencoder", new WebSocketFrameEncoder());
      return;
    }

    // Send an error page otherwise.
    sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));
  }
示例#12
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");
  }
示例#13
0
  private void websocketHandshake(final ChannelHandlerContext ctx, HttpRequest req, MessageEvent e)
      throws Exception {

    // Create the WebSocket handshake response.
    HttpResponse res =
        new DefaultHttpResponse(
            HttpVersion.HTTP_1_1, new HttpResponseStatus(101, "Web Socket Protocol Handshake"));
    res.addHeader(HttpHeaders.Names.UPGRADE, HttpHeaders.Values.WEBSOCKET);
    res.addHeader(CONNECTION, HttpHeaders.Values.UPGRADE);

    // Fill in the headers and contents depending on handshake method.
    if (req.containsHeader(SEC_WEBSOCKET_KEY1) && req.containsHeader(SEC_WEBSOCKET_KEY2)) {
      // New handshake method with a challenge:
      res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
      res.addHeader(
          SEC_WEBSOCKET_LOCATION, "ws://" + req.getHeader(HttpHeaders.Names.HOST) + req.getUri());
      String protocol = req.getHeader(SEC_WEBSOCKET_PROTOCOL);
      if (protocol != null) {
        res.addHeader(SEC_WEBSOCKET_PROTOCOL, protocol);
      }

      // Calculate the answer of the challenge.
      String key1 = req.getHeader(SEC_WEBSOCKET_KEY1);
      String key2 = req.getHeader(SEC_WEBSOCKET_KEY2);
      int a =
          (int)
              (Long.parseLong(key1.replaceAll("[^0-9]", ""))
                  / key1.replaceAll("[^ ]", "").length());
      int b =
          (int)
              (Long.parseLong(key2.replaceAll("[^0-9]", ""))
                  / key2.replaceAll("[^ ]", "").length());
      long c = req.getContent().readLong();
      ChannelBuffer input = ChannelBuffers.buffer(16);
      input.writeInt(a);
      input.writeInt(b);
      input.writeLong(c);
      try {
        ChannelBuffer output =
            ChannelBuffers.wrappedBuffer(MessageDigest.getInstance("MD5").digest(input.array()));
        res.setContent(output);
      } catch (NoSuchAlgorithmException ex) {
        throw new UnexpectedException(ex);
      }
    } else {
      // Old handshake method with no challenge:
      res.addHeader(WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
      res.addHeader(
          WEBSOCKET_LOCATION, "ws://" + req.getHeader(HttpHeaders.Names.HOST) + req.getUri());
      String protocol = req.getHeader(WEBSOCKET_PROTOCOL);
      if (protocol != null) {
        res.addHeader(WEBSOCKET_PROTOCOL, protocol);
      }
    }

    // Keep the original request
    Http.Request request = parseRequest(ctx, req);

    // Route the websocket request
    request.method = "WS";
    Map<String, String> route = Router.route(request.method, request.path);
    if (!route.containsKey("action")) {
      // No route found to handle this websocket connection
      ctx.getChannel()
          .write(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND));
      return;
    }

    // Upgrade the connection and send the handshake response.
    ChannelPipeline p = ctx.getChannel().getPipeline();
    p.remove("aggregator");
    p.replace("decoder", "wsdecoder", new WebSocketFrameDecoder());

    // Connect
    ctx.getChannel().write(res);

    p.replace("encoder", "wsencoder", new WebSocketFrameEncoder());
    req.setMethod(new HttpMethod("WEBSOCKET"));

    // Inbound
    Http.Inbound inbound =
        new Http.Inbound() {

          @Override
          public boolean isOpen() {
            return ctx.getChannel().isOpen();
          }
        };
    channels.put(ctx, inbound);

    // Outbound
    Http.Outbound outbound =
        new Http.Outbound() {

          final List<ChannelFuture> writeFutures =
              Collections.synchronizedList(new ArrayList<ChannelFuture>());
          Promise<Void> closeTask;

          synchronized void writeAndClose(ChannelFuture writeFuture) {
            if (!writeFuture.isDone()) {
              writeFutures.add(writeFuture);
              writeFuture.addListener(
                  new ChannelFutureListener() {

                    public void operationComplete(ChannelFuture cf) throws Exception {
                      writeFutures.remove(cf);
                      futureClose();
                    }
                  });
            }
          }

          void futureClose() {
            if (closeTask != null && writeFutures.isEmpty()) {
              closeTask.invoke(null);
            }
          }

          @Override
          public void send(String data) {
            if (!isOpen()) {
              throw new IllegalStateException("The outbound channel is closed");
            }
            writeAndClose(ctx.getChannel().write(new DefaultWebSocketFrame(data)));
          }

          @Override
          public void send(byte opcode, byte[] data, int offset, int length) {
            if (!isOpen()) {
              throw new IllegalStateException("The outbound channel is closed");
            }
            writeAndClose(
                ctx.getChannel()
                    .write(new DefaultWebSocketFrame(opcode, wrappedBuffer(data, offset, length))));
          }

          @Override
          public synchronized boolean isOpen() {
            return ctx.getChannel().isOpen() && closeTask == null;
          }

          @Override
          public synchronized void close() {
            closeTask = new Promise<Void>();
            closeTask.onRedeem(
                new Action<Promise<Void>>() {

                  public void invoke(Promise<Void> completed) {
                    writeFutures.clear();
                    ctx.getChannel().disconnect();
                    closeTask = null;
                  }
                });
            futureClose();
          }
        };

    Invoker.invoke(new WebSocketInvocation(route, request, inbound, outbound, ctx, e));
  }