Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: allow sending 1xx responses #42597

Closed
wants to merge 20 commits into from

Conversation

dunglas
Copy link
Contributor

@dunglas dunglas commented Nov 13, 2020

Currently, it's not possible to send informational responses such as
103 Early Hints or 102 Processing.

This patch allows calling WriteHeader() multiple times in order
to send informational responses before the final one.

If the status code is in the 1xx range, the current content of the header map
is also sent. Its content is not removed after the call to WriteHeader()
because the headers must also be included in the final response.

The Chrome and Fastly teams are starting a large-scale experiment to measure
the real-life impact of the 103 status code.
Using Early Hints is proposed as a (partial) alternative to Server Push,
which are going to be removed from Chrome:
https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/21anpFhxAQAJ

Being able to send this status code from servers implemented using Go would
help to see if implementing it in browsers is worth it.

Fixes #26089
Fixes #36734
Updates #26088

@google-cla google-cla bot added the cla: yes Used by googlebot to label PRs as having a valid CLA. The text of this label should not change. label Nov 13, 2020
@gopherbot
Copy link
Contributor

This PR (HEAD: 33505cb) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@gopherbot
Copy link
Contributor

Message from Brad Fitzpatrick:

Patch Set 1:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/269997.
After addressing review feedback, remember to publish your drafts!

@gopherbot
Copy link
Contributor

This PR (HEAD: 86d5d3e) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@gopherbot
Copy link
Contributor

This PR (HEAD: c33edb7) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@gopherbot
Copy link
Contributor

This PR (HEAD: 8979778) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@gopherbot
Copy link
Contributor

Message from Kévin Dunglas:

Patch Set 5:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/269997.
After addressing review feedback, remember to publish your drafts!

@gopherbot
Copy link
Contributor

Message from Brad Fitzpatrick:

Patch Set 5:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/269997.
After addressing review feedback, remember to publish your drafts!

@gopherbot
Copy link
Contributor

This PR (HEAD: 491d2db) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

dunglas added a commit to dunglas/quic-go that referenced this pull request Feb 17, 2021
Currently, it's not possible to send informational responses such as 103 Early Hints or 102 Processing.

