User:Stilkov/ISSUE-195

From W3C Wiki


ISSUE-195: Enhance HTTP request generation from forms

Summary

This proposal is intended to describe the simplest possible change that could be made to HTML specification for forms to support the PUT and DELETE verbs.

Rationale

With the rising popularity of using HTTP for programmatic system-to-system interaction, usually labeled as "RESTful services", implementers of web applications have started to support the PUT and DELETE verbs according to their semantics, even though HTML doesn't support them. While it's entirely possible to get by with the two verbs supported by HTML (GET and POST), developers have found the additional semantics (idempotency, support for creation of resources using a user-determined URI, explicit support for deletion) beneficial enough to use them in practice.

The fact that HTML does not support PUT and DELETE has led to a number of ugly hacks that are now widely deployed in existing systems, most commonly in the form of hidden fields (e.g. "_method=PUT"). This is a form of tunneling that bypasses firewalls that block PUT and DELETE, prevents intermediaries to exploit the information associated with these methods' semantics, and complicates request routing in server implementations.

Goals and Assumptions

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
  • integrate well with servers which already support PUT and DELETE (e.g. WebDAV)

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 enctype values that are currently valid for forms with the method=”POST” are also valid for forms with the method=”PUT”
  • All controls and enctype values are ignored for forms with the method=”DELETE”

Details

Requests

If the proposal is implemented, the resulting behavior would be:

  • The "method" attribute in HTML forms could be PUT and DELETE in addition to POST and GET
  • Handling of forms with a method attribute of PUT would be the same as currently specified for POST, with the following changes:
    • The browser will send PUT instead of POST as the request method
    • If the user requests a PUT action be carried out again (e.g. by invoking the browser's "refresh" action), no alert is displayed, because PUT is idempotent.
  • DELETE requests would be handled in the same way as GET requests, including the construction of URIs based on form field values, with the following changes:
    • The browser will send DELETE instead of POST as the request method
    • No request body will be sent.
    • If the user requests a DELETE action be carried out again (e.g. by invoking the browser's "refresh" action), no alert is displayed, because DELETE is idempotent.

Responses

Servers are free to return responses to PUT and DELETE as they see 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 just because the request was intiated using an HTML.FORM.

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

Required changes

  • Update the valid state for "method" and "formmethod" content to include PUT and DELETE (section 4.10.19.6 "Form submission")
  • Add example for PUT and DELETE to 4.10.22 Form submission
  • Update the table in 4.10.22.3 Form submission algorithm to:


GET POST PUT DELETE
http Mutate action URL Submit as entity body Submit as entity body Mutate action URL (Navigate?)
https Mutate action URL Submit as entity body Submit as entity body Mutate action URL (Navigate?)
ftp Get action URL Get action URL STOR entity body at action URL DELE action URL
javascript Get action URL Get action URL Get action URL Get action URL
data Get action URL Post to data: Post to data: Get action URL
mailto Mail with headers Mail as body Mail as body Mail with headers
  • Update step 5 in the description of pushState and replaceState to read: "If the current entry in the session history represents a non-idempotent request (e.g. it was the result of a POST submission) then update it to instead represent a GET request (or equivalent).
  • TODO: More change requests to the spec

Sample Usage Scenarios

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

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”>
  <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
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>	   						


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”>
  <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
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>

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”>
  <input type=”submit” />
</form>
...
</html>

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

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

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> 	   

Impact

Positive Effects

  • Correct use of HTTP without tunneling through the non-semantic and non-idempotent POST method
  • No need for explicit code paths within server applications that support access by different types of user agents (browsers and other applications)
  • Improved performance due to better understanding of HTTP methods by intermediaries, specifically proxies

Negative Effects

Risks

Other considerations

Declarative support for conditional request header

A very useful extension would be to add support for setting headers, specifically If-Match, If-None-Match, If-Modified-Since and If-Unmodified-Since. This would enable the HTML page author to ensure proper prevention of lost updates. Support for this useful feature is explicitly not part of this proposal, as it might be more usefully specified as part of a more general proposal such as [4].

References

  • Bug 10671 - consider adding support for PUT and DELETE as form methods [1]
  • ISSUE-195: Enhance HTTP request generation from forms [2]
  • Hypertext Transfer Protocol -- HTTP/1.1 [3]
  • Change proposal for the enhancement of HTML forms in complete integration with the HTTP protocol and the ability to generate entire requests through declarative HTML markup in the absence of scripting support [4]