Search in sources :

Example 91 with FullHttpResponse

use of io.netty.handler.codec.http.FullHttpResponse in project netty by netty.

the class Http2RequestHandler method handleImage.

private void handleImage(String x, String y, ChannelHandlerContext ctx, String streamId, int latency, FullHttpRequest request) {
    ByteBuf image = ImageCache.INSTANCE.image(parseInt(x), parseInt(y));
    FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, image.duplicate());
    response.headers().set(CONTENT_TYPE, "image/jpeg");
    sendResponse(ctx, streamId, latency, response, request);
}
Also used : DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) ByteBuf(io.netty.buffer.ByteBuf)

Example 92 with FullHttpResponse

use of io.netty.handler.codec.http.FullHttpResponse in project netty by netty.

the class WebSocketServerHandshaker08 method newHandshakeResponse.

/**
 * <p>
 * Handle the web socket handshake for the web socket specification <a href=
 * "https://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) {
    CharSequence key = req.headers().get(HttpHeaderNames.SEC_WEBSOCKET_KEY);
    if (key == null) {
        throw new WebSocketServerHandshakeException("not a WebSocket request: missing key", req);
    }
    FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS, req.content().alloc().buffer(0));
    if (headers != null) {
        res.headers().add(headers);
    }
    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().set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET).set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE).set(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT, accept);
    String subprotocols = req.headers().get(HttpHeaderNames.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().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
        }
    }
    return res;
}
Also used : DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse)

Example 93 with FullHttpResponse

use of io.netty.handler.codec.http.FullHttpResponse in project netty by netty.

the class WebSocketServerProtocolHandler method exceptionCaught.

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    if (cause instanceof WebSocketHandshakeException) {
        FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.BAD_REQUEST, Unpooled.wrappedBuffer(cause.getMessage().getBytes()));
        ctx.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    } else {
        ctx.fireExceptionCaught(cause);
        ctx.close();
    }
}
Also used : DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse)

Example 94 with FullHttpResponse

use of io.netty.handler.codec.http.FullHttpResponse in project netty by netty.

the class WebSocketServerHandshaker00 method newHandshakeResponse.

/**
 * <p>
 * Handle the web socket handshake for the web socket specification <a href=
 * "https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00">HyBi version 0</a> and lower. This standard
 * is really a rehash of <a href="https://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76" >hixie-76</a> and
 * <a href="https://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75" >hixie-75</a>.
 * </p>
 *
 * <p>
 * Browser request to the server:
 * </p>
 *
 * <pre>
 * GET /demo HTTP/1.1
 * Upgrade: WebSocket
 * Connection: Upgrade
 * Host: example.com
 * Origin: http://example.com
 * Sec-WebSocket-Protocol: chat, sample
 * Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
 * Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
 *
 * ^n:ds[4U
 * </pre>
 *
 * <p>
 * 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>
 */
