Subject: server applying PUT to a resource other than the request-URI

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 16:30:10 +0200

Hi,

and old discussion just started again over on the vcarddav mailing list...

Is the following server behavior a legal interpretation of PUT semantics?

C: PUT /folder/foo
C: Host: ...
C:
C: Content

S: HTTP/1.1 201 Created
S: Location: /folder/bar

That is, the server stored the information, but not at the request-URI, 
and tries to inform the client via the Location header that the content 
actually was stored somewhere else.

Looking at the *method* definition of PUT, this is totally an abuse of PUT:

<http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-04.html#rfc.section.8.6>:

"The PUT method requests that the enclosed entity be stored at the 
supplied Request-URI. If the Request-URI refers to an already existing 
resource, the enclosed entity SHOULD be considered as a modified version 
of the one residing on the origin server. If the Request-URI does not 
point to an existing resource, and that URI is capable of being defined 
as a new resource by the requesting user agent, the origin server can 
create the resource with that URI. If a new resource is created at the 
Request-URI, the origin server MUST inform the user agent via the 201 
(Created) response. If an existing resource is modified, either the 200 
(OK) or 204 (No Content) response codes SHOULD be sent to indicate 
successful completion of the request. If the resource could not be 
created or modified with the Request-URI, an appropriate error response 
SHOULD be given that reflects the nature of the problem...."

and

"In contrast, the URI in a PUT request identifies the entity enclosed 
with the request -- the user agent knows what URI is intended and the 
server MUST NOT attempt to apply the request to some other resource. If 
the server desires that the request be applied to a different URI, it 
MUST send a 301 (Moved Permanently) response; the user agent MAY then 
make its own decision regarding whether or not to redirect the request."

IMHO the *right* thing to do is:

C: PUT /folder/foo
C: Host: ...
C:
C: Content

S: HTTP/1.1 4xx
S:
S: You can't do that

and instead

C: POST /folder
C: Host: ...
C:
C: Content

S: HTTP/1.1 201 Created
S: Location: /folder/bar

Feedback appreciated,

Julian

---

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 20:39:53 +0200

Brian Smith wrote:
> Julian wrote:
> I think this is better, according to what you quoted above:
> 
> S: HTTP/1.1 301 Moved Permanently
> S: Location: /folder/bar
> S:
> S: Do it there
> 
> C: PUT /folder/bar
> C: ...

Of course that's not going to work in practice, as Cyrus pointed out. We 
want to help servers that generate the URL based on the underlying 
persistence, so the server really can't predict the final URL until the 
resource is created.

>> C: POST /folder
>> C: Host: ...
>> C:
>> C: Content
> 
> It is a bad idea to switch to POST just for this. There is already a
> standard way of making PUT idempotent but there is no standard way of making
> POST idempotent, and you can easily recover from a broken connection with
> PUT (just HEAD the same URI; if you get the old validators, issue another
> Conditional PUT). However, there's no standard way to recover from a failed
> connection during POST.
> 
> If anything, more applications should be switching from POST to PUT.

Well, do you have a proposal that uses PUT as allowed by the RFC2616, 
and works for the above use case?

BR, Julian

---

From: "Brian Smith" <[email-masked]>
Date: Mon, 20 Oct 2008 13:22:32 -0500

C: PUT /folder/bar
C: ...

- Brian

---

From: "Brian Smith" <[email-masked]>
Date: Mon, 20 Oct 2008 14:41:41 -0500

Julian Reschke wrote:
> Of course that's not going to work in practice, as Cyrus pointed out.
> We want to help servers that generate the URL based on the underlying

> and works for the above use case?

Proposal 1: Simply do allow that use case. WebDAV clients already expect the
server to create the resources at the URI they are given. This is a pretty
fundamental part of WebDAV; an extension of WebDAV that didn't support it
isn't an extension at all.

Proposal 2: Abandon carddav and use SyncML, which has basically the same
functionality and is already standardized and widely deployed.

Proposal 3: Standardize one of the other contact management APIs that have
been published in the last year. There are many to choose from.

- Brian

---

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 21:52:21 +0200

> isn't an extension at all.

I wasn't arguing with that use case. PUT-to-create for servers where the 
client can pick the URI is fine. PUT-for-update is fine as well.

The use case we were discussing was PUT-to-create, where the server 
wants to control the URI.

> functionality and is already standardized and widely deployed.

Hey great, head over to the vcarddav WG! :-)

> been published in the last year. There are many to choose from.

Again, vcarddav is just one potential application. The use case of 
server-assigns-URI is a generic one, it really isn't specific to the 
contact management space.

BR, Julian

---

From: Henrik Nordstrom <[email-masked]>
Date: Mon, 20 Oct 2008 22:21:47 +0200

On mån, 2008-10-20 at 22:12 +0200, Julian Reschke wrote:
> Henrik Nordstrom wrote:
> > Sorry. A bit tired. Didn't notice the change to POST.
> > 
> > Switching to POST isn't good either.
> > 
> > I'll second Brians response here.
> 
> Which part?

