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

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.

Related

JAX-RS validating Content-Type and Accept header for generic upload and download API

The requirement is to implement a POST /v1/data and GET /v1/data API.
The upload API (POST) can have any Content-Type. This is not a problem as the content type is stored in database along with data.
The download API (GET) should:
set the same Content-Type as the last upload call and
validate with the Content-Type and the Accept headers received in the request.
The problem is in validating the Content-Type with the Accept header. The Accept header can be */*, text/* (partially concrete) or text/plain (completely concrete). If the last uploaded Content-Type is text/plain all the three above Accept headers are valid.
Is there a built in method such as bool validate(accept_header, content_type) which does the validation?
You can convert a String to a MediaType object with MediaType#valueOf:
Creates a new instance of MediaType by parsing the supplied string.
and check it with MediaType#isCompatible:
Check if this media type is compatible with another media type. E.g. image/* is compatible with image/jpeg, image/png, etc. Media type parameters are ignored. The function is commutative.

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.

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.

What are the Valid values for http Pragma

What are the valid values for http header pragma . I know no-cache is one but i wnat to enable caching so what should i set it. I did some googleing and all that i got was most clients ignore this but no info on other values it accepts.
Surprisingly there is only one parameter defined by default, which is no-cache and no new Pragma directives will be defined in HTTP as per RFC.
ref: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.32
Moreover, you will need to use the Cache-Control header for managing the caching behaviors rather than the Pragma directive which seems to be still included only to support the legacy HTTP/1.0.
ref: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
Bonus: http://www.mnot.net/cache_docs/
You're probably looking for Cache-Control, this is supported in HTTP/1.1 and defines more states than Pragma.
Some more information, that might help some people that are less interested in caching, and more interested in http headers in general. i.e the literal interpretation of the original question, "what are the valid values for the http header pragma"?
The reference in the accepted answer (https://stackoverflow.com/a/7376516/3246928) is the RFC http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.32. It defines the snytax as:
Pragma = "Pragma" ":" 1#pragma-directive
pragma-directive = "no-cache" | extension-pragma
extension-pragma = token [ "=" ( token | quoted-string ) ]
This implies that any 'token=value' pair is acceptable (with the value being optional). The spec goes on to say
No new Pragma directives will be defined in HTTP.
and I would guess this is also meant to cover the "extension-pragma" part, but I wish they had been more unambiguous here.
This header does not seem to be specifically created for caching; the description in the RFC says:
The Pragma general-header field is used to include implementation-
specific directives that might apply to any recipient along the
request/response chain
So, in theory, you could add things here, and they could work. However, despite much searching, I have not found any reference to any other values ever being used here. It is effectively a dead and embarrassing part of http/1.
It seems like the normal thing to do is:
Only use pragma with the no-cache flag. This is the only value anyone should ever use. (And of course you should also use the cache-control header for your caching to behave as expected).
If you want to put some special information into a http header - i.e. If you want to "include implementation-specific directives that might apply to any recipient along the request/response chain", then create a custom http header. Google and Amazon, for example, do this:
http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html and
https://cloud.google.com/storage/docs/reference-headers
Note the naming convention on the http header. The "x-" prefix is deprecated
by https://www.rfc-editor.org/rfc/rfc6648, but everyone seems to use it
anyway.

URL query params or media type params (in Accept header) to configure the response to an HTTP request?

I'm working on designing a REST API that can respond with a variety of formats, one of which is a plain text format which can be configured to show or hide certain aspects from the response (e.g. section headings or footnotes). The traditional way that this is done is via URL query parameters, both to indicate the desired response type and the configuration options, for example:
http://api.example.com/foo-book/ch1/?format=text&headings=false&footnotes=true
However, a more elegant RESTful way to indicate the desired response type (instead of the format=text URL query param) is to use the Accept header, for example:
Accept: text/plain; charset=utf-8
Now, in addition to URLs, media types can take parameters per RFC 2046 and as seen in the ubiquitous text/html; charset=utf-8 and in Accept headers like audio/*; q=0.2. It's also shown that vendor-crafted MIME types can define their own parameters like:
application/vnd.example-com.foo+json; version=1.0
application/vnd.example-info.bar+xml; version=2.0
So for previously-registered MIME types like text/html or application/json, is it acceptable to include custom parameters for an application's needs? For example:
Accept: text/plain; charset=utf-8; headings=false; footnotes=true
This seems like an elegant RESTful solution, but it also seems like it would be violating something. RFC 2046 ยง1 says:
Parameters are modifiers of the media subtype, and as such do not
fundamentally affect the nature of the content. The set of
meaningful parameters depends on the media type and subtype. Most
parameters are associated with a single specific subtype. However, a
given top-level media type may define parameters which are applicable
to any subtype of that type. Parameters may be required by their
defining media type or subtype or they may be optional. MIME
implementations must also ignore any parameters whose names they do
not recognize.
Note this last sentence:
MIME implementations must also ignore any parameters whose names they do not recognize.
Does this mean that a client would be non-conforming if they recognized a footnotes=true parameter of the text/plain media type?
It seems to me that the distinction should run as follows:
Accept header parameters pertain to the packaging of the response.
Media type (e.g. application/json)
Character encoding (e.g. charset=utf-8)
Structure (e.g. vendor extensions that specify the "doctype";
application/vnd.example-com.foo+json; version=1.0)
Query parameters pertain to resource(s) as addressed.
Components (e.g. headings and footnotes)
Optional features (e.g. formatting)
Constraints (especially when addressing a range of like resources)
David Eyk is correct.
If you are changing the Entity returned, it should be in the URI. Anything else will break all sorts of things like caching etc.
The "format" inside the URI however is mostly wrong. If you can, use Accept. Response headers are already in place to provide a smooth ride.
However, if you are unable to use Accept (like in a standard webbrowser) I recommend using a DOS extension or similar to override the Accept.
e.g.
/image (is the resource)
/image.jpg
/image.gif