@Override
protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
    // Serve the WebSocket handshake request.
    if (!req.headers().containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE, true) || !HttpHeaderValues.WEBSOCKET.contentEqualsIgnoreCase(req.headers().get(HttpHeaderNames.UPGRADE))) {
        throw new WebSocketServerHandshakeException("not a WebSocket handshake request: missing upgrade", req);
    }
    // Hixie 75 does not contain these headers while Hixie 76 does
    boolean isHixie76 = req.headers().contains(HttpHeaderNames.SEC_WEBSOCKET_KEY1) && req.headers().contains(HttpHeaderNames.SEC_WEBSOCKET_KEY2);
    String origin = req.headers().get(HttpHeaderNames.ORIGIN);
    // throw before allocating FullHttpResponse
    if (origin == null && !isHixie76) {
        throw new WebSocketServerHandshakeException("Missing origin header, got only " + req.headers().names(), req);
    }
    // Create the WebSocket handshake response.
    FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, new HttpResponseStatus(101, isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake"), req.content().alloc().buffer(0));
    if (headers != null) {
        res.headers().add(headers);
    }
    res.headers().set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET).set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE);
    // Fill in the headers and contents depending on handshake getMethod.
    if (isHixie76) {
        // New handshake getMethod with a challenge:
        res.headers().add(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN, origin);
        res.headers().add(HttpHeaderNames.SEC_WEBSOCKET_LOCATION, uri());
        String subprotocols = req.headers().get(HttpHeaderNames.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().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
            }
        }
        // Calculate the answer of the challenge.
        String key1 = req.headers().get(HttpHeaderNames.SEC_WEBSOCKET_KEY1);
        String key2 = req.headers().get(HttpHeaderNames.SEC_WEBSOCKET_KEY2);
        int a = (int) (Long.parseLong(BEGINNING_DIGIT.matcher(key1).replaceAll("")) / BEGINNING_SPACE.matcher(key1).replaceAll("").length());
        int b = (int) (Long.parseLong(BEGINNING_DIGIT.matcher(key2).replaceAll("")) / BEGINNING_SPACE.matcher(key2).replaceAll("").length());
        long c = req.content().readLong();
        ByteBuf input = Unpooled.wrappedBuffer(new byte[16]).setIndex(0, 0);
        input.writeInt(a);
        input.writeInt(b);
        input.writeLong(c);
        res.content().writeBytes(WebSocketUtil.md5(input.array()));
    } else {
        // Old Hixie 75 handshake getMethod with no challenge:
        res.headers().add(HttpHeaderNames.WEBSOCKET_ORIGIN, origin);
        res.headers().add(HttpHeaderNames.WEBSOCKET_LOCATION, uri());
        String protocol = req.headers().get(HttpHeaderNames.WEBSOCKET_PROTOCOL);
        if (protocol != null) {
            res.headers().set(HttpHeaderNames.WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
        }
    }
    return res;
}
Also used : DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) ByteBuf(io.netty.buffer.ByteBuf)

Example 95 with FullHttpResponse

use of io.netty.handler.codec.http.FullHttpResponse in project netty by netty.

the class SpdyHttpDecoder method decode.

