I'm designing an RESTful API where some calls are public over HTTP, and some require an API key and encryption over HTTPS. I'm deliberating on what response code should be sent if an HTTP request is sent to one of the private resources. So far the only one that jumps out at me is 412 - Precondition Failed, but the standard indicates that the precondition is imposed by the requester not the server.
Is there an appropriate response code for this condition or do I just need to give in and do 400?
The most secure way to force HTTP client to use HTTPS is HTTP Strict Transport Security.
Previously a common suggestion was to drop the connection, but this practice has been removed in favor of HSTS (OWASP website).
Just send a redirect to the corresponding https: URI.
UPDATE
The is a wrong answer - see comments below
The appropriate error code to return would be similar to 403.4 - SSL required.
Although not explicitly documented in the RFC for HTTP 1.1, this behavior does match the requirements outlined there:
Adding your own subcode (as with the SSL example) might be helpful in some cases, but since this subcode would not be meaningful to third parties, I would recommend against it.
So, your final error message would be something like "403 - Private Resource". Note that, even in the case of a missing API key, "401 - Unauthorized" should not be used, unless your API key can actually be transmitted in a WWW-Authenticate header field.
I cannot say if this is broadly accepted by HTTP clients, but speaking strictly RFC, the server should respond with:
Source:
http://tools.ietf.org/html/rfc2817#section-4.2
Returning a 403 with reason phrase "HTTPS Required" seems like a practical option and what I use.
see https://en.wikipedia.org/wiki/HTTP_403
Redirecting a REST Api is not a good idea especially as you may have no idea as to how or what is consuming your service.