Search in sources :

Example 16 with HttpRequest

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpRequest in project rest.li by linkedin.

the class TestNettyRequestAdapter method testStreamToNettyRequest.

@Test
public void testStreamToNettyRequest() throws Exception {
    StreamRequestBuilder streamRequestBuilder = new StreamRequestBuilder(new URI(ANY_URI));
    streamRequestBuilder.setMethod("POST");
    streamRequestBuilder.setHeader("Content-Length", Integer.toString(ANY_ENTITY.length()));
    streamRequestBuilder.setHeader("Content-Type", "application/json");
    streamRequestBuilder.setCookies(Collections.singletonList("anyCookie"));
    StreamRequest streamRequest = streamRequestBuilder.build(EntityStreams.newEntityStream(new ByteStringWriter(ByteString.copy(ANY_ENTITY.getBytes()))));
    HttpRequest nettyRequest = NettyRequestAdapter.toNettyRequest(streamRequest);
    Assert.assertEquals(nettyRequest.uri(), "/foo/bar?q=baz");
    Assert.assertEquals(nettyRequest.method(), HttpMethod.POST);
    Assert.assertEquals(nettyRequest.protocolVersion(), HttpVersion.HTTP_1_1);
    Assert.assertNull(nettyRequest.headers().get("Content-Length"));
    Assert.assertEquals(nettyRequest.headers().get("Content-Type"), "application/json");
    Assert.assertEquals(nettyRequest.headers().get("Cookie"), ANY_COOKIE);
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URI(java.net.URI) ByteStringWriter(com.linkedin.r2.message.stream.entitystream.ByteStringWriter) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) Test(org.testng.annotations.Test)

Example 17 with HttpRequest

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpRequest in project rest.li by linkedin.

the class TestNettyRequestAdapter method testStreamToNettyRequestContentLengthIgnoreCase.

@Test
public void testStreamToNettyRequestContentLengthIgnoreCase() throws Exception {
    StreamRequestBuilder streamRequestBuilder = new StreamRequestBuilder(new URI(ANY_URI));
    streamRequestBuilder.setHeader("CONTENT-LENGTH", Integer.toString(ANY_ENTITY.length()));
    StreamRequest streamRequest = streamRequestBuilder.build(EntityStreams.newEntityStream(new ByteStringWriter(ByteString.copy(ANY_ENTITY.getBytes()))));
    HttpRequest nettyRequest = NettyRequestAdapter.toNettyRequest(streamRequest);
    Assert.assertNull(nettyRequest.headers().get("Content-Length"));
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URI(java.net.URI) ByteStringWriter(com.linkedin.r2.message.stream.entitystream.ByteStringWriter) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) Test(org.testng.annotations.Test)

Example 18 with HttpRequest

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpRequest in project camel by apache.

the class DefaultNettyHttpBinding method toNettyRequest.

