Search in sources :

Example 11 with HttpContext

use of org.apache.http.protocol.HttpContext in project nifi by apache.

the class SiteToSiteRestApiClient method initiateTransactionForSend.

/**
 * <p>
 * Initiate a transaction for sending data.
 * </p>
 *
 * <p>
 * If a proxy server requires auth, the proxy server returns 407 response with available auth schema such as basic or digest.
 * Then client has to resend the same request with its credential added.
 * This mechanism is problematic for sending data from NiFi.
 * </p>
 *
 * <p>
 * In order to resend a POST request with auth param,
 * NiFi has to either read flow-file contents to send again, or keep the POST body somewhere.
 * If we store that in memory, it would causes OOM, or storing it on disk slows down performance.
 * Rolling back processing session would be overkill.
 * Reading flow-file contents only when it's ready to send in a streaming way is ideal.
 * </p>
 *
 * <p>
 * Additionally, the way proxy authentication is done is vary among Proxy server software.
 * Some requires 407 and resend cycle for every requests, while others keep a connection between a client and
 * the proxy server, then consecutive requests skip auth steps.
 * The problem is, that how should we behave is only told after sending a request to the proxy.
 * </p>
 *
 * In order to handle above concerns correctly and efficiently, this method do the followings:
 *
 * <ol>
 * <li>Send a GET request to controller resource, to initiate an HttpAsyncClient. The instance will be used for further requests.
 *      This is not required by the Site-to-Site protocol, but it can setup proxy auth state safely.</li>
 * <li>Send a POST request to initiate a transaction. While doing so, it captures how a proxy server works.
 * If 407 and resend cycle occurs here, it implies that we need to do the same thing again when we actually send the data.
 * Because if the proxy keeps using the same connection and doesn't require an auth step, it doesn't do so here.</li>
 * <li>Then this method stores whether the final POST request should wait for the auth step.
 * So that {@link #openConnectionForSend} can determine when to produce contents.</li>
 * </ol>
 *
 * <p>
 * The above special sequence is only executed when a proxy instance is set, and its username is set.
 * </p>
 *
 * @param post a POST request to establish transaction
 * @return POST request response
 * @throws IOException thrown if the post request failed
 */
private HttpResponse initiateTransactionForSend(final HttpPost post) throws IOException {
    if (shouldCheckProxyAuth()) {
        final CloseableHttpAsyncClient asyncClient = getHttpAsyncClient();
        final HttpGet get = createGetControllerRequest();
        final Future<HttpResponse> getResult = asyncClient.execute(get, null);
        try {
            final HttpResponse getResponse = getResult.get(readTimeoutMillis, TimeUnit.MILLISECONDS);
            logger.debug("Proxy auth check has done. getResponse={}", getResponse.getStatusLine());
        } catch (final ExecutionException e) {
            logger.debug("Something has happened at get controller requesting thread for proxy auth check. {}", e.getMessage());
            throw toIOException(e);
        } catch (TimeoutException | InterruptedException e) {
            throw new IOException(e);
        }
    }
    final HttpAsyncRequestProducer asyncRequestProducer = new HttpAsyncRequestProducer() {

        private boolean requestHasBeenReset = false;

        @Override
        public HttpHost getTarget() {
            return URIUtils.extractHost(post.getURI());
        }

        @Override
        public HttpRequest generateRequest() throws IOException, HttpException {
            final BasicHttpEntity entity = new BasicHttpEntity();
            post.setEntity(entity);
            return post;
        }

        @Override
        public void produceContent(ContentEncoder encoder, IOControl ioctrl) throws IOException {
            encoder.complete();
            if (shouldCheckProxyAuth() && requestHasBeenReset) {
                logger.debug("Produced content again, assuming the proxy server requires authentication.");
                proxyAuthRequiresResend.set(true);
            }
        }

        @Override
        public void requestCompleted(HttpContext context) {
            debugProxyAuthState(context);
        }

        @Override
        public void failed(Exception ex) {
            final String msg = String.format("Failed to create transaction for %s", post.getURI());
            logger.error(msg, ex);
            eventReporter.reportEvent(Severity.WARNING, EVENT_CATEGORY, msg);
        }

        @Override
        public boolean isRepeatable() {
            return true;
        }

        @Override
        public void resetRequest() throws IOException {
            requestHasBeenReset = true;
        }

        @Override
        public void close() throws IOException {
        }
    };
    final Future<HttpResponse> responseFuture = getHttpAsyncClient().execute(asyncRequestProducer, new BasicAsyncResponseConsumer(), null);
    final HttpResponse response;
    try {
        response = responseFuture.get(readTimeoutMillis, TimeUnit.MILLISECONDS);
    } catch (final ExecutionException e) {
        logger.debug("Something has happened at initiate transaction requesting thread. {}", e.getMessage());
        throw toIOException(e);
    } catch (TimeoutException | InterruptedException e) {
        throw new IOException(e);
    }
    return response;
}
Also used : ContentEncoder(org.apache.http.nio.ContentEncoder) HttpGet(org.apache.http.client.methods.HttpGet) IOControl(org.apache.http.nio.IOControl) HttpContext(org.apache.http.protocol.HttpContext) HttpResponse(org.apache.http.HttpResponse) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) BasicHttpEntity(org.apache.http.entity.BasicHttpEntity) IOException(java.io.IOException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) HttpException(org.apache.http.HttpException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) URISyntaxException(java.net.URISyntaxException) TimeoutException(java.util.concurrent.TimeoutException) JsonParseException(com.fasterxml.jackson.core.JsonParseException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) JsonMappingException(com.fasterxml.jackson.databind.JsonMappingException) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) MalformedURLException(java.net.MalformedURLException) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) CertificateException(java.security.cert.CertificateException) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) HttpAsyncRequestProducer(org.apache.http.nio.protocol.HttpAsyncRequestProducer) BasicAsyncResponseConsumer(org.apache.http.nio.protocol.BasicAsyncResponseConsumer) CloseableHttpAsyncClient(org.apache.http.impl.nio.client.CloseableHttpAsyncClient) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException)

