/** * 转换为Netty所用Response * * @return FullHttpResponse */ public FullHttpResponse toFullHttpResponse() { final FullHttpResponse fullHttpResponse = new DefaultFullHttpResponse(httpVersion, status, content); // headers final HttpHeaders httpHeaders = fullHttpResponse.headers().add(headers); httpHeaders.set(Names.CONTENT_TYPE, contentType + "; charset=" + charset); httpHeaders.set(Names.CONTENT_ENCODING, charset); httpHeaders.set(Names.CONTENT_LENGTH, content.readableBytes()); // Cookies for (Cookie cookie : cookies) { httpHeaders.add(Names.SET_COOKIE, ServerCookieEncoder.encode(cookie)); } return fullHttpResponse; }
public static String getSessionId(FullHttpRequest msg, boolean anonymousAccessAllowed) { final StringBuilder buf = new StringBuilder(); msg.headers().getAll(Names.COOKIE).forEach(h -> { ServerCookieDecoder.STRICT.decode(h).forEach(c -> { if (c.name().equals(Constants.COOKIE_NAME)) { if (buf.length() == 0) { buf.append(c.value()); } } }); }); String sessionId = buf.toString(); if (sessionId.length() == 0 && anonymousAccessAllowed) { sessionId = NO_AUTHORIZATIONS; } else if (sessionId.length() == 0) { sessionId = null; } return sessionId; }
@Override protected ChannelHandler newNonSslHandler(ChannelHandlerContext context) { return new ChannelInboundHandlerAdapter() { private HttpResponseEncoder encoder = new HttpResponseEncoder(); @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { LOG.trace("Received non-SSL request, returning redirect"); FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.MOVED_PERMANENTLY, Unpooled.EMPTY_BUFFER); response.headers().set(Names.LOCATION, redirectAddress); LOG.trace(Constants.LOG_RETURNING_RESPONSE, response); encoder.write(ctx, response, ctx.voidPromise()); ctx.flush(); } }; }
@Test public void testBasicAuthenticationFailure() throws Exception { Configuration config = TestConfiguration.createMinimalConfigurationForTest(); BasicAuthLogin auth = new BasicAuthLogin(); auth.setUsername("test"); auth.setPassword("test2"); DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/login"); request.content().writeBytes(JsonSerializer.getObjectMapper().writeValueAsBytes(auth)); TestHttpQueryDecoder decoder = new TestHttpQueryDecoder(config); decoder.decode(null, request, results); Assert.assertEquals(1, results.size()); Object result = results.iterator().next(); Assert.assertEquals(BasicAuthLoginRequest.class, result.getClass()); BasicAuthLoginRequestHandler handler = new BasicAuthLoginRequestHandler(config); CaptureChannelHandlerContext ctx = new CaptureChannelHandlerContext(); handler.channelRead(ctx, result); Assert.assertNotNull(ctx.msg); Assert.assertTrue(ctx.msg instanceof DefaultFullHttpResponse); DefaultFullHttpResponse response = (DefaultFullHttpResponse) ctx.msg; Assert.assertEquals(HttpResponseStatus.UNAUTHORIZED, response.getStatus()); Assert.assertTrue(response.headers().contains(Names.CONTENT_TYPE)); Assert.assertEquals(Constants.JSON_TYPE, response.headers().get(Names.CONTENT_TYPE)); }
@Override protected void channelRead0(ChannelHandlerContext ctx, SuggestRequest msg) throws Exception { byte[] buf = null; try { buf = JsonUtil.getObjectMapper().writeValueAsBytes(dataStore.suggest(msg)); } catch (TimelyException e) { LOG.error(e.getMessage(), e); this.sendHttpError(ctx, e); return; } FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer(buf)); response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE); response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes()); sendResponse(ctx, response); }
@Override protected void channelRead0(ChannelHandlerContext ctx, SearchLookupRequest msg) throws Exception { byte[] buf = null; try { buf = JsonUtil.getObjectMapper().writeValueAsBytes(dataStore.lookup(msg)); } catch (TimelyException e) { LOG.error(e.getMessage(), e); this.sendHttpError(ctx, e); return; } FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer(buf)); response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE); response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes()); sendResponse(ctx, response); }
@Override protected void channelRead0(ChannelHandlerContext ctx, QueryRequest msg) throws Exception { byte[] buf; try { buf = JsonUtil.getObjectMapper().writeValueAsBytes(dataStore.query(msg)); } catch (TimelyException e) { if (e.getMessage().contains("No matching tags")) { LOG.trace(e.getMessage()); } else { LOG.error(e.getMessage(), e); } this.sendHttpError(ctx, e); return; } FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer(buf)); response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE); response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes()); sendResponse(ctx, response); }
protected String query(String getRequest, int expectedResponseCode, String acceptType) throws Exception { URL url = new URL(getRequest); HttpsURLConnection con = getUrlConnection(url); if (null != acceptType) { LOG.trace("Setting Accept header to {}", acceptType); con.addRequestProperty(Names.ACCEPT, acceptType); } LOG.trace("Sending HTTP Headers: {}", con.getRequestProperties()); int responseCode = con.getResponseCode(); assertEquals(expectedResponseCode, responseCode); if (200 == responseCode) { String result = IOUtils.toString(con.getInputStream(), UTF_8); LOG.info("Result is {}", result); return result; } else { throw new NotSuccessfulException(); } }
protected HttpsURLConnection getUrlConnection(String username, String password, URL url) throws Exception { HttpsURLConnection.setDefaultSSLSocketFactory(getSSLSocketFactory()); URL loginURL = new URL(url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + "/login"); HttpsURLConnection con = (HttpsURLConnection) loginURL.openConnection(); con.setHostnameVerifier((host, session) -> true); con.setRequestMethod("GET"); con.setDoOutput(true); con.setRequestProperty("Content-Type", "application/json"); con.connect(); int responseCode = con.getResponseCode(); if (401 == responseCode) { throw new UnauthorizedUserException(); } Assert.assertEquals(200, responseCode); List<String> cookies = con.getHeaderFields().get(Names.SET_COOKIE); Assert.assertEquals(1, cookies.size()); Cookie sessionCookie = ClientCookieDecoder.STRICT.decode(cookies.get(0)); Assert.assertEquals(Constants.COOKIE_NAME, sessionCookie.name()); con = (HttpsURLConnection) url.openConnection(); con.setRequestProperty(Names.COOKIE, sessionCookie.name() + "=" + sessionCookie.value()); con.setHostnameVerifier((host, session) -> true); return con; }
/** * <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); } }
@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())); }
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); }
/** * <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 (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, 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)); } }