Search in sources :

Example 1 with HttpVersion

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

the class HttpServerImpl method listen.

public synchronized HttpServer listen(int port, String host, Handler<AsyncResult<HttpServer>> listenHandler) {
    if (requestStream.handler() == null && wsStream.handler() == null) {
        throw new IllegalStateException("Set request or websocket handler first");
    }
    if (listening) {
        throw new IllegalStateException("Already listening");
    }
    listenContext = vertx.getOrCreateContext();
    listening = true;
    serverOrigin = (options.isSsl() ? "https" : "http") + "://" + host + ":" + port;
    List<HttpVersion> applicationProtocols = options.getAlpnVersions();
    if (listenContext.isWorkerContext()) {
        applicationProtocols = applicationProtocols.stream().filter(v -> v != HttpVersion.HTTP_2).collect(Collectors.toList());
    }
    sslHelper.setApplicationProtocols(applicationProtocols);
    synchronized (vertx.sharedHttpServers()) {
        // Will be updated on bind for a wildcard port
        this.actualPort = port;
        id = new ServerID(port, host);
        HttpServerImpl shared = vertx.sharedHttpServers().get(id);
        if (shared == null || port == 0) {
            serverChannelGroup = new DefaultChannelGroup("vertx-acceptor-channels", GlobalEventExecutor.INSTANCE);
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(vertx.getAcceptorEventLoopGroup(), availableWorkers);
            bootstrap.channel(NioServerSocketChannel.class);
            applyConnectionOptions(bootstrap);
            sslHelper.validate(vertx);
            bootstrap.childHandler(new ChannelInitializer<Channel>() {

                @Override
                protected void initChannel(Channel ch) throws Exception {
                    if (requestStream.isPaused() || wsStream.isPaused()) {
                        ch.close();
                        return;
                    }
                    ChannelPipeline pipeline = ch.pipeline();
                    if (sslHelper.isSSL()) {
                        pipeline.addLast("ssl", sslHelper.createSslHandler(vertx));
                        if (options.isUseAlpn()) {
                            pipeline.addLast("alpn", new ApplicationProtocolNegotiationHandler("http/1.1") {

                                @Override
                                protected void configurePipeline(ChannelHandlerContext ctx, String protocol) throws Exception {
                                    if (protocol.equals("http/1.1")) {
                                        configureHttp1(pipeline);
                                    } else {
                                        handleHttp2(ch);
                                    }
                                }
                            });
                        } else {
                            configureHttp1(pipeline);
                        }
                    } else {
                        if (DISABLE_HC2) {
                            configureHttp1(pipeline);
                        } else {
                            pipeline.addLast(new Http1xOrHttp2Handler());
                        }
                    }
                }
            });
            addHandlers(this, listenContext);
            try {
                bindFuture = AsyncResolveConnectHelper.doBind(vertx, port, host, bootstrap);
                bindFuture.addListener(res -> {
                    if (res.failed()) {
                        vertx.sharedHttpServers().remove(id);
                    } else {
                        Channel serverChannel = res.result();
                        HttpServerImpl.this.actualPort = ((InetSocketAddress) serverChannel.localAddress()).getPort();
                        serverChannelGroup.add(serverChannel);
                        metrics = vertx.metricsSPI().createMetrics(this, new SocketAddressImpl(port, host), options);
                    }
                });
            } catch (final Throwable t) {
                // Make sure we send the exception back through the handler (if any)
                if (listenHandler != null) {
                    vertx.runOnContext(v -> listenHandler.handle(Future.failedFuture(t)));
                } else {
                    // No handler - log so user can see failure
                    log.error(t);
                }
                listening = false;
                return this;
            }
            vertx.sharedHttpServers().put(id, this);
            actualServer = this;
        } else {
            // Server already exists with that host/port - we will use that
            actualServer = shared;
            this.actualPort = shared.actualPort;
            addHandlers(actualServer, listenContext);
            metrics = vertx.metricsSPI().createMetrics(this, new SocketAddressImpl(port, host), options);
        }
        actualServer.bindFuture.addListener(future -> {
            if (listenHandler != null) {
                final AsyncResult<HttpServer> res;
                if (future.succeeded()) {
                    res = Future.succeededFuture(HttpServerImpl.this);
                } else {
                    res = Future.failedFuture(future.cause());
                    listening = false;
                }
                listenContext.runOnContext((v) -> listenHandler.handle(res));
            } else if (future.failed()) {
                listening = false;
                log.error(future.cause());
            }
        });
    }
    return this;
}
Also used : DefaultChannelGroup(io.netty.channel.group.DefaultChannelGroup) VertxException(io.vertx.core.VertxException) HandlerManager(io.vertx.core.net.impl.HandlerManager) ServerWebSocket(io.vertx.core.http.ServerWebSocket) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) WebSocketServerHandshakerFactory(io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) DefaultChannelGroup(io.netty.channel.group.DefaultChannelGroup) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) HttpServer(io.vertx.core.http.HttpServer) URISyntaxException(java.net.URISyntaxException) ChunkedWriteHandler(io.netty.handler.stream.ChunkedWriteHandler) Unpooled(io.netty.buffer.Unpooled) GlobalEventExecutor(io.netty.util.concurrent.GlobalEventExecutor) HttpServerMetrics(io.vertx.core.spi.metrics.HttpServerMetrics) HttpVersion(io.vertx.core.http.HttpVersion) Http2Exception(io.netty.handler.codec.http2.Http2Exception) Map(java.util.Map) ApplicationProtocolNegotiationHandler(io.netty.handler.ssl.ApplicationProtocolNegotiationHandler) CharsetUtil(io.netty.util.CharsetUtil) ReadStream(io.vertx.core.streams.ReadStream) WebSocketFrameImpl(io.vertx.core.http.impl.ws.WebSocketFrameImpl) URI(java.net.URI) Logger(io.vertx.core.logging.Logger) ChannelGroup(io.netty.channel.group.ChannelGroup) HttpRequest(io.netty.handler.codec.http.HttpRequest) ChannelInitializer(io.netty.channel.ChannelInitializer) PartialPooledByteBufAllocator(io.vertx.core.net.impl.PartialPooledByteBufAllocator) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) MetricsProvider(io.vertx.core.spi.metrics.MetricsProvider) ChannelPipeline(io.netty.channel.ChannelPipeline) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) Future(io.vertx.core.Future) ServerID(io.vertx.core.net.impl.ServerID) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) SslHandler(io.netty.handler.ssl.SslHandler) HandlerHolder(io.vertx.core.net.impl.HandlerHolder) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) WebSocketFrameInternal(io.vertx.core.http.impl.ws.WebSocketFrameInternal) VertxEventLoopGroup(io.vertx.core.net.impl.VertxEventLoopGroup) HttpServerRequest(io.vertx.core.http.HttpServerRequest) HttpVersion(io.netty.handler.codec.http.HttpVersion) ChannelOption(io.netty.channel.ChannelOption) LoggingHandler(io.netty.handler.logging.LoggingHandler) ContextImpl(io.vertx.core.impl.ContextImpl) FlashPolicyHandler(io.vertx.core.http.impl.cgbystrom.FlashPolicyHandler) WebSocketHandshakeException(io.netty.handler.codec.http.websocketx.WebSocketHandshakeException) LoggerFactory(io.vertx.core.logging.LoggerFactory) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) WebSocketVersion(io.netty.handler.codec.http.websocketx.WebSocketVersion) ByteBuf(io.netty.buffer.ByteBuf) FixedRecvByteBufAllocator(io.netty.channel.FixedRecvByteBufAllocator) ChannelFutureListener(io.netty.channel.ChannelFutureListener) AsyncResult(io.vertx.core.AsyncResult) HttpConnection(io.vertx.core.http.HttpConnection) Metrics(io.vertx.core.spi.metrics.Metrics) HttpContent(io.netty.handler.codec.http.HttpContent) Closeable(io.vertx.core.Closeable) VertxInternal(io.vertx.core.impl.VertxInternal) HttpHeaderValues(io.netty.handler.codec.http.HttpHeaderValues) AsyncResolveConnectHelper(io.vertx.core.net.impl.AsyncResolveConnectHelper) HttpMethod(io.netty.handler.codec.http.HttpMethod) SSLHelper(io.vertx.core.net.impl.SSLHelper) Channel(io.netty.channel.Channel) Http2Settings(io.netty.handler.codec.http2.Http2Settings) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler) WebSocketServerHandshaker(io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) HttpServerOptions(io.vertx.core.http.HttpServerOptions) ChannelHandler(io.netty.channel.ChannelHandler) ChannelGroupFuture(io.netty.channel.group.ChannelGroupFuture) HttpContentDecompressor(io.netty.handler.codec.http.HttpContentDecompressor) HttpRequestDecoder(io.netty.handler.codec.http.HttpRequestDecoder) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) Handler(io.vertx.core.Handler) SocketAddressImpl(io.vertx.core.net.impl.SocketAddressImpl) Http2CodecUtil(io.netty.handler.codec.http2.Http2CodecUtil) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) Channel(io.netty.channel.Channel) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) VertxException(io.vertx.core.VertxException) URISyntaxException(java.net.URISyntaxException) Http2Exception(io.netty.handler.codec.http2.Http2Exception) WebSocketHandshakeException(io.netty.handler.codec.http.websocketx.WebSocketHandshakeException) ChannelPipeline(io.netty.channel.ChannelPipeline) ApplicationProtocolNegotiationHandler(io.netty.handler.ssl.ApplicationProtocolNegotiationHandler) ServerID(io.vertx.core.net.impl.ServerID) HttpServer(io.vertx.core.http.HttpServer) SocketAddressImpl(io.vertx.core.net.impl.SocketAddressImpl) HttpVersion(io.vertx.core.http.HttpVersion) HttpVersion(io.netty.handler.codec.http.HttpVersion)

