Search in sources :

Example 36 with HttpRequest

use of io.netty.handler.codec.http.HttpRequest in project async-http-client by AsyncHttpClient.

the class NettyRequestSender method writeRequest.

public <T> void writeRequest(NettyResponseFuture<T> future, Channel channel) {
    NettyRequest nettyRequest = future.getNettyRequest();
    HttpRequest httpRequest = nettyRequest.getHttpRequest();
    AsyncHandler<T> handler = future.getAsyncHandler();
    // we just let it go and the channelInactive do its work
    if (!Channels.isChannelValid(channel))
        return;
    try {
        if (handler instanceof TransferCompletionHandler)
            configureTransferAdapter(handler, httpRequest);
        boolean writeBody = !future.isDontWriteBodyBecauseExpectContinue() && httpRequest.method() != HttpMethod.CONNECT && nettyRequest.getBody() != null;
        if (!future.isHeadersAlreadyWrittenOnContinue()) {
            if (handler instanceof AsyncHandlerExtensions) {
                AsyncHandlerExtensions.class.cast(handler).onRequestSend(nettyRequest);
            }
            // if the request has a body, we want to track progress
            if (writeBody) {
                ChannelProgressivePromise promise = channel.newProgressivePromise();
                ChannelFuture f = channel.write(httpRequest, promise);
                f.addListener(new WriteProgressListener(future, true, 0L));
            } else {
                // we can just track write completion
                ChannelPromise promise = channel.newPromise();
                ChannelFuture f = channel.writeAndFlush(httpRequest, promise);
                f.addListener(new WriteCompleteListener(future));
            }
        }
        if (writeBody)
            nettyRequest.getBody().write(channel, future);
        // don't bother scheduling read timeout if channel became invalid
        if (Channels.isChannelValid(channel))
            scheduleReadTimeout(future);
    } catch (Exception e) {
        LOGGER.error("Can't write request", e);
        abort(channel, future, e);
    }
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) ChannelFuture(io.netty.channel.ChannelFuture) TransferCompletionHandler(org.asynchttpclient.handler.TransferCompletionHandler) ChannelPromise(io.netty.channel.ChannelPromise) AsyncHandlerExtensions(org.asynchttpclient.handler.AsyncHandlerExtensions) FilterException(org.asynchttpclient.filter.FilterException) IOException(java.io.IOException) RemotelyClosedException(org.asynchttpclient.exception.RemotelyClosedException) EXPECT(io.netty.handler.codec.http.HttpHeaderNames.EXPECT) ChannelProgressivePromise(io.netty.channel.ChannelProgressivePromise)

Example 37 with HttpRequest

use of io.netty.handler.codec.http.HttpRequest in project async-http-client by AsyncHttpClient.

the class Interceptors method exitAfterIntercept.

public //
boolean exitAfterIntercept(//
Channel channel, //
NettyResponseFuture<?> future, //
AsyncHandler<?> handler, //
HttpResponse response, //
HttpResponseStatus status, HttpResponseHeaders responseHeaders) throws Exception {
    HttpRequest httpRequest = future.getNettyRequest().getHttpRequest();
    ProxyServer proxyServer = future.getProxyServer();
    int statusCode = response.status().code();
    Request request = future.getCurrentRequest();
    Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();
    if (hasResponseFilters && responseFiltersInterceptor.exitAfterProcessingFilters(channel, future, handler, status, responseHeaders)) {
        return true;
    }
    if (statusCode == UNAUTHORIZED_401) {
        return unauthorized401Interceptor.exitAfterHandling401(channel, future, response, request, statusCode, realm, proxyServer, httpRequest);
    } else if (statusCode == PROXY_AUTHENTICATION_REQUIRED_407) {
        return proxyUnauthorized407Interceptor.exitAfterHandling407(channel, future, response, request, statusCode, proxyServer, httpRequest);
    } else if (statusCode == CONTINUE_100) {
        return continue100Interceptor.exitAfterHandling100(channel, future, statusCode);
    } else if (Redirect30xInterceptor.REDIRECT_STATUSES.contains(statusCode)) {
        return redirect30xInterceptor.exitAfterHandlingRedirect(channel, future, response, request, statusCode, realm);
    } else if (httpRequest.method() == HttpMethod.CONNECT && statusCode == OK_200) {
        return connectSuccessInterceptor.exitAfterHandlingConnect(channel, future, request, proxyServer, statusCode, httpRequest);
    }
    return false;
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) Request(org.asynchttpclient.Request) Realm(org.asynchttpclient.Realm) ProxyServer(org.asynchttpclient.proxy.ProxyServer)

