RFCs for content-type header? - http-headers

I've looked # rfc 2231 and 2183.
Dealing with a multipart/related mime payload.
I'm trying to decypher if the following is syntactically correct, specifically the "start" attribute for the first Content-Type, but I haven't been able to find the correct RFC.
Content-Type: multipart/related; boundary="=_34e1b39f5c290f66360ff510d4c38da4"; type="application/smil"; start="<cid:eaec2c30d892902b14044d57dbb6ff85>"
--=_34e1b39f5c290f66360ff510d4c38da4
Content-ID: <eaec2c30d892902b14044d57dbb6ff85>
Content-Type: application/vnd.oma.drm.message; boundary=ihvdxymhvdhobklkqbcn;
name="IrishJi2.dm";
Content-Disposition: attachment;
filename="IrishJi2.dm";
--ihvdxymhvdhobklkqbcn
Content-Type: audio/mpeg
Content-Transfer-Encoding: binary
Some background information for the curious. application/vnd.oma.drm.* file types is just a wrapper around a payload item (mp3,jpg, etc) that tells cellular devices the wrapped file is to be considered protected payload and not to allow it to be forwarded or transfered off the phone in anyway. If not for contractual obligations I'd just rip the wrapper off, send the payload on, and be happy, but that is too easy and probably illegal.

From RFC 2387 (The MIME Multipart/Related Content-type):
3.2. The Start Parameter
The start parameter, if given, is the content-ID of the compound object's "root". If not present the "root" is the first body part in the Multipart/Related entity. The "root" is the element the applications processes first.

Related