Example 2 with HttpVersion

use of io.netty.handler.codec.http.HttpVersion in project xipki by xipki.

the class HttpOcspServlet method servicePost.

private FullHttpResponse servicePost(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession, SslReverseProxyMode sslReverseProxyMode) throws Exception {
    HttpVersion version = request.protocolVersion();
    ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
    if (responderAndPath == null) {
        return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
    }
    try {
        // accept only "application/ocsp-request" as content type
        String reqContentType = request.headers().get("Content-Type");
        if (!CT_REQUEST.equalsIgnoreCase(reqContentType)) {
            return createErrorResponse(version, HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE);
        }
        Responder responder = responderAndPath.getResponder();
        int contentLen = request.content().readableBytes();
        // request too long
        if (contentLen > responder.getMaxRequestSize()) {
            return createErrorResponse(version, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE);
        }
        OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, readContent(request), false);
        if (ocspRespWithCacheInfo == null || ocspRespWithCacheInfo.getResponse() == null) {
            LOG.error("processRequest returned null, this should not happen");
            return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
        }
        byte[] encodedOcspResp = ocspRespWithCacheInfo.getResponse();
        return createOKResponse(version, CT_RESPONSE, encodedOcspResp);
    } catch (Throwable th) {
        if (th instanceof EOFException) {
            LogUtil.warn(LOG, th, "Connection reset by peer");
        } else {
            LOG.error("Throwable thrown, this should not happen!", th);
        }
        return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
    }