Example 12 with HttpContext

use of org.apache.http.protocol.HttpContext in project opennms by OpenNMS.

the class HttpClientWrapper method enablePreemptiveAuth.

protected void enablePreemptiveAuth(final HttpClientBuilder builder) {
    /**
     * Add an HttpRequestInterceptor that will perform preemptive authentication
     * @see http://hc.apache.org/httpcomponents-client-4.0.1/tutorial/html/authentication.html
     */
    final HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {

        @Override
        public void process(final HttpRequest request, final HttpContext context) throws IOException {
            if (context instanceof HttpClientContext) {
                final HttpClientContext clientContext = (HttpClientContext) context;
                final AuthState authState = clientContext.getTargetAuthState();
                final CredentialsProvider credsProvider = clientContext.getCredentialsProvider();
                final HttpHost targetHost = clientContext.getTargetHost();
                // If not authentication scheme has been initialized yet
                if (authState.getAuthScheme() == null) {
                    final AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());
                    // Obtain credentials matching the target host
                    final Credentials creds = credsProvider.getCredentials(authScope);
                    // If found, generate BasicScheme preemptively
                    if (creds != null) {
                        authState.update(new BasicScheme(), creds);
                    }
                }
            } else {
                throw new IllegalArgumentException("Not sure how to handle a non-HttpClientContext context.");
            }
        }
    };
    builder.addInterceptorFirst(preemptiveAuth);
}
Also used : HttpRequest(org.apache.http.HttpRequest) BasicScheme(org.apache.http.impl.auth.BasicScheme) AuthState(org.apache.http.auth.AuthState) HttpHost(org.apache.http.HttpHost) HttpRequestInterceptor(org.apache.http.HttpRequestInterceptor) HttpContext(org.apache.http.protocol.HttpContext) AuthScope(org.apache.http.auth.AuthScope) HttpClientContext(org.apache.http.client.protocol.HttpClientContext) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) CredentialsProvider(org.apache.http.client.CredentialsProvider) Credentials(org.apache.http.auth.Credentials) UsernamePasswordCredentials(org.apache.http.auth.UsernamePasswordCredentials)

Example 13 with HttpContext

use of org.apache.http.protocol.HttpContext in project oap by oaplatform.

the class BlockingHandlerAdapter method handle.

@Override
public void handle(final HttpRequest httpRequest, final HttpResponse httpResponse, final HttpContext httpContext) throws IOException {
    log.trace("Handling [{}]", httpRequest);
    final HttpInetConnection connection = (HttpInetConnection) httpContext.getAttribute(HTTP_CONNECTION);
    final InetAddress remoteAddress = connection.getRemoteAddress();
    final String httpContextProtocol = String.valueOf(httpContext.getAttribute("protocol"));
    final Request request = new Request(httpRequest, new Context(location, remoteAddress, httpContextProtocol));
    RequestCors cors = corsPolicy.getCors(request);
    final Response response = new Response(httpResponse, cors);
    if (Protocol.LOCAL.equals(this.protocol) && !Inet.isLocalAddress(remoteAddress)) {
        response.respond(HTTP_FORBIDDEN);
    } else if (cors.autoOptions && request.httpMethod == Request.HttpMethod.OPTIONS) {
        response.respond(NO_CONTENT);
    } else {
        handler.handle(request, response);
    }
}
Also used : HttpContext(org.apache.http.protocol.HttpContext) HttpResponse(org.apache.http.HttpResponse) RequestCors(oap.http.cors.RequestCors) HttpRequest(org.apache.http.HttpRequest) HttpInetConnection(org.apache.http.HttpInetConnection) InetAddress(java.net.InetAddress)

