Is there any way to set some headers in request interceptor based on the http protocol version after negotiation in httpClient - apache-httpclient-5.x

I have a use case where I have to send content-length in the request header for only http2 calls.
After setting content-length for all calls, in case of http1.1, it is throwing below exception,
Caused by: org.apache.hc.core5.http.ProtocolException: Content-Length header already present
at org.apache.hc.core5.http.protocol.RequestContent.process(RequestContent.java:103)
Even after adding the last request interceptor to add length-content at last level, It is throwing same exception looks like the last interceptor is not the last interceptor.
I have also tied to put some protocol version based check but again the version it tells is incorrect, says http1.1 thought actually it is http2.
I am using httpclient5 library.

Unfortunately HttpClient 5.1 fails to set the negotiated HTTP protocol version in the execution context correctly due to HTTPCLIENT-2200 [1]. The issue will be resolved in upcoming HttpClient 5.2-beta1.
For now use a custom header (X-Content-Length) for all protocol versions.
[1] https://issues.apache.org/jira/browse/HTTPCLIENT-2200

Related

Mule 4 - Unable to override some of the values of HTTP Response headers

I am facing difficulties in overriding the list of HTTP Response headers listed below
X-Content-Type-Options (from 1 to nosniff)
X-Frame-Options (from SAMEORIGIN to deny)
Set-Cookie (add HttpOnly;Secure)
I have tried to put these values into the Listener's HTTP Response headers as well as utilizing the Header Removal and Header Injection in the API Manager policies but to no success in overriding to the intended values.
May I know how do override the HTTP Response headers? Kindly refer to the photo of the values that I have set.
API Policies
Header Removal
Header Injection
Listener's response header values in the mule project
Response header from the API call
These headers "X-Content-Type-Options", "X-Frame-Options" are injected by DLB, so not able to remove or modify at Mule app or policy level, unless not using DLB. MuleSoft has fixed it and should be available in their next release.
In the API Manager policies, use the Inbound Header Map instead of the Outbound Header Map for both header removal and injection.

Postman Resolving "Invalid CORS request" for a POST Request

I've just started using Postman to test an API I am integrating to.
I have the following error that keeps showing up
Invalid CORS request
Note the following:
The API uses Bearer token authentication(OAuth2). I have this
working without a problem.
I do get the bearer token successfully, assign it to an Environment variable and then attempt to use it for the RESTful operations.
The problem is in the subsequent RESTful operation that uses the token.
When I use an old token (through a POST operation), it rightfully
tells me that it is expired and not authorized.
When I then generate a new one and try to run the restful call, it gives me that Invalid CORS request error.
Using cURL, I have no issues. But I am frustrated by Postman.
What I have found so far:
Using postman with Http POST requests - I don't get the part in bold
Just in case anybody else has this same problem, here is how to solve
it. Go to https://www.getpostman.com/docs/capture in your chrome
browser. Click on interceptor extension and then choose add to
chrome. Once it is added there is a new icon top right of both the
browser and postman that looks like a traffic light. In postman click
this and it turns green. Then add a header to every request going to
third light. Every header consists of the header name and a value.
Start typing over the header name and a list of allowed http headers
comes up. Choose "Origin". In the cell for value simply type the
full URL of your server. (Do not forget the 'http://' or 'https://').
What is the expected response to an invalid CORS request? - Best explanation I have seen so far on CORS errors.
The other material speaks about Access-Control-Allow-Method header, preflight requests
... and there is an illustrative Apache Tomcat flowchart of the CORS flow.
Here's the answer you found again:
Just in case anybody else has this same problem, here is how to solve it. Go to https://www.getpostman.com/docs/capture in your chrome browser. Click on interceptor extension and then choose add to chrome. Once it is added there is a new icon top right of both the browser and postman that looks like a traffic light. In postman click this and it turns green.
... With the bit in bold translated:
Then add a header to your request. The header Key should be "Origin" and the header Value should be the full URL of your server (Do not forget the http:// or https://).
Note that Chrome/Postman won't allow you to add a Header with a Key of Origin without the Interceptor plugin.
Also note that at least on my system the Interceptor icon no longer looks like a traffic light.
If your back-end service side code checks for origin of the request (just to avoid CORS attack) you may face this issues when testing your Rest API through postman.
How to Resolve this .?
You need to install a Chrome plugin called Postman Interceptor (https://chrome.google.com/webstore/detail/postman-interceptor/aicmkgpgakddgnaphhhpliifpcfhicfo?hl=en).
After successfully installing this plugin , in you Postman client you can see small icon called Postman Interceptor , you need to toggle it to turn it on.
Now you can add a Request header as below
RequestHeader Key "Origin"
RequestHeader Value "your application base URL"
Check this image
Now you should be able to over come CORS issues you are facing
Cheers !!
Just avoid using browser/chrome postman plugin. Use the desktop application instead!
Seems our server is seeing from a Postman manual HTTP POST that the orgin is invalid b/c its coming from Postman as "chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop"
Not sure why or how to resolve on client/Postman side. Seems our server is correclty rejecting it as is though and issuing a 403.
Value of "Origin" header set in Postman request should be allowed in API backend. For example, using Spring Boot for API should have next:
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Value("${cors.allowedOrigins}")
private String allowedOrigins;
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(allowedOrigins)
.allowedMethods("*")
.allowedHeaders("*");
}
}
where allowedOrigins is set using application.properties property cors.allowedOrigins having comma separated list of allowed origins, eg:
cors.allowedOrings=http://localhost:8080,http://example.com
and set 'Origin' value in Postman to any url from cors.allowedOrigins
I was getting this error when testing my APIs on the postman. Even after meticulously configuring my cors. So I used Insomnia instead of Postman and it works fine. I guess sometimes postman is the problem as it needs some extra effort.
You can try new version of PostMan. To me it works after upgraded postman version from 5.5.5 to 7.36.5