// end external try
}
Also used : OcspRespWithCacheInfo(org.xipki.ocsp.api.OcspRespWithCacheInfo) EOFException(java.io.EOFException) ResponderAndPath(org.xipki.ocsp.api.ResponderAndPath) HttpVersion(io.netty.handler.codec.http.HttpVersion) Responder(org.xipki.ocsp.api.Responder)

Example 3 with HttpVersion

use of io.netty.handler.codec.http.HttpVersion in project xipki by xipki.

the class HttpOcspServlet method serviceGet.

// method servicePost
private FullHttpResponse serviceGet(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession, SslReverseProxyMode sslReverseProxyMode) throws Exception {
    HttpVersion version = request.protocolVersion();
    ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
    if (responderAndPath == null) {
        return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
    }
    String path = servletUri.getPath();
    String servletPath = responderAndPath.getServletPath();
    Responder responder = responderAndPath.getResponder();
    if (!responder.supportsHttpGet()) {
        return createErrorResponse(version, HttpResponseStatus.METHOD_NOT_ALLOWED);
    }
    String b64OcspReq;
    int offset = servletPath.length();
    // GET URI contains the request and must be much longer than 10.
    if (path.length() - offset > 10) {
        if (path.charAt(offset) == '/') {
            offset++;
        }
        b64OcspReq = servletUri.getPath().substring(offset);
    } else {
        return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
    }
    try {
        // POST, we support GET for longer requests anyway.
        if (b64OcspReq.length() > responder.getMaxRequestSize()) {
            return createErrorResponse(version, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE);
        }
        OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, Base64.decode(b64OcspReq), true);
        if (ocspRespWithCacheInfo == null || ocspRespWithCacheInfo.getResponse() == null) {
            return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
        }
        byte[] encodedOcspResp = ocspRespWithCacheInfo.getResponse();
        FullHttpResponse response = createOKResponse(version, CT_RESPONSE, encodedOcspResp);
        OcspRespWithCacheInfo.ResponseCacheInfo cacheInfo = ocspRespWithCacheInfo.getCacheInfo();
        if (cacheInfo != null) {
            encodedOcspResp = ocspRespWithCacheInfo.getResponse();
            HttpHeaders headers = response.headers();
            // RFC 5019 6.2: Date: The date and time at which the OCSP server generated
            // the HTTP response.
            headers.add("Date", new Date());
            // RFC 5019 6.2: Last-Modified: date and time at which the OCSP responder
            // last modified the response.
            headers.add("Last-Modified", new Date(cacheInfo.getThisUpdate()));
            // This is overridden by max-age on HTTP/1.1 compatible components
            if (cacheInfo.getNextUpdate() != null) {
                headers.add("Expires", new Date(cacheInfo.getNextUpdate()));
            }
            // RFC 5019 6.2: This profile RECOMMENDS that the ETag value be the ASCII
            // HEX representation of the SHA1 hash of the OCSPResponse structure.
            headers.add("ETag", StringUtil.concat("\\", HashAlgo.SHA1.hexHash(encodedOcspResp), "\\"));
            // Max age must be in seconds in the cache-control header
            long maxAge;
            if (responder.getCacheMaxAge() != null) {
                maxAge = responder.getCacheMaxAge().longValue();
            } else {
                maxAge = DFLT_CACHE_MAX_AGE;
            }
            if (cacheInfo.getNextUpdate() != null) {
                maxAge = Math.min(maxAge, (cacheInfo.getNextUpdate() - cacheInfo.getThisUpdate()) / 1000);
            }
            headers.add("Cache-Control", StringUtil.concat("max-age=", Long.toString(maxAge), ",public,no-transform,must-revalidate"));
        }
        return response;
    } catch (Throwable th) {
        if (th instanceof EOFException) {
            LogUtil.warn(LOG, th, "Connection reset by peer");
        } else {
            LOG.error("Throwable thrown, this should not happen!", th);
        }
        return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
    }
