Will setDefaultRequestConfig method override system properties - CloseableHttpClient - httpclient

I am using the following code to make a Http request.
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(10000)
.setConnectionRequestTimeout(10000)
.setSocketTimeout(300000)
.build();
CloseableHttpClient httpClient = HttpClientBuilder.create().useSystemProperties().setDefaultRequestConfig(requestConfig).build();
My simple question, will the method setDefaultRequestConfig remove all the system properties and will keep only the properties given above OR will it override only the given properties and keep the other system properties while making the HTTP request.

System properties that HttpClientBuilder can optionally take into consideration are as follows
ssl.TrustManagerFactory.algorithm
javax.net.ssl.trustStoreType
javax.net.ssl.trustStore
javax.net.ssl.trustStoreProvider
javax.net.ssl.trustStorePassword
ssl.KeyManagerFactory.algorithm
javax.net.ssl.keyStoreType
javax.net.ssl.keyStore
javax.net.ssl.keyStoreProvider
javax.net.ssl.keyStorePassword
https.protocols
https.cipherSuites
http.proxyHost
http.proxyPort
http.nonProxyHosts
http.keepAlive
http.maxConnections
http.agent
Request level configuration have no effect on any of those settings with an exception of proxy host and port. Proxy setting at the request level will override those at the system level.

Related

How do I set MaxConnPerRoute, ConnectionRequestTimeout, keepAliveStrategy in Spring WebFlux WebClient