Example 38 with HttpRequest

use of io.netty.handler.codec.http.HttpRequest in project async-http-client by AsyncHttpClient.

the class ProxyUnauthorized407Interceptor method exitAfterHandling407.

public //
boolean exitAfterHandling407(//
Channel channel, //
NettyResponseFuture<?> future, //
HttpResponse response, //
Request request, //
int statusCode, //
ProxyServer proxyServer, HttpRequest httpRequest) {
    if (future.isAndSetInProxyAuth(true)) {
        LOGGER.info("Can't handle 407 as auth was already performed");
        return false;
    }
    Realm proxyRealm = future.getProxyRealm();
    if (proxyRealm == null) {
        LOGGER.debug("Can't handle 407 as there's no proxyRealm");
        return false;
    }
    List<String> proxyAuthHeaders = response.headers().getAll(PROXY_AUTHENTICATE);
    if (proxyAuthHeaders.isEmpty()) {
        LOGGER.info("Can't handle 407 as response doesn't contain Proxy-Authenticate headers");
        return false;
    }
    // FIXME what's this???
    future.setChannelState(ChannelState.NEW);
    HttpHeaders requestHeaders = new DefaultHttpHeaders(false).add(request.getHeaders());
    switch(proxyRealm.getScheme()) {
        case BASIC:
            if (getHeaderWithPrefix(proxyAuthHeaders, "Basic") == null) {
                LOGGER.info("Can't handle 407 with Basic realm as Proxy-Authenticate headers don't match");
                return false;
            }
            if (proxyRealm.isUsePreemptiveAuth()) {
                // FIXME do we need this, as future.getAndSetAuth
                // was tested above?
                // auth was already performed, most likely auth
                // failed
                LOGGER.info("Can't handle 407 with Basic realm as auth was preemptive and already performed");
                return false;
            }
            // FIXME do we want to update the realm, or directly
            // set the header?
            Realm newBasicRealm = //
            realm(proxyRealm).setUsePreemptiveAuth(//
            true).build();
            future.setProxyRealm(newBasicRealm);
            break;
        case DIGEST:
            String digestHeader = getHeaderWithPrefix(proxyAuthHeaders, "Digest");
            if (digestHeader == null) {
                LOGGER.info("Can't handle 407 with Digest realm as Proxy-Authenticate headers don't match");
                return false;
            }
            Realm newDigestRealm = //
            realm(proxyRealm).setUri(//
            request.getUri()).setMethodName(//
            request.getMethod()).setUsePreemptiveAuth(//
            true).parseProxyAuthenticateHeader(//
            digestHeader).build();
            future.setProxyRealm(newDigestRealm);
            break;
        case NTLM:
            String ntlmHeader = getHeaderWithPrefix(proxyAuthHeaders, "NTLM");
            if (ntlmHeader == null) {
                LOGGER.info("Can't handle 407 with NTLM realm as Proxy-Authenticate headers don't match");
                return false;
            }
            ntlmProxyChallenge(ntlmHeader, request, requestHeaders, proxyRealm, future);
            Realm newNtlmRealm = //
            realm(proxyRealm).setUsePreemptiveAuth(//
            true).build();
            future.setProxyRealm(newNtlmRealm);
            break;
        case KERBEROS:
        case SPNEGO:
            if (getHeaderWithPrefix(proxyAuthHeaders, NEGOTIATE) == null) {
                LOGGER.info("Can't handle 407 with Kerberos or Spnego realm as Proxy-Authenticate headers don't match");
                return false;
            }
            try {
                kerberosProxyChallenge(channel, proxyAuthHeaders, request, proxyServer, proxyRealm, requestHeaders, future);
            } catch (SpnegoEngineException e) {
                // FIXME
                String ntlmHeader2 = getHeaderWithPrefix(proxyAuthHeaders, "NTLM");
                if (ntlmHeader2 != null) {
                    LOGGER.warn("Kerberos/Spnego proxy auth failed, proceeding with NTLM");
                    ntlmProxyChallenge(ntlmHeader2, request, requestHeaders, proxyRealm, future);
                    Realm newNtlmRealm2 = //
                    realm(proxyRealm).setScheme(//
                    AuthScheme.NTLM).setUsePreemptiveAuth(//
                    true).build();
                    future.setProxyRealm(newNtlmRealm2);
                } else {
                    requestSender.abort(channel, future, e);
                    return false;
                }
            }
            break;
        default:
            throw new IllegalStateException("Invalid Authentication scheme " + proxyRealm.getScheme());
    }
    RequestBuilder nextRequestBuilder = new RequestBuilder(future.getCurrentRequest()).setHeaders(requestHeaders);
    if (future.getCurrentRequest().getUri().isSecured()) {
        nextRequestBuilder.setMethod(CONNECT);
    }
    final Request nextRequest = nextRequestBuilder.build();
    LOGGER.debug("Sending proxy authentication to {}", request.getUri());
    if (//
    future.isKeepAlive() && //
    !HttpUtil.isTransferEncodingChunked(httpRequest) && !HttpUtil.isTransferEncodingChunked(response)) {
        future.setConnectAllowed(true);
        future.setReuseChannel(true);
        requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
    } else {
        channelManager.closeChannel(channel);
        requestSender.sendNextRequest(nextRequest, future);
    }
    return true;
}
Also used : HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) RequestBuilder(org.asynchttpclient.RequestBuilder) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) SpnegoEngineException(org.asynchttpclient.spnego.SpnegoEngineException) Request(org.asynchttpclient.Request) HttpRequest(io.netty.handler.codec.http.HttpRequest) Realm(org.asynchttpclient.Realm)

