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.
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 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 PUTSince 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:
This is still a useful feature in theory, but more protocol design is required to make it work. 5.4.2 Avoiding Lost UpdatesRecall 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.
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 [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 SafelyPUT 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.
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.
5.4.4 Generating Unique URLsSometimes 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 PipeliningTo 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 CollectionsPUT 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. |