private static void sendHttpResponse( ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) { // Generate an error page if response getStatus code is not OK (200). if (res.getStatus().code() != 200) { ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8); res.content().writeBytes(buf); buf.release(); HttpHeaders.setContentLength(res, res.content().readableBytes()); } // Send the response and close the connection if necessary. ChannelFuture f = ctx.channel().writeAndFlush(res); if (!HttpHeaders.isKeepAlive(req) || res.getStatus().code() != 200) { f.addListener(ChannelFutureListener.CLOSE); } }
@Test public void iframeUppercase() throws Exception { final SockJsConfig config = config(); final String path = config.prefix() + "/IFRAME"; final FullHttpResponse response = Iframe.response(config, createHttpRequest(path)); assertThat(response.getStatus().code(), is(HttpResponseStatus.NOT_FOUND.code())); }
@Test public void ifNoneMatchHeader() throws Exception { final SockJsConfig config = config(); final String path = config.prefix() + "/iframe.html"; final HttpRequest httpRequest = createHttpRequest(path); httpRequest.headers().set(HttpHeaders.Names.IF_NONE_MATCH, "*"); final FullHttpResponse response = Iframe.response(config, httpRequest); assertThat( response.headers().get(HttpHeaders.Names.SET_COOKIE), equalTo("JSESSIONID=dummy; path=/")); assertThat(response.getStatus().code(), is(HttpResponseStatus.NOT_MODIFIED.code())); }
@Override public void channelRead0(final ChannelHandlerContext c, Object msg) throws Exception { Channel ch = ctx.channel(); if (response == null) { if (msg instanceof FullHttpResponse) { response = (FullHttpResponse) msg; } else { response = new WSResponse((DefaultHttpResponse) msg, ctx.alloc().buffer()); } if (completeHandshake(ctx)) { return; } } if (msg instanceof LastHttpContent) { return; } if (!(msg instanceof WebSocketFrame)) { throw new Exception( "Unexpected FullHttpResponse (getStatus=" + response.getStatus() + ", " + "content=" + response.content().toString(CharsetUtil.UTF_8) + ')'); } final WebSocketFrame frame = (WebSocketFrame) msg; if (frame instanceof TextWebSocketFrame) { for (WebSocketEventListener l : listensers) { l.onMessage(c, new WebSocketMessage(((TextWebSocketFrame) frame).text())); } } else if (frame instanceof PingWebSocketFrame) { if (autoPong) { ctx.writeAndFlush(new PongWebSocketFrame(frame.content().copy())); } for (WebSocketEventListener l : listensers) { l.onPing(c, (PingWebSocketFrame) frame.copy()); } } else if (frame instanceof PongWebSocketFrame) { Logger.getLogger(getClass()) .warn( String.format( "WebSocketClient received a PongWebSocketFrame, that shouldn't happen! Data : %s", frame.content().toString(CharsetUtil.UTF_8))); } else if (frame instanceof CloseWebSocketFrame) { ch.close(); for (WebSocketEventListener l : listensers) { l.onClose(c, (CloseWebSocketFrame) frame.copy()); } } }
private static void writeHttpResponse( ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res, Boolean close) { if (!omitDateHeader && !res.headers().contains(DefaultHttpHeaders.Names.DATE)) DefaultHttpHeaders.addDateHeader(res, DefaultHttpHeaders.Names.DATE, new Date()); // Send the response and close the connection if necessary. if (!HttpHeaders.isKeepAlive(req) || res.getStatus().code() != 200 || close == null || close) { res.headers().set(CONNECTION, HttpHeaders.Values.CLOSE); ctx.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE); } else { res.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); write(ctx, res); } }
@Test public void iframeHtml() throws Exception { final SockJsConfig config = config(); final String path = config.prefix() + "/iframe.html"; final FullHttpResponse response = Iframe.response(config, createHttpRequest(path)); assertThat(response.getStatus().code(), is(HttpResponseStatus.OK.code())); assertThat( response.headers().get(HttpHeaders.Names.CONTENT_TYPE), equalTo("text/html; charset=UTF-8")); assertThat( response.headers().get(HttpHeaders.Names.CACHE_CONTROL), equalTo("max-age=31536000, public")); assertThat(response.headers().get(HttpHeaders.Names.EXPIRES), is(notNullValue())); assertThat(response.headers().get(HttpHeaders.Names.SET_COOKIE), is(nullValue())); assertThat(response.headers().get(HttpHeaders.Names.ETAG), is(notNullValue())); }
protected boolean completeHandshake(ChannelHandlerContext ctx) { if (!handshaker.isHandshakeComplete()) { if (response != null && response.getStatus().code() > 299) { for (WebSocketEventListener l : listensers) { l.onError(ctx, null, response); } return true; } handshaker.finishHandshake(ctx.channel(), response); handshakeFuture.setSuccess(); for (WebSocketEventListener l : listensers) { l.onConnect(ctx); } return true; } return false; }
@Override protected ByteBuf extractResponse(Object message) throws XioException { if (!(message instanceof HttpObject)) { return null; } FullHttpResponse httpResponse = null; // HttpContent httpContent = null; // ByteBuf content = null; // XioClientChannel xioClientChannel; if (message instanceof FullHttpResponse) { httpResponse = (FullHttpResponse) message; // content = httpResponse.content(); // if (message instanceof LastHttpContent) { // LastHttpContent lastHttpContent = (LastHttpContent) message; // if (lastHttpContent.toString().equals("EmptyLastHttpContent")) { // ((LastHttpContent) message).release(); // } // } // if (message instanceof HttpContent) { // httpContent = (HttpContent) message; // // if (httpContent.getDecoderResult() == DecoderResult.SUCCESS) { // content = httpContent.content(); // } // // if (content != null) { // if (!content.isReadable()) { // log.error("Message Delivered with Unreadable Content"); // } // } // } // TODO(JR): Leave out for testing, ADD BACK BEFORE DEPLOYMENT!!!!! // switch (httpResponse.getStatus().reasonPhrase()) { // case("Unknown Status"): // throw wrapException(new XioTransportException("HTTP response had non-OK status: " // + httpResponse // .getStatus().toString())); // case("Informational"): // break; // case("Successful"): // break; // case("Redirection"): // break; // case("Client Error"): // throw wrapException(new XioTransportException("HTTP response had non-OK status: " // + httpResponse // .getStatus().toString())); // } // HttpContent httpContent = (HttpContent) httpResponse; String CRLF = "\r\n"; StringBuilder responseHeader = new StringBuilder(); responseHeader .append(httpResponse.getProtocolVersion()) .append(' ') .append(httpResponse.getStatus()) .append(CRLF); httpResponse .headers() .entries() .forEach( xs -> { responseHeader.append(xs.getKey()).append(": ").append(xs.getValue()).append(CRLF); }); responseHeader.append(CRLF); ByteBuf headerAndBody = getCtx().alloc().buffer(); headerAndBody.writeBytes(responseHeader.toString().getBytes(Charset.defaultCharset())); if (httpResponse.content() != null) { headerAndBody.writeBytes(httpResponse.content()); headerAndBody.writeBytes("\r\n".getBytes()); } return headerAndBody; } else { return null; } }