Network Working Group                                      M. Nottingham
Internet-Draft                                            March 19, 2005
Expires: September 17, 2005

                        POST Once Exactly (POE)

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

   The list of Internet-Draft Shadow Directories can be accessed at

   This Internet-Draft will expire on September 17, 2005.

Copyright Notice

   Copyright (C) The Internet Society (2005).  All Rights Reserved.


   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

   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

   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


   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",
   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

   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

      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

   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
          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"/>

   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
          POE: 1

   If the request is processed successfully, the server will respond

Nottingham             Expires September 17, 2005               [Page 6]

Internet-Draft                    POE                         March 2005


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


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,

   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

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

   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

Disclaimer of Validity

   This document and the information contained herein are provided on an

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.


   Funding for the RFC Editor function is currently provided by the
   Internet Society.

Nottingham             Expires September 17, 2005              [Page 10]