Search in sources :

Example 11 with DefaultHttpResponse

use of io.netty.handler.codec.http.DefaultHttpResponse in project camel by apache.

the class HttpServerChannelHandler method channelRead0.

@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
    HttpRequest request = (HttpRequest) msg;
    LOG.debug("Message received: {}", request);
    if (consumer.isSuspended()) {
        // are we suspended?
        LOG.debug("Consumer suspended, cannot service request {}", request);
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, SERVICE_UNAVAILABLE);
        response.headers().set(Exchange.CONTENT_TYPE, "text/plain");
        response.headers().set(Exchange.CONTENT_LENGTH, 0);
        ctx.writeAndFlush(response);
        ctx.channel().close();
        return;
    }
    // if its an OPTIONS request then return which methods is allowed
    boolean isRestrictedToOptions = consumer.getEndpoint().getHttpMethodRestrict() != null && consumer.getEndpoint().getHttpMethodRestrict().contains("OPTIONS");
    if ("OPTIONS".equals(request.method().name()) && !isRestrictedToOptions) {
        String s;
        if (consumer.getEndpoint().getHttpMethodRestrict() != null) {
            s = "OPTIONS," + consumer.getEndpoint().getHttpMethodRestrict();
        } else {
            // allow them all
            s = "GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,CONNECT,PATCH";
        }
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        response.headers().set("Allow", s);
        response.headers().set(Exchange.CONTENT_TYPE, "text/plain");
        response.headers().set(Exchange.CONTENT_LENGTH, 0);
        ctx.writeAndFlush(response);
        return;
    }
    if (consumer.getEndpoint().getHttpMethodRestrict() != null && !consumer.getEndpoint().getHttpMethodRestrict().contains(request.method().name())) {
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, METHOD_NOT_ALLOWED);
        response.headers().set(Exchange.CONTENT_TYPE, "text/plain");
        response.headers().set(Exchange.CONTENT_LENGTH, 0);
        ctx.writeAndFlush(response);
        ctx.channel().close();
        return;
    }
    if ("TRACE".equals(request.method().name()) && !consumer.getEndpoint().isTraceEnabled()) {
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, METHOD_NOT_ALLOWED);
        response.headers().set(Exchange.CONTENT_TYPE, "text/plain");
        response.headers().set(Exchange.CONTENT_LENGTH, 0);
        ctx.writeAndFlush(response);
        ctx.channel().close();
        return;
    }
    // must include HOST header as required by HTTP 1.1
    if (!request.headers().contains(HttpHeaderNames.HOST.toString())) {
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, BAD_REQUEST);
        //response.setChunked(false);
        response.headers().set(Exchange.CONTENT_TYPE, "text/plain");
        response.headers().set(Exchange.CONTENT_LENGTH, 0);
        ctx.writeAndFlush(response);
        ctx.channel().close();
        return;
    }
    // is basic auth configured
    NettyHttpSecurityConfiguration security = consumer.getEndpoint().getSecurityConfiguration();
    if (security != null && security.isAuthenticate() && "Basic".equalsIgnoreCase(security.getConstraint())) {
        String url = request.uri();
        // drop parameters from url
        if (url.contains("?")) {
            url = ObjectHelper.before(url, "?");
        }
        // we need the relative path without the hostname and port
        URI uri = new URI(request.uri());
        String target = uri.getPath();
        // strip the starting endpoint path so the target is relative to the endpoint uri
        String path = consumer.getConfiguration().getPath();
        if (path != null && target.startsWith(path)) {
            // need to match by lower case as we want to ignore case on context-path
            path = path.toLowerCase(Locale.US);
            String match = target.toLowerCase(Locale.US);
            if (match.startsWith(path)) {
                target = target.substring(path.length());
            }
        }
        // is it a restricted resource?
        String roles;
        if (security.getSecurityConstraint() != null) {
            // if restricted returns null, then the resource is not restricted and we should not authenticate the user
            roles = security.getSecurityConstraint().restricted(target);
        } else {
            // assume any roles is valid if no security constraint has been configured
            roles = "*";
        }
        if (roles != null) {
            // basic auth subject
            HttpPrincipal principal = extractBasicAuthSubject(request);
            // authenticate principal and check if the user is in role
            Subject subject = null;
            boolean inRole = true;
            if (principal != null) {
                subject = authenticate(security.getSecurityAuthenticator(), security.getLoginDeniedLoggingLevel(), principal);
                if (subject != null) {
                    String userRoles = security.getSecurityAuthenticator().getUserRoles(subject);
                    inRole = matchesRoles(roles, userRoles);
                }
            }
            if (principal == null || subject == null || !inRole) {
                if (principal == null) {
                    LOG.debug("Http Basic Auth required for resource: {}", url);
                } else if (subject == null) {
                    LOG.debug("Http Basic Auth not authorized for username: {}", principal.getUsername());
                } else {
                    LOG.debug("Http Basic Auth not in role for username: {}", principal.getUsername());
                }
                // restricted resource, so send back 401 to require valid username/password
                HttpResponse response = new DefaultHttpResponse(HTTP_1_1, UNAUTHORIZED);
                response.headers().set("WWW-Authenticate", "Basic realm=\"" + security.getRealm() + "\"");
                response.headers().set(Exchange.CONTENT_TYPE, "text/plain");
                response.headers().set(Exchange.CONTENT_LENGTH, 0);
                ctx.writeAndFlush(response);
                // close the channel
                ctx.channel().close();
                return;
            } else {
                LOG.debug("Http Basic Auth authorized for username: {}", principal.getUsername());
            }
        }
    }
    // let Camel process this message
    super.channelRead0(ctx, msg);
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) NettyHttpSecurityConfiguration(org.apache.camel.component.netty4.http.NettyHttpSecurityConfiguration) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(io.netty.handler.codec.http.HttpResponse) URI(java.net.URI) HttpPrincipal(org.apache.camel.component.netty4.http.HttpPrincipal) Subject(javax.security.auth.Subject)

