HTTP 100 Continue response CAN have a message body? - delphi

I am writing a HTTP Proxy in Delphi 6 using Synapse library.
I know that a regular response has the following syntax:
A Status-line
Zero or more header (General|Response|Entity) fields followed by CRLF
An empty line indicating the end of the header fields
Optionally a message-body
But 100 Continue is not a regular one, is just a inter-response that tells the client to continue and must be followed by a final regular response.
So, should I expect a body in a 100 Continue response?

No, 1xx status responses must not have a body. See http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-26.html#rfc.section.3.3.p.5:
"The presence of a message body in a response depends on both the request method to which it is responding and the response status code (Section 3.1.2). Responses to the HEAD request method (Section 4.3.2 of [Part2]) never include a message body because the associated response header fields (e.g., Transfer-Encoding, Content-Length, etc.), if present, indicate only what their values would have been if the request method had been GET (Section 4.3.1 of [Part2]). 2xx (Successful) responses to a CONNECT request method (Section 4.3.6 of [Part2]) switch to tunnel mode instead of having a message body. All 1xx (Informational), 204 (No Content), and 304 (Not Modified) responses do not include a message body. All other responses do include a message body, although the body might be of zero length."

Related

Charles, empty request body with non-empty response body

I used Charles to record a session and when I check one of the sessions, I found that there is no request body but I can see a response body, I am confused about this as how am I seeing a response without sending a request?
Also, I noticed that I can choose to see the request and response body on my phone's Charles, but on my desktop Charles, I can only see the tab called Content, I tried clicking on the request and response in the under the View tab, nothing happened as well. Does anyone know why?
Thanks!
I am confused about this as how am I seeing a response without sending a request?
A request consists of a few things:
Always: an HTTP method (GET, POST, or similar)
Always: a path (/document/123)
Optional: any number of HTTP headers (my-header: abc)
Optional: a request body
A response consists of:
Always: an HTTP status (404)
Always (in HTTP/1): an HTTP status message (Not Found)
Optional: any number of HTTP headers (my-header: abc)
Optional: a response body
In your case, you are sending a request, it's just that your request only contains a method, URL and headers, but no body. That's totally normal and this is very common for most HTTP requests.
The request and response body are totally independent: it's fine for neither to have a body, or for just one (either one) to have a body, or for both to have a body.
As an example, a GET request to https://google.com/search from a browser will include a method (GET) and a path (/search) and a selection of headers from the browser (such as a user-agent), but won't include any body, and the response will have a status (200) and message (OK), headers about the response data (e.g. content-length: ...) and the body will be the HTML for the google search page.

Lua scripting language: modify a response body in API gateway

I would like to modify the response body returned by the backend.
As background I'll detail my specific problem (but I don't require a solution to the specific problem, just the method for manipulating a response body). I want to insert/add a key value pair to the response body based on the status code of the response and I want to transform snake_case keys into camelCase keys.
For example, given a response with
status code: 401
body: {'detail_message': 'user is not logged in'}
I want to transform it to a response with
status code: 401
body: {'success': False, 'detailMessage': 'user is not logged in'}
The rule for success would be True for anything below 400 and False for anything above or equal.
Lua scripting can be used in my API gateway which is Krakend
https://www.krakend.io/docs/endpoints/lua/
The documentation only includes examples for printing the response body and modifying headers but not for modifying the response body.
I have no experience with Lua and only need it for one task. I haven't been able to find online example of response body manipulation which I could play with.
What methods do I need in order to add a key value pair to a response body and to manipulate the keys in the response body?

Runtime Error when sending a search request to outlook for a keyword that does not exist in the mailbox

When searching for a keyword ("Test email"), using Outlook API, and the keyword exist in my mailbox, I retrived a result within a second. However, if the keyword ("blablabla") does not exist in the mailbox I do not get a reply. Almost after 2 minutes I get a runtime error.
http get on: https://outlook.office365.com:443/api/v2.0/users/user#sub.onmicrosoft.com/messages?$search=blablablablabla&$top=100&$select=Sender,ToRecipients,CcRecipients,Weblink,Subject,ReceivedDateTime,BodyPreview
http headers:
Authorization: bearer theToken
x-AnchorMailbox: theEmailAddress
I expected to get an HTTP Response that says something like "Could not find any result"
Instead I get no reply upto two minutes and than a runtime error with that yellow background that instructs to turn on
<customError mode="Off" />
Though the http staus code is 200.
I think as an API consumer I should not get such replies.

iOS / Obj-c - Get HTTP status code response message (reason phrase)

