类 io.netty.handler.codec.http.HttpHeaders.Names 源码实例Demo

下面列出了怎么用 io.netty.handler.codec.http.HttpHeaders.Names 的API类实例代码及写法,或者点击链接到github查看源代码。


/**
 * <p>
 * Process server response:
 * </p>
 *
 * <pre>
 * HTTP/1.1 101 Switching Protocols
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 * Sec-WebSocket-Protocol: chat
 * </pre>
 *
 * @param response
 *            HTTP response returned from the server for the request sent by beginOpeningHandshake00().
 * @throws WebSocketHandshakeException
 */
@Override
protected void verify(FullHttpResponse response) {
    final HttpResponseStatus status = HttpResponseStatus.SWITCHING_PROTOCOLS;
    final HttpHeaders headers = response.headers();

    if (!response.getStatus().equals(status)) {
        throw new WebSocketHandshakeException("Invalid handshake response getStatus: " + response.getStatus());
    }

    String upgrade = headers.get(Names.UPGRADE);
    if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) {
        throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
    }

    String connection = headers.get(Names.CONNECTION);
    if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
        throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
    }

    String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
    if (accept == null || !accept.equals(expectedChallengeResponseString)) {
        throw new WebSocketHandshakeException(String.format(
                "Invalid challenge. Actual: %s. Expected: %s", accept, expectedChallengeResponseString));
    }
}
 

/**
 * Instances a new handshaker
 *
 * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web
 *         socket version is not supported.
 */
public WebSocketServerHandshaker newHandshaker(HttpRequest req) {

    String version = req.headers().get(Names.SEC_WEBSOCKET_VERSION);
    if (version != null) {
        if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) {
            // Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification).
            return new WebSocketServerHandshaker13(
                    webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
        } else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) {
            // Version 8 of the wire protocol - version 10 of the draft hybi specification.
            return new WebSocketServerHandshaker08(
                    webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
        } else if (version.equals(WebSocketVersion.V07.toHttpHeaderValue())) {
            // Version 8 of the wire protocol - version 07 of the draft hybi specification.
            return new WebSocketServerHandshaker07(
                    webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
        } else {
            return null;
        }
    } else {
        // Assume version 00 where version header was not specified
        return new WebSocketServerHandshaker00(webSocketURL, subprotocols, maxFramePayloadLength);
    }
}
 

/**
 * <p>
 * Process server response:
 * </p>
 *
 * <pre>
 * HTTP/1.1 101 Switching Protocols
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 * Sec-WebSocket-Protocol: chat
 * </pre>
 *
 * @param response
 *            HTTP response returned from the server for the request sent by beginOpeningHandshake00().
 * @throws WebSocketHandshakeException
 */
@Override
protected void verify(FullHttpResponse response) {
    final HttpResponseStatus status = HttpResponseStatus.SWITCHING_PROTOCOLS;
    final HttpHeaders headers = response.headers();

    if (!response.getStatus().equals(status)) {
        throw new WebSocketHandshakeException("Invalid handshake response getStatus: " + response.getStatus());
    }

    String upgrade = headers.get(Names.UPGRADE);
    if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) {
        throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
    }

    String connection = headers.get(Names.CONNECTION);
    if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
        throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
    }

    String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
    if (accept == null || !accept.equals(expectedChallengeResponseString)) {
        throw new WebSocketHandshakeException(String.format(
                "Invalid challenge. Actual: %s. Expected: %s", accept, expectedChallengeResponseString));
    }
}
 

/**
 * <p>
 * Process server response:
 * </p>
 *
 * <pre>
 * HTTP/1.1 101 Switching Protocols
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 * Sec-WebSocket-Protocol: chat
 * </pre>
 *
 * @param response
 *            HTTP response returned from the server for the request sent by beginOpeningHandshake00().
 * @throws WebSocketHandshakeException
 */