we have the following custom connection pooling implemented for RestTemplate.
PoolingHttpClientConnectionManager poolingConnManager =
new PoolingHttpClientConnectionManager();
poolingConnManager.setDefaultMaxPerRoute(restClientprops.getRestClientMaxPerRoutePool());
poolingConnManager.setMaxTotal(restClientprops.getRestClientMaxTotalPool());
HttpClientBuilder httpClientBuilder = HttpClients.custom()
.setConnectionManager(poolingConnManager)
.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
.setMaxConnPerRoute(restClientprops.getRestClientMaxPerRoutePool())
.setMaxConnTotal(restClientprops.getRestClientMaxTotalPool());
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(restClientprops.getConnectTimeout());
requestFactory.setReadTimeout(restClientprops.getReadTimeout());
requestFactory.setConnectionRequestTimeout(restClientprops.getConnectionRequestTimeout());
requestFactory.setHttpClient(httpClientBuilder.build());
this.restTemplate = new RestTemplate(requestFactory);
I am changing it to WebClient implementation, and this is what I could come up with.
HttpClient httpClient = HttpClient
.create(ConnectionProvider.create("webclient-pool", restClientprops.getRestClientMaxTotalPool()))
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, restClientprops.getConnectTimeout())
.responseTimeout(Duration.ofMillis(restClientprops.getConnectionRequestTimeout()))
.doOnConnected(conn -> conn.addHandler(new ReadTimeoutHandler(restClientprops.getReadTimeout(), TimeUnit.MILLISECONDS)))
.keepAlive(true);
Per this URL https://github.com/reactor/reactor-netty/issues/1159
from what I understood connection request timeout is renamed to responseTimeOut in webclient httpclient. Is that accurate?
How should I set MaxConnPerRoute in webclient that is in the RestTemplate implementation?
Is keepAlive(true) accurate translation of setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
Appreciate your help.
Per this URL https://github.com/reactor/reactor-netty/issues/1159 from what I understood connection request timeout is renamed to responseTimeOut in webclient httpclient. Is that accurate?
Yes that's true. More about all timeouts that can be configured for the HttpClient you can find in the Reference Documentation.
How should I set MaxConnPerRoute in webclient that is in the RestTemplate implementation?
You can provide connection pool configuration per remote address (if that's what you mean with MaxConnPerRoute), see javadoc for forRemoteHost.
ConnectionProvider.builder("test")
.maxConnections(2) // default max connections
.forRemoteHost(<socket-address>,spec -> spec.maxConnections(1)) // max connections only for this socket address
.build();
Is keepAlive(true) accurate translation of setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
If you mean specifying whether the connection is persistent or not then YES this configuration has to be used. By default the connection IS persistent. If you mean SO_KEEPALIVE then NO and you have to use .option() configuration. You can find more in the Reference Documentation.
HttpClient.create()
.option(ChannelOption.SO_KEEPALIVE, true)
This configuration can be removed is you use the timeout settings provided by Reactor Netty:
.doOnConnected(conn -> conn.addHandler(new ReadTimeoutHandler(restClientprops.getReadTimeout(), TimeUnit.MILLISECONDS)))

Issue with HttpClient in AEM

I have an HttpClient code written that is from org.apache.commons.httpclient package.
In that I am setting connection time and socket time out this way.
final HttpClient http = new HttpClient(this.connectionManager);
http.getParams().setParameter("http.connection.timeout", this.connectionTimeout);
http.getParams().setParameter("http.socket.timeout", this.socketTimeout);
Now the Adobe Cloud has raised issue that timeout is not being set(which is not true).
They suggested to set timeouts using
#Reference
private HttpClientBuilderFactory httpClientBuilderFactory;
public void doThis() {
HttpClientBuilder builder = httpClientBuilderFactory.newBuilder();
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(5000)
.build();
builder.setDefaultRequestConfig(requestConfig);
HttpClient httpClient = builder.build();
// do something with the client
}
Refer Link
But HttpClientBuilderFactory does not belong to **org.apache.commons.httpclient it belongs to org.apache.http.client**
And always returns Closable Http client.
How do I resolve this security issue? Can I add an annotation for exception? Or will I have to rewrite all my code?
This issue is with Adobe Experience Manager 6.5 instance.
Is it probably because you are not setting the right timeout parameter?
You are setting the property http.connection.timeout which is not available in the class org.apache.commons.httpclient.params.HttpClientParams.
http.getParams() returns an instance of HttpClientParams which has the socket timeout and connection manager timeout but not a connection timeout. You could probably use the constant HttpClientParams.CONNECTION_MANAGER_TIMEOUT to set a timeout for the connection manager?
On the other hand, the property http.connection.timeout is available for the class HttpConnectionParams.
Constant field values reference
The problem is Adobe has two versions of HttpClient the old 3.x that has package structure org.apache.commons.httpclient.HttpClient and the one that HttpClientBuilderFactory gives out that is 4.x org.apache.http.Httpclient.
I was breaking my head around this. Finally we were left with two options...
1) Rewrite all our commons http api(3.x) to the newer version of apache.http (4.x) that has the methods setTimeout and setConnectionTimeout
OR
2)#SuppressWarnings("CQRules:ConnectionTimeoutMechanism")
We chose Option number 2 as the effort arround this was huge and we are planning to go live soon.

Correct configuration for REST endpoints in Shiro