Auth Challenge Alamofire 2.0

Since we updated our project to Swift 2 and Alamofire to version 2.0 we observe the following behavior regarding base auth: When we send a request (no matter what kind of) with authentication set, the request is always sent without authentication header the first time. After the backend answers with status code 401, alamofire adds the authentication header and and resends the request once again. We send the request using the following snipped:
Alamofire.request(request).authenticate(user: Config.serviceAuthUser, password: Config.serviceAuthPassword)
Is there a way to force Alamofire to include the authentiation header in every request? We want to avoid this kind of auth challenge for every request to lower network and server traffic. We had one solution working for iOS8, where we added the auth header in the session config of the shared instance of Alamofires Manager as follows:
Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders = authHeader
But with iOS9 this does not work anymore, since only a copy of the configuration object is returned and modified.
Is there another way to avaoid this auth challenge process and force Alamofire to include the auth header with every request?
Making two requests is how the underlying URL Loading System was designed by Apple. The Alamofire authenticate methods simply allow you to provide the credentials to supply to the challenge if it occurs.
If you want to provide the header directly, the use the headers parameter on the request method. Additionally, you could insert the user:password credentials directly into the URL.

Using stomp.js over sock.js with ActiveMQ-Apollo does not seem to work

I am working through some samples in the ActiveMQ-Apollo installation and playing around with the examples/websocket.
In this file, Stomp.js is being used to establish connection:
client = Stomp.client(url);
The example works fine and I am able to see the messages being sent and received. The issue, is that Stomp uses default WebSocket which may not be available at times. So, I wanted to integrate with SockJS client library. According to the example for StompJS on this page (http://jmesnil.net/stomp-websocket/doc/) it should be possible with this code:
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<script>
// use SockJS implementation instead of the browser's native implementation
var ws = new SockJS(url);
var client = Stomp.over(ws);
[...]
</script>
The above code appears to execute correctly, however, later I see the following errors:
XMLHttpRequest cannot load ws://mylocaldomain.com:61623/info. Cross origin requests are only supported for HTTP. sockjs-0.3.js:807
Uncaught Error: NetworkError: DOM Exception 19
Then, I see the debug window show this message:
Opening Web Socket...
Whoops! Lost connection to undefined
I am serving the page from mylocaldomain.com:80, and the ActiveMQ Apollo server is running on the same machine, but listening on port 61623. I have also grabbed the latest version of StompJS (from dist directory on github) as well as SockJS directly from cdn.sockjs.org.
I tried this example on latest Chrome and Firefox (on OSX) and the same thing occurs. No connection is established.
Again, going back to the standard example which ships with the Apollo works fine, but I would like to find out why StompJS over StockJS is failing.
Has anyone seen this issue?
Thanks.
-AP_
You need to modify the ActiveMQ-Apollo web configuration to support Cross-Origin-Resource-Sharing (CORS) as described here:
Enabling CORS
W3C CORS Specification
Basically the server needs to do the following things:
Support the HTTP OPTIONS request (aka CORS pre-flight request) that is sent by browsers for Cross Domain requests. This includes responding to the OPTIONS request with:
Access-Control-Allow-Origin header (for example: "*" which means allow all origins)
Access-Control-Request-Method header (for example: "GET, POST, PUT, DELETE, OPTIONS")
Access-Control-Allow-Headers (for example: "X-Requested-With,Origin,Content-Type, Accept")
The handling of HTTP OPTIONS can typically be done using a single Web Filter matching filter pattern "/*".
See also "cors_origin" WebSocket connector URL query parameter supported by ActiveMQ Apollo 1.7

DotNetOpenAuth RP fails behind SSL appliance

I'm having trouble getting a DNOA RP working behind an SSL appliance (terminates the client HTTPS connection and reverse-proxies HTTP to the webserver behind it).
The problem is that the RP is incorrectly guessing the recipient endpoint from the incoming request (since it's not HTTPS by the time it hits the webserver) and comparing the endpoint with scheme on the return_to url (which is HTTPS)- it fails with the stacktrace below. I've spelunked around in the code a bit and I don't see a way to change this behavior without a custom build or a non-trivial subclass. I'm already passing the HTTPS version of the Realm and ReturnToUrl to OpenIdRelyingParty.CreateRequests()- that part's working fine.
Is it possible to fudge the detected recipient scheme to HTTPS or skip scheme comparison on a stock DNOA build, or am I patching up a custom build tomorrow?
Stacktrace:
ERROR DotNetOpenAuth.Messaging - 09 Jul 2010 00:11:39,450 - Protocol error: The openid.return_to parameter (https://XXX/Login.aspx?openid=XXX&dnoa.userSuppliedIdentifier=XXX) does not match the actual URL (http://XXX/Login.aspx?openid=XXX&dnoa.userSuppliedIdentifier=XXX&openid.ns=http://specs.openid.net/auth/2.0&openid.mode=id_res&openid.op_endpoint=XXX&openid.response_nonce=XXX&openid.return_to=https://XXX/Login.aspx?openid=XXX&dnoa.userSuppliedIdentifier=XXX&openid.assoc_handle=XXX&openid.signed=op_endpoint,claimed_id,identity,return_to,response_nonce,assoc_handle&openid.sig=XXX&openid.identity=XXX&openid.claimed_id=XXX) the request was made with.
at DotNetOpenAuth.Messaging.ErrorUtilities.VerifyProtocol(Boolean condition, String message, Object[] args)
at DotNetOpenAuth.OpenId.Messages.IndirectSignedResponse.VerifyReturnToMatchesRecipient()
at DotNetOpenAuth.OpenId.Messages.IndirectSignedResponse.EnsureValidMessage()
at DotNetOpenAuth.Messaging.MessageSerializer.Deserialize(IDictionary`2 fields, MessageDictionary messageDictionary)
at DotNetOpenAuth.Messaging.Reflection.MessageDictionary.Deserialize(IDictionary`2 fields)
at DotNetOpenAuth.Messaging.Channel.Receive(Dictionary`2 fields, MessageReceivingEndpoint recipient)
at DotNetOpenAuth.Messaging.Channel.ReadFromRequestCore(HttpRequestInfo request)
at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest)
at DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.GetResponse(HttpRequestInfo httpRequestInfo)
at DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.GetResponse()
DotNetOpenAuth has built-in support for SSL appliances when they add these special HTTP headers to the forwarded HTTP request: X_FORWARDED_PROTO and/or HTTP_HOST. When these are present, the auto-detection of the outside-facing URL is correct. If you can configure your SSL appliance to do this, that's probably the best option.
The alternative is to call OpenIdRelyingParty.GetResponse(HttpRequestInfo) instead of the overload that takes no parameters. You construct the HttpRequestInfo yourself using the outward-facing URL that you know is the real one. Then the URL matching logic inside DotNetOpenAuth won't fail the request.