Correct response for PROPFIND on a resource that does not exist - webdav

How should a WebDAV server response when it receives a PROPFIND request for a resource that does not exist?
The RFC seems to say you should always return a 207 and then use 404 for properties that don't exist. But what if the resource itself doesn't exist?

The right answer is 404, which is true in general for most methods.
Where does it suggest it should be 207?

Related

Return 405 or 404 for OPTIONS http requests

Example:
We provide a URL http://.../foo/download.csv
web client (MS office) opens above URL and tries to access (for reasons I really don't know) http://.../foo/ with an http OPTIONS request.
Up to now or app returns 404 since the above URL does not exist (even for GET requests).
I think All OPTIONS requests should get a 405. It should not matter if the URL would be accessible via GET or POST.
Does this match the http spec?
Here is my explanation why I think 405 fits better: If there is an OPTIONS request, I don't want to look at the path. I don't care what the path looks like, there should always be the same answer: Not allowed.
Up to now it depends: if there is a GET-view registered, then we return 405. Otherwise a 404 gets returned.
Update: 404 vs 405
HTTP-Spec 405 Method Not Allowed
The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.
Source: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6
It's not really clear why you want it to return a 405, to be honest. It'll never get as far as checking the method, because the 404 handler will be invoked first - there's no view logic for it to get, that's what the 404 is. This is the default, and correct, behaviour.
I suspect, if you don't want to write custom middleware for it, and you insist on implementing it, that overriding the 404 handler would be the way forward - if a 404 Handler is invoked, check the method and return that accordingly - this is messy though, and the custom middleware would be more pythonic.
def handler404(request):
if request.method == 'OPTION':
#return your custom 405 response
else:
#go on and do your regular 404.

http status code to use when server suspects posted form data is spam

Leaving aside the question of whether or not you should return "helpful" http status codes to someone who is spamming you, what would the appropriate http response code be in this situation. Let's say that you are scanning the form for blacklisted words and the submission has some.
403 Forbidden seems like the most appropriate code. The description from RFC 2616 says:
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.
A better option may be the new 422 Unprocessable Entity code, defined in RFC 4918.
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415(Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.
This blog post recommends it for situations like yours, where there's a semantic problem with the posted content, rather than a syntactic problem.
For me for SCAM or SPAM fits best HTTP 451.
HTTP 451 Unavailable For Legal Reasons is a proposed standard error status code of the HTTP protocol to be displayed when the user requests a resource which cannot be served for legal reasons, such as a web page censored ... The RFC 7725 is specific that a 451 response does not indicate whether the resource exists but requests for it have been blocked, if the resource has been removed for legal reasons and no longer exists, or even if the resource has never existed, but any discussion of its topic has been legally forbidden.

How to respond to an HTTP OPTIONS 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.

How does HTTP 302 work?

How does HTTP 302 work? I would like to know the internals
You mean how do browsers handle it? The server sends a 302 code along with a Location header, and the browser requests the new URI specified by the Location header instead.
Unlike 301 (Moved Permanently), the browser continues to use the original URI to do requests, in case the 302 code goes away
The server returns an HTTP response with the code 302, indicating a temporary redirection, and includes a Location: header indicating the new URI, e.g.
HTTP/1.1 302 Found
Location: http://some-other-url
And potentially other headers at the server's discretion.
The browser normally takes this as a directive to automatically make a new, separate request for the other URI specified by the location header. The client (browser) isn't forced to do this (it could, in theory, just display a message to the user, or do whatever else it wants), but that's how HTTP clients usually behave.
Note that since the 302 is a temporary redirection, a well-behaved client will continue to use the old URL in the future, rather than going directly to the new one (301 is a permanent redirection).
From:
http://www.ietf.org/rfc/rfc2616.txt
and
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
10.3.3 302 Found
The requested resource resides temporarily under a different URI.
Since the redirection might be altered on occasion, the client SHOULD
continue to use the Request-URI for future requests. This response
is only cacheable if indicated by a Cache-Control or Expires header
field.
The temporary URI SHOULD be given by the Location field in the
response. Unless the request method was HEAD, the entity of the
response SHOULD contain a short hypertext note with a hyperlink to
the new URI(s).
If the 302 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
Note: RFC 1945 and RFC 2068 specify that the client is not allowed
to change the method on the redirected request. However, most
existing user agent implementations treat 302 as if it were a 303
response, performing a GET on the Location field-value regardless
of the original request method. The status codes 303 and 307 have
been added for servers that wish to make unambiguously clear which
kind of reaction is expected of the client.
The internals of what? 302 is a return code the server gives the client, what the client does is upto it. The RFCs give guidance on what the client should do, but in the real world 301, 302, 303 and 307 are all handled the same way by the mainstream browsers.
Just an Addon-
Importantly, it is for stop client to hit same server url with same request consecutively/frequently.
302 Found:
Indicates that the resource requested has been temporarily moved to the URL given by the location header.
A browser redirects to this page but search engines don't update their links to the resource.
It is recommended to set the 302 code only as a response for GET or HEAD methods.
In cases where you want the method used to be changed to GET, use 303.

REST - what error to throw when a partly-invalid request is sent

I'm developing a REST api. To simplify my question, I have an API that allows people to create a new blogpost.
Blogposts can live in categories, and categories are specified by a category id. If a user would supply a category-id that doesn't exist, which HTTP error code is the most appropriate?
404 for Not Found seems bad, so I went with 400 Bad Request for now. Is there a better one?
I assume you are responding to a PUT or POST request on your blog post resource.
I would go with the 400 since the resource you are accessing with the URI is found. The blog post could have been modified if the request content had been correct.
Since this is the content of the sent query that is wrong and not the actual URI of the resource, I would stick with the 400 error.
If however, you are adding the blog post to the category by either PUTting or POSTing to the category, then you can return a 404 Not found.
I agree with Vincent in that, of the available defined status codes, 400 is the best. The client should know whether or not a category id is valid at the time it submits the request, and is therefore providing bad request content to the server.
With regard to some of the other answers provided:
404 Not Found - This is not the correct status to use, since the resource you're sending the request to actually was found - it was just a referenced resource within the provided resource that was not found.
406 Not Acceptable - This status is, like Evert commented, used with the Accept headers; see section 10.4.7 of RFC2616:
The resource identified by the request is only capable of generating
response entities which have content characteristics not acceptable
according to the accept headers sent in the request.
409 Conflict - This status is intended for conflicting states of resources, typically due to modifications to the resource perhaps by another channel or thread. The RFC (section 10.4.10) gives an example:
...if versioning were being used and the entity being PUT
included changes to a resource which conflict with those made by an
earlier (third-party) request, the server might use the 409 response
to indicate that it can't complete the request
HTTP does provide an alternative to 400 - if fitting, you can create your own 4XX status for this situation. In section 6.1.1 of the RFC:
HTTP status codes are extensible. HTTP applications are not required to understand the meaning of all registered status codes, though such understanding is obviously desirable.
You could therefore define your own custom "430 - Referenced Resource Not Found" or something similar. HTTP-abiding clients should, if this status is unknown to them, treat it as a 400, but if clients are being coded specifically to the API, they should be able to handle it as a 430 and work with it appropriately.
What about 409 Conflict which is an application specific violation of a rule? In this this case the category ID of the Blog post must already exist. When you return the 409 conflict reply identify what the user can do to correct the situation so they can retry the POST/PUT.
I think 404 Not Found is the most appropriate response - consider the client has tried to access a category which doesn't exist, so the perfect answer is "I can't find that category!"
404 has a very specific and commonly-used meaning, which is that the URL could not be found. Furthermore, some browsers will use their own 404 error page, confusing things more.
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
I would recommend "406 Not Acceptable
The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request."
400 isn't bad, though.

Resources