Example 14 with HttpContext

use of org.apache.http.protocol.HttpContext in project oap by oaplatform.

the class NioHandlerAdapter method handle.

@Override
public void handle(final HttpRequest httpRequest, final HttpAsyncExchange httpAsyncExchange, final HttpContext httpContext) throws HttpException, IOException {
    LOGGER.trace("handling [{}]", httpRequest);
    final HttpInetConnection connection = (HttpInetConnection) httpContext.getAttribute(HttpCoreContext.HTTP_CONNECTION);
    final InetAddress remoteAddress = connection.getRemoteAddress();
    final HttpResponse response = httpAsyncExchange.getResponse();
    final String httpContextProtocol = String.valueOf(httpContext.getAttribute("protocol"));
    if (Protocol.LOCAL.equals(this.protocol) && !Inet.isLocalAddress(remoteAddress)) {
        response.setStatusCode(HTTP_FORBIDDEN);
    } else {
        Request request = new Request(httpRequest, new Context(location, remoteAddress, httpContextProtocol));
        handler.handle(request, new Response(response, corsPolicy.getCors(request)));
    }
    httpAsyncExchange.submitResponse();
}
Also used : Context(oap.http.Context) HttpCoreContext(org.apache.http.protocol.HttpCoreContext) HttpContext(org.apache.http.protocol.HttpContext) Response(oap.http.Response) HttpResponse(org.apache.http.HttpResponse) HttpRequest(org.apache.http.HttpRequest) Request(oap.http.Request) HttpResponse(org.apache.http.HttpResponse) HttpInetConnection(org.apache.http.HttpInetConnection) InetAddress(java.net.InetAddress)

Example 15 with HttpContext

use of org.apache.http.protocol.HttpContext in project jaeger-client-java by jaegertracing.

the class TracingRequestInterceptorTest method testProcessNullScope.

@Test
public void testProcessNullScope() throws Exception {
    ScopeManager mockScopeManager = Mockito.mock(ScopeManager.class);
    when(mockScopeManager.active()).thenReturn(null);
    Tracer mockTracer = Mockito.mock(Tracer.class);
    when(mockTracer.scopeManager()).thenReturn(mockScopeManager);
    HttpRequestInterceptor interceptor = new TracingRequestInterceptor(mockTracer);
    PowerMockito.spy(interceptor);
    HttpRequest mockRequest = Mockito.mock(HttpRequest.class);
    HttpContext mockContext = Mockito.mock(HttpContext.class);
    interceptor.process(mockRequest, mockContext);
    PowerMockito.verifyPrivate(interceptor, times(0)).invoke("onSpanStarted", any(Span.class), mockRequest, mockContext);
}
Also used : HttpRequest(org.apache.http.HttpRequest) ScopeManager(io.opentracing.ScopeManager) Tracer(io.opentracing.Tracer) HttpRequestInterceptor(org.apache.http.HttpRequestInterceptor) HttpContext(org.apache.http.protocol.HttpContext) Span(io.opentracing.Span) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Aggregations

HttpContext (org.apache.http.protocol.HttpContext)187 HttpResponse (org.apache.http.HttpResponse)81 IOException (java.io.IOException)74 BasicHttpContext (org.apache.http.protocol.BasicHttpContext)59 HttpRequest (org.apache.http.HttpRequest)57 HttpException (org.apache.http.HttpException)34 HttpGet (org.apache.http.client.methods.HttpGet)31 Test (org.junit.Test)30 HttpHost (org.apache.http.HttpHost)28 HttpPost (org.apache.http.client.methods.HttpPost)28 StringEntity (org.apache.http.entity.StringEntity)23 ArrayList (java.util.ArrayList)22 Header (org.apache.http.Header)22 MessageContext (org.apache.axis2.context.MessageContext)19 NameValuePair (org.apache.http.NameValuePair)18 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)18 ProtocolException (org.apache.http.ProtocolException)17 UrlEncodedFormEntity (org.apache.http.client.entity.UrlEncodedFormEntity)17 DefaultHttpClient (org.apache.http.impl.client.DefaultHttpClient)17 URI (java.net.URI)16