[Zope3-dev] DISCUSS: Correct sequence for PUT
Paul Everitt
paul@zope-europe.org
Wed, 19 Feb 2003 10:12:17 +0100
Howdy. I just started putting PUT support into the stuff I'm doing with
Moztop. I used Shane's nice "tcpwatch" application to record the
request/response interaction, then compared it to a PUT to Apache.
At the end I have cut-and-pasted the request/response for Zope 3 and for
Apache 2.
Some points and questions:
1) Zope 3 identifies itself as an HTTP/1.1 server. I didn't realize we
supported HTTP/1.1. How much is actually there?
2) I'm not sure Zope 3 is doing the PUT correctly. I did a PUT of a new
resource, and RFC 2616 (HTTP/1.1) Section 9.6 says that a status code of
201 should be returned. Also, the server should return a Location:
header with the URI of the newly created resource.
Perhaps I'm reading 9.6 incorrectly?
3) Finally, I gentle plea for a feature. In Moztop (and in the
Rotterdam skin), I'd like to support Undo from the client, without
visiting a page. That is, I'd like the most recent transaction to be
undo-able simply by performing a gesture (click on an Undo button, for
instance).
To avoid sending the user to a page and making them select a transaction
to undo, I propose that Zope return transaction ids as part of the
response. This could be in an HTTP response header. Or, for things
like PUT, we could use the response body (which we're not using right now).
Finally, I'd like some advice on how to handle the sequence for creating
richer objects. Let's say I want to create a Smart Image without
filling in an HTML form. I want to create it using HTTP/DAV verbs.
To make this hard, presume two constraints:
1) You can't create a Smart Image without passing in three parameters to
the constructor. Let's say they are author, keyword, and
publicationname. Doesn't matter, I'm just being hypothetical.
2) The request body is, obviously, binary.
Using Shane's tcpwatch, I took a look at the sequence for using Windows
Web Folders to drag-n-drop an image to Apache 2. It was interesting:
1) Request: HEAD, to see if it already exists. Response: not found.
2) Request: PUT of the resource *without* the body. Response: 201
created, Location: the uri.
3) Request: Another HEAD, on the URI returned by (2). Response: nothing
terribly meaningful.
4) Request: Another PUT, this time we finally send the binary contents.
Response: 204 no content.
5) Request: Another HEAD. Response: The basic info again.
So for this Smart Image, do I do something like this:
1) HEAD to see if it exists.
2) PUT to create it, sending as the request body some XML for
construction. (I could do a PUT and then a PROPPATCH, but after the PUT
it is alread constructed, so I defeat the constructor.)
3) HEAD, just in case the server thinks the URI is different. :^)
4) PUT to actually send the body.
Geesh, hope our server is fast! Imagine dragging-and-dropping 100 files
onto a Zope site.
--Paul
Zope 3 Request-Response
------------------------------
[00:00.000 - client 192.168.1.3:58487 forwarded to 192.168.1.3:8380]
PUT /folder/monkeyboy HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US;
rv:1.3b) Gecko/20030210
Accept:
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: text/plain
Content-Length: 3
foo
[00:00.110 - server connected]
HTTP/1.1 200 Ok
Date: Wed, 19 Feb 2003 08:25:55 GMT
Content-Length: 0
X-Powered-By: Zope (www.zope.org), Python (www.python.org)
Server: zope.server.http (HTTP)
Apache 2 Request-Response
------------------------------
[00:00.000 - client 192.168.1.3:58488 forwarded to 192.168.1.2:9000]
PUT /somefile HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US;
rv:1.3b) Gecko/20030210
Accept:
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: text/plain
Content-Length: 3
[00:00.050 - server connected]
foo
HTTP/1.1 201 Created
Date: Wed, 19 Feb 2003 08:29:22 GMT
Server: Apache/2.0.40 (Unix) DAV/2
Location: http://localhost:9000/somefile
Content-Length: 251
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=ISO-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>201 Created</title>
</head><body>
<h1>Created</h1>
<p>Resource /somefile has been created.</p>
<hr />
<address>Apache/2.0.40 Server at localhost Port 9000</address>
</body></html>