Search in sources :

Example 66 with LastHttpContent

use of io.netty.handler.codec.http.LastHttpContent in project reactor-netty by reactor.

the class HttpTrafficHandler method write.

@Override
@SuppressWarnings("FutureReturnValueIgnored")
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
    // modify message on way out to add headers if needed
    if (msg instanceof HttpResponse) {
        final HttpResponse response = (HttpResponse) msg;
        nonInformationalResponse = !isInformational(response);
        // Assume the response writer knows if they can persist or not and sets isKeepAlive on the response
        boolean maxKeepAliveRequestsReached = maxKeepAliveRequests != -1 && HttpServerOperations.requestsCounter(ctx.channel()) == maxKeepAliveRequests;
        if (maxKeepAliveRequestsReached || !isKeepAlive(response) || !isSelfDefinedMessageLength(response)) {
            // No longer keep alive as the client can't tell when the message is done unless we close connection
            pendingResponses = 0;
            persistentConnection = false;
        }
        // Server might think it can keep connection alive, but we should fix response header if we know better
        if (!shouldKeepAlive()) {
            setKeepAlive(response, false);
        }
        if (response.status().equals(HttpResponseStatus.CONTINUE)) {
            // "FutureReturnValueIgnored" this is deliberate
            ctx.write(msg, promise);
            return;
        }
    }
    if (msg instanceof LastHttpContent) {
        if (!shouldKeepAlive()) {
            if (HttpServerOperations.log.isDebugEnabled()) {
                HttpServerOperations.log.debug(format(ctx.channel(), "Detected non persistent http " + "connection, preparing to close"), pendingResponses);
            }
            ctx.write(msg, promise.unvoid()).addListener(this).addListener(ChannelFutureListener.CLOSE);
            return;
        }
        ctx.write(msg, promise.unvoid()).addListener(this);
        if (!persistentConnection) {
            return;
        }
        if (nonInformationalResponse) {
            nonInformationalResponse = false;
            pendingResponses -= 1;
            if (HttpServerOperations.log.isDebugEnabled()) {
                HttpServerOperations.log.debug(format(ctx.channel(), "Decreasing pending responses, now {}"), pendingResponses);
            }
        }
        if (pipelined != null && !pipelined.isEmpty()) {
            if (HttpServerOperations.log.isDebugEnabled()) {
                HttpServerOperations.log.debug(format(ctx.channel(), "Draining next pipelined " + "request, pending response count: {}, queued: {}"), pendingResponses, pipelined.size());
            }
            ctx.executor().execute(this);
        } else {
            ctx.read();
        }
        return;
    }
    if (persistentConnection && pendingResponses == 0) {
        if (HttpServerOperations.log.isDebugEnabled()) {
            HttpServerOperations.log.debug(format(ctx.channel(), "Dropped HTTP content, " + "since response has been sent already: {}"), toPrettyHexDump(msg));
        }
        ReferenceCountUtil.release(msg);
        promise.setSuccess();
        return;
    }
    // "FutureReturnValueIgnored" this is deliberate
    ctx.write(msg, promise);
}
Also used : HttpResponse(io.netty.handler.codec.http.HttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent)

Example 67 with LastHttpContent

use of io.netty.handler.codec.http.LastHttpContent in project reactor-netty by reactor.

