jetty BadMessage: 400 No Host for HttpChannelOverHttp - http

I have seen previous posts about Jetty BadMessage: 400 No Host for HttpChannelOverHttp and I can confirm that I am able to repeat the problem.
I have a Jetty route in Camel Blueprint, which creates another request and forwards on to a Dropwizard service via Camel HTTP.
.process(new Processor() {
//Creates Object for request
}
.marshal(jsonFormat)
.convertBodyTo(String.class)
.setHeader(Exchange.HTTP_URI, simple(serviceEndpoint))
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethod.POST))
.to(userviceEndpoint)
When this request executes, I see the following error on Dropwizard
WARN [2014-11-12 23:15:35,333] org.eclipse.jetty.http.HttpParser: BadMessage: 400 No Host for HttpChannelOverHttp#3aa99dd2{r=0,a=IDLE,uri=-}
This happens constantly, and this problem does not occur when I send a request to the DW service using SOAP-UI (using the serviceEndpoint URL).
Please if anyone has solved this problem, I would like to know how. Thank you.

Capture your network traffic, and post the HTTP request headers you are sending to Jetty.
Odds are that your HTTP client is not sending the Host: header (which is required on HTTP/1.1)

In my case, I was setting header with null value. After removing header having null value from request solved the issue.
Jetty Version: 9.3.8

I got this error when I was making a request with incorrectly formatted headers. So instead of having the header as "X_S_ID: ABC" I had "X_S_ID: ["X_S_ID":BLAH]". So the error sometimes may not literally mean you need to pass a Host header.
Fixing the headers fixed this. Print the exact request you are making and make sure all headers are correctly formatted.

Related

Set ':authority' header in Postman

I'm currently trying to replicate a https request with the following headers.
The authentication is based on a Session Cookie.
However, there is also a header field called :authority,
which I'm not able to replicate in Postman.
Also, couldn't I find any solution for that problem
or what exactly the :authority header means on the Internet.
This header seems to be required, as I'm getting a 400 error code back
as soon as I send my replicated request.
I've proxied the request sent from Postman and can confirm that the only difference at the first glance is the missing :authority header.
Thanks ^^
Alright, taking a closer look at the Raw Request, I noticed that the actual header is called Host and is mapped in the UI to :autority. Now its working. cheers

Tomcat not handling encoded URL

I'm hitting a problem with Tomcat 8.5 when using URL that needs to be encoded. The URL contains [ and ] characters, and those are correctly being encoded as %5B and %5D. I send the request with curl e.g. curl http://somewhere.com/foo%5Bbar%5D but Tomcat throws a 400 error stating that "The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).".
In the Tomcat access log the URL is report in its decoded form along with the 400 response.
I do have an nginx reverse proxy in between, but I don't think that would be decoding the URL.
Any ideas what's wrong?
So it turned out to be a know problem with the nginx ingress in that when it has to rewrite the URL is decodes it and sends the decoded URL downstream to Tomcat which then blows up.
There's various discussions on this, but as I needed to fix this as part of the K8S ingress definition I used the info described here. I've not sure where the upstream_balancer thing comes from but must be some black magic, but it does seem to fix the problem. I'm sure there are other approaches that would also work.

HTTP 403 Forbidden Message Format

What is the correct format for sending an HTTP 403 forbidden message?
I'm writing a proxy in c for a homework project that has a content filtering system built in. When my proxy detects that a server's response has certain keywords that are contained in the content blacklist, I would like to send a HTTP 403 Forbidden message.
Currently, I am sending the message as: "HTTP/1.1 403 Forbidden\r\n\r\n" (without the quotes) as per this standard: https://www.rfc-editor.org/rfc/rfc7231#section-6.5.3
When I send this message, the browser doesn't display an error and looks like it's still trying to load the page.
Are there any required header fields for this http message that I missed? Also, is this the correct usage for the 403 error? I couldn't find anything else that would be more fitting, so I chose 403 because the client won't automatically re-request the data.
Thanks in advance for any help!
For those struggling with this issue as I did, you need to make sure to close the socket or set Connection: Close as Sami noted in the comments. I assumed that you could keep it open so they could send another request with http persistent connections, but they will need to open a new connection.
As for the html displayed, you can send a body with the response (make sure you set Content-Length) that contains the html you want displayed.
Finally, here are two references, one to the HTTP response spec, and the other to the Amazon Restful response spec:
https://www.rfc-editor.org/rfc/rfc7231#section-6.5.3
https://developer.amazon.com/docs/amazon-drive/ad-restful-api-response-codes.html

Akka-http POST results in "The server-side HTTP version is not supported"

I have an issue when trying to do a simple POST request to some internal endpoint using akka-http. When this piece of code is executed:
for {
request <- Marshal(merchantTransactionRequest).to[RequestEntity]
response <- Http().singleRequest(
HttpRequest(
method = HttpMethods.POST,
uri = "http://foo/bar:8080",
entity = request.withContentType(ContentTypes.`application/json`)
)
)
...
} yield ...
I get greeted with the following error:
akka.http.scaladsl.model.IllegalResponseException: The server-side HTTP version is not supported
at akka.http.impl.engine.client.OutgoingConnectionBlueprint$PrepareResponse$$anon$1.onPush(OutgoingConnectionBlueprint.scala:191)
...
which is immediately preceded by the following log:
[0] </10.0.0.135:42610->foo:8080> pushing request to connection: POST bar Strict(508 bytes)
As part of my debugging journey, I executed the same query to the endpoint using curl, which magically succeeded (and responds with HTTP/1.1). Since HttpRequest(...) defaults to using protocol = HttpProtocols.`HTTP/1.1`, it is my suspicion that somehow the HTTP version negotiated between akka-http and this other endpoint is incorrect.
Is it possible to somehow enforce a HTTP version when akka-http does a POST? Or any other clue as to why curl succeeds doing the POST, while akka-http does not? Note that problem only occurs while doing POST's, not GET's.
It turned out the problem had a very strange solution: Instead of connecting to directly connecting to the other endpoint through address http://foo/bar:8080 (using our internal DNS resolver), we connected indirectly to the endpoint using https://our-domain.com:443. Everything worked as expected in that case. It seems that akka-http is somehow troubled by the absence of a TLD.

How does HTTP caching works in a proxy server?

It's my understanding that caching is one of the main utilities of a proxy server. I'm currently trying to develop a simple one and I would like to know exactly how caching works.
Intuitively I think that it's basically an association between a request and a response. For example: for the following request: "GET google.com" you have the following response: "HTTP/1.0 200 OK..."
That way, whenever the proxy server receives a request for that URL he can reply with the cached response (I'm not really worried right now about when to serve the cached response and when to actually send the request to the real destination).
What I don't understand is how to establish the association between a request and a response since the HTTP response doesn't have any field saying "hey this is the response you get when you request the X URL" (or does it?).
Should I get this information by analyzing the underlying protocols? If so, how?
Your cache proxy server is already putted into play when a request arrives. Therefore you have the requested resource URL. Then you look in your cache and try to find the cached resource for the requested resource URL, if you cannot find the resource in your cache (or the cache is outdated), you fetch the data from the source. Keep in Mind, that you have to invalidate the cached resource if you receive a PUT, POST or DELETE request.

Resources