// end external try
}
Also used : HttpHeaders(io.netty.handler.codec.http.HttpHeaders) ResponderAndPath(org.xipki.ocsp.api.ResponderAndPath) Date(java.util.Date) OcspRespWithCacheInfo(org.xipki.ocsp.api.OcspRespWithCacheInfo) EOFException(java.io.EOFException) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) HttpVersion(io.netty.handler.codec.http.HttpVersion) Responder(org.xipki.ocsp.api.Responder)

Example 4 with HttpVersion

use of io.netty.handler.codec.http.HttpVersion in project xipki by xipki.

the class HealthCheckServlet method service0.

private FullHttpResponse service0(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession) {
    HttpVersion version = request.protocolVersion();
    HttpMethod method = request.method();
    if (method != HttpMethod.GET) {
        return createErrorResponse(version, HttpResponseStatus.METHOD_NOT_ALLOWED);
    }
    try {
        if (server == null) {
            LOG.error("server in servlet not configured");
            return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
        }
        ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
        if (responderAndPath == null) {
            return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
        }
        HealthCheckResult healthResult = server.healthCheck(responderAndPath.getResponder());
        HttpResponseStatus status = healthResult.isHealthy() ? HttpResponseStatus.OK : HttpResponseStatus.INTERNAL_SERVER_ERROR;
        byte[] respBytes = healthResult.toJsonMessage(true).getBytes();
        return createResponse(version, status, HealthCheckServlet.CT_RESPONSE, respBytes);
    } catch (Throwable th) {
        if (th instanceof EOFException) {
            LogUtil.warn(LOG, th, "connection reset by peer");
        } else {
            LOG.error("Throwable thrown, this should not happen", th);
        }
        return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
    }
}
Also used : HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) EOFException(java.io.EOFException) HealthCheckResult(org.xipki.common.HealthCheckResult) ResponderAndPath(org.xipki.ocsp.api.ResponderAndPath) HttpVersion(io.netty.handler.codec.http.HttpVersion) HttpMethod(io.netty.handler.codec.http.HttpMethod)