@Override
protected void decode(ChannelHandlerContext ctx, SpdyFrame msg, List<Object> out) throws Exception {
    if (msg instanceof SpdySynStreamFrame) {
        // HTTP requests/responses are mapped one-to-one to SPDY streams.
        SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
        int streamId = spdySynStreamFrame.streamId();
        if (SpdyCodecUtil.isServerId(streamId)) {
            // SYN_STREAM frames initiated by the server are pushed resources
            int associatedToStreamId = spdySynStreamFrame.associatedStreamId();
            // it must reply with a RST_STREAM with error code INVALID_STREAM.
            if (associatedToStreamId == 0) {
                SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.INVALID_STREAM);
                ctx.writeAndFlush(spdyRstStreamFrame);
                return;
            }
            // (we only support pushed resources divided into two header blocks).
            if (spdySynStreamFrame.isLast()) {
                SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.PROTOCOL_ERROR);
                ctx.writeAndFlush(spdyRstStreamFrame);
                return;
            }
            // reply with a RST_STREAM with error code INTERNAL_ERROR.
            if (spdySynStreamFrame.isTruncated()) {
                SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.INTERNAL_ERROR);
                ctx.writeAndFlush(spdyRstStreamFrame);
                return;
            }
            try {
                FullHttpRequest httpRequestWithEntity = createHttpRequest(spdySynStreamFrame, ctx.alloc());
                // Set the Stream-ID, Associated-To-Stream-ID, and Priority as headers
                httpRequestWithEntity.headers().setInt(Names.STREAM_ID, streamId);
                httpRequestWithEntity.headers().setInt(Names.ASSOCIATED_TO_STREAM_ID, associatedToStreamId);
                httpRequestWithEntity.headers().setInt(Names.PRIORITY, spdySynStreamFrame.priority());
                out.add(httpRequestWithEntity);
            } catch (Throwable ignored) {
                SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.PROTOCOL_ERROR);
                ctx.writeAndFlush(spdyRstStreamFrame);
            }
        } else {
            // reply with an HTTP 431 REQUEST HEADER FIELDS TOO LARGE reply.
            if (spdySynStreamFrame.isTruncated()) {
                SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId);
                spdySynReplyFrame.setLast(true);
                SpdyHeaders frameHeaders = spdySynReplyFrame.headers();
                frameHeaders.setInt(STATUS, HttpResponseStatus.REQUEST_HEADER_FIELDS_TOO_LARGE.code());
                frameHeaders.setObject(VERSION, HttpVersion.HTTP_1_0);
                ctx.writeAndFlush(spdySynReplyFrame);
                return;
            }
            try {
                FullHttpRequest httpRequestWithEntity = createHttpRequest(spdySynStreamFrame, ctx.alloc());
                // Set the Stream-ID as a header
                httpRequestWithEntity.headers().setInt(Names.STREAM_ID, streamId);
                if (spdySynStreamFrame.isLast()) {
                    out.add(httpRequestWithEntity);
                } else {
                    // Request body will follow in a series of Data Frames
                    putMessage(streamId, httpRequestWithEntity);
                }
            } catch (Throwable t) {
                // If a client sends a SYN_STREAM without all of the getMethod, url (host and path),
                // scheme, and version headers the server must reply with an HTTP 400 BAD REQUEST reply.
                // Also sends HTTP 400 BAD REQUEST reply if header name/value pairs are invalid
                SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId);
                spdySynReplyFrame.setLast(true);
                SpdyHeaders frameHeaders = spdySynReplyFrame.headers();
                frameHeaders.setInt(STATUS, HttpResponseStatus.BAD_REQUEST.code());
                frameHeaders.setObject(VERSION, HttpVersion.HTTP_1_0);
                ctx.writeAndFlush(spdySynReplyFrame);
            }
        }
    } else if (msg instanceof SpdySynReplyFrame) {
        SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
        int streamId = spdySynReplyFrame.streamId();
        // reply with a RST_STREAM frame with error code INTERNAL_ERROR.
        if (spdySynReplyFrame.isTruncated()) {
            SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.INTERNAL_ERROR);
            ctx.writeAndFlush(spdyRstStreamFrame);
            return;
        }
        try {
            FullHttpResponse httpResponseWithEntity = createHttpResponse(spdySynReplyFrame, ctx.alloc(), validateHeaders);
            // Set the Stream-ID as a header
            httpResponseWithEntity.headers().setInt(Names.STREAM_ID, streamId);
            if (spdySynReplyFrame.isLast()) {
                HttpUtil.setContentLength(httpResponseWithEntity, 0);
                out.add(httpResponseWithEntity);
            } else {
                // Response body will follow in a series of Data Frames
                putMessage(streamId, httpResponseWithEntity);
            }
        } catch (Throwable t) {
            // If a client receives a SYN_REPLY without valid getStatus and version headers
            // the client must reply with a RST_STREAM frame indicating a PROTOCOL_ERROR
            SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.PROTOCOL_ERROR);
            ctx.writeAndFlush(spdyRstStreamFrame);
        }
    } else if (msg instanceof SpdyHeadersFrame) {
        SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
        int streamId = spdyHeadersFrame.streamId();
        FullHttpMessage fullHttpMessage = getMessage(streamId);
        if (fullHttpMessage == null) {
            // HEADERS frames may initiate a pushed response
            if (SpdyCodecUtil.isServerId(streamId)) {
                // reply with a RST_STREAM frame with error code INTERNAL_ERROR.
                if (spdyHeadersFrame.isTruncated()) {
                    SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.INTERNAL_ERROR);
                    ctx.writeAndFlush(spdyRstStreamFrame);
                    return;
                }
                try {
                    fullHttpMessage = createHttpResponse(spdyHeadersFrame, ctx.alloc(), validateHeaders);
                    // Set the Stream-ID as a header
                    fullHttpMessage.headers().setInt(Names.STREAM_ID, streamId);
                    if (spdyHeadersFrame.isLast()) {
                        HttpUtil.setContentLength(fullHttpMessage, 0);
                        out.add(fullHttpMessage);
                    } else {
                        // Response body will follow in a series of Data Frames
                        putMessage(streamId, fullHttpMessage);
                    }
                } catch (Throwable t) {
                    // If a client receives a SYN_REPLY without valid getStatus and version headers
                    // the client must reply with a RST_STREAM frame indicating a PROTOCOL_ERROR
                    SpdyRstStreamFrame spdyRstStreamFrame = new DefaultSpdyRstStreamFrame(streamId, SpdyStreamStatus.PROTOCOL_ERROR);
                    ctx.writeAndFlush(spdyRstStreamFrame);
                }
            }
            return;
        }
        // Ignore trailers in a truncated HEADERS frame.
        if (!spdyHeadersFrame.isTruncated()) {
            for (Map.Entry<CharSequence, CharSequence> e : spdyHeadersFrame.headers()) {
                fullHttpMessage.headers().add(e.getKey(), e.getValue());
            }
        }
        if (spdyHeadersFrame.isLast()) {
            HttpUtil.setContentLength(fullHttpMessage, fullHttpMessage.content().readableBytes());
            removeMessage(streamId);
            out.add(fullHttpMessage);
        }
    } else if (msg instanceof SpdyDataFrame) {
        SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
        int streamId = spdyDataFrame.streamId();
        FullHttpMessage fullHttpMessage = getMessage(streamId);
        // If message is not in map discard Data Frame.
        if (fullHttpMessage == null) {
            return;
        }
        ByteBuf content = fullHttpMessage.content();
        if (content.readableBytes() > maxContentLength - spdyDataFrame.content().readableBytes()) {
            removeMessage(streamId);
            throw new TooLongFrameException("HTTP content length exceeded " + maxContentLength + " bytes.");
        }
        ByteBuf spdyDataFrameData = spdyDataFrame.content();
        int spdyDataFrameDataLen = spdyDataFrameData.readableBytes();
        content.writeBytes(spdyDataFrameData, spdyDataFrameData.readerIndex(), spdyDataFrameDataLen);
        if (spdyDataFrame.isLast()) {
            HttpUtil.setContentLength(fullHttpMessage, content.readableBytes());
            removeMessage(streamId);
            out.add(fullHttpMessage);
        }
    } else if (msg instanceof SpdyRstStreamFrame) {
        SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg;
        int streamId = spdyRstStreamFrame.streamId();
        removeMessage(streamId);
    }
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) TooLongFrameException(io.netty.handler.codec.TooLongFrameException) FullHttpMessage(io.netty.handler.codec.http.FullHttpMessage) ByteBuf(io.netty.buffer.ByteBuf) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)256 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)172 ByteBuf (io.netty.buffer.ByteBuf)53 Test (org.junit.Test)50 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)38 HttpRequest (io.netty.handler.codec.http.HttpRequest)34 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)24 HttpObject (io.netty.handler.codec.http.HttpObject)23 IOException (java.io.IOException)23 HttpTrade (org.jocean.http.server.HttpServerBuilder.HttpTrade)23 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)21 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)21 LastHttpContent (io.netty.handler.codec.http.LastHttpContent)21 Test (org.junit.jupiter.api.Test)21 ChannelFuture (io.netty.channel.ChannelFuture)20 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)20 HttpInitiator (org.jocean.http.client.HttpClient.HttpInitiator)20 Subscription (rx.Subscription)20 LocalAddress (io.netty.channel.local.LocalAddress)19 HttpResponse (io.netty.handler.codec.http.HttpResponse)19