@Override
protected void verify(FullHttpResponse response) {
    final HttpResponseStatus status = HttpResponseStatus.SWITCHING_PROTOCOLS;
    final HttpHeaders headers = response.headers();

    if (!response.getStatus().equals(status)) {
        throw new WebSocketHandshakeException("Invalid handshake response getStatus: " + response.getStatus());
    }

    String upgrade = headers.get(Names.UPGRADE);
    if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) {
        throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
    }

    String connection = headers.get(Names.CONNECTION);
    if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
        throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
    }

    String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
    if (accept == null || !accept.equals(expectedChallengeResponseString)) {
        throw new WebSocketHandshakeException(String.format(
                "Invalid challenge. Actual: %s. Expected: %s", accept, expectedChallengeResponseString));
    }
}
 

@Test
public void testFullContent() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new TestEncoder());
    ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));

    FullHttpResponse res = new DefaultFullHttpResponse(
            HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(new byte[42]));
    res.headers().set(Names.CONTENT_LENGTH, 42);
    ch.writeOutbound(res);

    assertEncodedResponse(ch);
    HttpContent c = (HttpContent) ch.readOutbound();
    assertThat(c.content().readableBytes(), is(2));
    assertThat(c.content().toString(CharsetUtil.US_ASCII), is("42"));
    c.release();

    LastHttpContent last = (LastHttpContent) ch.readOutbound();
    assertThat(last.content().readableBytes(), is(0));
    last.release();

    assertThat(ch.readOutbound(), is(nullValue()));
}
 

/**
 * If the length of the content is 0 for sure, {@link HttpContentEncoder} should skip encoding.
 */
@Test
public void testEmptyFullContent() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new TestEncoder());
    ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));

    FullHttpResponse res = new DefaultFullHttpResponse(
            HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.EMPTY_BUFFER);
    ch.writeOutbound(res);

    Object o = ch.readOutbound();
    assertThat(o, is(instanceOf(FullHttpResponse.class)));

    res = (FullHttpResponse) o;
    assertThat(res.headers().get(Names.TRANSFER_ENCODING), is(nullValue()));

    // Content encoding shouldn't be modified.
    assertThat(res.headers().get(Names.CONTENT_ENCODING), is(nullValue()));
    assertThat(res.content().readableBytes(), is(0));
    assertThat(res.content().toString(CharsetUtil.US_ASCII), is(""));
    res.release();

    assertThat(ch.readOutbound(), is(nullValue()));
}
 

@Test
public void testEmptyFullContentWithTrailer() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new TestEncoder());
    ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));

    FullHttpResponse res = new DefaultFullHttpResponse(
            HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.EMPTY_BUFFER);
    res.trailingHeaders().set("X-Test", "Netty");
    ch.writeOutbound(res);

    Object o = ch.readOutbound();
    assertThat(o, is(instanceOf(FullHttpResponse.class)));

    res = (FullHttpResponse) o;
    assertThat(res.headers().get(Names.TRANSFER_ENCODING), is(nullValue()));

    // Content encoding shouldn't be modified.
    assertThat(res.headers().get(Names.CONTENT_ENCODING), is(nullValue()));
    assertThat(res.content().readableBytes(), is(0));
    assertThat(res.content().toString(CharsetUtil.US_ASCII), is(""));
    assertEquals("Netty", res.trailingHeaders().get("X-Test"));
    assertThat(ch.readOutbound(), is(nullValue()));
}
 

public FullHttpRequest build() {
    FullHttpRequest req = new DefaultFullHttpRequest(httpVersion, method, uri);
    HttpHeaders headers = req.headers();

    if (host != null) {
        headers.set(Names.HOST, host);
    }
    if (upgrade != null) {
        headers.set(Names.UPGRADE, upgrade);
    }
    if (connection != null) {
        headers.set(Names.CONNECTION, connection);
    }
    if (key != null) {
        headers.set(Names.SEC_WEBSOCKET_KEY, key);
    }
    if (origin != null) {
        headers.set(Names.SEC_WEBSOCKET_ORIGIN, origin);
    }
    if (version != null) {
        headers.set(Names.SEC_WEBSOCKET_VERSION, version.toHttpHeaderValue());
    }
    return req;
}
 