Example 39 with HttpRequest

use of io.netty.handler.codec.http.HttpRequest in project async-http-client by AsyncHttpClient.

the class Unauthorized401Interceptor method exitAfterHandling401.

public //
boolean exitAfterHandling401(//
final Channel channel, //
final NettyResponseFuture<?> future, //
HttpResponse response, //
final Request request, //
int statusCode, //
Realm realm, //
ProxyServer proxyServer, HttpRequest httpRequest) {
    if (realm == null) {
        LOGGER.debug("Can't handle 401 as there's no realm");
        return false;
    }
    if (future.isAndSetInAuth(true)) {
        LOGGER.info("Can't handle 401 as auth was already performed");
        return false;
    }
    List<String> wwwAuthHeaders = response.headers().getAll(WWW_AUTHENTICATE);
    if (wwwAuthHeaders.isEmpty()) {
        LOGGER.info("Can't handle 401 as response doesn't contain WWW-Authenticate headers");
        return false;
    }
    // FIXME what's this???
    future.setChannelState(ChannelState.NEW);
    HttpHeaders requestHeaders = new DefaultHttpHeaders(false).add(request.getHeaders());
    switch(realm.getScheme()) {
        case BASIC:
            if (getHeaderWithPrefix(wwwAuthHeaders, "Basic") == null) {
                LOGGER.info("Can't handle 401 with Basic realm as WWW-Authenticate headers don't match");
                return false;
            }
            if (realm.isUsePreemptiveAuth()) {
                // FIXME do we need this, as future.getAndSetAuth
                // was tested above?
                // auth was already performed, most likely auth
                // failed
                LOGGER.info("Can't handle 401 with Basic realm as auth was preemptive and already performed");
                return false;
            }
            // FIXME do we want to update the realm, or directly
            // set the header?
            Realm newBasicRealm = //
            realm(realm).setUsePreemptiveAuth(//
            true).build();
            future.setRealm(newBasicRealm);
            break;
        case DIGEST:
            String digestHeader = getHeaderWithPrefix(wwwAuthHeaders, "Digest");
            if (digestHeader == null) {
                LOGGER.info("Can't handle 401 with Digest realm as WWW-Authenticate headers don't match");
                return false;
            }
            Realm newDigestRealm = //
            realm(realm).setUri(//
            request.getUri()).setMethodName(//
            request.getMethod()).setUsePreemptiveAuth(//
            true).parseWWWAuthenticateHeader(//
            digestHeader).build();
            future.setRealm(newDigestRealm);
            break;
        case NTLM:
            String ntlmHeader = getHeaderWithPrefix(wwwAuthHeaders, "NTLM");
            if (ntlmHeader == null) {
                LOGGER.info("Can't handle 401 with NTLM realm as WWW-Authenticate headers don't match");
                return false;
            }
            ntlmChallenge(ntlmHeader, request, requestHeaders, realm, future);
            Realm newNtlmRealm = //
            realm(realm).setUsePreemptiveAuth(//
            true).build();
            future.setRealm(newNtlmRealm);
            break;
        case KERBEROS:
        case SPNEGO:
            if (getHeaderWithPrefix(wwwAuthHeaders, NEGOTIATE) == null) {
                LOGGER.info("Can't handle 401 with Kerberos or Spnego realm as WWW-Authenticate headers don't match");
                return false;
            }
            try {
                kerberosChallenge(channel, wwwAuthHeaders, request, requestHeaders, realm, future);
            } catch (SpnegoEngineException e) {
                // FIXME
                String ntlmHeader2 = getHeaderWithPrefix(wwwAuthHeaders, "NTLM");
                if (ntlmHeader2 != null) {
                    LOGGER.warn("Kerberos/Spnego auth failed, proceeding with NTLM");
                    ntlmChallenge(ntlmHeader2, request, requestHeaders, realm, future);
                    Realm newNtlmRealm2 = //
                    realm(realm).setScheme(//
                    AuthScheme.NTLM).setUsePreemptiveAuth(//
                    true).build();
                    future.setRealm(newNtlmRealm2);
                } else {
                    requestSender.abort(channel, future, e);
                    return false;
                }
            }
            break;
        default:
            throw new IllegalStateException("Invalid Authentication scheme " + realm.getScheme());
    }
    final Request nextRequest = new RequestBuilder(future.getCurrentRequest()).setHeaders(requestHeaders).build();
    LOGGER.debug("Sending authentication to {}", request.getUri());
    if (//
    future.isKeepAlive() && //
    !HttpUtil.isTransferEncodingChunked(httpRequest) && !HttpUtil.isTransferEncodingChunked(response)) {
        future.setReuseChannel(true);
        requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
    } else {
        channelManager.closeChannel(channel);
        requestSender.sendNextRequest(nextRequest, future);
    }
    return true;
}
Also used : HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) RequestBuilder(org.asynchttpclient.RequestBuilder) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) SpnegoEngineException(org.asynchttpclient.spnego.SpnegoEngineException) Request(org.asynchttpclient.Request) HttpRequest(io.netty.handler.codec.http.HttpRequest) Realm(org.asynchttpclient.Realm)

