5.4 PUT

The PUT method is much more useful combined with WebDAV functionality than with HTTP alone. Now the client can figure out which resources are collections and what resources already exist in those collections. Then the client can either create new resources in a collection or modify existing resources. The format in which the resource is sent is typically the format in which it is stored and returned in response to future GET requests.

The Translate Header

Microsoft IIS 5.0 and Exchange 2000 implemented an alternative approach to retrieving source code. The custom-defined Translate header takes a value of T for true or F for false. When the value is F, the server returns the source code file for the resource, unprocessed. With a value of T, the resource is returned as it is for normal browsers. When the header is not present, it's assumed to be T, because that's the way normal browsers would send requests.

When Microsoft WebDAV clients are in authoring mode, as opposed to browsing, they send "Translate: F" with each request. For example, Office 2000 is an authoring tool and therefore sends this header.

The WebDAV Working Group rejected this approach because source code can involve more than one file per resource.


Normally, PUT requests must include the Content-Type and Content-Length headers (in addition to the Host header required on every request). The Content-Type header is necessary so that the server knows what MIME type to store for the document, because file extensions are an unreliable way of determining the type of document. The client must send the Content-Length header unless it chooses another way to indicate the end of the body, such as chunked transfer encoding (Section 3.2.8). This is the only encoding that a client can assume the server will support. Thus, a file sent in a zipped format will remain a zipped file when stored on the server, and other clients will download the same zipped file.

When a resource already exists with the address used in the Request-URI of the PUT request, the server will normally overwrite the previous resource. If the client doesn't expect an existing resource to be overwritten, it must use the If-None-Match header (Section 3.7.6).

Normally, the body sent in a PUT request is stored exactly the way it was received after the transfer encodings are undone. However, some servers (e.g., the Tamino XML server) are known to modify the file so that the results of a subsequent GET return a slightly different body. The Content-Length of the stored file is immediately different from the length the client sent.

Normally, a file body doesn't change from one PUT to another, but some servers modify the file body in other situations. For example, Exchange 2000 modifies the bodies of some resources such as appointments when the properties of the appointment are changed. A client holding a lock on the resource may be surprised to see the body change when it hasn't issued a PUT request, but clearly with Exchange 2000 this can happen.

WebDAV defines a few new status codes that can be returned in response to a PUT request. These include 423 Locked, 424 Failed Dependency, and 507 Insufficient Storage. These errors are used to report PUT operation failures in distributed authoring situations: when the resource is locked, when the parent collection hasn't been created yet, and when quota or disk storage has been used up.

PUT and Dynamic Resources

graphics/bomb_icon.jpg

Only a few WebDAV servers (such as IIS 5.0) support authoring dynamic resources. When PUT can be used to create or overwrite dynamic resources, it behaves in much the same way as with static resources. These servers only support dynamic resources like JSP and ASP files where the source code is stored in a single file on the file system along with static resources. Thus, the Request-URI for the source code is the same as for the dynamically generated response.

No WebDAV servers are known to allow the PUT method to overwrite auxiliary files such as class files or library files that may be used in generating dynamic pages.


PUT requests are frequently forbidden due to permission restrictions. As with other methods, if permission is denied, the server should use the status response 401 Unauthorized.

5.4.1 Partial PUT

Since WebDAV clients use PUT much more frequently, several have suggested using the HTTP Range header (Section 3.7.12) on the PUT request to enable the client to upload only part of a file. This doesn't work, because HTTP defines the Range header (including how to handle it and what errors to return) only for the GET method.

Even if a server added custom support for the Range header on PUT requests, the feature would be problematic:

  • The Range header has no way to change the length of the file. It only expresses ranges of bytes within the known length of the body.

  • Many file formats require internal consistency. A Word document might become invalid if only some of its bytes were changed. The client might intend to do multiple partial PUT requests to finish changing the file to a new valid document, but in the meantime, other clients could download a corrupted document.

This is still a useful feature in theory, but more protocol design is required to make it work.

5.4.2 Avoiding Lost Updates

Recall the lost update problem described in Section 2.4.2; a client can never know if a file has changed since it was last downloaded unless it uses ETags (Section 3.4) to tell the server what state the resource ought to be in.

WebDAV clients use PUT much more often, so now I'll show exactly how to avoid the lost update problem, whether or not the server supports locks (see Listing 5-3). The client includes the If-Match header (Section 3.7.6) with the ETag that corresponds to the state of the entity when it was downloaded. If all the ETags in the header match, then the request should go ahead. Otherwise, the server must fail the request.

graphics/excd_icon.jpg

All WebDAV clients should use If-Match to avoid the lost update problem whenever possible. (Section 8.6.3 explains why this is needed even if the resource is locked.)