@Test
public void testPrematureClosureWithChunkedEncoding1() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());
    ch.writeInbound(
            Unpooled.copiedBuffer("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n", CharsetUtil.US_ASCII));

    // Read the response headers.
    HttpResponse res = (HttpResponse) ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));
    assertThat(res.headers().get(Names.TRANSFER_ENCODING), is("chunked"));
    assertThat(ch.readInbound(), is(nullValue()));

    // Close the connection without sending anything.
    ch.finish();
    // The decoder should not generate the last chunk because it's closed prematurely.
    assertThat(ch.readInbound(), is(nullValue()));
}
 

@Test
public void testFullContent() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
    ch.writeInbound(newRequest());

    FullHttpResponse res = new DefaultFullHttpResponse(
            HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
            Unpooled.copiedBuffer("Hello, World", CharsetUtil.US_ASCII));
    res.headers().set(Names.CONTENT_LENGTH, res.content().readableBytes());
    ch.writeOutbound(res);

    assertEncodedResponse(ch);
    HttpContent c = (HttpContent) ch.readOutbound();
    assertThat(ByteBufUtil.hexDump(c.content()), is("1f8b0800000000000000f248cdc9c9d75108cf2fca4901000000ffff"));
    c.release();

    c = (HttpContent) ch.readOutbound();
    assertThat(ByteBufUtil.hexDump(c.content()), is("0300c6865b260c000000"));
    c.release();

    LastHttpContent last = (LastHttpContent) ch.readOutbound();
    assertThat(last.content().readableBytes(), is(0));
    last.release();

    assertThat(ch.readOutbound(), is(nullValue()));
}
 

/**
 * If the length of the content is 0 for sure, {@link HttpContentEncoder} should skip encoding.
 */
@Test
public void testEmptyFullContent() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
    ch.writeInbound(newRequest());

    FullHttpResponse res = new DefaultFullHttpResponse(
            HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.EMPTY_BUFFER);
    ch.writeOutbound(res);

    Object o = ch.readOutbound();
    assertThat(o, is(instanceOf(FullHttpResponse.class)));

    res = (FullHttpResponse) o;
    assertThat(res.headers().get(Names.TRANSFER_ENCODING), is(nullValue()));

    // Content encoding shouldn't be modified.
    assertThat(res.headers().get(Names.CONTENT_ENCODING), is(nullValue()));
    assertThat(res.content().readableBytes(), is(0));
    assertThat(res.content().toString(CharsetUtil.US_ASCII), is(""));
    res.release();

    assertThat(ch.readOutbound(), is(nullValue()));
}
 

@Test
public void testEmptyFullContentWithTrailer() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
    ch.writeInbound(newRequest());

    FullHttpResponse res = new DefaultFullHttpResponse(
            HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.EMPTY_BUFFER);
    res.trailingHeaders().set("X-Test", "Netty");
    ch.writeOutbound(res);

    Object o = ch.readOutbound();
    assertThat(o, is(instanceOf(FullHttpResponse.class)));

    res = (FullHttpResponse) o;
    assertThat(res.headers().get(Names.TRANSFER_ENCODING), is(nullValue()));

    // Content encoding shouldn't be modified.
    assertThat(res.headers().get(Names.CONTENT_ENCODING), is(nullValue()));
    assertThat(res.content().readableBytes(), is(0));
    assertThat(res.content().toString(CharsetUtil.US_ASCII), is(""));
    assertEquals("Netty", res.trailingHeaders().get("X-Test"));
    assertThat(ch.readOutbound(), is(nullValue()));
}
 
源代码13 项目: tajo   文件: ExampleHttpServerHandler.java

private void processHead(ChannelHandlerContext context, FullHttpRequest request) {
  HttpHeaders headers = request.headers();
  FullHttpResponse response = null;

  if (headers.contains(Names.CONTENT_LENGTH)) {

    try {
      File file = getRequestedFile(request.getUri());

      response = new DefaultFullHttpResponse(
          HTTP_1_1,
          request.getDecoderResult().isSuccess() ? OK : BAD_REQUEST
      );

      HttpHeaders.setContentLength(response, file.length());


    } catch (FileNotFoundException | URISyntaxException e) {
      response = getBadRequest(e.getMessage());
    }
  }

  context.writeAndFlush(response);
}
 
