Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:96192 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 23902 invoked from network); 2 Oct 2016 21:12:26 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Oct 2016 21:12:26 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.46 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.82.46 mail-wm0-f46.google.com Received: from [74.125.82.46] ([74.125.82.46:37470] helo=mail-wm0-f46.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 9E/72-06241-93871F75 for ; Sun, 02 Oct 2016 17:12:25 -0400 Received: by mail-wm0-f46.google.com with SMTP id b201so46415848wmb.0 for ; Sun, 02 Oct 2016 14:12:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:subject:to:message-id:date:user-agent:mime-version :content-transfer-encoding; bh=tBdH2/RaF2upPZgihgRh8X2/zTfVkGsp4JDHDy4mnbM=; b=tL8TIFwl9ERzN0stdCGJQPnwADR3i5HGBn38GOehg8B8dq47vC5KrpN4uWEIMlWJTn 3G9pN/CifGtZIgj2CnUmlmWeSCxRgomPNRD+nIJl8gJCJDnetQ8SMs2pC+csown5HNxV d4N+a51/91Jax2Ta9YOqs2DVp7/gi8A8cnQoMcxgFaC21ZNYPDKPsvH8c74cCZxQdl+s rermN5h9MK7fpmmChepy/3sy3ZKER9E5hNlOYPaMupT+eEgEKREMJIupzZH92QZCxQnf rdPVINjUXxhe+zkM9ZWf0rDGNRMgtMQ4tEIUy96Rx19lFXXwWGlkStVumG/v0V/Sep4E lsjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-transfer-encoding; bh=tBdH2/RaF2upPZgihgRh8X2/zTfVkGsp4JDHDy4mnbM=; b=RV8m/rhvCHN6Nilvl/pfXBrriR0tqP/FzbKi2hLkMQGWFp8ZfoX8O0I1pWnin7/Yy+ BFReqrNvGdzXUOmJZDF8LXrwJdp24TjL4HCf/B34DxpqsyyYsOuH0UGhLOCCMHwomQUM Fi7tkhWnoaC2ywxY0s7CgTT7NM9jWYjHOrUTLE876/VWgPxeiQNrWIDtBlGmfYqgw0RA V464Hbki7uBi3fKzwMN5eFBiH5PloToPxYVE0p4uXSItQXf3LiTIT87V1eaaT/mbjb75 lv5db3c7dwL62Y/jv2Zcf8lytRoMPkybzSPwi/b4taAcPnF2k6uuAvLiqqlKBCV1uWlZ dKow== X-Gm-Message-State: AA6/9RmELwxGSULckQyvX4fUTolIoSge/dt9xqhgwVZzu9gBrJ9LveAyue4v2RuDhqFaFw== X-Received: by 10.194.241.227 with SMTP id wl3mr14115135wjc.177.1475442741412; Sun, 02 Oct 2016 14:12:21 -0700 (PDT) Received: from [192.168.1.5] ([95.148.161.240]) by smtp.googlemail.com with ESMTPSA id a84sm15700917wme.6.2016.10.02.14.12.20 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 02 Oct 2016 14:12:20 -0700 (PDT) To: PHP Internals Message-ID: <1de78ecd-74e5-438c-9744-103163218ebd@gmail.com> Date: Sun, 2 Oct 2016 22:12:19 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Add support for HTTP/1.1 From: rowan.collins@gmail.com (Rowan Collins) Hi internallers! No, you haven't misread the subject line, I'm not talking about the exciting new HTTP/2, but HTTP/1.1, 20 years old this year. To my surprise, PHP's HTTP stream wrapper (e.g. file_get_contents('http://example.com');) defaults to sending HTTP/1.0 requests. You can tell it to use HTTP/1.1 with an appropriate "stream context", but it's fiddly [1], and the implementation is incomplete. There's actually already an exception to this: some SOAP servers were discovered to only talk HTTP/1.1, so ext/soap forces the wrapper to upgrade by default [bug-43069]. This in turn revealed some of the bugs in the wrapper's protocol support, one of which I have recently created a patch for [bug-47021]. It's reasonable to suppose that 9 years on from that bug those SOAP servers aren't alone in rejecting (or mishandling) HTTP/1.0 requests, and moves to implement HTTP/2.0 will only make that more likely. I think it would be good to get this support into a better state, make it easier to switch on - e.g. with an INI setting, or some new stream URL syntax - and possibly make HTTP/1.1 the default in PHP 8.0. As I understand it, supporting HTTP/1.1 as a client requires the following mandatory features on top of HTTP/1.0: a) Send a "Host" header with every request. (RFC 7230 Section 5.4) b) Support persistent connections, or send "Connection: Close" with each request. (RFC 7230 Section 6.1) c) Ignore 1xx status lines (notably, "100 Continue") "even if the client does not expect one" (RFC 7231 Section 6.2) d) Support "chunked" transfer encoding (RFC 7230 Section 4.1) Let me know if there are any I've missed. I believe this is the current state of the PHP implementation: a) Host header always sent regardless of protocol version. b) The SOAP wrapper explicitly generates a "Connection: Close" header as well as forcing HTTP/1.1; users need to set it as a further option in stream_context_create(). It would be better if this was implicit with the protocol version. c) I can't find a bug report for this, but 100 Continue appears to be treated as an error status. This should be fixed. d) Chunked encoding itself was implemented, but the code for parsing headers was broken. If my PR [pr-1902] is approved, this will hopefully work correctly. What do people think? Would this be a worthwhile effort? [1]: Sample HTTP/1.1 context https://gist.github.com/IMSoP/8c62c97afc8765f418468b28a501409e [bug-43069]: https://bugs.php.net/bug.php?id=43069 [bug-47021]: https://bugs.php.net/bug.php?id=47021 [pr-1902]: https://github.com/php/php-src/pull/1902 Regards, -- Rowan Collins [IMSoP]