Example 5 with HttpVersion

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

the class SpdyHttpDecoder method createHttpResponse.

private static FullHttpResponse createHttpResponse(SpdyHeadersFrame responseFrame, ByteBufAllocator alloc, boolean validateHeaders) throws Exception {
    // Create the first line of the response from the name/value pairs
    SpdyHeaders headers = responseFrame.headers();
    HttpResponseStatus status = HttpResponseStatus.parseLine(headers.get(STATUS));
    HttpVersion version = HttpVersion.valueOf(headers.getAsString(VERSION));
    headers.remove(STATUS);
    headers.remove(VERSION);
    boolean release = true;
    ByteBuf buffer = alloc.buffer();
    try {
        FullHttpResponse res = new DefaultFullHttpResponse(version, status, buffer, validateHeaders);
        for (Map.Entry<CharSequence, CharSequence> e : responseFrame.headers()) {
            res.headers().add(e.getKey(), e.getValue());
        }
        // The Connection and Keep-Alive headers are no longer valid
        HttpUtil.setKeepAlive(res, true);
        // Transfer-Encoding header is not valid
        res.headers().remove(HttpHeaderNames.TRANSFER_ENCODING);
        res.headers().remove(HttpHeaderNames.TRAILER);
        release = false;
        return res;
    } finally {
        if (release) {
            buffer.release();
        }
    }
}
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) HttpVersion(io.netty.handler.codec.http.HttpVersion) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

HttpVersion (io.netty.handler.codec.http.HttpVersion)20 HttpMethod (io.netty.handler.codec.http.HttpMethod)11 ByteBuf (io.netty.buffer.ByteBuf)8 HttpResponseStatus (io.netty.handler.codec.http.HttpResponseStatus)7 EOFException (java.io.EOFException)7 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)6 FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)5 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)5 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)4 Map (java.util.Map)4 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)3 HttpRequest (io.netty.handler.codec.http.HttpRequest)3 Date (java.util.Date)3 HashMap (java.util.HashMap)3 Test (org.junit.Test)3 AuditEvent (org.xipki.audit.AuditEvent)3 ResponderAndPath (org.xipki.ocsp.api.ResponderAndPath)3 DataProvider (com.tngtech.java.junit.dataprovider.DataProvider)2 Unpooled (io.netty.buffer.Unpooled)2 Channel (io.netty.channel.Channel)2