源代码14 项目: DDMQ   文件: NettyHttpServerHandler.java

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    BackupState backupState = BackupState.ERROR;

    if (msg instanceof FullHttpRequest) {
        FullHttpRequest req = (FullHttpRequest) msg;
        if (req.getUri().equals("/chronos/backup")) {
            backupState = BackupDB.backup();
            LOGGER.info("backupState:{}", backupState.getDesc());

            RestoreState restoreState = BackupDB.restore();
            LOGGER.info("restoreState:{}", restoreState.getDesc());
        }
    } else {
        LOGGER.error("request is not FullHttpRequest");
    }

    FullHttpResponse response = new DefaultFullHttpResponse(
            HttpVersion.HTTP_1_1,
            HttpResponseStatus.OK,
            Unpooled.wrappedBuffer(backupState.getDesc().getBytes("utf-8")));
    response.headers().set(Names.CONTENT_TYPE, "text/plain;charset=UTF-8");
    response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
    response.headers().set(Names.CONNECTION, Values.KEEP_ALIVE);
    ctx.write(response);
    ctx.flush();
}
 
源代码15 项目: DDMQ   文件: NettyHttpServerHandler.java

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    BackupState backupState = BackupState.ERROR;

    if (msg instanceof FullHttpRequest) {
        FullHttpRequest req = (FullHttpRequest) msg;
        if (req.getUri().equals("/chronos/backup")) {
            backupState = BackupDB.backup();
            LOGGER.info("backupState:{}", backupState.getDesc());

            RestoreState restoreState = BackupDB.restore();
            LOGGER.info("restoreState:{}", restoreState.getDesc());
        }
    } else {
        LOGGER.error("request is not FullHttpRequest");
    }

    FullHttpResponse response = new DefaultFullHttpResponse(
            HttpVersion.HTTP_1_1,
            HttpResponseStatus.OK,
            Unpooled.wrappedBuffer(backupState.getDesc().getBytes("utf-8")));
    response.headers().set(Names.CONTENT_TYPE, "text/plain;charset=UTF-8");
    response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
    response.headers().set(Names.CONNECTION, Values.KEEP_ALIVE);
    ctx.write(response);
    ctx.flush();
}
 
源代码16 项目: Jinx   文件: NettyHttpServletRequest.java

@Override
public Enumeration<Locale> getLocales() {
    Collection<Locale> locales = Utils.parseAcceptLanguageHeader(HttpHeaders.getHeader(this.request,
                                                                                       Names.ACCEPT_LANGUAGE));

    if (locales == null || locales.isEmpty()) {
        locales = new ArrayList<Locale>();
        locales.add(Locale.getDefault());
    }
    return Utils.enumeration(locales);
}
 

@Override
protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out)
        throws Exception {
    String acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING);
    if (acceptedEncoding == null) {
        acceptedEncoding = HttpHeaders.Values.IDENTITY;
    }
    acceptEncodingQueue.add(acceptedEncoding);
    out.add(ReferenceCountUtil.retain(msg));
}
 

/**
 * <p>
 * Handle the web socket handshake for the web socket specification <a href=
 * "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17">HyBi versions 13-17</a>. Versions 13-17
 * share the same wire protocol.
 * </p>
 *
 * <p>
 * Browser request to the server:
 * </p>
 *
 * <pre>
 * GET /chat HTTP/1.1
 * Host: server.example.com
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
 * Sec-WebSocket-Origin: http://example.com
 * Sec-WebSocket-Protocol: chat, superchat
 * Sec-WebSocket-Version: 13
 * </pre>
 *
 * <p>
 * Server response:
 * </p>
 *
 * <pre>
 * HTTP/1.1 101 Switching Protocols
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 * Sec-WebSocket-Protocol: chat
 * </pre>
 */