Example 40 with HttpRequest

use of io.netty.handler.codec.http.HttpRequest in project riposte by Nike-Inc.

the class VerifyDecoderFailedResultIsHandledTest method standardEndpoint_should_handle_decode_exception.

@Test
public void standardEndpoint_should_handle_decode_exception() throws Exception {
    // given
    int payloadSize = 100000;
    ByteBuf payload = ComponentTestUtils.createByteBufPayload(payloadSize);
    HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, DownstreamEndpoint.MATCHING_PATH, payload);
    //leave off content-length and transfer-encoding to trigger DecoderFailedResult
    request.headers().set(HttpHeaders.Names.HOST, "localhost");
    // when
    Pair<Integer, String> serverResponse = executeRequest(request, downstreamServerConfig.endpointsPort(), incompleteCallTimeoutMillis);
    // then
    assertErrorResponse(serverResponse);
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) ByteBuf(io.netty.buffer.ByteBuf) ProxyRouterEndpoint(com.nike.riposte.server.http.ProxyRouterEndpoint) StandardEndpoint(com.nike.riposte.server.http.StandardEndpoint) Endpoint(com.nike.riposte.server.http.Endpoint) Test(org.junit.Test)

Aggregations

HttpRequest (io.netty.handler.codec.http.HttpRequest)114 Test (org.junit.Test)38 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)29 HttpResponse (io.netty.handler.codec.http.HttpResponse)26 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)22 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)19 DefaultHttpRequest (io.netty.handler.codec.http.DefaultHttpRequest)17 ByteBuf (io.netty.buffer.ByteBuf)13 HttpContent (io.netty.handler.codec.http.HttpContent)13 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)13 LastHttpContent (io.netty.handler.codec.http.LastHttpContent)12 URI (java.net.URI)12 Channel (io.netty.channel.Channel)10 ChannelFuture (io.netty.channel.ChannelFuture)9 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)9 FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)9 Map (java.util.Map)9 DefaultHttpResponse (io.netty.handler.codec.http.DefaultHttpResponse)7 Endpoint (com.nike.riposte.server.http.Endpoint)6 Bootstrap (io.netty.bootstrap.Bootstrap)6