views:

95

answers:

3

Let's say that I'm uploading a large file via a POST HTTP request.

Let's also say that I have another parameter (other than the file) that names the resource which the file is updating.

The resource cannot be not part of the URL the way you can do it with REST (e.g. foo.com/bar/123). Let's say this is due to a combination of technical and political reasons.

The server needs to ignore the file if the resource name is invalid or, say, the IP address and/or the logged in user are not authorized to update the resource. This can easily be done if the resource parameter came first in the POST request.

Looks like, if this POST came from an HTML form that contains the resource name first and file field second, for most (all?) browsers, this order is preserved in the POST request. But it would be naive to fully rely on that, no?

In other words the order of HTTP parameters is insignificant and a client is free to construct the POST in any order. Isn't that true?

Which means that, at least in theory, the server may end up storing the whole large file before it can deny the request.

It seems to me that this is a clear case where RESTful urls have an advantage, since you don't have to look at the POST content to perform certain authorization/error checking on the request.

Do you agree? What are your thoughts, experiences?

More comments please! In my mind, everyone who's doing large file uploads (or any file uploads for that matter) should have thought about this.

+2  A: 

You can't rely on the order of POST variables that's for sure. Especially you can't trust form arrays to be in correct order when submitting/POSTing the form. You might want to check the credentials etc. somewhere else before getting to the point of posting the actual data if you want to save the bandwidth.

Timo
Client side validation? Come on. That's not reliable as well.My point with this is that I made the conclusion that this can only be solved efficiently with REST. Do you agree?
pq
Not client side validation, but validation of the user before getting to the html page with the form. Say, you do one request first with the authorization data, save it in a cookie and then do another request with the actual content. The approach below is nice too.
Timo
I see. You propose two requests. One to get a cookie for the resource, one to POST to the resource. Yes, this would work but, boy, what an artificial solution! Compare that with the elegance of REST.
pq
I'm not saying that these solutions are better than REST. You should use which works best and if REST scheme is the one you should use it. In any case I would say that this case is not the ultimate proof that REST is better than X or vice versa.
Timo
Yeah, I agree, unfortunately, it's not the ultimate proof, because you can do things alternatively, even with inconvenience and complication (imagine that you have something that tracks all your requests; the request tracker will have to be fixed to accommodate your solution).
pq
+1  A: 

I'd just stick whatever variables you need first in the request's querystring.

On the client,

<form action="/yourhandler?user=0&resource=name" method="post">
<input type="file" name="upload" /></form>

Gets you

POST /yourhandler?user=0&resource=name HTTP/1.1
Content-Type: multipart/form-data; boundary=-----
...

-----
Content-Disposition: form-data; name="upload"; filename="somebigfile.txt"
Content-Type: text/plain

...

On the server, you'd then be able to check the querystring before the upload completes and shut it down if necessary. (This is more or less the same as REST but may be easier to implement based on what you have to work with, technically and politically speaking.)

Your other option might be to use a cookie to store that data, but this obviously fails when a user has cookies disabled. You might also be able to use the Authorization header.

josh3736
This sounds better than the other comment. But it still sounds hackish. It should basically work but I'm nervous that it may confuse certain frameworks that try to automate things for you. And, it's not as elegant as REST.
pq
A: 

You should provide more background on your use case. So far, I see absolutely no reason, why you should not simply PUT the large entity to the resource you intend to create or update.

PUT /documents/some-doc-name
Content-Type: text/plain

[many bytes of text data]

Why do you think that is not a possible solution in your case?

Jan

Jan Algermissen
"The resource cannot be not part of the URL the way you can do it with REST (e.g. foo.com/bar/123). Let's say this is due to a combination of technical and political reasons."
pq
I sure did read that :-) But I doubt that it is really a requirement. Hence I asked you to explain the background. There cannot be technical or political reasons that make it necessary to move part of the resource identification into the request entity.
Jan Algermissen