@Override
protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
    FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS);
    if (headers != null) {
        res.headers().add(headers);
    }

    String key = req.headers().get(Names.SEC_WEBSOCKET_KEY);
    if (key == null) {
        throw new WebSocketHandshakeException("not a WebSocket request: missing key");
    }
    String acceptSeed = key + WEBSOCKET_13_ACCEPT_GUID;
    byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII));
    String accept = WebSocketUtil.base64(sha1);

    if (logger.isDebugEnabled()) {
        logger.debug("WebSocket version 13 server handshake key: {}, response: {}", key, accept);
    }

    res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase());
    res.headers().add(Names.CONNECTION, Names.UPGRADE);
    res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept);
    String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL);
    if (subprotocols != null) {
        String selectedSubprotocol = selectSubprotocol(subprotocols);
        if (selectedSubprotocol == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
            }
        } else {
            res.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
        }
    }
    return res;
}
 

/**
 * <p>
 * Handle the web socket handshake for the web socket specification <a href=
 * "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07">HyBi version 7</a>.
 * </p>
 *
 * <p>
 * Browser request to the server:
 * </p>
 *
 * <pre>
 * GET /chat HTTP/1.1
 * Host: server.example.com
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
 * Sec-WebSocket-Origin: http://example.com
 * Sec-WebSocket-Protocol: chat, superchat
 * Sec-WebSocket-Version: 7
 * </pre>
 *
 * <p>
 * Server response:
 * </p>
 *
 * <pre>
 * HTTP/1.1 101 Switching Protocols
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 * Sec-WebSocket-Protocol: chat
 * </pre>
 */
@Override
protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {

    FullHttpResponse res =
            new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS);

    if (headers != null) {
        res.headers().add(headers);
    }

    String key = req.headers().get(Names.SEC_WEBSOCKET_KEY);
    if (key == null) {
        throw new WebSocketHandshakeException("not a WebSocket request: missing key");
    }
    String acceptSeed = key + WEBSOCKET_07_ACCEPT_GUID;
    byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII));
    String accept = WebSocketUtil.base64(sha1);

    if (logger.isDebugEnabled()) {
        logger.debug("WebSocket version 07 server handshake key: {}, response: {}.", key, accept);
    }

    res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase());
    res.headers().add(Names.CONNECTION, Names.UPGRADE);
    res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept);
    String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL);
    if (subprotocols != null) {
        String selectedSubprotocol = selectSubprotocol(subprotocols);
        if (selectedSubprotocol == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
            }
        } else {
            res.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
        }
    }
    return res;
}
 

/**
 * <p>
 * Handle the web socket handshake for the web socket specification <a href=
 * "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-08">HyBi version 8 to 10</a>. Version 8, 9 and
 * 10 share the same wire protocol.
 * </p>
 *
 * <p>
 * Browser request to the server:
 * </p>
 *
 * <pre>
 * GET /chat HTTP/1.1
 * Host: server.example.com
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
 * Sec-WebSocket-Origin: http://example.com
 * Sec-WebSocket-Protocol: chat, superchat
 * Sec-WebSocket-Version: 8
 * </pre>
 *
 * <p>
 * Server response:
 * </p>
 *
 * <pre>
 * HTTP/1.1 101 Switching Protocols
 * Upgrade: websocket
 * Connection: Upgrade
 * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 * Sec-WebSocket-Protocol: chat
 * </pre>
 */
@Override
protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
    FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS);

    if (headers != null) {
        res.headers().add(headers);
    }

    String key = req.headers().get(Names.SEC_WEBSOCKET_KEY);
    if (key == null) {
        throw new WebSocketHandshakeException("not a WebSocket request: missing key");
    }
    String acceptSeed = key + WEBSOCKET_08_ACCEPT_GUID;
    byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII));
    String accept = WebSocketUtil.base64(sha1);

    if (logger.isDebugEnabled()) {
        logger.debug("WebSocket version 08 server handshake key: {}, response: {}", key, accept);
    }

    res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase());
    res.headers().add(Names.CONNECTION, Names.UPGRADE);
    res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept);
    String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL);
    if (subprotocols != null) {
        String selectedSubprotocol = selectSubprotocol(subprotocols);
        if (selectedSubprotocol == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
            }
        } else {
            res.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
        }
    }
    return res;
}
 

