[Docs] [txt|pdf] [Tracker] [WG] [Email] [Nits]
Versions: 00
Network Working Group M. Nottingham
Internet-Draft March 19, 2005
Expires: September 17, 2005
POST Once Exactly (POE)
draft-nottingham-http-poe-00
Status of this Memo
By submitting this Internet-Draft, I certify that any applicable
patent or other IPR claims of which I am aware have been disclosed,
and any of which I become aware will be disclosed, in accordance with
RFC 3668.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups. Note that
other groups may also distribute working documents as
Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
This Internet-Draft will expire on September 17, 2005.
Copyright Notice
Copyright (C) The Internet Society (2005). All Rights Reserved.
Abstract
This specification describes a pattern of use that allows HTTP
clients to automatically retry POST requests in a manner that assures
no unintended side effects will take place, and defines mechanisms to
allow implementations to automatically determine when such patterns
are supported.
Nottingham Expires September 17, 2005 [Page 1]
Internet-Draft POE March 2005
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1 Notational Conventions . . . . . . . . . . . . . . . . . . 4
1.2 Relationships to Other Specifications . . . . . . . . . . 4
2. POE Resources . . . . . . . . . . . . . . . . . . . . . . . . 4
3. The POE-Links HTTP Response Header . . . . . . . . . . . . . . 5
4. The POE HTTP Request Header . . . . . . . . . . . . . . . . . 6
5. Example: Hyperlinking to a POE Resource . . . . . . . . . . . 6
6. Example: Manual Retry . . . . . . . . . . . . . . . . . . . . 7
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 8
8. Security Considerations . . . . . . . . . . . . . . . . . . . 8
9. Normative References . . . . . . . . . . . . . . . . . . . . . 8
Author's Address . . . . . . . . . . . . . . . . . . . . . . . 8
A. Implementation Notes . . . . . . . . . . . . . . . . . . . . . 8
B. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 9
Intellectual Property and Copyright Statements . . . . . . . . 10
Nottingham Expires September 17, 2005 [Page 2]
Internet-Draft POE March 2005
1. Introduction
A very common sight on the Web is an admonishment to only "click
submit once." This is because there are some cases where an HTTP
request's status on the server is not known to the client; in some
instances, a delay in a response might be due to a temporary load on
the server that doesn't interfere with the request's processing, if
given enough time. In other cases, it could be caused by a server
failing, or a network problem; in these cases, the request may need
to be retried.
As a result, users (as well as automated agents) are placed in a
quandary; without a response, they don't know whether their request
has been successfully processed or not.
This isn't a problem for those HTTP requests that use idempotent
methods (e.g., GET and PUT); by definition, if the same request is
repeated (either by an impatient user pressing "reload" or an
automated agent timing out), there will be no additional side
effects.
However, non-idempotent HTTP methods, namely POST, may have
additional side effects when the same request is sent more than once.
To give a common example, POST is used by Web shopping baskets; when
the user wishes to finalise their purchase, a POST request is sent to
the server which processes the credit card transaction and fills the
order.
If the POST is sent twice, there is the danger of a duplicate order
being made.
RFC 2616, Section 8.1.4, states:
Non-idempotent methods or sequences MUST NOT be automatically
retried, although user agents MAY offer a human operator the
choice of retrying the request(s). Confirmation by user-agent
software with semantic understanding of the application MAY
substitute for user confirmation.
This specification provides applications with one means for gaining
such semantic understanding. Specifically, it describes a pattern of
use that allows clients to automatically retry POST requests in a
manner that assures no unintended side effects will take place.
It also defines HTTP header-fields to allow implementations to
automatically determine when such patterns are supported. These are
not an exclusive mechanism; other means for identifying POE resources
(e.g., format-specific markup on links in the entity body) may be
Nottingham Expires September 17, 2005 [Page 3]
Internet-Draft POE March 2005
used.
Note that the pattern described here can also be used in situations
where user intervention is required.
1.1 Notational Conventions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in BCP 14, [RFC2119], as
scoped to those conformance targets.
This specification defines extensions to the HTTP/1.1 [RFC2616]
specification. It uses the augmented BNF of that document, and
relies on both the non-terminals defined in that document and other
aspects of the HTTP/1.1 specification.
1.2 Relationships to Other Specifications
There are a number of "reliable" application protocols layered on top
of HTTP. Generally, these operate by treating HTTP as a transport
protocol, rather than a transfer protocol; i.e., they seek to make
any message delivered by HTTP reliable.
This specification is more focused; it only attempts to provide
reliable POST semantics, because most other HTTP methods, being
idempotent, do not require reliable delivery of either the request or
the response, in an application-to-application sense.
This specification does not address methods other than POST; however,
similar techniques might be applied to other non-idempotent methods.
Likewise, it does not address non-idempotent sequences of requests,
or guaranteed ordered delivery of requests.
2. POE Resources
A POE resource is an HTTP [RFC2616] resource with particular
properties that clients can take advantage of to assure that POST
requests are made once exactly, without requiring user intervention.
A POE resource will respond to a POST request successfully exactly
once; that is, a server MUST NOT respond to a POST with a 2xx-series
status code if it has been successfully POSTed to at some point in
the past.
If a POE resource is subsequently POSTed to, it SHOULD respond with a
405 Method Not Allowed status code. Such a response MUST NOT include
POST in the content of the Allow header.
Nottingham Expires September 17, 2005 [Page 4]
Internet-Draft POE March 2005
If the response to a POST to a POE resource contains an entity body,
that entity body SHOULD be available by GETting it from the resource,
to allow the client to retrieve the state of the response in the case
that a POST was successful, but the client did not receive the
response.
For example, if the POST response is cacheable, the same entity body
should be available through a subsequent GET; or, if the response has
a 303 See Other status code, subsequent GETs should redirect to the
indicated resource.
Note that a POE resource MAY require HTTP authentication, employ some
forms of HTTP redirection, etc.
When a client sends a POST request to a POE resource, it MAY
automatically (i.e., without user intervention) retry the request if
the response is indeterminate (e.g., the connection is lost or times
out). However, clients MUST NOT retry requests indefinitely.
User-agents SHOULD inform users that they are retrying a request
automatically, and MUST inform users if they stop retrying.
3. The POE-Links HTTP Response Header
The POE-Links HTTP header is an entity-header field whose field-value
is a comma-separated list of quoted URI-references [RFC3986] (without
fragment identifiers) that the origin server asserts to be POE
resources.
POE-Links = "POE-Links" ":" 1#( <"> POE-URI <"> )
POE-URI = absolute-URI | ( relative-part [ "?" query ] )
The contents of the POE-Links response header SHOULD correspond to
links found in the content of the response body.
[[ Some reviewers have suggested using the "Link" HTTP header with a
"rel" attribute instead of a special-purpose HTTP header, thereby
allowing link mechanisms in HTML to be used without further
specification.
Whilst this is attractive, it would require the Link header to be
standardized (it never was) and would introduce the potential need
for implementations to scan body content, whereas this is not
necessary in the current design (which does not preclude in-body
identification of POE resources, but does not encourage it).
Feedback on this design decision is sought.]]
Nottingham Expires September 17, 2005 [Page 5]
Internet-Draft POE March 2005
4. The POE HTTP Request Header
The POE HTTP header is a request-header field whose field-value
indicates the version of POE that a client supports.
POE = "POE" ":" POE-version
POE-version = 1*DIGIT
The POE-version that identifies this specification is "1".
Clients SHOULD send the POE request header on all requests to inform
the decisions of the server. Servers MAY vary their content based
upon the presence of the POE header (e.g., changing the operation of
submit buttons, changing user instructions), and MAY use the POE
header to determine when to send a POE-Links response header.
5. Example: Hyperlinking to a POE Resource
A typical use case for POE is assuring that an order to a Web
shopping basket is only POSTed once, so that only one order is made.
Here, the client retrieves the state of the shopping basket to allow
the user to review it prior to checking out;
C: GET /accounts/bob/shopping_basket HTTP/1.1
Host: www.example.com
POE: 1
...
The server returns a summary of the shopping basket in HTML, along
with a form that allows the user to check out.
S: 200 OK HTTP/1.1
POE-Links: "/accounts/bob/orders/12345"
...
<form method="POST" action="/accounts/bob/orders/12345">
<input type="submit" value="Submit Order 12345"/>
</form>
...
When the user activates 'Submit Order 12345', it sends a POST request
to what has been identified as a POE resource;
C: POST /accounts/bob/orders/12345 HTTP/1.1
Host: www.example.com
POE: 1
...
If the request is processed successfully, the server will respond
Nottingham Expires September 17, 2005 [Page 6]
Internet-Draft POE March 2005
with
S: 200 OK HTTP/1.1
...
If the client does not receive that response, it can retry the POST
request automatically;
C: POST /accounts/bob/orders/12345
Host: www.example.com
POE: 1
If the server had received and accepted the first request, it will
respond with
S: 405 Method Not Allowed HTTP/1.1
Allow: GET
...
If the response status is "405 Method Not Allowed" the client can
infer that the earlier POST succeeded. A 2xx response indicates that
earlier POST did not succeed, but that this one has. When the client
receives either of these responses, it knows that the request has
been accepted, and it can stop retrying.
6. Example: Manual Retry
As noted, it is not necessary to use POE-specific HTTP headers in
conjunction with this pattern. As such, it is possible to assure
exactly one POST without special accommodation on the User-Agent,
because the user can retry requests as needed.
Operation is the same as in the previous example, with the caveat
that POE-specific HTTP headers are optional. If the user is unsure
whether the POST has succeeded (e.g., the browser "hangs"), they can
be instructed to do one of two things;
1. submit a GET to the POE resource to determine its state
2. re-submit their POST to the resource
Many implementations support one or both of these actions through
"reloading" the page, or re-requesting the page manually (through an
"address bar" UI widget or similar).
In either case, the server can return an unambiguous response as to
the success of the POST, along with a user-friendly message in the
entity body.
Nottingham Expires September 17, 2005 [Page 7]
Internet-Draft POE March 2005
7. IANA Considerations
[[ TBD: header registration templates ]]
8. Security Considerations
Clients that indiscriminately retry requests may be used to
manufacture a denial-of-service attack on third party Web sites;
i.e., if a particular implementation retries aggressively or
indefinitely, an attack can be engineered whereby a number of clients
send a large number of requests to a particular site. This risk can
be mitigated by reasonable retry periods, backoff algorithms, a
reasonable maximum count for retries before manual intervention, and
selective treatment of links across administrative domains (e.g.,
those with different authorities).
9 Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
Masinter, L., Leach, P. and T. Berners-Lee, "Hypertext
Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
[RFC3986] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66, RFC
3986, January 2005.
Author's Address
Mark Nottingham
EMail: mnot@pobox.com
URI: http://www.mnot.net/
Appendix A. Implementation Notes
Implementations of POE resources need to carefully consider how to
guarantee that only one POST request is allowed, whilst still
assuring that the desired side effects take place. In practice, this
means that the information needed to enact the side effects needs to
be stored durably and that the state of the resource needs to be
updated, all in an atomic fashion.
Careful consideration needs to be given to the generation of URIs for
POE resources, since they should never be reused. Long-lived, unique
Nottingham Expires September 17, 2005 [Page 8]
Internet-Draft POE March 2005
identifiers can be generated by combining a date with one or more
other sources of context. For example,
http://www.example.com/users/bob/orders/2005/03/15/no2
encodes the date ("2005/03/15") along with a system-unique userid
("bob") and an order number for that day (no2"), allowing the system
to generate unique identifiers without storing more information than
the userid and how many orders have been made in the current day.
Note that this is an example only; the structure of POE URIs, like
other URIs, is opaque to consumers in the absence of authoritative
information.
Appendix B. Acknowledgements
The author would like to thank Yves Lafon, Roy Fielding and Rohit
Khare for their feedback. None of the flaws in this specification
are theirs.
Nottingham Expires September 17, 2005 [Page 9]
Internet-Draft POE March 2005
Intellectual Property Statement
The IETF takes no position regarding the validity or scope of any
Intellectual Property Rights or other rights that might be claimed to
pertain to the implementation or use of the technology described in
this document or the extent to which any license under such rights
might or might not be available; nor does it represent that it has
made any independent effort to identify any such rights. Information
on the procedures with respect to rights in RFC documents can be
found in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat and any
assurances of licenses to be made available, or the result of an
attempt made to obtain a general license or permission for the use of
such proprietary rights by implementers or users of this
specification can be obtained from the IETF on-line IPR repository at
http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any
copyrights, patents or patent applications, or other proprietary
rights that may cover technology that may be required to implement
this standard. Please address the information to the IETF at
ietf-ipr@ietf.org.
Disclaimer of Validity
This document and the information contained herein are provided on an
"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Copyright Statement
Copyright (C) The Internet Society (2005). This document is subject
to the rights, licenses and restrictions contained in BCP 78, and
except as set forth therein, the authors retain all their rights.
Acknowledgment
Funding for the RFC Editor function is currently provided by the
Internet Society.
Nottingham Expires September 17, 2005 [Page 10]
Html markup produced by rfcmarkup 1.126, available from
https://tools.ietf.org/tools/rfcmarkup/