My original post is here
I am trying to protect a set of REST endpoints with Shiro. My theory is that if I pass a JWT with my REST request, that I can use Shiro (via annotations) to secure my endpoints.
I've create my endpoints like this (for example):
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("status/{companyId}")
#RequiresAuthentication
#RequiresRoles("SomeRole")
public Response getStatus(#PathParam("companyId") int companyId){
... do stuff ...
}
I'm expecting that if I call the endpoint without authenticating, I will get a HTTP 401 error. However, the method is called successfully if the JWT is not supplied as it would be when there is no security on it at all.
I assume then that my Shiro config is incorrect. Since this is strictly a 'backend' application, I have no use for the Shiro/Stormpath configurations that apply to anything 'front-end' related (such as loginURLs, etc.)
Here is my shiro.ini :
[main]
#ERRORS IF UNCOMMENTED
#cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
#securityManager.cacheManager = $cacheManager
#stormpathClient.cacheManager = $cacheManager
# NOT NEEDED?
#sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
#securityManager.sessionManager = $sessionManager
#securityManager.sessionManager.sessionIdCookieEnabled = false
#securityManager.sessionManager.sessionIdUrlRewritingEnabled = false
[urls]
/** = rest
This configuration lets every request through (as described above).
If I uncomment the [main] section, I get IllegalArgumentException: Configuration error. Specified object [stormpathClient] with property [cacheManager] without first defining that object's class. Please first specify the class property first, e.g. myObject = fully_qualified_class_name and then define additional properties.
What I need to figure out is what is the correct minimum Shiro configuration for REST endpoints (and ONLY REST endpoints) so I can allow access with a JWT.
Thanks for any help.
I'm guessing the annotations are not being processed by anything at runtime. You will need to tell your JAX-RS app to process them.
I've done this with this lib in the past:
https://github.com/silb/shiro-jersey/
Specifically something like this:
https://github.com/silb/shiro-jersey/blob/master/src/main/java/org/secnod/shiro/jersey/AuthorizationFilterFeature.java
As for the second part of the problem, my only guess is Stormpath/Shiro environment is not setup correctly.
Did you put filter config in your web.xml or is all of the config loaded from the servlet fragment?

How to handle redirect by httpClient fluent?

I'm writing acceptance tests with HttpClient fluent api and have some trouble.
#When("^I submit delivery address and delivery time$")
public void I_submit_delivery_address_and_delivery_time() throws Throwable {
Response response = Request
.Post("http://localhost:9999/food2go/booking/placeOrder")
.bodyForm(
param("deliveryAddressStreet1",
deliveryAddress.getStreet1()),
param("deliveryAddressStreet2",
deliveryAddress.getStreet2()),
param("deliveryTime", deliveryTime)).execute();
content = response.returnContent();
log.debug(content.toString());
}
This code works well when I use post-forward strategy, but an exception is thrown when I use redirect instead.
org.apache.http.client.HttpResponseException: Found
What I want is getting the content of the redirected page. Any idea is appreciate, thanks in advance.
The HTTP specification requires entity enclosing methods such as POST and PUT be redirected after human intervention only. HttpClient honors this requirement by default. .
10.3 Redirection 3xx
This class of status code indicates that further action needs to be
taken by the user agent in order to fulfill the request. The action
required MAY be carried out by the user agent without interaction
with the user if and only if the method used in the second request is
GET or HEAD.
...
If the 302 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
One can use a custom redirect strategy to relax restrictions on automatic redirection if necessary.
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new LaxRedirectStrategy());
Executor exec = Executor.newInstance(client);
String s = exec.execute(Request
.Post("http://localhost:9999/food2go/booking/placeOrder")
.bodyForm(...)).returnContent().asString();
This is for an updated version of apache:
CloseableHttpClient httpClient =
HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy())
.build();

same HttpClient multiple request ends up with different HttpSession

I am using the new Apache HttpClient 4.2 (not the one from Apache Commons).
I need to open up one HttpClient and make multiple requests to the same server. From the documentation, the httpClient should automatically maintain the cookie, and therefore have the multiple requests fall in the same session. However, on the server side, I am debugging thru and see that
HttpSession session = req.getHttpSession(true);
is returning a new HttpSession Object every time.
my client code is like this.
// 1st time
HttpClient httpClient = new DefaultHttpClient();
req.getSession(true).setAttribute(HTTPCLIENT, httpClient);
HttpGet httpget = new HttpGet(redirectUrl);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String content = httpClient.execute(httpget, responseHandler);
// subsequent calls
HttpClient httpClient = getHttpClient(req);
HttpGet httpget = new HttpGet(redirectUrl);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String content = httpClient.execute(httpget, responseHandler);
// supported by the private method
private HttpClient getHttpClient(HttpServletRequest req){
return (HttpClient) req.getSession(true).getAttribute(HTTPCLIENT);
}
did I do anything wrong?
my dumb experiment.
it was because I was mixing up using and by passing the HttpClient on different requests from the same browser (e.g. by passing on .js and .css files). These by passed resources returned a different sessionId to the browser, and subsequently, the browser started using the new sessionId.