/**
 * Return that we need cannot not support the web socket version
 */
public static ChannelFuture sendUnsupportedVersionResponse(Channel channel, ChannelPromise promise) {
    HttpResponse res = new DefaultHttpResponse(
            HttpVersion.HTTP_1_1,
            HttpResponseStatus.UPGRADE_REQUIRED);
    res.headers().set(Names.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue());
    return channel.write(res, promise);
}
 

/**
 * <p>
 * Process server response:
 * </p>
 *
 * <pre>
 * HTTP/1.1 101 WebSocket Protocol Handshake
 * Upgrade: WebSocket
 * Connection: Upgrade
 * Sec-WebSocket-Origin: http://example.com
 * Sec-WebSocket-Location: ws://example.com/demo
 * Sec-WebSocket-Protocol: sample
 *
 * 8jKS'y:G*Co,Wxa-
 * </pre>
 *
 * @param response
 *            HTTP response returned from the server for the request sent by beginOpeningHandshake00().
 * @throws WebSocketHandshakeException
 */
@Override
protected void verify(FullHttpResponse response) {
    final HttpResponseStatus status = new HttpResponseStatus(101, "WebSocket Protocol Handshake");

    if (!response.getStatus().equals(status)) {
        throw new WebSocketHandshakeException("Invalid handshake response getStatus: " + response.getStatus());
    }

    HttpHeaders headers = response.headers();

    String upgrade = headers.get(Names.UPGRADE);
    if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) {
        throw new WebSocketHandshakeException("Invalid handshake response upgrade: "
                + upgrade);
    }

    String connection = headers.get(Names.CONNECTION);
    if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
        throw new WebSocketHandshakeException("Invalid handshake response connection: "
                + connection);
    }

    ByteBuf challenge = response.content();
    if (!challenge.equals(expectedChallengeResponseBytes)) {
        throw new WebSocketHandshakeException("Invalid challenge");
    }
}
 
源代码23 项目: netty4.0.27Learn   文件: CorsConfig.java

/**
 * Builds a {@link CorsConfig} with settings specified by previous method calls.
 *
 * @return {@link CorsConfig} the configured CorsConfig instance.
 */
public CorsConfig build() {
    if (preflightHeaders.isEmpty() && !noPreflightHeaders) {
        preflightHeaders.put(Names.DATE, new DateValueGenerator());
        preflightHeaders.put(Names.CONTENT_LENGTH, new ConstantValueGenerator("0"));
    }
    return new CorsConfig(this);
}
 

@Test
public void testChunkedContent() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new TestEncoder());
    ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));

    HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    res.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED);
    ch.writeOutbound(res);

    assertEncodedResponse(ch);

    ch.writeOutbound(new DefaultHttpContent(Unpooled.wrappedBuffer(new byte[3])));
    ch.writeOutbound(new DefaultHttpContent(Unpooled.wrappedBuffer(new byte[2])));
    ch.writeOutbound(new DefaultLastHttpContent(Unpooled.wrappedBuffer(new byte[1])));

    HttpContent chunk;
    chunk = (HttpContent) ch.readOutbound();
    assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("3"));
    chunk.release();

    chunk = (HttpContent) ch.readOutbound();
    assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("2"));
    chunk.release();

    chunk = (HttpContent) ch.readOutbound();
    assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("1"));
    assertThat(chunk, is(instanceOf(HttpContent.class)));
    chunk.release();

    chunk = (HttpContent) ch.readOutbound();
    assertThat(chunk.content().isReadable(), is(false));
    assertThat(chunk, is(instanceOf(LastHttpContent.class)));
    chunk.release();

    assertThat(ch.readOutbound(), is(nullValue()));
}
 

