0

Does it ever make sense for a server to provide a 200 response when a GET request is made for a non-existent file? Shouldn't the response always be a 404?

Here's the response header:

{'Date': 'Tue, 08 Jan 2019 22:56:26 GMT', 'Server': 'Apache', 'Strict-Transport-Security': 'max-age=31536000; preload', 'X-Frame-Options': 'SAMEORIGIN', 'XX-RequestId': 'pw01-225626->serv_31-225626', 'Vary': 'Accept-Encoding', 'Content-Encoding': 'gzip', 'X-Content-Type-Options': 'nosniff', 'X-Permitted-Cross-Domain-Policies': 'none', 'Cache-Control': 'max-age=0, no-cache, no-store', 'Content-Length': '20', 'Keep-Alive': 'timeout=5, max=100', 'Connection': 'Keep-Alive', 'Content-Type': 'application/json'}

Even though Content-Length says 20 we end up with a zero-byte zip file that gets downloaded.

3 Answers3

2

Yes, there are cases where it makes sense to return a 200 response for a non-existent file. A 200 response indicates that the logical entity that the client was requesting exists. It is perfectly reasonable to return a response indicating that the logical entity exists even if a file doesn't exist so long as the existence of the file and the existence of the logical entity are not the same thing.

Suppose I have a file system where each file indicates a username that is in some particular status. The absence of a file doesn't indicate that the username doesn't exist, it just indicates that the username is not in that particular status. In this case, it would be an error to return a 403 for a non-existent file because that would indicate that the resource requested doesn't exist and it does.

Imagine that the names "Adam" and "Jeff" are reserved but every other name is available and this is indicated by having a file called "Adam" and a file called "Jeff" and no other files. This system uses a file to indicate that a name is reserved. To argue that a file not present can't yield a 200, you'd have to argue that we may not return 200 for any name but "Adam" and "Jeff".

Now imagine a similar system where all names but "Adam" and "Jeff" are reserved. Only "Adam" and "Jeff" are available. This system uses a file to indicate that a name is available. To argue that a file not present can't yield a 200, you'd have to again argue that we may not return 200 for any name but "Adam" and "Jeff".

But look at how odd these two results are together. In both cases, we have a system where people query for name availability. And we have some differences in internal implementation, but to someone querying the system, they shouldn't have to know about that. But our arguments say that one system must not return 200 for a reserved name and one system must not return 200 for a non-reserved name because they internally implement reservation differently. That's quite absurd.

David Schwartz
  • 31,215
  • 2
  • 53
  • 82
1

According to the standards it should always be a 404 when the URI doesn't map, see rfc2616 section 10.4.5.

Unfortunately esoteric business cases do sometimes justify going against the standards. On the plus side going against the standard should fall to the team making the unusual request. You can always fall back to "standards are standards for a reason".

Tim Brigham
  • 15,465
  • 7
  • 72
  • 113
  • The standards say it should be a 404 when there's no resource matching the URI. The absence of a file doesn't mean there's no resource matching the URI. (If it did, web servers that don't use file systems to store their resources would always have to return a 404!) – David Schwartz Jan 09 '19 at 02:47
0

Does it ever make sense for a server to provide a 200 response when a GET request is made for a non-existent file?

In my opinion any URL that fails to complete its operation (ie the resulting file is invalid or not returned) should really return a 5XX error. The spec implies a response should always be sent with a 200 response:

200 OK - The request has succeeded. The information returned...

This is further implied by the existence of the 204 response which is specifically for requests that dont return a response:

204 No Content The server has fulfilled the request but does not need to return an entity-body

Does the described behaviour make sense? No.

Shouldn't the response always be a 404?

404 seems like a good choice to me...

The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. ... This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.

Though if the script returned a 404 i would still expect a JSON encoded response the size of the content length header.

Bare in mind "should you" and "will it work" are 2 different questions. So long as the consumer of a website/service understands the meaning of a 0 byte response its perfectly legal. You can set the response code to any number between 1 and 999, you can invent new headers etc - but most clients wouldnt know what to do with those responses. The Mismatch between content length and content received will likely cause requests to hang until the connection times out or is explicitly closed.

not my server/code and the definitely does not exist on server

The described behaviour seems like some active script is intercepting the URL and quietly failing to load data based on it from somewhere (filesystem, database etc). This is a common pattern for controlling access, analytics, caching etc.

Essentially i think the server is sending the response headers before actually checking the data exists. This would result in a 200 response, without returning any data. In short, this smells like a bug/bad practise.

See HTTP spec

MisterSmith
  • 166
  • 4