Several 100-continue received from the server - c++

I'm using libcurl (c++) library to make a request to an IIS 7.5 server. The transaction is a common SOAP webservice
Everything is working fine, my requests send an "Expect 100-continue" flag, and the server responds with a 100-continue and inmediately after that a 200 ok code along with the web service response.
But from time to time, the client receives a 100-continue message and after that, another 100 code. This makes the client report an error, as it expects a final status code right after the server 100 code. I read in W3C HTTP1.1 protocol:
An origin server that sends a 100 (Continue) response MUST
ultimately send a final status code, once the request body is
received and processed, unless it terminates the transport
connection prematurely.
The word "ultimately" makes me loose the track. Is it possible/common that a server sends several 100 codes after a final status code?
If anyone has faced this issue before, can point me to any explanation on how to handle multiple 100 response codes with libcurl?
Thanks in advance

The current spec says this on 100-continue:
The 100 (Continue) status code indicates that the initial part of a
request has been received and has not yet been rejected by the server. The server intends to send a final response after the request has been fully received and acted upon.
When the request contains an Expect header field that includes a
100- continue expectation, the 100 response indicates that the server wishes to receive the request payload body, as described in
Section 5.1.1. The client ought to continue sending the request and discard the 100 response.
If the request did not contain an Expect header field containing the 100-continue expectation, the client can simply discard this interim response.
The way I read it, it is not supposed to be more than one 100-continue response header and that's why libcurl works like this. I've never seen this (multiple 100 responses) happen and I've been doing HTTP for a while (I am the main developer of curl). To change this behavior I would expect you'd need to patch libcurl slightly to allow for this to happen.
It is not related to CURLOPT_FAILONERROR.

I suspect it's because there is an unhandled error that is not handled by the client properly. Make sure you set the CURLOPT_FAILONERROR flag.
See this SO post for more information.

Related

Is there a workaround for Postman's bug when content is returned with a 204?

Using Postman, when I make a PUT request to an endpoint which returns a 204 with content, Postman is unable to parse the response, and my collection runner stops that iteration, indicating that an error has occurred.
When run outside of the runner, Postman displays the following:
Other people have also had this problem
Unfortunately I cannot fix the non-standard endpoint. Is there a workaround that will let Postman continue without throwing an error, especially when using the collection runner?
The 204 (204 NO CONTENT) response from the server means that the server processed your request successfully and a response is not needed.
More here: https://httpstatuses.com/204
Actually as much as I know, if the server is sending a 204 with a payload response, the endpoint is not developed as it should.
This would be the main reason Postman is not showing a response payload. You will only be able to read response headers.
So if you send a PUT request, and only receive headers, it means everything is ok. If you spect data the server should be responding with a 200 code.
Now, said this, if postman is telling you that “it could not get any response” it means basically the server is not responding any thing. Now try to increase the timeout in the postman settings. It’s very probable that the server is taking to much time. Check outside the runner how much time it’s taking to response.
I hope this helps you.

Jetty - large messages filtering

Hi I want to refuse incoming requests with too large body or header in my Jetty.I suppose that I have to set some filter, but I haven't found any solution. Do you have any suggestions? Thanks.
Easy enough to build a Servlet Filter or Jetty Handler that pays attention to the request's Content-Length header and then rejects (responds with an http error status code) the request.
As for the header size limit, that's controlled by the HttpConfiguration.setRequestHeaderSize(int)
However, there are a class of requests, that uses Chunked Transfer-Encoding, with these kinds of requests, there is no Content-Length and you will just have to reject the request when reading from the HttpServletRequest.getInputStream() after it hits a certain size.
There is also the complication of Mime multi-part request body content and how you determine the request content is too large.
One other note, unfortunately, due to how HTTP connection handling must be performed, even if a client sends you too large of a request body content, the server still has to read that entire body content and throw it away. This is the half-closed scenario found in the spec, its up to the client to see the early rejected http response and close/terminate the connection.

Jetty-9 warning: badMessage: 400 Illegal character