@Test
public void testChunkedContentWithTrailingHeader() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new TestEncoder());
    ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));

    HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    res.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED);
    ch.writeOutbound(res);

    assertEncodedResponse(ch);

    ch.writeOutbound(new DefaultHttpContent(Unpooled.wrappedBuffer(new byte[3])));
    ch.writeOutbound(new DefaultHttpContent(Unpooled.wrappedBuffer(new byte[2])));
    LastHttpContent content = new DefaultLastHttpContent(Unpooled.wrappedBuffer(new byte[1]));
    content.trailingHeaders().set("X-Test", "Netty");
    ch.writeOutbound(content);

    HttpContent chunk;
    chunk = (HttpContent) ch.readOutbound();
    assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("3"));
    chunk.release();

    chunk = (HttpContent) ch.readOutbound();
    assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("2"));
    chunk.release();

    chunk = (HttpContent) ch.readOutbound();
    assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("1"));
    assertThat(chunk, is(instanceOf(HttpContent.class)));
    chunk.release();

    chunk = (HttpContent) ch.readOutbound();
    assertThat(chunk.content().isReadable(), is(false));
    assertThat(chunk, is(instanceOf(LastHttpContent.class)));
    assertEquals("Netty", ((LastHttpContent) chunk).trailingHeaders().get("X-Test"));
    chunk.release();

    assertThat(ch.readOutbound(), is(nullValue()));
}
 

private static void assertEncodedResponse(EmbeddedChannel ch) {
    Object o = ch.readOutbound();
    assertThat(o, is(instanceOf(HttpResponse.class)));

    HttpResponse res = (HttpResponse) o;
    assertThat(res, is(not(instanceOf(HttpContent.class))));
    assertThat(res.headers().get(Names.TRANSFER_ENCODING), is("chunked"));
    assertThat(res.headers().get(Names.CONTENT_LENGTH), is(nullValue()));
    assertThat(res.headers().get(Names.CONTENT_ENCODING), is("test"));
}
 