Listing 5-3 PUT using the If header.
 PUT /hr/ergonomics/posture.doc HTTP/1.1 Host: www.example.com If-Match: "etag1101" Content-Length: xxx Content-Type: application/ms-word graphics/enter.gif [body omitted] 

If-Match may also be used with any other request method to ensure that the state of the resource on the server is what the client expects. If the state does not match, the request fails.

5.4.3 Creating New Resources Safely

PUT can also be used to create new resources on the server. The hierarchical namespace and data model allow the client to construct a new URL. The client takes the URL of the collection where it wants to create a resource, adds the name of the resource (separated by slash), and the result is the new resource's URL. For example, to create index.html in the collection /hr/, the client constructs the absolute path /hr/index.html.

graphics/excd_icon.jpg

It's very important for the client to ensure that it is indeed creating a new resource, because otherwise the client may overwrite an existing resource unwittingly and the content that was stored there will be lost. It's not enough to simply check to see if the resource exists by getting a directory listing before the PUT, because in the meantime, a resource with the same name can be created by another client. There are only a few special circumstances where it really doesn't matter if a resource of the same name already exists (e.g., when a backup process uploads all the resources in a directory, it may create or overwrite resources without checking).

To create a new resource without any risk of overwriting an existing resource, clients use the If-None-Match header. With the special * value indicating "any ETag," this header allows the client to assert that there must be no entity stored at this URL.

 
 If-None-Match: * 

If the resource does not exist that is, if the requested URI does not refer to any entity at all the request will be allowed.

A Poor Solution to Safe Resource Creation

IE 5.5 uses a poor approach when attempting to create a new resource; it sends a HEAD request to the resource it's planning to create. If the HEAD response returns with results, IE prompts the user whether to overwrite the existing resource. If the resource is 404 Not Found, IE 5.5 creates the file without prompting. The problem with this approach is that there's a period after the HEAD response during which a file with that name can be created by another client. The PUT request from IE 5.5 will overwrite that resource if it is created in the meantime.

It's not clear why IE 5.5 uses HEAD instead of locking; perhaps it was designed to function with Web servers as well as WebDAV servers.


5.4.4 Generating Unique URLs

Sometimes clients need to add a resource with a unique name to a collection. The client doesn't care what name the resource is given, it only wants to make sure to add a new resource rather than overwrite a resource already there. Section 5.4.3 described how to use conditional headers to avoid overwriting a resource if the name does conflict, but it would be nice to have a unique URL that won't conflict with one already there.

To do this, first the client should generate a relatively unique ID it could include the user's ID or machine name plus a random number. The client can use HEAD as described earlier to see if the file already exists. If it does, choose another name. When the file is actually being created, the client should be sure to use the If-None-Match: * header on the PUT request.

Microsoft has a nonstandard solution for this little problem. With some Microsoft WebDAV servers, the client may use the POST request with the parent collection as the target of the request. The server saves the body of the request as a new resource (just like PUT), but it generates a unique URL for the new file. Exchange 2000 is known to support this feature. However, this behavior is not required, nor is it advertised as supported; therefore, the client can't rely on the server behaving in this manner.

5.4.5 Pipelining

To modify or create a number of documents, an equal number of PUT requests must be generated. If the server supports pipelining (and most do), all the PUT requests can be shoved into a connection as fast as they can be streamed onto the network. This has the advantage of incurring the cost of the connection latency only once, instead of once per request. Keeping latency costs down is key to good performance over the Internet and is usually more important than keeping messages brief.

Pipelining PUT requests is only possible when each PUT request will be made independently of the success of previous pipelined requests.

5.4.6 PUT and Collections

PUT is not defined for a collection. It's not forbidden, so in theory a server could accept a PUT request on a collection and do something with the entity in the request body. No clients or servers are known to support this.

The WebDAV specification doesn't say exactly which error to use if a server receives a PUT request for a collection URL. The 409 Conflict error is a reasonable choice, but it is already defined for PUT, to be used when the parent collection doesn't exist yet. It might be more helpful to use 403 Forbidden.

Servers that don't allow PUT to a collection may still show PUT as an allowed method in the OPTIONS response for a collection (see Listing 5-2). One line of reasoning assumes that PUT is allowed to create a new resource inside a collection, so PUT should appear in the Allow header. Another line of reasoning is that PUT is not allowed on the collection URL itself; therefore, it shouldn't appear in the Allow header. Clients must be prepared for either behavior.



WebDAV. Next Generation Collaborative Web Authoring
WebDAV. Next Generation Collaborative Web Authoring
ISBN: 130652083
EAN: N/A
Year: 2003
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net