Note: I am new to Tomcat...
I am getting this message in the Tomcat localhost_access_log:
127.0.0.1 - - [09/Oct/2009:09:37:30 -0700] "OPTIONS /stl/foo HTTP/1.1" 200 -
Can anyone explain to me where the OPTIONS comes from? I am using a 3rd party library (DirectJngine) but in perusing the source I can't see any reference to this being set. The docs imply that it will always use GET or POST. Is OPTIONS some kind of default inside Tomcat?
The same log file shows a more normal looking GET when I do the same thing from a browser:
127.0.0.1 - - [09/Oct/2009:09:07:24 -0700] "GET /stl/foo HTTP/1.1" 500 1805
The OPTIONS method is a request from the client to the server asking about available transfer options, but without actually requesting the resource.
From the spec at http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
9.2 OPTIONS
The OPTIONS method represents a
request for information about the
communication options available on the
request/response chain identified by
the Request-URI. This method allows
the client to determine the options
and/or requirements associated with a
resource, or the capabilities of a
server, without implying a resource
action or initiating a resource
retrieval.
It would appear your 3rd-party library is using the OPTIONS command prior to fetching the resource.
That's the request coming from the client.
GET and POST aren't the only allowed requests. You might also see
OPTIONS
HEAD
PUT
DELETE
TRACE
CONNECT
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Related
I build a service worker which always responds with data from the cache and then, in the background, sends a request to the server. If the server responds with HTTP 304 - not modified everything is fine, if the server responds with HTTP 200, that means the data was changed and the new file is put into the cache, also the user is notified and asked for a page refresh.
I use the not-modified-since / last-modified headers to make sure the client gets the most up-to-date version. When a request is sent via fetch() the request passes the HTTP-cache on it's way to the network - also the response passes the HTTP cache when it arrives on the client. The problem is when the response has the status 304 - not modified the HTTP cache responds to the service worker with the cached version and replaces the status with 200 (as it is described in the fetch specification - HTTP-network-or-cache-fetch). In the service worker there is no possibility to find out whether the 200 response was initially sent by the server (the user needs to be updated) or it was sent by the cache and the server originally responded with 304 (most up-to-date version is already loaded).
There is the cache-mode flag which can be set to no-cache, but this bypasses the HTTP-cache also when the request is sent to the server, which means that the if-modified-since header is not set and the server has no chance to find out which version the client has. Also this flag is only supported by firefox nightly right now.
I think the best solution is to set a custom HTTP header like x-was-modified when the server responds with 200. This custom header can be accessed in the service worker and can be used to find out whether a resource was updated or not - even if the HTTP cache replaces the 304 status with 200.
Is this a legit solution/workaround? Are there any suggested approaches to solve this problem?
Should I even rely on HTTP headers which are supposed to handle the HTTP cache when implementing the service worker cache? Or should I rather use custom x-if-modified-since / x-last-modified headers and use indexedDB to store the information on the client and append it to each request?
Why does fetch() even replace the 304 code with 200 if there is a up-to-date version in the cache?
You can’t rely on the status code (304 vs. 200) to determine whether something has changed. What if some other part of your code requests the same resource, thus updating the browser’s cache?
Instead, simply compare the response’s Last-Modified header to what you sent in If-Modified-Since, or whatever you last saw in Last-Modified. If the values don’t match, something has changed.
For more precision (if the data can change several times in 1 second), consider using ETag instead of Last-Modified.
Why does fetch() even replace the 304 code with 200 if there is a up-to-date version in the cache?
Because usually people just want to get fresh content, regardless of where it comes from. A 304 response is only interesting to those who implement their own HTTP caches.
I am building a web server, I was wondering what status code should I use if the client wants to request this?
PUT /index.html HTTP/1.1
Host: localhost:1111
Lets say the client is trying to add a new file to the server, but that file already exist, what HTTP status code should the server respond with?
I read the definition for 406, on the e HTTP/1.1 RFC, but looks like it for something else.
Seems to me like this is the case for a 405 response "Method not allowed", because this
method is not allowed for the requested url.
"for example, ... or using PUT on a read-only resource"
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error
Of course, that assumes you want to use the convention of using put only to insert new
content and never to edit it.
The exception contains this statusCode=Optional.of(406) , access rights to the particular service is not present for the user.
Enable the access to the user, then you will get the response from the rest calls.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
REST response code for invalid data
Have the following REST resource:
POST /user/{primary_key}
The resource is intended to work like an "ADD/UPDATE" operation. This means that it can be used to:
Create a new user
Update information on an existing user
If a client wanted to create a new user, some information is required:
POST user/{pimary_key}
Paylod:
- Username - (must be unique)
- Password
If a client wants to simply update an existing user, the call only needs to include the primary key and the new/changed information. For example:
POST user/{pimary_key}
Paylod:
- favorite hamburger type
This situation creates the potential for several requests from the client that are invalid:
CONFLICT - The client updates an existing user attempting to change the username to a value that is already in use by a different user.
MISSING INFORMATION - The client attempts to create a new user without including necessary information such as the username and password.
What are the correct HTTP response codes to return in these cases?
Thanks so much!
code 201 for created user, quite obvious
400 for incorrect input parameters is the most suitable, google API uses it
seems 409 the best for conflicting situation like yours
I would only recommend to separate creation and editing, and use different methods for them - POST to create, PUT to update. What if the user was going to modify something, but had a typo? It is better to show an error
Here's a good table of "typical" HTTP responses to RESTful operations.
From that table, here's what's recommended for POST operations:
200 (OK) - if an existing resource has been updated
201 (created) - if a new resource is created
202 (accepted) - accepted for processing but not been completed (Async processing)
301 (Moved Permanently) - the resource URI has been updated
303 (See Other) - e.g. load balancing
400 (bad request) - indicates a bad request
404 (not found) - the resource does not exits
406 (not acceptable) - the server does not support the required representation
409 (conflict) - general conflict
412 (Precondition Failed) e.g. conflict by performing conditional update
415 (unsupported media type) - received representation is not supported
500 (internal server error) - generic error response
503 (Service Unavailable) - The server is currently unable to handle the request
The HTTP OPTIONS method is supposedly used to determine what other methods the server supports on a given resource. Given that, I have two questions:
What does this response look like? I have seen examples with CSV lists in Public, Allow, and even Access-Control-Allow-Methods headers. Are they all needed? What's the difference? RFC 2616 doesn't seem to be very helpful here.
Would it be appropriate to use this to list the actions that a resource supports in a non-REST-API environment? For example, if my ConversionController supports the action convert, would a response like this make sense:
Request:
OPTIONS /conversion HTTP/1.1
Response:
HTTP/1.1 200 OK
...
Allow: CONVERT
...
RFC 2616 defines "Allow" (http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.14.7). "Public" is not in use anymore. "Access-Control-Allow-Methods" is defined in the CORS specification (see http://www.w3.org/TR/cors/).
What is an HTTP OPTIONS request?
It is a request from the client to know what HTTP methods the server will allow, like GET, POST, etc.
Request
The request might look like this when asking about the options for a particular resource:
OPTIONS /index.html HTTP/1.1
or like this when asking about the server in general:
OPTIONS * HTTP/1.1
Response
The response would contain an Allow header with the allowed methods:
Allow: OPTIONS, GET, HEAD, POST
Why is the server receiving an HTTP OPTIONS request?
Some REST APIs need it (but if you are defining the API, you'd know that)
Browsers send it to servers as "preflighted" requests to see if the server understands CORS
Attackers send it to get more information about the API
How to respond to an HTTP OPTIONS request?
You could respond with an Allowed header and even document your API in the body.
You could respond with additional CORS defined Access-Control-Request-* headers.
You could respond with 405 Method Not Allowed or 501 Not Implemented.
How do I stop getting HTTP OPTIONS requests?
If it's coming from a browser then update your API so that it isn't doing anything "dangerous" (like PUT or DELETE, or POST with application/json). Only perform simple requests.
See also
RFC 2616 Section 9: Method definitions
MDN Web docs: OPTIONS
MDN Web docs: Cross-Origin Resource Sharing (CORS)
CORS - What is the motivation behind introducing preflight requests?
How to exploit HTTP Methods
In response to the title: "How to respond to an HTTP OPTIONS request?" To answer that, I'd want to know why you want to respond to an OPTIONS request? Who/what is sending you an OPTIONS request, and why? Many public servers respond with some form of "error" or "not allowed" (500, 501, 405). So, unless you're in a specific situation where your clients will be reasonably sending OPTIONS requests and expecting useful/meaningful information back (e.g., WebDAV, CORS), you probably want to respond with: "don't do that."
In terms of your question about the "OPTIONS /conversion HTTP/1.1" request: unless you know that there's some client of your server, a client which would send an OPTIONS request to "/conversion" and expect a response with "Allow: CONVERT," the answer is no: it wouldn't make sense to respond like that. I think that most implementations that do support OPTIONS and respond with "Allow," respond with standard HTTP methods.
Here's a great article on the topic.
Summary: OPTIONS is immediately problematic because it doesn't support caching. Alternatives: server-wide metadata: try well-known URI's. Resource-specific: try using a Link header on its responses, or a link in the representation format for that resource.
Lastly, if what you're after is a service description, have a look at WADL or RSDL.
EDIT:
dotnetguy makes a good point in the comment below: OPTIONS is undeniably valuable in certain contexts (e.g., CORS); I certainly didn't mean to suggest otherwise.
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?
I cannot say if this is broadly accepted by HTTP clients, but speaking strictly RFC, the server should respond with:
HTTP/1.1 426 Upgrade Required
Upgrade: TLS/1.0, HTTP/1.1
Connection: Upgrade
Source:
https://www.rfc-editor.org/rfc/rfc2817#section-4.2
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).
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:
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
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.
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.
Just send a redirect to the corresponding https: URI.
UPDATE
The is a wrong answer - see comments below