private static void testPerformOpeningHandshake0(boolean subProtocol) {
    EmbeddedChannel ch = new EmbeddedChannel(
            new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder());

    FullHttpRequest req = ReferenceCountUtil.releaseLater(
            new DefaultFullHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"));
    req.headers().set(Names.HOST, "server.example.com");
    req.headers().set(Names.UPGRADE, WEBSOCKET.toLowerCase());
    req.headers().set(Names.CONNECTION, "Upgrade");
    req.headers().set(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ==");
    req.headers().set(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com");
    req.headers().set(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat");
    req.headers().set(Names.SEC_WEBSOCKET_VERSION, "8");

    if (subProtocol) {
        new WebSocketServerHandshaker08(
                "ws://example.com/chat", "chat", false, Integer.MAX_VALUE).handshake(ch, req);
    } else {
        new WebSocketServerHandshaker08(
                "ws://example.com/chat", null, false, Integer.MAX_VALUE).handshake(ch, req);
    }

    ByteBuf resBuf = (ByteBuf) ch.readOutbound();

    EmbeddedChannel ch2 = new EmbeddedChannel(new HttpResponseDecoder());
    ch2.writeInbound(resBuf);
    HttpResponse res = (HttpResponse) ch2.readInbound();

    Assert.assertEquals(
            "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.headers().get(Names.SEC_WEBSOCKET_ACCEPT));
    if (subProtocol) {
        Assert.assertEquals("chat", res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL));
    } else {
        Assert.assertNull(res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL));
    }
    ReferenceCountUtil.release(res);
}
 

private static void testPerformOpeningHandshake0(boolean subProtocol) {
    EmbeddedChannel ch = new EmbeddedChannel(
            new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder());

    FullHttpRequest req = ReferenceCountUtil.releaseLater(new DefaultFullHttpRequest(
            HTTP_1_1, HttpMethod.GET, "/chat", Unpooled.copiedBuffer("^n:ds[4U", CharsetUtil.US_ASCII)));

    req.headers().set(Names.HOST, "server.example.com");
    req.headers().set(Names.UPGRADE, WEBSOCKET.toLowerCase());
    req.headers().set(Names.CONNECTION, "Upgrade");
    req.headers().set(Names.ORIGIN, "http://example.com");
    req.headers().set(Names.SEC_WEBSOCKET_KEY1, "4 @1  46546xW%0l 1 5");
    req.headers().set(Names.SEC_WEBSOCKET_KEY2, "12998 5 Y3 1  .P00");
    req.headers().set(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat");

    if (subProtocol) {
        new WebSocketServerHandshaker00(
                "ws://example.com/chat", "chat", Integer.MAX_VALUE).handshake(ch, req);
    } else {
        new WebSocketServerHandshaker00(
                "ws://example.com/chat", null, Integer.MAX_VALUE).handshake(ch, req);
    }

    EmbeddedChannel ch2 = new EmbeddedChannel(new HttpResponseDecoder());
    ch2.writeInbound(ch.readOutbound());
    HttpResponse res = (HttpResponse) ch2.readInbound();

    Assert.assertEquals("ws://example.com/chat", res.headers().get(Names.SEC_WEBSOCKET_LOCATION));
    if (subProtocol) {
        Assert.assertEquals("chat", res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL));
    } else {
        Assert.assertNull(res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL));
    }
    LastHttpContent content = (LastHttpContent) ch2.readInbound();

    Assert.assertEquals("8jKS'y:G*Co,Wxa-", content.content().toString(CharsetUtil.US_ASCII));
    content.release();
}
 

private static void testPerformOpeningHandshake0(boolean subProtocol) {
    EmbeddedChannel ch = new EmbeddedChannel(
            new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder());

    FullHttpRequest req = ReferenceCountUtil.releaseLater(
            new DefaultFullHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"));
    req.headers().set(Names.HOST, "server.example.com");
    req.headers().set(Names.UPGRADE, WEBSOCKET.toLowerCase());
    req.headers().set(Names.CONNECTION, "Upgrade");
    req.headers().set(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ==");
    req.headers().set(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com");
    req.headers().set(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat");
    req.headers().set(Names.SEC_WEBSOCKET_VERSION, "13");

    if (subProtocol) {
        new WebSocketServerHandshaker13(
                "ws://example.com/chat", "chat", false, Integer.MAX_VALUE).handshake(ch, req);
    } else {
        new WebSocketServerHandshaker13(
                "ws://example.com/chat", null, false, Integer.MAX_VALUE).handshake(ch, req);
    }

    ByteBuf resBuf = (ByteBuf) ch.readOutbound();

    EmbeddedChannel ch2 = new EmbeddedChannel(new HttpResponseDecoder());
    ch2.writeInbound(resBuf);
    HttpResponse res = (HttpResponse) ch2.readInbound();

    Assert.assertEquals(
            "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.headers().get(Names.SEC_WEBSOCKET_ACCEPT));
    if (subProtocol) {
        Assert.assertEquals("chat", res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL));
    } else {
        Assert.assertNull(res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL));
    }
    ReferenceCountUtil.release(res);
}
 

@Test
public void testPrematureClosureWithChunkedEncoding2() throws Exception {
    EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder());

    // Write the partial response.
    ch.writeInbound(Unpooled.copiedBuffer(
            "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n8\r\n12345678", CharsetUtil.US_ASCII));

    // Read the response headers.
    HttpResponse res = (HttpResponse) ch.readInbound();
    assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
    assertThat(res.getStatus(), is(HttpResponseStatus.OK));
    assertThat(res.headers().get(Names.TRANSFER_ENCODING), is("chunked"));

    // Read the partial content.
    HttpContent content = (HttpContent) ch.readInbound();
    assertThat(content.content().toString(CharsetUtil.US_ASCII), is("12345678"));
    assertThat(content, is(not(instanceOf(LastHttpContent.class))));
    content.release();

    assertThat(ch.readInbound(), is(nullValue()));

    // Close the connection.
    ch.finish();

    // The decoder should not generate the last chunk because it's closed prematurely.
    assertThat(ch.readInbound(), is(nullValue()));
}
 
 类方法
 同包方法