User:Jmoore6/ISSUE-195

From W3C Wiki


ISSUE-195: Enhance HTTP request generation from forms

Summary

This proposal allows a simple method for specifying HTTP headers to be sent with a FORM submission.

Rationale

HTML FORMs provide a declarative way for authors to provide a "recipe" for clients to follow while issuing a subsequent request. Multiple URL schemes such as http, https, and mailto offer network protocols where message headers may alter the semantics of a base request in important ways, yet HTML does not currently offer a way for FORM authors to access these semantics. For example, the HTTP header If-Match changes an unconditional request into a conditional one--a fairly large change in semantics.

Goals and Assumptions

Goals

  • FORM authors that do not require the use of headers to alter semantics may continue using the current FORM facilities unchanged, especially for URL schemes without a notion of a "header" (for example, data or javascript).
  • Certain major use cases, such as conditional requests, should be simple to describe.
  • Processing rules should be intuitive for implementers.
  • The standard "ignore what you don't implement" robustness principle should not result in poor behavior.
  • Conceptual compatibility with header manipulation via XMLHttpRequest.

Assumptions

  • Support for using PUT/DELETE in FORMs certainly makes this proposal more valuable, although there is still usefulness even for POST (for which conditional requests can likewise be applied). Therefore we expect addressing [1] will make this proposal more attractive, and vice versa.

Details

We propose the creation of a new input type "header" which a FORM author may include in the FORM; for example:

<input type="header" name="If-Match" value="&quot;etag&quot;"/>

For UI purposes, implementers SHOULD treat this input similarly to an input of type "hidden", and not present the value for editing. Upon FORM submission, the value of this input is neither used to mutate the action URL nor included in the request body; instead, a header of 'If-Match: "etag"' SHOULD be added to the request for a URL scheme that supports headers.

Scheme Support

For form submissions where the action URL has the scheme "http", "https", or "mailto", any INPUTs of type "header" SHOULD result in appending the given header to the resulting request. For form submissions where the action URL has the scheme "ftp", "javascript", or "data", any INPUTs of type "header" MUST be ignored. For other URL schemes, this specification does not define the behavior for processing INPUTs of type "header", although implementors are encouraged to treat schemes similarly to "http" where the schemes contain a construct semantically similar to request headers, and to ignore the INPUTs otherwise.

Blacklisted Headers

Certain headers MUST NOT be created via INPUTs of type "header". If an implementation encounters an INPUT with type "header" whose @name is a case-insensitive match for any of the disallowed headers, then it MUST ignore this input during FORM submission.

Disallowed HTTP and HTTPS Headers

Certain headers are not allowed to be modified in this way. Specifically, the list of headers that are disallowed include those disallowed by XMLHttpRequest, specifically:

  • Accept-Charset
  • Accept-Encoding
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Connection
  • Content-Length
  • Cookie
  • Cookie2
  • Content-Transfer-Encoding
  • Date
  • Expect
  • Host
  • Keep-Alive
  • Origin
  • Referer
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade
  • User-Agent
  • Via

In addition, if the start of the header name is a case-insensitive match for "Sec-" or "Proxy-", then this header is disallowed, as with XMLHttpRequest.

Finally, the following additional headers are disallowed as they are affected by the existing FORM submission process.

  • Content-Encoding
  • Content-Type
  • Content-MD5

Disallowed Mail Headers

  • MIME-Version
  • Content-Type
  • Content-Transfer-Encoding
  • Return-Path
  • Received
  • Date
  • From
  • Sender
  • Resent-*

Extension Headers

Unless explicitly excluded in the above list of disallowed headers, clients SHOULD add any syntactically well-formed headers to a request sent to an action URL with one of the supported schemes.

Syntactically Invalid Headers

Clients MUST ignore INPUTs of type "header" that would result in a syntactically incorrect header for the request protocol specified by the action URL of the FORM.

Required changes

Sample Usage Scenarios

Explicit language selection:

<form method="GET" action="/example">
  <input type="header" name="Accept-Language" value="fr;q=1.0"/>
  ...
</form>

Conditional requests:

<form method="POST" action="/example">
  <input type="header" name="If-Match" value="&quot;v1&quot;">
  ...
</form>

Impact

Positive Effects

  • Allows for greater FORM expressiveness vis-a-vis the construction of requests via greater access to underlying protocols, without requiring scripting.
  • May share implementations with non-rendering of "hidden" inputs, and with header setting on XMLHttpRequests via setRequestHeader().
  • Enhances the utility of supporting PUT and DELETE as @method values in FORMs by enabling conditional variants of these write operations.

Negative Effects

  • Expansion of input types that must be implemented.
  • Only allows for static header value assignment by the FORM author; this scheme cannot set headers based on client input (in a non-scripting environment).

Risks

  • Form authors should attempt to use "header" INPUTs in a way that can degrade gracefully if the headers are omitted from the request by an implementation that does not support them.
  • Failure to blacklist an unsafe header may lead to security issues.

Other considerations

This is a simple and straightforward proposal that solves a tangible need: being able to issue conditional requests from FORM submissions. It is certainly not as general as other proposals [5], though, so it is a fair question whether this actually provides enough "power" vis-a-vis header manipulation. If we were to adopt this proposal, we may well find ourselves down the road in a position where we need to support this proposal as well as some more general solution, which may well lead to more complex implementations. That said, there is something to be said for "the simplest thing that could possibly work".

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]
  • XMLHttpRequest Level 2, The setRequestHeader Method [4]
  • Proposal for ISSUE-195 by Cameron Jones [5]