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;
}
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);
}
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);
}
}
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();
}
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);
}
Aggregations