Supporting PUT and DELETE with HTML FORMS

Author:
Mike Amundsen (mca@mamund.com)
Dates:
2011-04-01 (Created)
2011-12-01 (Updated)
Status:
Active Draft

1.

Summary

1.1.

Goals

Support for PUT/DELETE should be:

  • as complete as possible (per HTTP spec[RFC2616])
  • as seamless as possible (per current Browser behaviors)
  • easy to use via HTML (for both servers to emit and browser to process)
  • not introduce any new security problems
  • not veer substantially from support for PUT/DELETE via XHR
  • should integrate well with servers which already support PUT and DELETE (e.g. WebDAV, etc.)

1.2.

Assumptions

This proposal assumes:

  • Any controls that are currently valid for FORMs with the method=”post” are also valid for FORMs with the method=”put.”
  • Any enc-type values that are currently valid for FORMs with the method=”post” are also valid for FORMs with the method=”put.”
  • All controls and enc-type values are ignored for FORMs with the method=”delete.”

1.3.

A Simple HTML Example

<form action="http://example.org/user/12"” method=”put” if-match="*">
  <input name="user-name" type="text" value="" />
  <input name="hat-size" type="text" value="" />
  <input type="submit" />
</form>				

Filling the “user-name” and “hat-size” inputs with “mike” and “small” respectively, will result in the following HTTP request:

PUT /user/123 HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
If-Match: "*"
...
user-name=mike&hat-size=small

Responses

Servers are free to return responses to PUT and DELETE as theysee fit. Servers are not responsible for trying to determing if the PUT/DELETE request comes from an HTML.FORM and are not required to make special adjustments to the response juste because the request was intiated using an HTML.FORM.

All User Agentw (including Web browsers) SHOULD be prepared to handle any valid server response returned for a PUT/DELETE request; even those generated via HTML.FORM (see Handling Responses for details).

2.

Added Attributes for the FORM element

The following OPTIONAL attributes SHOULD be supported for the FORM element. Valid values for these new attributes MUST be the same as those outlined in the HTTP spec[RFC2616].

2.1.

If-Match

The etag associated w/ the entity to PUT/DELETE.

  • This value is used to populate the “If-Match” header[cite]
  • Sent with PUT and DELETE, only if !={empty}
  • Default to {empty}

2.2.

If-None-Match

The etag associated w/ the entity to PUT.

  • This value is used to populate the “If-None-Match” header[cite]
  • Sent with PUT, only if !={empty}
  • Default to {empty}

2.3.

If-Unmodified-Since

The if-unmodified-since header[cite] associated w/ the entity.

  • Sent with PUT and DELETE, only if !={empty}
  • Defaults to {empty}

3.

Sample Usage Scenarios

Below are example usage scenarios for PUT and DELETE w/ HTML Forms.

3.1.

Creating a New Resource

PUT can be used to create a new resource.

*** REQUEST
GET /users/;create HTTP/1.1
Host: www.example.org
...

*** RESPONSE
200 OK HTTP/1.1
...

<html>
...
<form action=”http://www.example.org/users/123” method=”put” if-none-match=”*”>
  <input name=”user-name” value=”” />
  <input name=”hat-size” value=”” />
  <input type=”submit” />
</form>
...
</html>


*** REQUEST
PUT /users/123 HTTP/1.1
Host: www.example.org
If-None-Match: "*"
Content-Type: application/x-www-form-urlencoded
Content-Length: nnn

user-name=mike&hat-size=small

*** RESPONSE
201 OK HTTP/1.1
...
<html>
...
<ul>
  <li>user-name: mike</li>
  <li>hat-size: small</li>
</ul>
...
<html>	   						
	   					

3.2.

Updating an Existing Resource

PUT can be used to update an existing resource.

*** REQUEST
GET /users/123 HTTP/1.1
Host: www.example.org
...

*** RESPONSE
200 OK HTTP/1.1
...

<html>
...
<form action=”http://www.example.org/users/123” method=”put” if-match=”q1w2e3r4t5”>
  <input name=”user-name” value=”” />
  <input name=”hat-size” value=”” />
  <input type=”submit” />
</form>
...
</html>

*** REQUEST
PUT /users/123 HTTP/1.1
Host: www.example.org
If-Match: "q1w2e3r4t5"
Content-Type: application/x-www-form-urlencoded
Content-Length: nnn

user-name=mike&hat-size=medium

*** RESPONSE
200 OK HTTP/1.1
...
<html>
...
<ul>
  <li>user-name: mike</li>
  <li>hat-size: medium</li>
</ul>
...
<html>
	   					

3.3.

Deleting an Existing Resource

DELETE can be used to remove an existing resource.

*** REQUEST
GET /users/123 HTTP/1.1
Host: www.example.org
...