Example 12 with DefaultHttpResponse

use of io.netty.handler.codec.http.DefaultHttpResponse in project camel by apache.

the class HttpServerMultiplexChannelHandler method channelRead0.

@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
    // store request, as this channel handler is created per pipeline
    HttpRequest request = (HttpRequest) msg;
    LOG.debug("Message received: {}", request);
    HttpServerChannelHandler handler = getHandler(request);
    if (handler != null) {
        Attribute<HttpServerChannelHandler> attr = ctx.channel().attr(SERVER_HANDLER_KEY);
        // store handler as attachment
        attr.set(handler);
        if (msg instanceof HttpContent) {
            // need to hold the reference of content
            HttpContent httpContent = (HttpContent) msg;
            httpContent.content().retain();
        }
        handler.channelRead(ctx, request);
    } else {
        // this resource is not found, so send empty response back
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND);
        response.headers().set(Exchange.CONTENT_TYPE, "text/plain");
        response.headers().set(Exchange.CONTENT_LENGTH, 0);
        ctx.writeAndFlush(response);
        ctx.close();
    }
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(io.netty.handler.codec.http.HttpResponse) HttpContent(io.netty.handler.codec.http.HttpContent)

Example 13 with DefaultHttpResponse

use of io.netty.handler.codec.http.DefaultHttpResponse in project camel by apache.