I'm working with an API that sends back HTTP 406's for many different errors, along with a custom message (reason phrase). It may look something like:
406 Not Acceptable: User is already logged in
406 Not Acceptable: Missing password field
406 Not Acceptable: Node does not exist.
I can get the 406 status code and the standard "Not Acceptable" string using:
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
NSInteger statusCode = [HTTPResponse statusCode];
[NSHTTPURLResponse localizedStringForStatusCode:HTTPResponse.statusCode];
However I really require the reason phrase message to know how to handle the response. How can I get it, preferably using the standard iOS SDK?
I really require the reason phrase message to know how to handle the response.
Then the API is broken. The reason phrase is a debugging aid only. It's not meant to inform client behaviour.
From RFC 2616 ยง 6.1.1:
The Status-Code is intended for use by automata and the Reason-Phrase is intended for the human user. The client is not required to examine or display the Reason- Phrase.
If there is information about the response that cannot be conveyed by the status code alone, the proper place for it is as a header or in the response body. The reason phrase is not a correct place to put information necessary for a client to use.
Status code 406 means that the server cannot respond with the accept-header specified in the request.
406 Not Acceptable The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request.
These error codes are not iOS-specific. If you want to display different messages based on different occurrence reasons, I suppose you should check it with your API/web server, and use conditions in your code to display your custom messages for each of them.
Ultimately, you can get the reason phrase using the ASIHTTPRequest library.
http://allseeing-i.com/ASIHTTPRequest/
It was just as simple to use in my case as AFNetworking and NSURLSession.

Does every successful HTTP request always return status code 200?

In Delphi, I'm using Indy's TIdHTTPWebBrokerBridge coupled with TIdHTTP to send/receive data via HTTP. On the Server, I don't have any fancy handling, I always just respond with a simple content stream. If there's any issues, I only return information about that issue in the response content (such as authentication failed, invalid request, etc.). So, on the client side, can I assume that every successful request I make to this server will always have a response code of 200 (OK)?
I'm wondering because on the client, the requests are wrapped inside functions which return just a boolean for the success of the request.
Inside this function:
IdHTTP.Get(SomeURL, AStream);
Result:= IdHTTP.ResponseCode = 200;
This function handles any and every request which could possibly fetch data. If there were any issues in the request, This function should return False. In my scenario, since I always return some sort of content on the server, would the client always receive a response code of 200 in this function?
I guess the real question is, if I always return some sort of content and handle all exceptions on the server, then will the server always return status code of 200 to each request?
"Does every successful HTTP request always return status code 200?"
See w3.org: HTTP/1.1 Status Code Definitions (RFC 2616)
The answer is No. All 2xx are considered successful.
That may depend on the HTTP method used.
Should your web-server application always return 200 upon success? That may as well depend on the request method and the signal it intends for the client . e.g.
for PUT method (emphasis is mine):
If an existing resource is modified, either the 200 (OK) or 204 (No
Content) response codes SHOULD be sent to indicate successful
completion of the request.
for POST method:
The action performed by the POST method might not result in a resource
that can be identified by a URI. In this case, either 200 (OK) or 204
(No Content) is the appropriate response status, depending on whether
or not the response includes an entity that describes the result.
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header (see section 14.30). Responses to this method are not
cacheable, unless the response includes appropriate Cache-Control or
Expires header fields. However, the 303 (See Other) response can be
used to direct the user agent to retrieve a cacheable resource.
As you can learn from the RCF, every method SHOULD have it's own success status codes, depending on the implementation.
Your other question:
"can I assume that every successful request I make to this server will always have a response code of 200 (OK)?"
You can always expect Status code 200, if your web server always responds with Status 200. Your web server application controls what response it returns to the client.
That said, Status code 200 is the Standard response for successful HTTP requests (The actual response will depend on the request method used), and in the real world of web servers, SHOULD be set as default upon successful request, unless told otherwise (As explained in Remy's answer).
To answer your specific question:
can I assume that every successful request I make to this server will always have a response code of 200 (OK)?
The answer is Yes, because TIdHTTPWebBrokerBridge wraps TIdHTTPServer, which always sets the default response code to 200 for every request, unless you overwrite it with a different value yourself, or have your server do something that implicitly replies with a different response code (like Redirect() which uses 302, or SmartServeFile() which uses 304), or encounter an error that causes TIdHTTPServer to assign a 4xx or 5xx error response code.
However, in general, what others have told you is true. On the client side, you should handle any possible HTTP success response code, not just 200 by itself. Don't make any assumptions about the server implementation.
In fact, TIdHTTP already handles that for you. If TIdHTTP encounters a response code that it considers to be an error code, it will raise an EIdHTTPProtocolException exception into your code. So if you don't get an exception, assume the response is successful. You don't need to check the response code manually.
If there is a particular response code that normally raises an exception but you do not want it to, you can specify that value in the optional AIgnoreReplies parameter of TIdHTTP.Get() or TIdHTTP.DoRequest(). Or, if you are are using an up-to-date Indy 10 SVN revision, a new hoNoProtocolErrorException flag was recently added to the TIdHTTP.HTTPOptions property so the EIdHTTPProtocolException exception is not raised for any response code.
Successful resposes are 2xx List_of_HTTP_status_codes
i did the following. Process straight all 200`s and LOG exceptions. worked, not a single non 200 - except unauthorized and timeouts (password or sometimes unavaliable server). but many/all responses will be considered for a wide range of mainstream apps.
while (iRedo < 3) do begin
s := Self.HTTPComponent.Get( sUrl );
if self.HTTPComponent.ResponseCode = 200 then begin
break;
end;
// IDEIA - log what happend if not 200
logWhatHappend( s, HTTPComponent ); // then log content, headers, etc
inc( iRedo ); sleep( 5 );
end;

Resources