Emanuel Hategan Emanuel Hategan - 3 years ago 287
HTTP Question

Are single use download links in accordance with HTTP spec?

In the context of a restful web service, is it acceptable to have side effects for GET methods?

Single use download links for example

GET /downloads/664d92b3-b373-4dac-a4fb-7a41d015109a

will return 200 and "the thing" and 404 on next request.

HTTP spec says GET methods should be safe and according to https://tools.ietf.org/html/rfc7231#section-4.2.1

Request methods are considered "safe" if their defined semantics are
essentially read-only; i.e., the client does not request, and does
not expect, any state change on the origin server as a result of
applying a safe method to a target resource.


This definition of safe methods does not prevent an implementation
from including behavior that is potentially harmful, that is not
entirely read-only, or that causes side effects while invoking a safe
method. What is important, however, is that the client did not
request that additional behavior and cannot be held accountable for

Several clarifying examples are provided which make me think safe methods are not allowed to purposefully remove the resource.

For example, most servers append request information to access
log files at the completion of every response, regardless of the
method, and that is considered safe even though the log storage might
become full and crash the server.


Likewise, a safe request initiated
by selecting an advertisement on the Web will often have the side
effect of charging an advertising account.


For example, it is
common for Web-based content editing software to use actions within
query parameters, such as "page?do=delete". If the purpose of such a
resource is to perform an unsafe action, then the resource owner MUST
disable or disallow that action when it is accessed using a safe
request method.

Single use links are obviously a reality. I just wonder whether they're abusing the spec or I just don't get it.

Having an opinion is fine but having worked on these specs and understanding their subtleties would be most convincing.

Answer Source

What you're suggesting is acceptable in some situations, and not necessarily an abuse of the spec.

Firstly, 2616 says regarding safe methods that they:

SHOULD NOT have the significance of taking an action other than retrieval

And the phrase "SHOULD NOT" is defined as follows (emphasis added):

This phrase, or the phrase "NOT RECOMMENDED" mean that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications should be understood and the case carefully weighed before implementing any behavior described with this label.

The new version you linked to (which I think supercedes 2616) doesn't use the term "SHOULD NOT" - but they haven't replaced it with "MUST NOT" either. They also acknowledge that side effects are not ruled out as long as the client is not held responsible. So I think the idea of safe methods is the same.

So since the spec acknowledges that there are situations where it's ok, how do we know if yours is such a situation - and more importantly, how do we stay generally within the "spirit" of the spec i.e. make sure we're not abusing it?

I'd refer to this quote from 7231:

The purpose of distinguishing between safe and unsafe methods is to
allow automated retrieval processes (spiders) and cache performance
optimization (pre-fetching) to work without fear of causing harm.

If your app is a private intranet app and you're not concerned with the issues mentioned here, your approach is ok. Put another way: taking into consideration all the possible ways that a GET could happen, are you ok with this side effect?

Working outside RESTful guidelines is not always bad. It's just important to make sure you understand the effect it has.

With all that said, if you are looking for a way to implement reliable, consistent one-time delivery of a resource over HTTP, it's well worth reading Bill de hÓra's HTTPLR spec (http://www.dehora.net/doc/httplr/draft-httplr-01.html). This approach relies on the client acknowledging receipt of the message. You might be able to use something like to allow this user agents that are unaware of the one-use policy (spiders etc.) to GET the resource without causing side effects, but still allow participating clients to cause the resource to become unavailable after one GET.

A transactional approach like this has the added benefit of allowing the client to re-try the download as often as they need to. This is important because otherwise the server cannot know whether the client successfully received the message or not.

If you really need to enforce the once-only policy from the server side for any possible user agent, then your original approach might be best, but bear in mind it's really an "at most once" policy.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download