The whole message with 3 alternatives, all three of them.

> > Additionally allowing for PUT to create a new resoure-URI completely
> > different from the request-URI would make sense, but needs to be
> > negotiated by a request header indicating that the client accepts this.
> 
> Well, I proposed a new method for this in 2005, and the answer to that 
> was: just use POST. And that is what AtomPub has done.
> 
> So is this suddenly the wrong advice?

It's a matter of semantics. POST is meant for application transfers, for
data being processed by the server, with no direct content mapping to
the created resource (if any). PUT is a request to store an entity
"as-is".

However, creating a new method for this is defenitely not the right
thing. Better to extend PUT to allow this use case by conditionally
relaxing the target resource URI requirements, or use POST.

Regards
Henrik

---

From: Helge Hess <[email-masked]>
Date: Mon, 20 Oct 2008 22:13:06 +0200

On 20.10.2008, at 22:01, Henrik Nordstrom wrote:
> GET requests to the request-URI just after
> the PUT should return the stored resource

I'm not entirely sure why this property is considered so important. In  
a typical WebDAV environment another user can MOVE the resource  
anyways. Whether the server rebinds the resource or another user, is  
not really relevant to the client, it needs to deal with the situation  
anyways.

Whats the practical, real-world, consequence for clients?

Thanks,
   Helge
-- 
Helge Hess
http://helgehess.eu/

---

From: Henrik Nordstrom <[email-masked]>
Date: Mon, 20 Oct 2008 22:07:17 +0200

Regards
Henrik

On mån, 2008-10-20 at 22:01 +0200, Henrik Nordstrom wrote:
> Why 4xx. A redirect to the URI where the resource may be stored is more
> appropriate.
> 
> Hmm.. the text in PUT should be fixed as well.. 301 is not a good redirect code to use there due to the amount of broken implementations..
> 
> > and instead
> > 
> > C: POST /folder
> > C: Host: ...
> > C:
> > C: Content
> > 
> > S: HTTP/1.1 201 Created
> > S: Location: /folder/bar
> 
> No. See above.
> 
> REgards
> Henrik

---

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 22:10:14 +0200

Henrik Nordstrom wrote:
> On mån, 2008-10-20 at 16:30 +0200, Julian Reschke wrote:
> 
> The "not at the request-URI" part worries me.
> 
> 201 Location in response to PUT is not meant to be used like this. It's
> more meant in the case like when the created resource-verstion gets a
> persistent URL, or when the request-URI is a usable URI for the resource
> but not the preferred URI. GET requests to the request-URI just after
> the PUT should return the stored resource, even if 201 did indicate
> another preferred location.

+1

> ...

Problem is that in many cases, the server doesn't know the URL until the 
resource is created.

A 4xx signals a client error, and in WebDAV, the response body can 
reveal additional information where to POST to instead.

> Hmm.. the text in PUT should be fixed as well.. 301 is not a good redirect code to use there due to the amount of broken implementations..

Actually, it's also a bad choice because this should be a temporary 
redirect (== the client should keep using the original request-URI for 
the next attempt of creating a resource).

> ...

BR, Julian

---

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 22:30:37 +0200

> The whole message with 3 alternatives, all three of them.

Proposal 2 and 3 were specific to the Vcarddav WG in general, not this 
specific technical issue.

Proposal 1 IMHO breaks the PUT semantics (that's why I started this thread).

> the created resource (if any). PUT is a request to store an entity

But POST can do that as well. The only missing piece is that the client 
needs to know that it will. For instance in AtomPub, this is by the 
definition of the AtomPub collection resource.

> relaxing the target resource URI requirements, or use POST.

I still do not see how this functionality can be implemented without 
breaking the semantics of PUT.

It *can* be implemented using POST, but requires a way for the client to 
find out that it actually can use POST for it. That can be by contract 
(AtomPub), by inspection of the error response for PUT, or by some other 
way of discovery (WebDAV properties, Link header, whatnot). The latter 
cases are covered by my (currently WebDAV-specific) proposal at 
<http://greenbytes.de/tech/webdav/draft-reschke-webdav-post-01.html>).

BR, Julian

---

From: Helge Hess <[email-masked]>
Date: Mon, 20 Oct 2008 22:16:21 +0200

Hm, I wonder whether we could just use a different header, NOT  
location. Something like this:

   PUT /new.txt
   Accept-Relocation: same-col, same-server, full

   HTTP/1.x 201 Created
   Relocation: /123.txt

would that possibly work for everyone?

Helge

---

From: Henrik Nordstrom <[email-masked]>
Date: Mon, 20 Oct 2008 22:01:05 +0200

No. See above.

REgards
Henrik

---

From: "Robert Brewer" <[email-masked]>
Date: Mon, 20 Oct 2008 13:15:24 -0700

Helge Hess wrote:
> On 20.10.2008, at 20:39, Julian Reschke wrote:
> Thats exaggerated. Lets see where the requirement comes from. Its
> originated in servers which use an RDBMS as the storage. Such servers
> do not want to maintain an additional namespace for DAV but just want
> to use the records primary key as the relative resource name.
> 
> Example: PUT /new.txt => Location: 1.txt, PUT /new.txt => Location:
> 2.txt, etc.

Sure looks to me like PUT is not idempotent for that process.

Robert Brewer
[email-masked]

---

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 22:12:05 +0200

Which part?

BR, Julian

---

From: Helge Hess <[email-masked]>
Date: Mon, 20 Oct 2008 22:08:00 +0200

Most applications use SQL sequences to create the primary keys, since  
you usually need the key anyways to fill up foreign keys in related  
records. In such a scenario the 301 works OK. The server can  
preallocate a key from the sequence and then tell the client to use  
that.

Its a bit more difficult with 'SERIAL' keys, primary keys which are  
allocated by the RDBMS only during the INSERT of the actual record. In  
this case you indeed need to insert before you get the primary key.
BUT lets get real:
a) its not hard to change the SERIAL code to use a real sequence,
    server compat is hardly affected by such a switch
