Пример #1
0
  private void encodeChunkedContent(
      ChannelHandlerContext ctx, Object msg, int contentLength, List<Object> out) {
    if (contentLength > 0) {
      byte[] length = Integer.toHexString(contentLength).getBytes(CharsetUtil.US_ASCII);
      ByteBuf buf = ctx.alloc().buffer(length.length + 2);
      buf.writeBytes(length);
      buf.writeBytes(CRLF);
      out.add(buf);
      out.add(encodeAndRetain(msg));
      out.add(CRLF_BUF.duplicate());
    }

    if (msg instanceof LastHttpContent) {
      HttpHeaders headers = ((LastHttpContent) msg).trailingHeaders();
      if (headers.isEmpty()) {
        out.add(ZERO_CRLF_CRLF_BUF.duplicate());
      } else {
        ByteBuf buf = ctx.alloc().buffer();
        buf.writeBytes(ZERO_CRLF);
        HttpHeaders.encode(headers, buf);
        buf.writeBytes(CRLF);
        out.add(buf);
      }

      state = ST_INIT;
    } else {
      if (contentLength == 0) {
        // Need to produce some output otherwise an
        // IllegalstateException will be thrown
        out.add(EMPTY_BUFFER);
      }
    }
  }
Пример #2
0
 /**
  * Sets the value of the {@code "Connection"} header depending on the protocol version of the
  * specified message. This getMethod sets or removes the {@code "Connection"} header depending on
  * what the default keep alive mode of the message's protocol version is, as specified by {@link
  * HttpVersion#isKeepAliveDefault()}.
  *
  * <ul>
  *   <li>If the connection is kept alive by default:
  *       <ul>
  *         <li>set to {@code "close"} if {@code keepAlive} is {@code false}.
  *         <li>remove otherwise.
  *       </ul>
  *   <li>If the connection is closed by default:
  *       <ul>
  *         <li>set to {@code "keep-alive"} if {@code keepAlive} is {@code true}.
  *         <li>remove otherwise.
  *       </ul>
  * </ul>
  */
 public static void setKeepAlive(HttpMessage message, boolean keepAlive) {
   HttpHeaders h = message.headers();
   if (message.getProtocolVersion().isKeepAliveDefault()) {
     if (keepAlive) {
       h.remove(Names.CONNECTION);
     } else {
       h.set(Names.CONNECTION, Values.CLOSE);
     }
   } else {
     if (keepAlive) {
       h.set(Names.CONNECTION, Values.KEEP_ALIVE);
     } else {
       h.remove(Names.CONNECTION);
     }
   }
 }
Пример #3
0
  /**
   * Returns the content length of the specified web socket message. If the specified message is not
   * a web socket message, {@code -1} is returned.
   */
  private static int getWebSocketContentLength(HttpMessage message) {
    // WebSockset messages have constant content-lengths.
    HttpHeaders h = message.headers();
    if (message instanceof HttpRequest) {
      HttpRequest req = (HttpRequest) message;
      if (HttpMethod.GET.equals(req.getMethod())
          && h.contains(Names.SEC_WEBSOCKET_KEY1)
          && h.contains(Names.SEC_WEBSOCKET_KEY2)) {
        return 8;
      }
    } else if (message instanceof HttpResponse) {
      HttpResponse res = (HttpResponse) message;
      if (res.getStatus().code() == 101
          && h.contains(Names.SEC_WEBSOCKET_ORIGIN)
          && h.contains(Names.SEC_WEBSOCKET_LOCATION)) {
        return 16;
      }
    }

    // Not a web socket message
    return -1;
  }
Пример #4
0
  @Override
  protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
    ByteBuf buf = null;
    if (msg instanceof HttpMessage) {
      if (state != ST_INIT) {
        throw new IllegalStateException(
            "unexpected message type: " + StringUtil.simpleClassName(msg));
      }

      @SuppressWarnings({"unchecked", "CastConflictsWithInstanceof"})
      H m = (H) msg;

      buf = ctx.alloc().buffer();
      // Encode the message.
      encodeInitialLine(buf, m);
      HttpHeaders.encode(m.headers(), buf);
      buf.writeBytes(CRLF);
      state = HttpHeaders.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK;
    }
    if (msg instanceof HttpContent || msg instanceof ByteBuf || msg instanceof FileRegion) {
      if (state == ST_INIT) {
        throw new IllegalStateException(
            "unexpected message type: " + StringUtil.simpleClassName(msg));
      }

      int contentLength = contentLength(msg);
      if (state == ST_CONTENT_NON_CHUNK) {
        if (contentLength > 0) {
          if (buf != null && buf.writableBytes() >= contentLength && msg instanceof HttpContent) {
            // merge into other buffer for performance reasons
            buf.writeBytes(((HttpContent) msg).content());
            out.add(buf);
          } else {
            if (buf != null) {
              out.add(buf);
            }
            out.add(encodeAndRetain(msg));
          }
        } else {
          if (buf != null) {
            out.add(buf);
          } else {
            // Need to produce some output otherwise an
            // IllegalStateException will be thrown
            out.add(EMPTY_BUFFER);
          }
        }

        if (msg instanceof LastHttpContent) {
          state = ST_INIT;
        }
      } else if (state == ST_CONTENT_CHUNK) {
        if (buf != null) {
          out.add(buf);
        }
        encodeChunkedContent(ctx, msg, contentLength, out);
      } else {
        throw new Error();
      }
    } else {
      if (buf != null) {
        out.add(buf);
      }
    }
  }
Пример #5
0
 @Deprecated
 protected static void encodeAscii(String s, ByteBuf buf) {
   HttpHeaders.encodeAscii0(s, buf);
 }
Пример #6
0
  @Override
  protected void encode(ChannelHandlerContext ctx, HttpObject msg, ByteBuf out) throws Exception {
    if (msg instanceof HttpMessage) {
      if (state != ST_INIT) {
        throw new IllegalStateException(
            "unexpected message type: " + msg.getClass().getSimpleName());
      }

      @SuppressWarnings({"unchecked", "CastConflictsWithInstanceof"})
      H m = (H) msg;

      // Encode the message.
      encodeInitialLine(out, m);
      encodeHeaders(out, m);
      out.writeByte(CR);
      out.writeByte(LF);

      state = HttpHeaders.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK;
    }

    if (msg instanceof HttpContent) {
      if (state == ST_INIT) {
        throw new IllegalStateException(
            "unexpected message type: " + msg.getClass().getSimpleName());
      }

      HttpContent chunk = (HttpContent) msg;
      ByteBuf content = chunk.content();
      int contentLength = content.readableBytes();

      if (state == ST_CONTENT_NON_CHUNK) {
        if (contentLength > 0) {
          out.writeBytes(content, content.readerIndex(), content.readableBytes());
        }

        if (chunk instanceof LastHttpContent) {
          state = ST_INIT;
        }
      } else if (state == ST_CONTENT_CHUNK) {
        if (contentLength > 0) {
          out.writeBytes(copiedBuffer(Integer.toHexString(contentLength), CharsetUtil.US_ASCII));
          out.writeByte(CR);
          out.writeByte(LF);
          out.writeBytes(content, content.readerIndex(), contentLength);
          out.writeByte(CR);
          out.writeByte(LF);
        }

        if (chunk instanceof LastHttpContent) {
          out.writeByte((byte) '0');
          out.writeByte(CR);
          out.writeByte(LF);
          encodeTrailingHeaders(out, (LastHttpContent) chunk);
          out.writeByte(CR);
          out.writeByte(LF);
          state = ST_INIT;
        }
      } else {
        throw new Error();
      }
    }
  }