the class HttpServerMultiplexChannelHandler method exceptionCaught.

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    Attribute<HttpServerChannelHandler> attr = ctx.channel().attr(SERVER_HANDLER_KEY);
    HttpServerChannelHandler handler = attr.get();
    if (handler != null) {
        handler.exceptionCaught(ctx, cause);
    } else {
        if (cause instanceof ClosedChannelException) {
            // The channel is closed so we do nothing here
            LOG.debug("Channel already closed. Ignoring this exception.");
            return;
        } else {
            // we cannot throw the exception here
            LOG.warn("HttpServerChannelHandler is not found as attachment to handle exception, send 404 back to the client.", cause);
            // Now we just send 404 back to the client
            HttpResponse response = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND);
            response.headers().set(Exchange.CONTENT_TYPE, "text/plain");
            response.headers().set(Exchange.CONTENT_LENGTH, 0);
            ctx.writeAndFlush(response);
            ctx.close();
        }
    }
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(io.netty.handler.codec.http.HttpResponse)

Example 14 with DefaultHttpResponse

use of io.netty.handler.codec.http.DefaultHttpResponse in project rest.li by linkedin.

the class TestChannelPoolStreamHandler method testConnectionClose.

@Test(dataProvider = "connectionClose")
public void testConnectionClose(String headerName, List<String> headerValue) {
    EmbeddedChannel ch = getChannel();
    FakePool pool = new FakePool();
    ch.attr(ChannelPoolStreamHandler.CHANNEL_POOL_ATTR_KEY).set(pool);
    HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.ACCEPTED);
    HttpContent lastChunk = new DefaultLastHttpContent();
    response.headers().set(headerName, headerValue);
    ch.writeInbound(response);
    ch.writeInbound(lastChunk);
    Assert.assertTrue(pool.isDisposeCalled());
    Assert.assertFalse(pool.isPutCalled());
}
Also used : DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(io.netty.handler.codec.http.HttpResponse) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) Test(org.testng.annotations.Test)

Example 15 with DefaultHttpResponse

use of io.netty.handler.codec.http.DefaultHttpResponse in project rest.li by linkedin.

the class TestChannelPoolStreamHandler method testConnectionKeepAlive.

@Test(dataProvider = "connectionKeepAlive")
public void testConnectionKeepAlive(String headerName, List<String> headerValue) {
    EmbeddedChannel ch = getChannel();
    FakePool pool = new FakePool();
    ch.attr(ChannelPoolStreamHandler.CHANNEL_POOL_ATTR_KEY).set(pool);
    HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.ACCEPTED);
    HttpContent lastChunk = new DefaultLastHttpContent();
    response.headers().set(headerName, headerValue);
    ch.writeInbound(response);
    ch.writeInbound(lastChunk);
    Assert.assertFalse(pool.isDisposeCalled());
    Assert.assertTrue(pool.isPutCalled());
}
Also used : DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(io.netty.handler.codec.http.HttpResponse) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultLastHttpContent(io.netty.handler.codec.http.DefaultLastHttpContent) Test(org.testng.annotations.Test)

Aggregations

DefaultHttpResponse (io.netty.handler.codec.http.DefaultHttpResponse)32 HttpResponse (io.netty.handler.codec.http.HttpResponse)21 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)10 ChannelFuture (io.netty.channel.ChannelFuture)8 FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)6 HttpChunkedInput (io.netty.handler.codec.http.HttpChunkedInput)5 HttpRequest (io.netty.handler.codec.http.HttpRequest)5 ByteBuf (io.netty.buffer.ByteBuf)4 Channel (io.netty.channel.Channel)4 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)4 HttpContent (io.netty.handler.codec.http.HttpContent)4 DefaultFileRegion (io.netty.channel.DefaultFileRegion)3 QueryStringDecoder (io.netty.handler.codec.http.QueryStringDecoder)3 ChunkedFile (io.netty.handler.stream.ChunkedFile)3 File (java.io.File)3 FileNotFoundException (java.io.FileNotFoundException)3 RandomAccessFile (java.io.RandomAccessFile)3 Bootstrap (io.netty.bootstrap.Bootstrap)2 ChannelPipeline (io.netty.channel.ChannelPipeline)2 ChannelProgressiveFuture (io.netty.channel.ChannelProgressiveFuture)2