the class HttpTrafficHandler method channelRead.

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    if (secure == null) {
        secure = ctx.channel().pipeline().get(SslHandler.class) != null;
    }
    if (remoteAddress == null) {
        remoteAddress = Optional.ofNullable(HAProxyMessageReader.resolveRemoteAddressFromProxyProtocol(ctx.channel())).orElse(ctx.channel().remoteAddress());
    }
    // read message and track if it was keepAlive
    if (msg instanceof HttpRequest) {
        IdleTimeoutHandler.removeIdleTimeoutHandler(ctx.pipeline());
        final HttpRequest request = (HttpRequest) msg;
        if (H2.equals(request.protocolVersion())) {
            sendDecodingFailures(new IllegalStateException("Unexpected request [" + request.method() + " " + request.uri() + " HTTP/2.0]"), msg);
            return;
        }
        if (persistentConnection) {
            pendingResponses += 1;
            if (HttpServerOperations.log.isDebugEnabled()) {
                HttpServerOperations.log.debug(format(ctx.channel(), "Increasing pending responses, now {}"), pendingResponses);
            }
            persistentConnection = isKeepAlive(request);
        } else {
            if (HttpServerOperations.log.isDebugEnabled()) {
                HttpServerOperations.log.debug(format(ctx.channel(), "Dropping pipelined HTTP request, " + "previous response requested connection close"));
            }
            ReferenceCountUtil.release(msg);
            return;
        }
        if (pendingResponses > 1) {
            if (HttpServerOperations.log.isDebugEnabled()) {
                HttpServerOperations.log.debug(format(ctx.channel(), "Buffering pipelined HTTP request, " + "pending response count: {}, queue: {}"), pendingResponses, pipelined != null ? pipelined.size() : 0);
            }
            overflow = true;
            doPipeline(ctx, msg);
            return;
        } else {
            overflow = false;
            DecoderResult decoderResult = request.decoderResult();
            if (decoderResult.isFailure()) {
                sendDecodingFailures(decoderResult.cause(), msg);
                return;
            }
            HttpServerOperations ops;
            try {
                ops = new HttpServerOperations(Connection.from(ctx.channel()), listener, request, compress, ConnectionInfo.from(ctx.channel(), request, secure, remoteAddress, forwardedHeaderHandler), cookieDecoder, cookieEncoder, formDecoderProvider, mapHandle, secure);
            } catch (RuntimeException e) {
                sendDecodingFailures(e, msg);
                return;
            }
            ops.bind();
            listener.onStateChange(ops, ConnectionObserver.State.CONFIGURED);
            ctx.fireChannelRead(msg);
            return;
        }
    } else if (persistentConnection && pendingResponses == 0) {
        if (msg instanceof LastHttpContent) {
            DecoderResult decoderResult = ((LastHttpContent) msg).decoderResult();
            if (decoderResult.isFailure()) {
                sendDecodingFailures(decoderResult.cause(), msg);
                return;
            }
            ctx.fireChannelRead(msg);
        } else {
            if (HttpServerOperations.log.isDebugEnabled()) {
                HttpServerOperations.log.debug(format(ctx.channel(), "Dropped HTTP content, " + "since response has been sent already: {}"), msg);
            }
            ReferenceCountUtil.release(msg);
        }
        ctx.read();
        return;
    } else if (overflow) {
        if (HttpServerOperations.log.isDebugEnabled()) {
            HttpServerOperations.log.debug(format(ctx.channel(), "Buffering pipelined HTTP content, " + "pending response count: {}, pending pipeline:{}"), pendingResponses, pipelined != null ? pipelined.size() : 0);
        }
        doPipeline(ctx, msg);
        return;
    }
    if (msg instanceof DecoderResultProvider) {
        DecoderResult decoderResult = ((DecoderResultProvider) msg).decoderResult();
        if (decoderResult.isFailure()) {
            sendDecodingFailures(decoderResult.cause(), msg);
            return;
        }
    }
    ctx.fireChannelRead(msg);
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) DecoderResultProvider(io.netty.handler.codec.DecoderResultProvider) DecoderResult(io.netty.handler.codec.DecoderResult) LastHttpContent(io.netty.handler.codec.http.LastHttpContent)

Example 68 with LastHttpContent

use of io.netty.handler.codec.http.LastHttpContent in project apn-proxy by apn-proxy.

the class TestHttpClientHandler method channelRead0.

@Override
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
    //        }
    if (msg instanceof HttpResponse) {
        HttpResponse response = (HttpResponse) msg;
        TestResultHolder.httpStatusCode(response.getStatus().code());
    }
    if (msg instanceof LastHttpContent) {
        ctx.close();
    }
}
Also used : HttpResponse(io.netty.handler.codec.http.HttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent)

Example 69 with LastHttpContent

use of io.netty.handler.codec.http.LastHttpContent in project vert.x by eclipse.

the class VertxHttpHandler method safeObject.

@Override
protected Object safeObject(Object msg, ByteBufAllocator allocator) throws Exception {
    if (msg instanceof HttpContent) {
        HttpContent content = (HttpContent) msg;
        ByteBuf buf = content.content();
        if (buf != Unpooled.EMPTY_BUFFER && buf.isDirect()) {
            ByteBuf newBuf = safeBuffer(content, allocator);
            if (msg instanceof LastHttpContent) {
                LastHttpContent last = (LastHttpContent) msg;
                return new AssembledLastHttpContent(newBuf, last.trailingHeaders(), last.getDecoderResult());
            } else {
                return new DefaultHttpContent(newBuf);
            }
        }
    } else if (msg instanceof WebSocketFrame) {
        ByteBuf payload = safeBuffer((WebSocketFrame) msg, allocator);
        boolean isFinal = ((WebSocketFrame) msg).isFinalFragment();
        FrameType frameType;
        if (msg instanceof BinaryWebSocketFrame) {
            frameType = FrameType.BINARY;
        } else if (msg instanceof CloseWebSocketFrame) {
            frameType = FrameType.CLOSE;
        } else if (msg instanceof PingWebSocketFrame) {
            frameType = FrameType.PING;
        } else if (msg instanceof PongWebSocketFrame) {
            frameType = FrameType.PONG;
        } else if (msg instanceof TextWebSocketFrame) {
            frameType = FrameType.TEXT;
        } else if (msg instanceof ContinuationWebSocketFrame) {
            frameType = FrameType.CONTINUATION;
        } else {
            throw new IllegalStateException("Unsupported websocket msg " + msg);
        }
        return new WebSocketFrameImpl(frameType, payload, isFinal);
    }
    return msg;
}
Also used : DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) ByteBuf(io.netty.buffer.ByteBuf) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) WebSocketFrameImpl(io.vertx.core.http.impl.ws.WebSocketFrameImpl) HttpContent(io.netty.handler.codec.http.HttpContent) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent)

