Re: Using conditional requests with 100 Continue

"Roy T. Fielding" <> Wed, 23 October 2019 00:28 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 959691201CE for <>; Tue, 22 Oct 2019 17:28:44 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.75
X-Spam-Status: No, score=-2.75 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (1024-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id E_0HYYvCWLCB for <>; Tue, 22 Oct 2019 17:28:42 -0700 (PDT)
Received: from ( [IPv6:2603:400a:ffff:804:801e:34:0:38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 9E0A6120152 for <>; Tue, 22 Oct 2019 17:28:42 -0700 (PDT)
Received: from lists by with local (Exim 4.89) (envelope-from <>) id 1iN4TY-0005cg-H0 for; Wed, 23 Oct 2019 00:26:08 +0000
Resent-Date: Wed, 23 Oct 2019 00:26:08 +0000
Resent-Message-Id: <>
Received: from ([2603:400a:ffff:804:801e:34:0:4f]) by with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from <>) id 1iN4TW-0005as-Np for; Wed, 23 Oct 2019 00:26:06 +0000
Received: from ([]) by with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from <>) id 1iN4TS-0007eB-5j for; Wed, 23 Oct 2019 00:26:06 +0000
X-Sender-Id: dreamhost|x-authsender|
Received: from (localhost []) by (Postfix) with ESMTP id D9B45600EC8; Wed, 23 Oct 2019 00:25:58 +0000 (UTC)
Received: from (100-96-171-212.trex.outbound.svc.cluster.local []) (Authenticated sender: dreamhost) by (Postfix) with ESMTPA id 32AB6600EA3; Wed, 23 Oct 2019 00:25:58 +0000 (UTC)
X-Sender-Id: dreamhost|x-authsender|
Received: from ([TEMPUNAVAIL]. []) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by (trex/5.18.5); Wed, 23 Oct 2019 00:25:58 +0000
X-MC-Relay: Neutral
X-MailChannels-SenderId: dreamhost|x-authsender|
X-MailChannels-Auth-Id: dreamhost
X-Imminent-Hook: 79698e51308125fe_1571790358612_3012198093
X-MC-Loop-Signature: 1571790358612:1005954434
X-MC-Ingress-Time: 1571790358612
Received: from (localhost []) by (Postfix) with ESMTP id 213079A973; Tue, 22 Oct 2019 17:25:55 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed;; h=from :message-id:content-type:mime-version:subject:date:in-reply-to :cc:to:references;; bh=iiQsoHnDY76Xa8Xt1MilUce0H/4=; b= Q0bIkiZSJ5sMNmnsu+fRfyQZq909+PwjgbmIehDlBi0VbC+oobFJ6s7yz7kg1ND2 gaNtmnPBQgX3pJuaxySQcbgLDGOen+lcK9FYZTq/0BwegQ2JQQfXpqZLxbE86Dgi ePh1Q97g+KYmFzGOS7GwWFd7SQSXnLU7dQXCc16bwmo=
Received: from [] ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: by (Postfix) with ESMTPSA id 205F99A982; Tue, 22 Oct 2019 17:25:53 -0700 (PDT)
X-DH-BACKEND: pdx1-sub0-mail-a49
From: "Roy T. Fielding" <>
Message-Id: <>
Content-Type: multipart/alternative; boundary="Apple-Mail=_A65BD8DE-BA10-488D-BDCF-C94C8CD5C4A1"
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\))
Date: Tue, 22 Oct 2019 17:25:52 -0700
In-Reply-To: <>
To: Austin Wright <>
References: <>
X-Mailer: Apple Mail (2.3445.104.11)
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-9.1
X-W3C-Hub-Spam-Report: BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, W3C_AA=-1, W3C_DB=-1, W3C_IRA=-1, W3C_IRR=-3, W3C_WL=-1
X-W3C-Scan-Sig: 1iN4TS-0007eB-5j 30ec78b0c6f5581b0dfc5cf7ebb44b22
Subject: Re: Using conditional requests with 100 Continue
Archived-At: <>
X-Mailing-List: <> archive/latest/37069
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

> On Oct 21, 2019, at 3:41 PM, Austin Wright <> wrote:
> Hello,
> I’m reading through RFC 7231 and RFC 7232 to implement an HTTP server that supports a PUT method on a resource, with 100 Continue and 412 Precondition Failed responses; and I am wondering why 412 must be tested last, after all other errors.
> The uploaded document must conform to certain media type and validation requirements, perhaps responding with an error like 400 (Bad Request) or 422 (Unprocessable Entity) if the upload is not well-formed. Suppose I issue a request with:
> Expect: 100-continue
> If-Match: “etag”
> In this case, it seems to me the server should issue a 412 Precondition Failed if the resource has been changed, and that I shouldn’t have to upload the entire document just to find out that it has been changed. Yet, RFC 7232 HTTP Conditional Requests says:
> > A server MUST ignore all received preconditions if its response to the same request without those conditions would have been a status code other than a 2xx (Successful) or 412 (Precondition Failed). In other words, redirects and failures take precedence over the evaluation of preconditions in conditional requests.
> This suggests that I must validate the document in its entirety if I’m going to return a status like 422, before testing the precondition, even if the upload is very long.
> (1) Is there a particular reason that the precondition test must be tested after all other 4xx (even 5xx) errors?

The simple answer is that 422 did not exist at the time the requirement was written.
The more complex answer is that the requirement should be restated to talk only about
errors that are discovered before the body is processed.

If you can, please add an issue for that to " <>"
(if not, let me know and I will add one).

> Now, I imagine this requirement might have the effect of reducing some race conditions, but even then it would not completely eliminate race conditions, without a way of locking the database/filesystem record for writing.
> (2) Are there clients in the wild that would be broken if the precondition test happened earlier? i.e. are there any clients that would incorrectly assume the upload is well-formed if they received a 412 error instead of a 400, 415, and/or 422?
> (3) For 100-continue and performance purposes, can this limitation be relaxed so it’s the last thing tested before errors relating to the request entity-body?