I am using jetty-9.2.2 with CometD-3.0.1. I am seeing below warning in my setup. It comes ~4,5 times in a day.:
2014-08-28 08:50:53.712:WARN:oejh.HttpParser:qtp607635164-15194: badMessage:
400 Illegal character for HttpChannelOverHttp#5946f125{r=1,a=IDLE,uri=-}
There is no details that can be debugged from the warning message. I have already logged a request https://bugs.eclipse.org/bugs/show_bug.cgi?id=443049 to provide detailed warning.
Meanwhile I want to know what is causing this warning? Can I ignore this or some messages are lost because of this?
Change https to http in the url.
I had the same error, then found out it's because my application did not support https, so jetty cannot recognize the https encrypted request.
Update May 2017
For Jetty 9.3+ users, you might see a log message that makes this response code more clear.
See Header parse error after upgrade to Jetty 9.3 for details.
Original Answer
The Bad Message: 400 Illegal Character can occur during parsing of a bad HTTP Request.
That is the HTTP error response that the client sees.
Some (not all) situations in which it can occur.
The EOL is not "\r\n" (CR + LF) (HTTP spec requirement)
The HTTP Method token is either not recognized or has invalid whitespace after it
The HTTP Version is not recognized or has invalid characters
HTTP Header name does not follow spec
HTTP Header value does not follow spec
This message is common on public (internet facing) servers.
You have bad HTTP requests coming in. Why?
A legitimate HTTP client has a bug
A legitimate HTTP client is not following the HTTP spec
A non HTTP client attempted to connect to your server (such as attempting to use non-encrypted HTTP on a SSL/TLS/HTTPS port, or even something as odd as an SMTP/IMAP email client attempting to talk to your HTTP port)
A malicious client is attempting to probe your system for weaknesses
This error can be caused, as it was for me, by a silly little mistake.
When testing on my localhost Jetty instance, I received a very similar 400 Illegal Character message. Then I realized why. I had simply assumed application address on my local Jetty was:
https://localhost:8080
whereas the correct address was unsecured:
http://localhost:8080
No problems after that.
Jetty is cautious about detailed error messages that include user sent data, as these can be part of an attack - even if echo'd just to a terminal.
However, we can do better and log some sanitised data. Acting on the bugzilla
Well, I met this problem because I mistook the "http://" as "https://"

"Range:" http header causes hang in ColdFusion app

Whenever I add the "range" header in a HTTP request for a .cfm or .cfc file on my server, I get a timeout. The server simply does not respond.
To debug, I created a blank file called "/signup/test.cfm" on my server. It contains nothing. Next, I make a normal request and an edited request for the file:
Request:
GET /signup/test.cfm HTTP/1.1
Host: site.com
Response:
HTTP/1.1 200 OK
Request:
GET /signup/test.cfm HTTP/1.1
Host: site.com
Range: bytes=0-40960
Response:
timeout in transmission from site.com
If I include the Range header in a request to a static file, there is no problem.
What could be causing this, and how do I debug it? The file I am requesting is empty, so no code should be executing. Application.cfc is empty. Since I assume no code is executing, does this mean that it is a server configuration problem?
EDIT: By adding a tag to my script, I have confirmed that it does execute the ColdFusion code. The response is just never sent back to me.
Most likely the cf parser doesn't work with ranged requests while the static file handler does.
Range is for fetching part of content and subsequently fetching more later. E.g. Video file streaming or download continuation. Not something easily handled by a script handler as the request is meant to be returned all at once.
Here's a stackoverflow with a sample range request to show how this works
Sample http range request session

Connecting a desktop application with a website

I made an application using Qt/C++ that reads some values every 5-7 seconds and sends them to a website.
My approach is very simple. I am just reading the values i want to send and then i make an HTTP POST to the website. I also send the username and password to the website.
The problem is that i cannot find out if the request is successful. I mean that if i send the request and server gets it, i will get an HTTP:200 always. For example if the password is not correct, there is no way to know it. It is the way HTTP works.
Now i think i will need some kind of a protocol to take care the communication between the application and the website.
The question is what protocol to use?
If the action performed completes before the response header is sent you have the option of adding a custom status to it. If your website is built on PHP you can call header() to add the custom status of the operation.
header('XAppRequest-Status: complete');
if you can modify the server side script you could do the following
on one end :
You can make the HTTP post request via ajax
and evaluate the result of the ajax request.
On the serve side
On the HTTP request you do your process and if everything goes accordingly you can send data back to the ajax script that called it.
solves your problem .. ?