Is it correct to specify HTTP response Content-Type as image/*?

I'm curious whether sending Content-Type: image/* in a HTTP response is correct. I know it's advisable to specify the exact MIME type but I'd like to hear if I can use such a header as a fallback when I know it's an image but I don't know its type.
I don't see any evidence that you can or should use wildcards in Content-Type.
RFC 7231 does allow wildcards like that in the Accept header, where you're indicating a range of acceptable content types. The definition of Content-Type does not give any special meaning to the * character, and image/* is not listed as a registered type.
If you cannot identify the media type accurately, you should just leave off the header entirely.

HTTP response for an unacceptable Accept header

My RESTFul API can only respond JSON-encoded data (i.e. all my headers have Content-Type: application/json). What should I return, if the request has an Accept header that does not allow JSON (for example, Accept: text/html)? Should I just return a 400 Bad Request with an explanation in the body, or is there a more specific status code for this exception?
Note that this is different from unsupported request content-types.
If you want to be semantically correct:
If the request is HTTP/1.0:
a 406 Not Acceptable is the correct thing to return, as the client may not be able to handle a response that isn't of the type requested.
in HTTP/1.1, that's still the "right" thing to do, but there are exceptions,
From RFC 2616 Sec 10.4.7
Note: HTTP/1.1 servers are allowed to return responses which are
not acceptable according to the accept headers sent in the
request. In some cases, this may even be preferable to sending a
406 response. User agents are encouraged to inspect the headers of
an incoming response to determine if it is acceptable.
In truth, the likelihood of it mattering is pretty low, as #Jack has mentioned. I'm only including this answer in the interests of completeness.
Don't bother.
There will be cases whereby consumers of your service wouldn't bother to set this header, e.g. when using cURL or file_get_contents() in PHP.
If your API documentation states that your service only supports JSON output, that should be good enough.
You could also work with extensions to enforce the format, e.g. /path/to/resource.json?a=b or /path/to/resource.xml?a=b for JSON and XML respectively.
In the case that you want to support multiple output formats and the Accept request header value is non-conclusive, you should define a default output format.

Do any browsers support trailers sent in chunked encoding responses?

HTTP/1.1 specifies that a response sent as Transfer-Encoding: chunked can include optional trailers (ie. what would normally be sent as headers, but for whatever reason can't be calculated before the content, so they can be appended to the end), for example:
Request:
GET /trailers.html HTTP/1.1
TE: chunked, trailers
Response:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Trailer: My-Test-Trailer
D\r\n
All your base\r\n
B\r\n;
are belong\r\n
6\r\n
to us\r\n
0\r\n
My-Test-Trailer: something\r\n
\r\n
This request specifies in the TE header that it's expecting a chunked response, and will be looking for trailers after the final chunk.
The response specifies in the Trailer header the list of trailers it will be sending (in this case, just one: My-Test-Trailer)
Each of the chunks are sent as:
size of chunk in hex (D = 13), followed by a CRLF
chunk data (All your base), followed by a CRLF
A zero size chunk (0\r\n) indicates the end of the body.
Then the trailer(s) are specified (My-Test-Trailer: something\r\n), followed by a final CRLF.
Now, from everything I've read so far, trailers are rarely (if ever) used. Most discussions here and elsewhere concerning trailers typically start with "but why do you want to use trailers anyway?".
Putting aside the question of why, out of curiosity I've been trying to simulate a HTTP request/response exchange that uses trailers; but so far I have not yet been able to get it to work, and I'm not sure if it's something wrong with response I'm generating, or whether (as some have suggested) there are simply no clients that look for trailing headers.
Clients I've tried include: curl, wfetch, Chrome + jQuery.
In all cases, the client receives and correctly reconstructs the chunked response (All your base are belong to us); and I can see in the response headers that Trailer: My-Test-Trailer is being sent; but I'm not seeing My-Test-Trailier: something returned either in the response headers, or anywhere.
It's unclear whether a trailing header like this should appear in the client as a normal response header, after the entire response has been received and the connection closed?
Interestingly, the curl change logs appear to suggest that curl does support optional trailers, and that curl will process any trailers it finds into the normal header stream.
So does anybody know:
of a valid URL that I could ping, which sends trailers in a chunked response? (so that I can confirm whether it's just my test response that's not working); and
which clients are known to support (and access/display) trailers sent by the server?
No common browsers support HTTP/1.1 trailers. Look at the column "Headers in trailer" in the "Network" tab of browserscope.
Chrome: No, and won't fix (bug). Supports H/2 trailers (bug).
Firefox: No, and I don't see a ticket in bugzilla for it. Appears to support H/2.
IE: No
Edge: No
Safari: No
Opera: Old versions only (v10 - 12, removed in 14)
As you've discovered, a number of non-browser clients support it.
Over 5 years since asking this question, I can now definitively answer it myself.
Mozilla just announced that they will be supporting the new Server-Timing field as a HTTP trailing header (their first ever support for trailers).
https://bugzilla.mozilla.org/show_bug.cgi?id=1413999
However, more importantly, they confirm that it will be whitelisted so that Server-Timing is the only support value (emphasis mine):
Server-Timing is an HTTP trailer, not a header. :mcmanus tells me we currently parse trailers, but then silently throw them away. We don't want to change that behavior in general (we don't want to encourage trailers), so we'll want to whitelist the Server-Timing trailer, store it somewhere (probably even just a mServerTiming header will work for now, since it's the only trailer we support) and then make it available via some new channel.getTrailers() call.
So I guess that confirms it once and for all: trailing headers are not supported (and never likely to be in a general sense) by Moz, and presumably the same stance is taken by all other browser vendors.
Since this commit, Jodd HTTP Java client support trailer headers.
On the first question, I haven't yet found any live response that uses them ;)
As of May 2022, all browsers support the Trailer response header: https://caniuse.com/mdn-http_headers_trailer.
Library support:
Node.js
Jodd
EDIT ME, to add more. (This is a Community wiki answer.)
Just recently, according to caniuse.com, it is claimed that most major browser providers now support the Trailer response header in their latest versions (e.g. Firefox-88, Safari-14.1, Chrome-88, etc).
However, it seems that this only due to their support of Server-Timing (which can use trailers as mentioned in another answer), and there does not currently seem to be a general way to access a Trailer header from the browser Javascript - it's currently an open issue for the Fetch API, and the bug request for trailers in Chrome is marked wontfix.

Understanding caching strategies of a dynamically generated search page

While studying the caching strategies adopted by various search engine websites and Stackoverflow itself, I can't help but notice the subtle differences in the response headers:
Google Search
Cache-Control: private, max-age=0
Expires: -1
Yahoo Search
Cache-Control: private
Connection: Keep-Alive
Keep-Alive: timeout=60, max=100
Stackoverflow Search
Cache-Control: private
There must be some logical explanation behind the settings adopted. Can someone care to explain the differences so that everyone of us can learn and benefit?
From RFC2616 HTTP/1.1 Header Field Definitions, 14.9.1 What is Cacheable:
private
Indicates that all or part of the response message is intended for a single
user and MUST NOT be cached by a shared cache. This allows an origin server
to state that the specified parts of the response are intended for only one
user and are not a valid response for requests by other users. A private
(non-shared) cache MAY cache the response.
max-age=0 means that it may be cached up to 0 seconds. The value zero would mean that no caching should be performed.
Expires=-1 should be ignored when there's a max-age present, and -1 is an invalid date and should be parsed as a value in the past (meaning already expired).
From RFC2616 HTTP/1.1 Header Field Definitions, 14.21 Expires:
Note: if a response includes a Cache-Control field with the max-age directive
(see section 14.9.3), that directive overrides the Expires field
HTTP/1.1 clients and caches MUST treat other invalid date formats, especially
including the value "0", as in the past (i.e., "already expired").
The Connection: Keep-Alive and Keep-Alive: timeout=60, max=100 configures settings for persistent connections. All connections using HTTP/1.1 are persistent unless otherwise specified, but these headers change the actual timeout values instead of using the browsers default (which varies greatly).

content-type request header

I'm making an ajax call to a rest API and specified the following header an http post request.
Content-Type application/json; charset=UTF-8
My post body contains some japanese/chinese characters.
Now what my question is, do I need the encode the body of the post request with UTF-8 encoding or the browser takes care of encoding?
When your Content-Type header declares UTF-8 charset, then you must send the content in the UTF-8 encoding.
Although browsers sometimes "guess" or "fix" the encoding, you should never rely on this, as this is a very fragile logic that often fails to work properly.
If your Chinese/Japanese content was in a different encoding (like Shift-JIS), then you will have to convert the text with library like iconv.
Alternatively you could declare that other encoding in the header, but note that you can use only single encoding for all of the response body. Converting everything to UTF-8 is usually the best solution.