b) most RDBMS implement SERIAL with a sequence anyways

Summary: IMHO the 301+location solution is not great, but OK. Primary  
disadvantage is the additional roundtrip, but thats acceptable,  
especially in combination with 100-continue.

> Well, do you have a proposal that uses PUT as allowed by the  
> RFC2616, and works for the above use case?

Lets modify RFC2616 to explicitly state that the PUT with 201+Location  
is allowed. Maybe in a separate RFC, I don't know. Its the obvious  
thing to do. It works well with existing clients, its already done  
that way by serveral servers and it fits into the overall design.

Thanks,
   Helge
-- 
Helge Hess
http://helgehess.eu/

---

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 22:35:09 +0200

Helge Hess wrote:
> 
> Hm, I wonder whether we could just use a different header, NOT location. 
> Something like this:
> 
>   PUT /new.txt

It's just a new request header that modifies the behavior of PUT to do 
something else-but-similar.

And, again, how does a client find out about the request-URI? You will need

   If-None-Match: *

to avoid unintentional overwrites on /new.txt, but as soon as you 
include it, a conforming server will have to reject the request with 412 
if /new.txt is already taken.

How exactly is that better than POST, which already can have that semantics?

BR, Julian

---

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 22:18:32 +0200

> Thats exaggerated. Lets see where the requirement comes from. Its 

OK, it's not *always* going to work.

> originated in servers which use an RDBMS as the storage. Such servers do 
> not want to maintain an additional namespace for DAV but just want to 
> use the records primary key as the relative resource name.
> 

Yes. Doesn't need to be an RDBMS, but the use case is similar.

> records. In such a scenario the 301 works OK. The server can preallocate 
> a key from the sequence and then tell the client to use that.

That may work sometimes, but not always. For instance, when the API of 
the underlying store simply doesn't allow you that "preallocate" step.

> especially in combination with 100-continue.

301 is IMHO terrible wrong as it indicates a permanent redirect.

The other big question is: what is the request-URI? How do you discover 
server support for this?

> is allowed. Maybe in a separate RFC, I don't know. Its the obvious thing 
> to do. It works well with existing clients, its already done that way by 
> serveral servers and it fits into the overall design.

It would break existing clients, so I don't see how it could be done in 
HTTP/1.1.

The semantics for PUT are clear from RFC2616: the client picks the URI.

If you don't want that semantics, do not use PUT. One solutions is to 
use POST (as done in AtomPub), another one would be to define a new 
method (as proposed earlier). But changing the semantics of PUT IMHO is 
the wrong choice.

BR, Julian

---

From: "Brian Smith" <[email-masked]>
Date: Mon, 20 Oct 2008 15:40:25 -0500