Example 70 with LastHttpContent

use of io.netty.handler.codec.http.LastHttpContent in project vert.x by eclipse.

the class ClientHandler method doMessageReceived.

@Override
protected void doMessageReceived(ClientConnection conn, ChannelHandlerContext ctx, Object msg) {
    if (conn == null) {
        return;
    }
    if (msg instanceof HttpObject) {
        HttpObject obj = (HttpObject) msg;
        DecoderResult result = obj.decoderResult();
        if (result.isFailure()) {
            // Close the connection as Netty's HttpResponseDecoder will not try further processing
            // see https://github.com/netty/netty/issues/3362
            conn.handleException(result.cause());
            conn.close();
            return;
        }
        if (msg instanceof HttpResponse) {
            HttpResponse response = (HttpResponse) obj;
            conn.handleResponse(response);
            return;
        }
        if (msg instanceof HttpContent) {
            HttpContent chunk = (HttpContent) obj;
            if (chunk.content().isReadable()) {
                Buffer buff = Buffer.buffer(chunk.content().slice());
                conn.handleResponseChunk(buff);
            }
            if (chunk instanceof LastHttpContent) {
                conn.handleResponseEnd((LastHttpContent) chunk);
            }
            return;
        }
    } else if (msg instanceof WebSocketFrameInternal) {
        WebSocketFrameInternal frame = (WebSocketFrameInternal) msg;
        switch(frame.type()) {
            case BINARY:
            case CONTINUATION:
            case TEXT:
                conn.handleWsFrame(frame);
                break;
            case PING:
                // Echo back the content of the PING frame as PONG frame as specified in RFC 6455 Section 5.5.2
                ctx.writeAndFlush(new WebSocketFrameImpl(FrameType.PONG, frame.getBinaryData()));
                break;
            case PONG:
                // Just ignore it
                break;
            case CLOSE:
                if (!closeFrameSent) {
                    // Echo back close frame and close the connection once it was written.
                    // This is specified in the WebSockets RFC 6455 Section  5.4.1
                    ctx.writeAndFlush(frame).addListener(ChannelFutureListener.CLOSE);
                    closeFrameSent = true;
                }
                break;
            default:
                throw new IllegalStateException("Invalid type: " + frame.type());
        }
        return;
    }
    throw new IllegalStateException("Invalid object " + msg);
}
Also used : Buffer(io.vertx.core.buffer.Buffer) WebSocketFrameImpl(io.vertx.core.http.impl.ws.WebSocketFrameImpl) HttpObject(io.netty.handler.codec.http.HttpObject) DecoderResult(io.netty.handler.codec.DecoderResult) HttpResponse(io.netty.handler.codec.http.HttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) WebSocketFrameInternal(io.vertx.core.http.impl.ws.WebSocketFrameInternal)

Aggregations

LastHttpContent (io.netty.handler.codec.http.LastHttpContent)137 DefaultLastHttpContent (io.netty.handler.codec.http.DefaultLastHttpContent)63 HttpContent (io.netty.handler.codec.http.HttpContent)55 ByteBuf (io.netty.buffer.ByteBuf)49 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)43 HttpResponse (io.netty.handler.codec.http.HttpResponse)42 HttpRequest (io.netty.handler.codec.http.HttpRequest)34 Test (org.junit.Test)27 Test (org.junit.jupiter.api.Test)24 DefaultHttpContent (io.netty.handler.codec.http.DefaultHttpContent)23 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)20 FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)18 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)13 ChannelFuture (io.netty.channel.ChannelFuture)11 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)10 HttpObject (io.netty.handler.codec.http.HttpObject)10 JsonObjectDecoder (io.netty.handler.codec.json.JsonObjectDecoder)10 IOException (java.io.IOException)10 HttpProcessingState (com.nike.riposte.server.http.HttpProcessingState)9 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)9