This patch allows calling WriteHeader() multiple times in order to send informational responses before the final one.
It follows the patch for HTTP/1 (golang/go#42597) and HTTP/2 (golang/net#96).

In conformance with RFC 8297, if the status code is 103 the current content of the header map is also sent. Its content is not removed after the call to WriteHeader() because the headers must also be included in the final response.

The Chrome and Fastly teams are starting a large-scale experiment to measure the real-life impact of the 103 status code.
Using Early Hints is proposed as a (partial) alternative to Server Push, which are going to be removed from Chrome: https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/21anpFhxAQAJ

Being able to send this status code from servers implemented using Go would help to see if implementing it in browsers is worth it.
dunglas added a commit to dunglas/quic-go that referenced this pull request Feb 18, 2021
Currently, it's not possible to send informational responses such as 103 Early Hints or 102 Processing.

This patch allows calling WriteHeader() multiple times in order to send informational responses before the final one.
It follows the patch for HTTP/1 (golang/go#42597) and HTTP/2 (golang/net#96).

In conformance with RFC 8297, if the status code is 103 the current content of the header map is also sent. Its content is not removed after the call to WriteHeader() because the headers must also be included in the final response.

The Chrome and Fastly teams are starting a large-scale experiment to measure the real-life impact of the 103 status code.
Using Early Hints is proposed as a (partial) alternative to Server Push, which are going to be removed from Chrome: https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/21anpFhxAQAJ

Being able to send this status code from servers implemented using Go would help to see if implementing it in browsers is worth it.
marten-seemann pushed a commit to quic-go/quic-go that referenced this pull request Mar 5, 2021
Currently, it's not possible to send informational responses such as 103 Early Hints or 102 Processing.

This patch allows calling WriteHeader() multiple times in order to send informational responses before the final one.
It follows the patch for HTTP/1 (golang/go#42597) and HTTP/2 (golang/net#96).

In conformance with RFC 8297, if the status code is 103 the current content of the header map is also sent. Its content is not removed after the call to WriteHeader() because the headers must also be included in the final response.

The Chrome and Fastly teams are starting a large-scale experiment to measure the real-life impact of the 103 status code.
Using Early Hints is proposed as a (partial) alternative to Server Push, which are going to be removed from Chrome: https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/21anpFhxAQAJ

Being able to send this status code from servers implemented using Go would help to see if implementing it in browsers is worth it.
@gopherbot
Copy link
Contributor

This PR (HEAD: 81c6f3f) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@dunglas
Copy link
Contributor Author

dunglas commented Mar 5, 2021

Hi @bradfitz,

Is the tree open again? I improved the PR to flush headers as soon as possible and improved the documentation.
Also, a similar PR adding support for the 103 status code to the HTTP/3 implementation has been merged: quic-go/quic-go#3047

Cheers,

@gopherbot
Copy link
Contributor

This PR (HEAD: 57a11d5) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@gopherbot
Copy link
Contributor

This PR (HEAD: f32be5c) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@dunglas
Copy link
Contributor Author

dunglas commented Jul 16, 2021

Hi @bradfitz,

I replied to all your comments and rebased. Is there anything else I can do to get this patch merged?

Thanks!

@gopherbot
Copy link
Contributor

Message from Brad Fitzpatrick:

Patch Set 1:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/269997.
After addressing review feedback, remember to publish your drafts!

@gopherbot
Copy link
Contributor

Message from Kévin Dunglas:

Patch Set 5:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/269997.
After addressing review feedback, remember to publish your drafts!

@gopherbot
Copy link
Contributor

Message from Gopher Robot:

Patch Set 27: TryBot-Result+1

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/269997.
After addressing review feedback, remember to publish your drafts!

@gopherbot
Copy link
Contributor

Message from Damien Neil:

Patch Set 27:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/269997.
After addressing review feedback, remember to publish your drafts!

@dunglas dunglas force-pushed the feat/http-103-status-code branch from 65e065a to 06d749d Compare May 17, 2022 16:01
@gopherbot
Copy link
Contributor

This PR (HEAD: 06d749d) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/269997 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@gopherbot
Copy link
Contributor

Message from Kévin Dunglas:

Patch Set 29:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/269997.
After addressing review feedback, remember to publish your drafts!

gopherbot pushed a commit that referenced this pull request May 17, 2022
Currently, it's not possible to send informational responses such as
103 Early Hints or 102 Processing.

This patch allows calling WriteHeader() multiple times in order
to send informational responses before the final one.

If the status code is in the 1xx range, the current content of the header map
is also sent. Its content is not removed after the call to WriteHeader()
because the headers must also be included in the final response.

The Chrome and Fastly teams are starting a large-scale experiment to measure
the real-life impact of the 103 status code.
Using Early Hints is proposed as a (partial) alternative to Server Push,
which are going to be removed from Chrome:
https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/21anpFhxAQAJ

Being able to send this status code from servers implemented using Go would
help to see if implementing it in browsers is worth it.

Fixes #26089
Fixes #36734
Updates #26088

Change-Id: Ib7023c1892c35e8915d4305dd7f6373dbd00a19d
GitHub-Last-Rev: 06d749d
GitHub-Pull-Request: #42597
Reviewed-on: https://go-review.googlesource.com/c/go/+/269997
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
@gopherbot
Copy link
Contributor

This PR is being closed because golang.org/cl/269997 has been merged.

@gopherbot gopherbot closed this May 17, 2022
gopherbot pushed a commit to golang/net that referenced this pull request May 17, 2022
Content-Length and Transfer-Encoding must not be sent when the response
has no body.

Necessary to fix the tests of golang/go#42597.

Change-Id: Ibe90048bb122cc3ad1e04f8ebf9aa966b40489ae
GitHub-Last-Rev: 2605919
GitHub-Pull-Request: #134
Reviewed-on: https://go-review.googlesource.com/c/net/+/406494
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
dunglas added a commit to dunglas/go that referenced this pull request May 31, 2022
Support for 1xx responses has recently been merged in
net/http (golang#42597).

As discussed in this CL
(https://go-review.googlesource.com/c/go/+/269997/comments/1ff70bef_c25a829a),
support for forwarding 1xx responses in ReverseProxy has been extracted
in this separate patch.

According to RFC 7231, "a proxy MUST forward 1xx responses unless the
proxy itself requested the generation of the 1xx response".
Consequently, all received 1xx responses are automatically forwarded as long as the
underlying transport supports ClientTrace.Got1xxResponse.
dunglas added a commit to dunglas/go that referenced this pull request May 31, 2022
Support for 1xx responses has recently been merged in
net/http (golang#42597).

As discussed in this CL
(https://go-review.googlesource.com/c/go/+/269997/comments/1ff70bef_c25a829a),
support for forwarding 1xx responses in ReverseProxy has been extracted
in this separate patch.

According to RFC 7231, "a proxy MUST forward 1xx responses unless the
proxy itself requested the generation of the 1xx response".
Consequently, all received 1xx responses are automatically forwarded as long as the
underlying transport supports ClientTrace.Got1xxResponse.

Fixes golang#26088
Fixes golang#36734
dunglas added a commit to dunglas/go that referenced this pull request May 31, 2022
Support for 1xx responses has recently been merged in
net/http (golang#42597).

As discussed in this CL
(https://go-review.googlesource.com/c/go/+/269997/comments/1ff70bef_c25a829a),
support for forwarding 1xx responses in ReverseProxy has been extracted
in this separate patch.

According to RFC 7231, "a proxy MUST forward 1xx responses unless the
proxy itself requested the generation of the 1xx response".
Consequently, all received 1xx responses are automatically forwarded as long as the
underlying transport supports ClientTrace.Got1xxResponse.

Fixes golang#26088
Fixes golang#36734
dunglas added a commit to dunglas/go that referenced this pull request May 31, 2022
Support for 1xx responses has recently been merged in
net/http (golang#42597).

As discussed in this CL
(https://go-review.googlesource.com/c/go/+/269997/comments/1ff70bef_c25a829a),
support for forwarding 1xx responses in ReverseProxy has been extracted
in this separate patch.

According to RFC 7231, "a proxy MUST forward 1xx responses unless the
proxy itself requested the generation of the 1xx response".
Consequently, all received 1xx responses are automatically forwarded as long as the
underlying transport supports ClientTrace.Got1xxResponse.

Fixes golang#26088
Fixes golang#51914
dteh pushed a commit to dteh/fhttp that referenced this pull request Jun 10, 2022
Currently, it's not possible to send informational responses such as
103 Early Hints or 102 Processing.

This patch allows calling WriteHeader() multiple times in order
to send informational responses before the final one.

If the status code is in the 1xx range, the current content of the header map
is also sent. Its content is not removed after the call to WriteHeader()
because the headers must also be included in the final response.

The Chrome and Fastly teams are starting a large-scale experiment to measure
the real-life impact of the 103 status code.
Using Early Hints is proposed as a (partial) alternative to Server Push,
which are going to be removed from Chrome:
https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/21anpFhxAQAJ

Being able to send this status code from servers implemented using Go would
help to see if implementing it in browsers is worth it.

Fixes #26089
Fixes #36734
Updates #26088

Change-Id: Ib7023c1892c35e8915d4305dd7f6373dbd00a19d
GitHub-Last-Rev: 06d749d3454aa35c177a50ce4a25715df21fd742
GitHub-Pull-Request: golang/go#42597
Reviewed-on: https://go-review.googlesource.com/c/go/+/269997
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
dteh pushed a commit to dteh/fhttp that referenced this pull request Jun 22, 2022
Content-Length and Transfer-Encoding must not be sent when the response
has no body.

Necessary to fix the tests of golang/go#42597.

Change-Id: Ibe90048bb122cc3ad1e04f8ebf9aa966b40489ae
GitHub-Last-Rev: 2605919859d0b6b4b5d41da68c8bc3efddea4cbf
GitHub-Pull-Request: golang/net#134
Reviewed-on: https://go-review.googlesource.com/c/net/+/406494
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
dunglas added a commit to dunglas/go that referenced this pull request Jul 12, 2022
Support for 1xx responses has recently been merged in
net/http (golang#42597).

As discussed in this CL
(https://go-review.googlesource.com/c/go/+/269997/comments/1ff70bef_c25a829a),
support for forwarding 1xx responses in ReverseProxy has been extracted
in this separate patch.

According to RFC 7231, "a proxy MUST forward 1xx responses unless the
proxy itself requested the generation of the 1xx response".
Consequently, all received 1xx responses are automatically forwarded as long as the
underlying transport supports ClientTrace.Got1xxResponse.

Fixes golang#26088
Fixes golang#51914
dunglas added a commit to dunglas/go that referenced this pull request Aug 8, 2022
Support for 1xx responses has recently been merged in
net/http (golang#42597).

As discussed in this CL
(https://go-review.googlesource.com/c/go/+/269997/comments/1ff70bef_c25a829a),
support for forwarding 1xx responses in ReverseProxy has been extracted
in this separate patch.

According to RFC 7231, "a proxy MUST forward 1xx responses unless the
proxy itself requested the generation of the 1xx response".
Consequently, all received 1xx responses are automatically forwarded as long as the
underlying transport supports ClientTrace.Got1xxResponse.

Fixes golang#26088
Fixes golang#51914
dunglas added a commit to dunglas/go that referenced this pull request Aug 30, 2022
Support for 1xx responses has recently been merged in
net/http (golang#42597).

As discussed in this CL
(https://go-review.googlesource.com/c/go/+/269997/comments/1ff70bef_c25a829a),
support for forwarding 1xx responses in ReverseProxy has been extracted
in this separate patch.

According to RFC 7231, "a proxy MUST forward 1xx responses unless the
proxy itself requested the generation of the 1xx response".
Consequently, all received 1xx responses are automatically forwarded as long as the
underlying transport supports ClientTrace.Got1xxResponse.

Fixes golang#26088
Fixes golang#51914
WeiminShang added a commit to WeiminShang/net that referenced this pull request Nov 16, 2022
Content-Length and Transfer-Encoding must not be sent when the response
has no body.

Necessary to fix the tests of golang/go#42597.

Change-Id: Ibe90048bb122cc3ad1e04f8ebf9aa966b40489ae
GitHub-Last-Rev: 2605919859d0b6b4b5d41da68c8bc3efddea4cbf
GitHub-Pull-Request: golang/net#134
Reviewed-on: https://go-review.googlesource.com/c/net/+/406494
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
nicolas-grekas added a commit to symfony/symfony that referenced this pull request Mar 13, 2023
…Early Hints) and other 1XX statuses (dunglas)

This PR was squashed before being merged into the 6.3 branch.

Discussion
----------

[HttpFoundation] Add support for the 103 status code (Early Hints) and other 1XX statuses

| Q             | A
| ------------- | ---
| Branch?       | 6.3
| Bug fix?      | no
| New feature?  | yes <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | yes <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | n/a <!-- prefix each issue number with "Fix #", no need to create an issue if none exists, explain below instead -->
| License       | MIT
| Doc PR        | todo

This patch adds support for sending informational responses, including [Early Hints responses](https://developer.chrome.com/blog/early-hints/) if supported by the SAPI. It also allows sending other informational status codes such as 102 Processing.

According to [Shopify](https://twitter.com/colinbendell/status/1539322190541295616) and [Cloudflare](http://blog.cloudflare.com/early-hints-performance), using Early Hints, the performance improvement to the Largest Contentful Paint can go from several hundred milliseconds, and up to a second faster.

Usage:

```php
<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\WebLink\Link;

class HomepageController extends AbstractController
{
    #[Route("/", name: "homepage")]
    public function index(): Response
    {
        $response = $this->sendEarlyHints([
            (new Link(href: '/style.css'))->withAttribute('as', 'stylesheet'),
            (new Link(href: '/script.js'))->withAttribute('as', 'script'),
        ]);

        // Do something slow...

        return $this->render('homepage/index.html.twig', response: $response);
    }
}
```

With this patch, HttpFoundation will leverage the `headers_send()` function provided by [FrankenPHP](https://frankenphp.dev). FrankenPHP is currently the only SAPI supporting Early Hints, but other SAPI such as mod_apache will probably implement this function at some point: php/php-src#7025 (comment)

The low-level API is similar to the one provided by Go: golang/go#42597
The high-level API helper in `AbstractController` is similar to Node's one: nodejs/node#44180

Commits
-------

5be52b2 [HttpFoundation] Add support for the 103 status code (Early Hints) and other 1XX statuses
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Used by googlebot to label PRs as having a valid CLA. The text of this label should not change.
Projects
None yet
6 participants