> Proposal 1 IMHO breaks the PUT semantics (that's why I started this

Proposal 1 was: "Simply do allow that use case. WebDAV clients already expect the server to create the resources at the URI they are given. This is a pretty fundamental part of WebDAV; an extension of WebDAV that didn't support it isn't an extension at all."

In other words, just let the client pick the URI like we always have in WebDAV, and don't attempt to support servers that do not want to let the client pick the URI. There is nothing that breaks PUT's semantics there.

> breaking the semantics of PUT.

The functionality doesn't need to be implemented in the first place, so it doesn't matter.

- Brian

---

From: Henrik Nordstrom <[email-masked]>
Date: Mon, 20 Oct 2008 22:44:15 +0200

> Proposal 1 IMHO breaks the PUT semantics (that's why I started this thread).

Not if negotiated imho.

> definition of the AtomPub collection resource.

POST can do anything any other method can do. It's just a matter of
defining the context.

> breaking the semantics of PUT.

Maybe. Not so sure. Depends on what one puts into the strict semantics
of a PUT.

> <http://greenbytes.de/tech/webdav/draft-reschke-webdav-post-01.html>).

I don't like relying on round-trip discovery and application protocols
for simple storage, especially for use cases like "I want to store this
at this approximate location". And not having support for this family of
requests opens up for a myriad of different POST protocols for
performing this kind of action. There is already too many of those.

Regards
Henrik

---

From: "Brian Smith" <[email-masked]>
Date: Mon, 20 Oct 2008 15:49:22 -0500

> So is this suddenly the wrong advice?

It was always bad advice. Take AtomPub for example: in many AtomPub implementations, there is no idempotent creation operation, and there is no reliable way to tell if an entry was successfully added to the collection if the connection dropped before you got the response. Both of these problems are consequences of using POST instead of PUT to create resources. Plus, AtomPub had to invent a new header (Slug) that would be unnecessary for PUT-to-create.

- Brian

---

From: Henrik Nordstrom <[email-masked]>
Date: Mon, 20 Oct 2008 22:53:31 +0200

> > Proposal 1 IMHO breaks the PUT semantics (that's why I started this thread).

Now I am tired again, mixing up my addition and proposal 1.. Sorry
Brian. I understood you the first time.

Regards
Henrik

---

From: Julian Reschke <[email-masked]>
Date: Mon, 20 Oct 2008 22:20:48 +0200

> Sure looks to me like PUT is not idempotent for that process.

Correct.

Also, and again: what is the "special" request-URI? Either it needs to 
be hard-wired, or client needs a way to discover it, or there's no way 
to have a collection that supports both user-defined and server-defined 
URIs.

BR, Julian

---

From: Helge Hess <[email-masked]>
Date: Tue, 21 Oct 2008 00:05:30 +0200

On 20.10.2008, at 22:18, Julian Reschke wrote:
> The other big question is: what is the request-URI? How do you  
> discover server support for this?

If-None-Match: *
?!

>> Lets modify RFC2616 to explicitly state that the PUT with  
>> 201+Location is allowed. Maybe in a separate RFC, I don't know. Its  
>> the obvious thing to do. It works well with existing clients, its  
>> already done that way by serveral servers and it fits into the  
>> overall design.
> It would break existing clients, so I don't see how it could be done  
> in HTTP/1.1.

Exactly which client are you talking about and how does it break?

Thanks,
   Helge

---

From: Helge Hess <[email-masked]>
Date: Tue, 21 Oct 2008 00:08:20 +0200

On 20.10.2008, at 22:35, Julian Reschke wrote:
> include it, a conforming server will have to reject the request with  
> 412 if /new.txt is already taken.

So? Whats wrong with the 412? A client can easily deal with it.

Thanks,
   Helge
-- 
Helge Hess
http://helgehess.eu/

---

From: Helge Hess <[email-masked]>
Date: Tue, 21 Oct 2008 00:12:02 +0200

On 20.10.2008, at 22:40, Brian Smith wrote:
> Proposal 1 was: "Simply do allow that use case. WebDAV clients  
> already expect the server to create the resources at the URI they  
> are given. This is a pretty fundamental part of WebDAV; an extension  
> of WebDAV that didn't support it isn't an extension at all."
>
> In other words, just let the client pick the URI like we always have  
> in WebDAV, and don't attempt to support servers that do not want to  
> let the client pick the URI. There is nothing that breaks PUT's  
> semantics there.

+1

I actually prefer that over adding some custom POST to CardDAV / xyz.

Thanks,
   Helge
-- 
Helge Hess
http://helgehess.eu/

---

From: Julian Reschke <[email-masked]>
Date: Tue, 21 Oct 2008 09:24:17 +0200

>> discover server support for this?

?

> Exactly which client are you talking about and how does it break?

For instance clients that do first a PUT-for-create, then a PROPPATCH.

BR, Julian

---

From: Julian Reschke <[email-masked]>
Date: Tue, 21 Oct 2008 09:25:32 +0200

> So? Whats wrong with the 412? A client can easily deal with it.

Yes. But if the server returns 412, no resource was created, and the 
client still needs to figure out what request-URI to use.

Or are you suggesting that *any* unmapped URL is fine? What if the 
server wants to support both (client- and server-assigned URIs) in the 
same collection?

BR, Julian

---

From: Julian Reschke <[email-masked]>
Date: Tue, 21 Oct 2008 09:27:44 +0200

Helge Hess wrote:
>> Proposal 1 was: "Simply do allow that use case. WebDAV clients already 
>> expect the server to create the resources at the URI they are given. 
>> This is a pretty fundamental part of WebDAV; an extension of WebDAV 
>> that didn't support it isn't an extension at all."
>>

Of course that's one possibility.

However, I have my doubts. CalDAV does the same, server implementers 
have been complaining about the unnecessary overhead. Because of it, 
some servers use a workaround that's not allowed per RFC2616, and 
clients are expected to deal with it.

That really sounds like a problem looking for a proper solution, sorry.

BR, Julian

---

From: Yves <[email-masked]>
Date: Tue, 21 Oct 2008 03:46:58 -0400 (EDT)

On Mon, 20 Oct 2008, Julian Reschke wrote:

>> not want to maintain an additional namespace for DAV but just want to use 
>> the records primary key as the relative resource name.
>> 
>> Example: PUT /new.txt => Location: 1.txt, PUT /new.txt => Location: 2.txt, 
>> etc.
>

When you know that /new.txt will generate new URIs, the correct method to 
trigger is is POST and clearly not PUT.
What's wrong with
POST /give_me_a_new_URI
=> 303 See Other
    Location: /new1.txt
=> PUT /new1.txt
...

>> Most applications use SQL sequences to create the primary keys, since you 
>> usually need the key anyways to fill up foreign keys in related records. In 
>> such a scenario the 301 works OK. The server can preallocate a key from the 
>> sequence and then tell the client to use that.
>
> That may work sometimes, but not always. For instance, when the API of the 
> underlying store simply doesn't allow you that "preallocate" step.
>
>> allocated by the RDBMS only during the INSERT of the actual record. In this 
>> case you indeed need to insert before you get the primary key.
>> BUT lets get real:

Well, everytime underlying implementation surface at the URI level, you 
run into that kind of issue, nothing new there.

>> disadvantage is the additional roundtrip, but thats acceptable, especially 
>> in combination with 100-continue.
>

Yep 307 is far better. (I bet that the HTTP stacks are all supporting it 
by now, no ?)

>> Lets modify RFC2616 to explicitly state that the PUT with 201+Location is 
>> allowed. Maybe in a separate RFC, I don't know. Its the obvious thing to 
>> do. It works well with existing clients, its already done that way by 
> If you don't want that semantics, do not use PUT. One solutions is to use 
> POST (as done in AtomPub), another one would be to define a new method (as 
> proposed earlier). But changing the semantics of PUT IMHO is the wrong 
> choice.

+1 (meaning that I should read the entire email before replying :) )

-- 
Baroula que barouleras, au tiéu toujou t'entourneras.

         ~~Yves

---

From: Helge Hess <[email-masked]>
Date: Tue, 21 Oct 2008 10:35:31 +0200

On 21.10.2008, at 09:46, Yves wrote:
> When you know that /new.txt will generate new URIs, the correct  
> method to trigger is is POST and clearly not PUT.

You don't know that the specific new.txt will generate new URIs, it  
was just an example. Of course you need to do the same If-None-Match:  
* iterations as usual.
And yes, of course new.txt is a very bad choice, high potential for  
conflict. Most CalDAV/CardDAV client would start with the UID of the  
item and then proceed.

Again: why is POST a bad choice? Because a client using POST wouldn't  
be able to create items in a regular WebDAV server. The suggestion has  
very bad downgrade behaviour. IMHO it has very little chance for  
adoption.

But anyways, I don't think this thread will lead anywhere, as  
usual ..., I'll quit :-)

Well, actually it gave (me) one new insight, so it apparently _was_  
worth the annual PUT-redirect posting :-)
A 307+Location is apparently accepted by everyone (?) as a method for  
producing server generated URLs in a HTTP compliant way. (might be a  
little harder for the server and client, but its a starting point).

Thanks,
   Helge
-- 
Helge Hess
http://zideone.com/

---

From: Julian Reschke <[email-masked]>
Date: Tue, 21 Oct 2008 10:58:52 +0200

Helge Hess wrote:
> You don't know that the specific new.txt will generate new URIs, it was 
> just an example. Of course you need to do the same If-None-Match: * 
> iterations as usual.
> Again: why is POST a bad choice? Because a client using POST wouldn't be 
> able to create items in a regular WebDAV server. The suggestion has very 
> bad downgrade behaviour. IMHO it has very little chance for adoption.

A client can discover via OPTIONS, status codes, and the Allow response 
header whether they can use PUT-for-create.

There is no compatibility problem for servers that want to support both.

The only reason not to support PUT-for-create is when the server needs 
select the final URI. We're discussing only that use case.

> But anyways, I don't think this thread will lead anywhere, as usual ..., 
> I'll quit :-)
> 

307 is better than 301, but:

"If the 307 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."

BR, Julian

---

From: "Roy T. Fielding" <[email-masked]>
Date: Tue, 21 Oct 2008 08:29:36 -0700

On Oct 20, 2008, at 11:39 AM, Julian Reschke wrote:
> Of course that's not going to work in practice, as Cyrus pointed  
> out. We want to help servers that generate the URL based on the  
> underlying persistence, so the server really can't predict the  
> final URL until the resource is created.

No, we don't want to help those servers.  Why help bad design?

The whole premise of this question is just silly. If the server
doesn't intend to support PUT on a given URI, then it won't be
allowing PUT on that URI in the first place; it will be directing
the client to POST.  If the server actually does accept PUT on a
given URI and is simply creating aliases for other things (like
Slug-based permalinks), then that doesn't need to be noted in the
response -- both resources still exist, both allow PUT, and the fact
that one's state overlaps with another is simply irrelevant to
the protocol.

The answer is that if PUT is used and the server needs to redirect
the request, then redirect with 307.  Any other response in that case
is not compliant with HTTP.  If the server doesn't want that to happen
then it will offer a POST interface instead, just like the spec says.

....Roy

---

From: Julian Reschke <[email-masked]>
Date: Tue, 21 Oct 2008 17:42:10 +0200

Roy T. Fielding wrote:
>> persistence, so the server really can't predict the final URL until 
>> the resource is created.
> 

So, should AtomPub have required support for PUT-to-create? (trying to 
understand what you're saying...)

> the client to POST.  If the server actually does accept PUT on a

Yes. So what is the best way to do that?

> that one's state overlaps with another is simply irrelevant to

That's true, but I don't think this is the use case I was interested in.

> then it will offer a POST interface instead, just like the spec says.

Of course a redirect needs to be a 3xx.

The question I'm interested in is: if a server behaves similar to an 
AtomPub server, in that new entries need to be POSTed to a collection 
URI, but can be updated using PUT on the individual resource URIs, what 
is the best behavior for the case where the client *tries* a PUT on an 
unmapped URI?

I would have thought that a 4xx status code such as 405 Method Not 
Allowed (server does understand PUT, but not on this URI) or 409 
Conflict (current state of the resource conflicts with the request) 
would be adequate?

BR, Julian

---

From: Julian Reschke <[email-masked]>
Date: Tue, 21 Oct 2008 17:50:02 +0200

> then it will offer a POST interface instead, just like the spec says.

HTTPbis currently says in 
<http://svn.tools.ietf.org/svn/wg/httpbis/draft-ietf-httpbis/latest/p2-semantics.html#rfc.section.8.6>:

Note it says "MUST send 301".

So should this be changed to say 307 instead? (I'm a bit concerned that 
this is currently is a MUST level requirement, so changing it to 307 
will affect servers that are currently conformant).

BR, Julian

---

From: "Roy T. Fielding" <[email-masked]>
Date: Wed, 22 Oct 2008 04:04:10 -0700

On Oct 21, 2008, at 8:42 AM, Julian Reschke wrote:
> So, should AtomPub have required support for PUT-to-create? (trying  
> to understand what you're saying...)

AtomPub requires HTTP.  HTTP already defined PUT.  There is no need
to define what has already been defined.  AtomPub needed to define what
its link relations meant, not what the response to POST meant.

> Yes. So what is the best way to do that?

Use an element that says: POST to this URI if you want to do X.

> Of course a redirect needs to be a 3xx.

Sorry, I meant 301.  307 is only for temporary redirects.

> The question I'm interested in is: if a server behaves similar to  
> an AtomPub server, in that new entries need to be POSTed to a  
> collection URI, but can be updated using PUT on the individual  
> resource URIs, what is the best behavior for the case where the  
> client *tries* a PUT on an unmapped URI?

The best behavior is already defined by HTTP -- respond accordingly.

> Conflict (current state of the resource conflicts with the request)  

It might be.  It largely depends on what you consider to be adequate,
whether you want the client to offer redirection to the user, and if
the client properly displays the body of the response to explain
what just occurred.  Each response gives the client some idea of how
(or if) the problem can be fixed.  The only fix that can be automated
is the one for 301, which is why that is defined in a way that can
be automated (if the user agrees or has preconfigured their client
to follow that redirect).

Personally, I would code the server to accept the resource as defined
by the client and then create a 302 binding for the slug URI.  But
that's just me.  There is no single way to do this in HTTP and there
is no need for one because the response tells you what worked.

....Roy

---

From: Helge Hess <[email-masked]>
Date: Wed, 22 Oct 2008 22:50:54 +0200

On 21.10.2008, at 09:24, Julian Reschke wrote:
>>> It would break existing clients, so I don't see how it could be  
>>> done in HTTP/1.1.

What happens in 'those' clients (_exactly_ which ones?!) when another  
client MOVEs the resource before the PROPPATCH. Thats a perfectly  
viable and normal situation. How is it different?

Thanks,
   Helge
-- 
Helge Hess
http://helgehess.eu/

---

From: "Roy T. Fielding" <[email-masked]>
Date: Thu, 23 Oct 2008 01:55:54 -0700

On Oct 22, 2008, at 11:37 PM, Julian Reschke wrote:
> But in this case a temporary redirect is actually needed. If the  
> client gets a 301, it potentially use the URI given in Location:  
> for all subsequent request, and that's definitively not what people  
> want in this case.

In that case, use of PUT is not an option.  PUT implies that the client
wants to use that URI.  301 is saying that they can't use that URI, but
they should try using this other URI for the *same resource*.

It seems to me that their use case requires POST.  Why is that a  
problem?

>> ...
>>> I would have thought that a 4xx status code such as 405 Method  
>>> Not Allowed (server does understand PUT, but not on this URI) or  
>>> 409 Conflict (current state of the resource conflicts with the  
>>> request) would be adequate?
> That approach would work, but still requires the server to persist  
> the names chosen by the client. I'm not saying this is bad, but it  
> was the claim that some servers couldn't do that started this  
> discussion.

I don't believe that claim.  If they can store data, they can save  
redirects.

> Right now some work around their problem by accepting the PUT (with  
> 201), but storing the resource under a different URI, and it seems  
> to me that this a bad idea (given the PUT semantics defined in HTTP).

It isn't allowed by HTTP for that reason.

....Roy

---

From: Jamie Lokier <[email-masked]>
Date: Thu, 23 Oct 2008 11:00:09 +0100

> viable and normal situation. How is it different?

That's what WebDAV's LOCK is for preventing, isn't it?

-- Jamie

---

From: Etan Wexler <[email-masked]>
Date: Fri, 24 Oct 2008 07:13:59 -0400

Yves Lafon (as “Yves”) wrote in
<http://www.w3.org/mid/[email-masked]>:

> When you know that /new.txt will generate new URIs, the correct method 
> to trigger [it] is POST and clearly not PUT.
> What's wrong with [the following scenario?]
> POST /give_me_a_new_URI
> => 303 See Other
>    Location: /new1.txt
> => PUT /new1.txt
> ...

In HTTP, a response whose status code is “303” fails to direct the user 
agent to issue a request whose method is “PUT”. RFC 2616 recommends that 
the user agent issue a request whose method is “GET” and whose 
Request-URI is the URI that appeared in the “Location” header field of 
the preceding response (see, for example, 
<http://greenbytes.de/tech/webdav/rfc2616.html#status.303>). The latest 
(as of 2008-10-24) working draft of a revision to that part of RFC 2616 
allows, but does not mandate, a request whose method is “GET” (see, for 
example, 
<http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-04.html#status.303>).

Specifications aside, user agents in the field will react to a status 
code of “303” with a request whose method is “GET”. Many operators of 
origin servers rely on such behavior, as do the people who direct their 
user agents to those origin servers.

-- 
Please do not include my address in public replies. I will read public 
replies on the list.

---

From: Yves Lafon <[email-masked]>
Date: Fri, 24 Oct 2008 09:25:27 -0400 (EDT)

On Fri, 24 Oct 2008, Etan Wexler wrote:

>
> Yves Lafon (as Yves) wrote in
>> trigger [it] is POST and clearly not PUT.
> In HTTP, a response whose status code is 303 fails to direct the user agent 
> to issue a request whose method is PUT. RFC 2616 recommends that the user 
> agent issue a request whose method is GET and whose Request-URI is the URI 
> that appeared in the Location header field of the preceding response (see, 
> for example, <http://greenbytes.de/tech/webdav/rfc2616.html#status.303>). The 
> latest (as of 2008-10-24) working draft of a revision to that part of RFC 
> 2616 allows, but does not mandate, a request whose method is GET (see, for 
> example, 

Well, sure, the goal is not to redirect PUT, but to create a resource form 
a "templating" one. In that case you can even get the result of the 
creation using a GET, then do a PUT there.

> Specifications aside, user agents in the field will react to a status code of 
> 303 with a request whose method is GET. Many operators of origin servers rely 
> on such behavior, as do the people who direct their user agents to those 
> origin servers.

Well I didn't say the opposite, the 303 was not to redirect the PUT, just 
part of an orchestration of calls.
Cheers,

         ~~Yves

---

From: Henrik Nordstrom <[email-masked]>
Date: Fri, 24 Oct 2008 21:22:22 +0200

Have given this some more thought over the last days, and I now stay
completely by the side that "unnamed" PUT is a completely bad idea and
that POST should be used in those situations if really really needed,
even if it means applications need to learn the actual POST protocol
used.

As Brian correctly points out in most cases applications needing servers
to assign resource names at PUT time is a information management design
error. The name should be assigned prior to the PUT, or you'll lose
idempotence and other aspects which is generally important for this kind
of operation.

Yes, it means one round-trip more to the server in applications needing
such naming assignments if they really want to use PUT for creting the
resource (instead of POST, but that's not the end of the world.

Playing games with redirects et al is nice, but does not solve the
problem in a good manner. Neither is adding a new method for the task.

So the recommendation to anyone needing this is

1. Rethink what you are doing. Are you really really sure it's a good
idea?

2. If you absolutely must operate in this manner use POST for creating
the resource. There is no standard POST application protocol for
creating server named resources so invent your own ontop of POST. This
could be as simple as having the complete payload just as PUT, or a more
elaborate protocol with added meta data such as the forms POST protocol
or something similar, it's up to the application.

Regards
Henrik

---

From: "Brian Smith" <[email-masked]>
Date: Fri, 24 Oct 2008 16:24:41 -0500

Henrik Nordstrom wrote:
> could be as simple as having the complete payload just as PUT, or a
> more elaborate protocol with added meta data such as the forms POST
> protocol or something similar, it's up to the application.

But, this doesn't work for WebDAV and extensions of it. For WebDAV you
*must* let the client choose the name. Otherwise, your server isn't a WebDAV
server.

- Brian

---

From: Henrik Nordstrom <[email-masked]>
Date: Fri, 24 Oct 2008 23:48:59 +0200

> *must* let the client choose the name. Otherwise, your server isn't a WebDAV

I didn't say anything else. Looking at the problem scope from a general
HTTP point of view, not specific WebDAV.

I don't see why WebDAV servers can't also implement a POST interface for
creating resoures. Would be very odd if WebDAV prohibits this when it is
allowed by HTTP. But it's not part of the WebDAV application of HTTP.
But I would be very annoyed if installing WebDAV support made my photo
album application no longer can accept form based uploads of images
where the server names the image based on exif information in the image.

Regards
Henrik

---

From: Julian Reschke <[email-masked]>
Date: Sat, 25 Oct 2008 01:33:36 +0200

> *must* let the client choose the name. Otherwise, your server isn't a WebDAV

That's not totally correct. WebDAV doesn't require that any WebDAV 
collection supports PUT for on direct members (for create).

Of course right now most servers do that, and clients do rely on it, but 
it's not something that WebDAV requires anymore than, for instance, HTTP 
or AtomPub.

BR, Julian

---

From: Julian Reschke <[email-masked]>
Date: Sat, 25 Oct 2008 01:35:51 +0200

> allowed by HTTP. But it's not part of the WebDAV application of HTTP.

It's totally optional. 
<http://greenbytes.de/tech/webdav/draft-reschke-webdav-post-01.html> 
describes how a server can advertise that it does allow POST-for-create 
(and also allows the URI to be posted to to be different from the 
collection URI).

> where the server names the image based on exif information in the image.

Right.

BR, Julian

---

From: Julian Reschke <[email-masked]>
Date: Sat, 25 Oct 2008 01:39:11 +0200

Roy T. Fielding wrote:
>> client gets a 301, it potentially use the URI given in Location: for 
>> all subsequent request, and that's definitively not what people want 
>> in this case.
> 
> It seems to me that their use case requires POST.  Why is that a problem?

The only problem is that in WebDAV land there's some reluctance to use 
POST for *anything*, because of it's open ended semantics.

That's why I made a proposal through which a server can advertise a URI 
that accepts POST requests for the purpose of creating collection 
membbers (WebDAV property/link relation/element in response body).

>> 201), but storing the resource under a different URI, and it seems to 
>> me that this a bad idea (given the PUT semantics defined in HTTP).
> 

Indeed.

BR, Julian

---

From: Julian Reschke <[email-masked]>
Date: Sat, 25 Oct 2008 01:40:26 +0200

> That's what WebDAV's LOCK is for preventing, isn't it?

LOCK can prevent that, but the likelihood of race conditions is small, 
so why bother? LOCK has a performance penalty (2 more roundtrips), and 
also is truly optional.

BR, Julian

---

From: "Brian Smith" <[email-masked]>
Date: Sat, 25 Oct 2008 11:38:53 -0500

Julian Reschke wrote:
> Brian Smith wrote:
> > But, this doesn't work for WebDAV and extensions of it. For WebDAV
> > you *must* let the client choose the name. Otherwise, your server
> > isn't a WebDAV server.
> 

That may be technically true, but practically support for PUT is required.
Just reading the specifications you can see that support for PUT is taken
for granted throughout them all. And, no existing WebDAV client can create
new resources without PUT. Consequently, any WebDAV implementation that
cares about interoperability with existing clients, or wants to support the
rapid development of new clients using existing WebDAV implementations, has
to support PUT for creation and editing resource entities. 

> Of course right now most servers do that, and clients do rely on it,
> [...]

Regards,
Brian

---

From: Helge Hess <[email-masked]>
Date: Fri, 24 Oct 2008 23:58:19 +0200

On 24.10.2008, at 23:48, Henrik Nordstrom wrote:
>> you

Yes. The problem is that Julian pushes his POST extension towards  
WebDAV based protocols (CalDAV/CardDAV). While I'm not against adding  
a specialized POST as an extension, it does not really fit WebDAV and  
IMHO does not belong into such (DAV) specs. Hence I think it has  
little chance for adoption.

Greets,
   Helge
-- 
Helge Hess
http://helgehess.eu/

---

From: Julian Reschke <[email-masked]>
Date: Mon, 27 Oct 2008 11:05:18 +0100

Helge Hess wrote:
> Yes. The problem is that Julian pushes his POST extension towards WebDAV 
> based protocols (CalDAV/CardDAV). While I'm not against adding a 
> specialized POST as an extension, it does not really fit WebDAV and IMHO 
> does not belong into such (DAV) specs. Hence I think it has little 
> chance for adoption.
> ...

Well, I continue to disagree.

For instance, I think an AtomPub server that also supports WebDAV 
methods would be good thing, and this extension is something that aligns 
WebDAV semantics with AtomPub semantics.

BR, Julian