*** RESPONSE
200 OK HTTP/1.1
...

<html>
...
<form action=”http://www.example.org/users/123” method=”delete” if-match=”q1w2e3r4t5”>
  <input type=”submit” />
</form>
...
</html>

*** REQUEST
DELETE /users/123 HTTP/1.1
Host: www.example.org
If-Match: "q1w2e3r4t5"

*** RESPONSE
200 OK HTTP/1.1
...
<html>
...
<p>/user/123 has been deleted</p>
...
<html>	   						
	   					

3.4.

Binary Transfers

PUT can be used to send binary data to servers.

*** REQUEST
GET /users/123/avatar HTTP/1.1
Host: www.example.org
Accept: text/html
...

*** RESPONSE
200 OK HTTP/1.1
...

<html>
...
<form action=”http://www.example.org/users/123” method=”put” if-match=”*”>
  <input type="file" name="imagefile" value="" />
  <input type=”submit” />
</form>
...
</html>

*** REQUEST
PUT /user/123/avatar HTTP/1.1
Host: example.org
If-None-Match: "*"
Content-Type: multipart/form-data; boundary=---------------------------3652875324033
Content-Length: nnn

-----------------------------3652875324033
Content-Disposition: form-data; name="imagefile"; filename="my-avatar.jpg"
Content-Type: image/jpeg

... binary data ...

*** RESPONSE
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: nnn

<html>
...
<h1>Your avatar has been created</h1>
...
</html> 	   						
	   					

4.

Other Considerations

4.1.

Handling Responses

Typical responses from PUT (200/201/204) and DELETE (200/202/204) SHOULD be handled the same way these responses are handled for POST[cite].

Q: How *are* they handled by UAs? (Is this in HTML5?). (Julian Reschke)
A: See Browser Matrix from Cameron Heavon-Jones)

Q: How do WebDAV servers commonly respond to PUT/DELETE? (Mike Amundsen)
A: from Julian Rescheke:

PUT -> 200 or 201 (for new resources)
DELETE -> 200 or 204.
		   				  

4.2.

Handling Security

Security constraints for PUT/DELETE via FORMS SHOULD be handled the same as using PUT/DELETE via XHR.

4.3.

Handling Caching

The same caching rules outlined in the HTTP spec[RFC2616] SHOULD be applied when handling PUT/DELETE responses.

4.4.

Optional Added FORM Content-Types

Currently, HTML FORMS support three content-types for sending request entities[cite]:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

It is possible that additional content-types could be supported for FORMS including JSON[cite] and XML[cite]. While this is not required in order to add support for PUT in HTML FORMS, there are a number of scenarios where this will be desireable. It is assumed that any additional content-types would be supported for FORMS where the "method" atttribute is set to POST or PUT.

4.5.

Optional Support for Prefer Header

It is possible that HTML FORMS could support the Prefer Header[Prefer] as a way to communicate to the server the agent's preference for a response. This would allow agent's to indicate they wish a body returned for responses where a body MAY not always be returned by servers (201/202).

4.6.

Support for Atom-Style PUT/DELETE

The current proposal relies on added attributes in the FORM element (see above). An alternative approach is to adopt the way AtomPub[AtomPub] handles PUT/DELETE; only support it in cases where the current response representation is the actual resource to PUT/DELETE.

This would mean agents would automatically use the ETag returned with a GET request on the target resource as the If-Match header for PUT and DELETE. While this can work for PUT(update) and DELETE, it's not clear how this would work for PUT(create).

This approach would also preclude cases where servers might return a single resource representation which contains a number of FORMs, with methods set to PUT/DELETE since the ETag for this list representation will never be a valid ETag for any of the included FORMs on the page.

4.7.

Alternate DELETE Implementation

This proposal outlines a DELETE implementation based on a complete URI and an otional if-match attribute. However, an alternate approach is to adopt the URI encoding support for GET. IOW, allow the possibility of HTML.INPUT values to be encoded into the URI for DELETE. (per email discussion )

<form action="http://example.org/user" method="delete" if-match="*">
  <input name="hat-size" type="text" value="" />
  <input type="submit" />
</form>	

*** REQUEST
DELETE /user?hat-size=small HTTP/1.1
Host: www.example.org
If-Match: "*"	   						
	   					

5.

References

6.

Changes

2011-04-05
  • Added "Alternate DELETE Implementation" to the "Other Considerations" section.
2011-04-04
  • Added "integrate w/ existing servers..." to the Goals section.
  • Added "Binary Transfers" to the Scenarios section.
  • Added Julian Reschke's query regarding exsting browsers handling 201/202/204 response to the Handling Responses section.
  • Added "Optional Added FORM Content Types", "Optional Support for Prefer Header", and "Support for Atom-Style PUT/DELETE" to the "Other Considerations" section.