Re: Question on HTTP 408

Sébastien Barnoud <sebastien.barnoud@prologism.fr> Wed, 04 June 2014 13:15 UTC

Return-Path: <ietf-http-wg-request@listhub.w3.org>
X-Original-To: ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com
Delivered-To: ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 9D6F31A0238 for <ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com>; Wed, 4 Jun 2014 06:15:49 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -7.253
X-Spam-Level:
X-Spam-Status: No, score=-7.253 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, MIME_8BIT_HEADER=0.3, RCVD_IN_DNSWL_HI=-5, RP_MATCHES_RCVD=-0.651, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=ham
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id k1I6rT_J5hn7 for <ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com>; Wed, 4 Jun 2014 06:15:44 -0700 (PDT)
Received: from frink.w3.org (frink.w3.org [128.30.52.56]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id ADE671A0236 for <httpbisa-archive-bis2Juki@lists.ietf.org>; Wed, 4 Jun 2014 06:15:44 -0700 (PDT)
Received: from lists by frink.w3.org with local (Exim 4.72) (envelope-from <ietf-http-wg-request@listhub.w3.org>) id 1WsAzI-0006Ex-TI for ietf-http-wg-dist@listhub.w3.org; Wed, 04 Jun 2014 13:12:16 +0000
Resent-Date: Wed, 04 Jun 2014 13:12:16 +0000
Resent-Message-Id: <E1WsAzI-0006Ex-TI@frink.w3.org>
Received: from lisa.w3.org ([128.30.52.41]) by frink.w3.org with esmtp (Exim 4.72) (envelope-from <sebastien.barnoud@prologism.fr>) id 1WsAz7-0006Cn-H1 for ietf-http-wg@listhub.w3.org; Wed, 04 Jun 2014 13:12:05 +0000
Received: from mail-wi0-f173.google.com ([209.85.212.173]) by lisa.w3.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.72) (envelope-from <sebastien.barnoud@prologism.fr>) id 1WsAz5-00011s-Tx for ietf-http-wg@w3.org; Wed, 04 Jun 2014 13:12:05 +0000
Received: by mail-wi0-f173.google.com with SMTP id bs8so8410021wib.0 for <ietf-http-wg@w3.org>; Wed, 04 Jun 2014 06:11:35 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:content-type:mime-version:subject:from :in-reply-to:date:cc:content-transfer-encoding:message-id:references :to; bh=O2fcjrKlkapq1j33QTqVDVMrlPgeGPdU0sYQHtwv8lQ=; b=kzPctHquHKpsqLnB+LXGhIeCjFRMPlX8nAFY67QTmS2WRCyzGXUxJTtu94CpfGCH2H V9P0aWlGsP/DLfGVqEFZaVHg5mU2MqWGyXRBBsRDVMy4kBRbHXr3Oz3n1CBTolp7RbcS jsDDz6CWvK0yj11hU6Cs4JYVMWuq/71Htv3+aCHLdW7rseNMyj/I0G7Z0OWDuBlqhoLk 9TqyfyH7nBpqALdd+izwkxOfWo6B804ts9dLoeyRWduc5J0ymIBmVlNHI56ofvfyJ/bw ZnAuPsAcutBwbT5gcGqaW6syfQAhGPcmsyDZhJE0m61w69TyI1akNXQd0lKCVkZrni+x 2RVQ==
X-Gm-Message-State: ALoCoQkEd+u8QpNvD4gTPKQPfLIm5NAigN6i7ZLguBGo8dlUXkwf02yIznQIIrJ2lrn/ZJTCKtP8
X-Received: by 10.195.17.169 with SMTP id gf9mr71839416wjd.10.1401887495370; Wed, 04 Jun 2014 06:11:35 -0700 (PDT)
Received: from [100.125.186.255] (130.20.90.92.rev.sfr.net. [92.90.20.130]) by mx.google.com with ESMTPSA id dk10sm30433418wib.1.2014.06.04.06.11.33 for <multiple recipients> (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 04 Jun 2014 06:11:33 -0700 (PDT)
Content-Type: text/plain; charset="utf-8"
Mime-Version: 1.0 (1.0)
From: Sébastien Barnoud <sebastien.barnoud@prologism.fr>
X-Mailer: iPhone Mail (11D201)
In-Reply-To: <20140604124910.GV3154@1wt.eu>
Date: Wed, 04 Jun 2014 15:11:34 +0200
Cc: Michael Sweet <msweet@apple.com>, "William Chan (?????????)" <willchan@chromium.org>, HTTP Working Group <ietf-http-wg@w3.org>, Matt Menke <mmenke@chromium.org>
Content-Transfer-Encoding: quoted-printable
Message-Id: <D84BEE28-2B8E-404E-922C-EDB3E7E15C38@prologism.fr>
References: <CAA4WUYgEWo4UMj+3=CO=d8NV5aUdirKe0zR1YEik_KQVkqabCQ@mail.gmail.com> <13EF864C-1236-4497-BDE0-08403AA67379@apple.com> <20140604044243.GU3154@1wt.eu> <090B6662-635A-42A3-941C-C9D6CB24ACF4@apple.com> <20140604124910.GV3154@1wt.eu>
To: Willy Tarreau <w@1wt.eu>
Received-SPF: softfail client-ip=209.85.212.173; envelope-from=sebastien.barnoud@prologism.fr; helo=mail-wi0-f173.google.com
X-W3C-Hub-Spam-Status: No, score=0.3
X-W3C-Hub-Spam-Report: MIME_QP_LONG_LINE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_SOFTFAIL=0.972
X-W3C-Scan-Sig: lisa.w3.org 1WsAz5-00011s-Tx 4efe954603965f6474d3fda37f038575
X-Original-To: ietf-http-wg@w3.org
Subject: Re: Question on HTTP 408
Archived-At: <http://www.w3.org/mid/D84BEE28-2B8E-404E-922C-EDB3E7E15C38@prologism.fr>
Resent-From: ietf-http-wg@w3.org
X-Mailing-List: <ietf-http-wg@w3.org> archive/latest/24094
X-Loop: ietf-http-wg@w3.org
Resent-Sender: ietf-http-wg-request@w3.org
Precedence: list
List-Id: <ietf-http-wg.w3.org>
List-Help: <http://www.w3.org/Mail/>
List-Post: <mailto:ietf-http-wg@w3.org>
List-Unsubscribe: <mailto:ietf-http-wg-request@w3.org?subject=unsubscribe>

Hi,

I have several years ago used customized Curl and GSoap to automaticaly retry requests on such a condition. 
As this is used for money transfer, it is very important to distinguish retryable errors (connect timeout, ...) from others errors (request timeout, ...).
On a close, no retry is possible except if the server replies with this 408.
So i agree with you, and i know that some application uses this feature. 

> Le 4 juin 2014 à 14:49, Willy Tarreau <w@1wt.eu> a écrit :
> 
> Hi Michael,
> 
>> On Wed, Jun 04, 2014 at 07:52:27AM -0400, Michael Sweet wrote:
>> Willy,
>> 
>>> On Jun 4, 2014, at 12:42 AM, Willy Tarreau <w@1wt.eu> wrote:
>>> Hi Michael,
>>> 
>>>> On Tue, Jun 03, 2014 at 07:54:18AM -0400, Michael Sweet wrote:
>>>> William,
>>>> 
>>>> This sounds like a pretty obvious bug - a HTTP server only responds when it
>>>> has received something.  The usual keep-alive timeout of connections is
>>>> silent (server just closes the connection, with a preceding TLS shutdown for
>>>> HTTPS).
>>> 
>>> Please could you check my other response to Roy ? In short I do instead
>>> think that responding 408 is the only way to gracefully shut down *and*
>>> inform the client it can safely retry and I really think it was designed
>>> for this exact purpose.
>> 
>> I don't think it was designed for being returned when no request had started
>> coming in, but rather when a partial request was received and then timed out.
> 
> It's hard to navigate through the W3C archives to find the original discussion
> for this status code introduced in HTTP/1.1. Some minutes talk about request
> timeout :
> 
>  http://lists.w3.org/Archives/Public/ietf-http-wg-old/1994SepDec/0257.html
> 
> On the WG, 408 was already mentionned in a few exchanges here :
> 
>  http://lists.w3.org/Archives/Public/ietf-http-wg-old/1995MayAug/0340.html
>  http://lists.w3.org/Archives/Public/ietf-http-wg-old/1995SepDec/0158.html
> 
> 
> The first mention of it I could find in a published draft was in draft-00
> dated 1995/11/22 :
> 
>    http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-00.txt
> 
> And the text says :
> 
>  "
>   408 Request Timeout
> 
>   The client did not produce a request within the time that the 
>   server was prepared to wait. The client may repeat the request 
>   without modifications at any later time.
>  "
> 
> At least I'm not seeing any mention about starting to send anything, there
> is a client and it did not produce a request, that's how I've always read
> it. Also, please note this specific point in -p2 :
> 
>   http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-26#section-6.5.7
>   6.5.7. 408 Request Timeout
>   The 408 (Request Timeout) status code indicates that the server did
>   not receive a complete request message within the time that it was
>   prepared to wait.  A server SHOULD send the close connection option
>   (Section 6.1 of [Part1]) in the response, since 408 implies that the
>   server has decided to close the connection rather than continue
>   waiting.  If the client has an outstanding request in transit, the
>   client MAY repeat that request on a new connection.
> 
> Note the last sentence : "*If* the client has an outstanding request ...".
> For me that clearly means that the client might very well receive a 408
> while it did not have an outstanding request, which implies that no byte
> was sent over the wire yet.
> 
>> There is nothing in any of the HTTP RFCs that talks about returning a
>> response line, headers, and message body to the client without first
>> receiving something from the client.
> 
> Of course, but the same is true for the reverse proposition, nothing
> says it's not possible. And in fact, 400 bad request is a perfect
> example. If the client sends unparsable crap (so nothing matching
> even the beginning of a valid request), a 400 bad req will be
> returned. We're talking about protocol errors here leading to a
> connection being closed as a result, I'm not seeing anything wrong
> with that.
> 
>> What CUPS does (and this was largely based on asking the question, "What does
>> Apache HTTP Server do?" many years ago) is to silently close the connection
>> after the configured timeout, which is large enough (300 seconds for CUPS and
>> Apache) to account for any reasonable traffic delays (on the Earth, at
>> least).
> 
> But as I said in the other thread, the spec prevents the client from retrying
> a non-idempotent request if the server does this, while 408 explicitly allows
> it to. So I think that the intent behind the 408 was pretty clearly to inform
> the client that no damage was made and that it had a chance to retry. On silent
> close, you must not resend a POST for example, since it might very well have
> already been processed :
> 
>   http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-26#section-6.3.1
>   6.3.1. Retrying Requests
>   Connections can be closed at any time, with or without intention.
>   Implementations ought to anticipate the need to recover from
>   asynchronous close events.
> 
>   When an inbound connection is closed prematurely, a client MAY open a
>   new connection and automatically retransmit an aborted sequence of
>   requests if all of those requests have idempotent methods (Section
>   4.2.2 of [Part2]).  A proxy MUST NOT automatically retry non-
>   idempotent requests.
> 
>   A user agent MUST NOT automatically retry a request with a non-
>   idempotent method unless it has some means to know that the request
>   semantics are actually idempotent, regardless of the method, or some
>   means to detect that the original request was never applied.
> 
>> I can understand if you don't want to have as large of a timeout for a proxy
>> that is shared by thousands of clients, but you can definitely make this
>> configurable and default to something reasonable (30-60 seconds).  If the
>> network connectivity is so bad that the request line and headers don't start
>> flowing within that timeframe, then there is probably no point in retrying
>> automatically anyways.
> 
> I'm seeing some sites running with smaller timeouts to limit the risk of DoS.
> When you know that you can accept 300k connections per second, with a 5s
> timeout you already have 1.5 million connections. That's not unreasonable
> to use aggressive timeouts in such conditions (especially for sites which
> run older pre-forked servers which cannot accept such large numbers).
> 
> And you can clearly have a few seconds pause on 3G during a handover. I've
> observed multi-second delays which cumulate with TCP retransmits to result
> in something in the 10s range. The handover is an interesting case because
> the network condition is temporarily bad and is good again once you get the
> response, so there's a real incentive to retry instead of telling the user
> "I'm sorry, I tried to validate your order but something has cut in the
> middle so I don't know if you'll get it or not, please check your cart".
> 
> In the case of haproxy, sending the 408 only if something was started on
> the connection is a trivial change, and I even delayed its final release
> by a few days so that we have the time to discuss this use case and decide
> what the proper cut-off mode is. But I think it would be a wrong change
> that degrades the client's ability to seamlessly recover. For me the most
> likely explanation for a close is "the server crashed after receiving the
> request" (FIN) or "before receiving the request" (RST). 408 makes it pretty
> clear that it's neither.
> 
> What would be interesting in fact is to know how various clients act on
> silent close an on 408, with idempotent and non-idempotent requests. And
> based on that we should likely clarify the text on what should be done.
> Pat said that Firefox handles 408 fairly well (I found a bug report for
> it being fixed in 2004). I don't know however how a POST over a silently
> closed connection is handled there. Maybe non-browser clients like Curl
> would help us determine the best behaviour as well. Daniel ?
> 
> Regards,
> Willy
> 
>