@Override
public HttpRequest toNettyRequest(Message message, String uri, NettyHttpConfiguration configuration) throws Exception {
    LOG.trace("toNettyRequest: {}", message);
    // the message body may already be a Netty HTTP response
    if (message.getBody() instanceof HttpRequest) {
        return (HttpRequest) message.getBody();
    }
    String uriForRequest = uri;
    if (configuration.isUseRelativePath()) {
        int indexOfPath = uri.indexOf((new URI(uri)).getPath());
        if (indexOfPath > 0) {
            uriForRequest = uri.substring(indexOfPath);
        }
    }
    // just assume GET for now, we will later change that to the actual method to use
    HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uriForRequest);
    Object body = message.getBody();
    if (body != null) {
        // support bodies as native Netty
        ByteBuf buffer;
        if (body instanceof ByteBuf) {
            buffer = (ByteBuf) body;
        } else {
            // try to convert to buffer first
            buffer = message.getBody(ByteBuf.class);
            if (buffer == null) {
                // fallback to byte array as last resort
                byte[] data = message.getMandatoryBody(byte[].class);
                buffer = NettyConverter.toByteBuffer(data);
            }
        }
        if (buffer != null) {
            request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uriForRequest, buffer);
            int len = buffer.readableBytes();
            // set content-length
            request.headers().set(HttpHeaderNames.CONTENT_LENGTH.toString(), len);
            LOG.trace("Content-Length: {}", len);
        } else {
            // we do not support this kind of body
            throw new NoTypeConversionAvailableException(body, ByteBuf.class);
        }
    }
    // update HTTP method accordingly as we know if we have a body or not
    HttpMethod method = NettyHttpHelper.createMethod(message, body != null);
    request.setMethod(method);
    TypeConverter tc = message.getExchange().getContext().getTypeConverter();
    // if we bridge endpoint then we need to skip matching headers with the HTTP_QUERY to avoid sending
    // duplicated headers to the receiver, so use this skipRequestHeaders as the list of headers to skip
    Map<String, Object> skipRequestHeaders = null;
    if (configuration.isBridgeEndpoint()) {
        String queryString = message.getHeader(Exchange.HTTP_QUERY, String.class);
        if (queryString != null) {
            skipRequestHeaders = URISupport.parseQuery(queryString, false, true);
        }
        // Need to remove the Host key as it should be not used
        message.getHeaders().remove("host");
    }
    // must use entrySet to ensure case of keys is preserved
    for (Map.Entry<String, Object> entry : message.getHeaders().entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
        // as then we would duplicate headers on both the endpoint uri, and in HTTP headers as well
        if (skipRequestHeaders != null && skipRequestHeaders.containsKey(key)) {
            continue;
        }
        // use an iterator as there can be multiple values. (must not use a delimiter)
        final Iterator<?> it = ObjectHelper.createIterator(value, null, true);
        while (it.hasNext()) {
            String headerValue = tc.convertTo(String.class, it.next());
            if (headerValue != null && headerFilterStrategy != null && !headerFilterStrategy.applyFilterToCamelHeaders(key, headerValue, message.getExchange())) {
                LOG.trace("HTTP-Header: {}={}", key, headerValue);
                request.headers().add(key, headerValue);
            }
        }
    }
    // set the content type in the response.
    String contentType = MessageHelper.getContentType(message);
    if (contentType != null) {
        // set content-type
        request.headers().set(HttpHeaderNames.CONTENT_TYPE.toString(), contentType);
        LOG.trace("Content-Type: {}", contentType);
    }
    // must include HOST header as required by HTTP 1.1
    // use URI as its faster than URL (no DNS lookup)
    URI u = new URI(uri);
    String hostHeader = u.getHost() + (u.getPort() == 80 ? "" : ":" + u.getPort());
    request.headers().set(HttpHeaderNames.HOST.toString(), hostHeader);
    LOG.trace("Host: {}", hostHeader);
    // configure connection to accordingly to keep alive configuration
    // favor using the header from the message
    String connection = message.getHeader(HttpHeaderNames.CONNECTION.toString(), String.class);
    if (connection == null) {
        // fallback and use the keep alive from the configuration
        if (configuration.isKeepAlive()) {
            connection = HttpHeaderValues.KEEP_ALIVE.toString();
        } else {
            connection = HttpHeaderValues.CLOSE.toString();
        }
    }
    request.headers().set(HttpHeaderNames.CONNECTION.toString(), connection);
    LOG.trace("Connection: {}", connection);
    return request;
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) NoTypeConversionAvailableException(org.apache.camel.NoTypeConversionAvailableException) ByteBuf(io.netty.buffer.ByteBuf) URI(java.net.URI) TypeConverter(org.apache.camel.TypeConverter) Map(java.util.Map) HttpMethod(io.netty.handler.codec.http.HttpMethod)

Example 19 with HttpRequest

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpRequest in project camel by apache.

the class NettyHttpConverter method convertToHttpRequest.

/**
     * A fallback converter that allows us to easily call Java beans and use the raw Netty {@link HttpRequest} as parameter types.
     */
@FallbackConverter
public static Object convertToHttpRequest(Class<?> type, Exchange exchange, Object value, TypeConverterRegistry registry) {
    // if we want to covert to HttpRequest
    if (value != null && HttpRequest.class.isAssignableFrom(type)) {
        // okay we may need to cheat a bit when we want to grab the HttpRequest as its stored on the NettyHttpMessage
        // so if the message instance is a NettyHttpMessage and its body is the value, then we can grab the
        // HttpRequest from the NettyHttpMessage
        NettyHttpMessage msg;
        if (exchange.hasOut()) {
            msg = exchange.getOut(NettyHttpMessage.class);
        } else {
            msg = exchange.getIn(NettyHttpMessage.class);
        }
        if (msg != null && msg.getBody() == value) {
            // ensure the http request content is reset so we can read all the content out-of-the-box
            FullHttpRequest request = msg.getHttpRequest();
            request.content().resetReaderIndex();
            return request;
        }
    }
    return null;
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) FallbackConverter(org.apache.camel.FallbackConverter)

Example 20 with HttpRequest

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpRequest 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)

Aggregations

HttpRequest (io.netty.handler.codec.http.HttpRequest)283 DefaultHttpRequest (io.netty.handler.codec.http.DefaultHttpRequest)104 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)95 Test (org.junit.Test)83 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)66 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)50 HttpResponse (io.netty.handler.codec.http.HttpResponse)49 FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)34 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)34 ByteBuf (io.netty.buffer.ByteBuf)32 LastHttpContent (io.netty.handler.codec.http.LastHttpContent)31 HttpContent (io.netty.handler.codec.http.HttpContent)30 Test (org.junit.jupiter.api.Test)30 URI (java.net.URI)29 Channel (io.netty.channel.Channel)28 HttpMethod (io.netty.handler.codec.http.HttpMethod)26 IOException (java.io.IOException)25 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)24 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)19 DefaultHttpHeaders (io.netty.handler.codec.http.DefaultHttpHeaders)19