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

http: add writeEarlyHints function to ServerResponse #44180

Merged
merged 6 commits into from
Aug 17, 2022

Conversation

wingleung
Copy link
Contributor

@wingleung wingleung commented Aug 8, 2022

Similar to the writeContinue and writeProcessing functions, we could introduce a writeEarlyHints function where we could write the early hints response in a slightly friendlier way

response._writeRaw('HTTP/1.1 103 Early Hints\r\nLink: <\/styles.css>; rel=preload; as=style\r\n\r\n', 'ascii')

would become

response.writeEarlyHints('</styles.css>; rel=preload; as=style')

// or in case of multiple links
response.writeEarlyHints(
  [
    '</globals.css>; rel=preload; as=style',
    '</styles.css>; rel=preload; as=style'
  ]
)

Problem: multiple headers

_writeRaw() cannot be used with multiple headers so I folded the headers into one line.

Link: </styles.css>; rel=preload; as=style, </scripts.js>; rel=preload; as=script

an alternative way to write this is the following

  this._writeRaw('HTTP/1.1 103 Early Hints\r\n', 'ascii');
  this._writeRaw('Link: </styles.css>; rel=preload; as=style\r\n', 'ascii');
  this._writeRaw('Link: </scripts.js>; rel=preload; as=script\r\n\r\n', 'ascii');

however, this also folds into a oneliner, so I think prefolding it before calling _writeRaw() just once was better.

The problem is these folded headers may work now but could become deprecated in future http releases. So maybe I should just write _writeRaw() multiple times and look into unfolding or prevent the folding of the sent header elsewhere 🤔

thoughts?

Resources

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/http
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run. labels Aug 8, 2022
@wingleung wingleung changed the title introduce writeEarlyHints function to ServerResponse src: add writeEarlyHints function to ServerResponse Aug 8, 2022
@wingleung wingleung force-pushed the add-writeEarlyHints-function branch from 9c87898 to 3c6b924 Compare August 8, 2022 18:37
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, solid work. It seems Chrome supports them now:

https://developer.chrome.com/blog/early-hints/

Could you add them to HTTP/2 too? Or it would be better to do it in a follow-up PR?

@mcollina mcollina added request-ci Add this label to start a Jenkins CI on a PR. semver-minor PRs that contain new features and should be released in the next minor version. labels Aug 8, 2022
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 8, 2022
@nodejs-github-bot
Copy link
Collaborator

doc/api/http.md Outdated Show resolved Hide resolved
doc/api/http.md Outdated Show resolved Hide resolved
Copy link
Contributor

@ShogunPanda ShogunPanda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@wingleung
Copy link
Contributor Author

lgtm, solid work. It seems Chrome supports them now:

https://developer.chrome.com/blog/early-hints/

Could you add them to HTTP/2 too? Or it would be better to do it in a follow-up PR?

@mcollina good idea! I'll have to look into the http2 implementation first, I haven't read up on how the stream internals work exactly, first thought is to add it here but I'm not sure yet how it would work in a stream. Will have another look

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should happen if the array is empty? Could you add a test for this case?

lib/_http_server.js Outdated Show resolved Hide resolved
lib/internal/validators.js Outdated Show resolved Hide resolved
test/parallel/test-http-early-hints-multiple-links.js Outdated Show resolved Hide resolved
test/parallel/test-http-early-hints.js Outdated Show resolved Hide resolved
@LiviaMedeiros LiviaMedeiros changed the title src: add writeEarlyHints function to ServerResponse http: add writeEarlyHints function to ServerResponse Aug 9, 2022
@mscdex
Copy link
Contributor

mscdex commented Aug 9, 2022

Also what should happen when neither a string nor array is passed in? Is a 103 without headers permitted? Should we throw an exception? Either way we should also add tests for other value types.

@wingleung
Copy link
Contributor Author

wingleung commented Aug 9, 2022

Also what should happen when neither a string nor array is passed in? Is a 103 without headers permitted? Should we throw an exception? Either way we should also add tests for other value types.

@mscdex I added an else clause that will throw an ERR_INVALID_ARG_VALUE exception if it's not a string or an array. test case 👉 test/parallel/test-http-early-hints-invalid-argument.js

wdyt?

@wingleung
Copy link
Contributor Author

wingleung commented Aug 9, 2022

What should happen if the array is empty? Could you add a test for this case?

@mcollina I think there will be scenarios where we want to create a links variable, do some manipulations on that based on the resource content and then pass it on to writeEarlyHints(), so if we would have content that results in an empty array then I think we can be graceful with it and just do nothing.

As opposed to invalid types like objects (what @mscdex mentioned ☝️ ), I think that's more of a programmatic error so in that case I'm throwing ERR_INVALID_ARG_VALUE

wdyt?

Added test cases

lib/internal/validators.js Outdated Show resolved Hide resolved
@mscdex
Copy link
Contributor

mscdex commented Aug 9, 2022

minor nit: perhaps we could consolidate the tests into one file for this new feature?

Additionally we should test that the function throws when it should.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@wingleung
Copy link
Contributor Author

minor nit: perhaps we could consolidate the tests into one file for this new feature?

Additionally we should test that the function throws when it should.

@mscdex because the invalid argument test throws an exception where I process.exit(0) afterwards, the other test might fail. I can work around it by adding a timeout but I think it's more scalable if we separate the throwable tests to their dedicated files 🤔 I kept the 3 happy flow test in 1 file though

@LiviaMedeiros LiviaMedeiros added the commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. label Aug 10, 2022
Copy link
Contributor

@LiviaMedeiros LiviaMedeiros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first commit in PR should start with affected sybsystem, which is http (src mostly refers to generic changes in C++ parts of code). This can be fixed by rebasing and force-pushing, or on landing stage.

lib/_http_server.js Outdated Show resolved Hide resolved
doc/api/http.md Show resolved Hide resolved
Fyko pushed a commit to Fyko/node that referenced this pull request Sep 15, 2022
Co-Authored-By: Matteo Collina <[email protected]>
Co-Authored-By: Livia Medeiros <[email protected]>
PR-URL: nodejs#44180
Reviewed-By: Robert Nagy <[email protected]>
Reviewed-By: Paolo Insogna <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: LiviaMedeiros <[email protected]>
RafaelGSS added a commit that referenced this pull request Oct 4, 2022
Notable Changes:

cli:
  * (SEMVER-MINOR) add `--watch` (Moshe Atlow) #44366
esm:
  * remove specifier resolution flag (Geoffrey Booth) #44859
  * convert `resolve` hook to synchronous (Jacob Smith) #43363
http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing) #44180
  * (SEMVER-MAJOR) use Keep-Alive by default in global agents (Paolo Insogna) #43522
build:
  * (SEMVER-MAJOR) remove dtrace & etw support (Ben Noordhuis) #43652
  * (SEMVER-MAJOR) remove systemtap support (Ben Noordhuis) #43651

Deprecation and Removals:

* (SEMVER-MAJOR) runtime deprecate exports double slash maps (Guy Bedford) #44495

Semver-Major Commits:

* [aa3a572] - (SEMVER-MAJOR) build: remove dtrace & etw support (Ben Noordhuis) #43652
* [38f1e27] - (SEMVER-MAJOR) build: remove systemtap support (Ben Noordhuis) #43651
* [2849283] - (SEMVER-MAJOR) crypto: remove non-standard `webcrypto.Crypto.prototype.CryptoKey` (Antoine du Hamel) #42083
* [a1653ac] - (SEMVER-MAJOR) crypto: do not allow to call setFips from the worker thread (Sergey Petushkov) #43624
* [a4fa526] - (SEMVER-MAJOR) fs: add directory autodetection to fsPromises.symlink() (Livia Medeiros) #42894
* [bb4891d] - (SEMVER-MAJOR) fs: add validateBuffer to improve error (Hirotaka Tagawa / wafuwafu13) #44769
* [950a441] - (SEMVER-MAJOR) fs: remove coercion to string in writing methods (Livia Medeiros) #42796
* [41a6d82] - (SEMVER-MAJOR) fs: harden fs.readSync(buffer, options) typecheck (LiviaMedeiros) #42772
* [2275faa] - (SEMVER-MAJOR) fs: harden fs.read(params, callback) typecheck (LiviaMedeiros) #42772
* [29953a0] - (SEMVER-MAJOR) fs: harden filehandle.read(params) typecheck (LiviaMedeiros) #42772
* [4267b92] - (SEMVER-MAJOR) http: use Keep-Alive by default in global agents (Paolo Insogna) #43522
* [f529f73] - (SEMVER-MAJOR) lib: brand check event handler property receivers (Chengzhong Wu) #44483
* [6de2673] - (SEMVER-MAJOR) lib: enable global WebCrypto by default (Antoine du Hamel) #42083
* [73ba883] - (SEMVER-MAJOR) lib: use private field in AbortController (Joyee Cheung) #43820
* [7dd2f41] - (SEMVER-MAJOR) module: runtime deprecate exports double slash maps (Guy Bedford) #44495
* [587367d] - (SEMVER-MAJOR) perf_hooks: expose webperf global scope interfaces (Chengzhong Wu) #44483
* [364c0e1] - (SEMVER-MAJOR) perf_hooks: fix webperf idlharness (Chengzhong Wu) #44483
* [e0ab8dd] - (SEMVER-MAJOR) process: make process.config read only (Sergey Petushkov) #43627
* [481a959] - (SEMVER-MAJOR) readline: remove `question` method from `InterfaceConstructor` (Antoine du Hamel) #44606
* [77e5856] - (SEMVER-MAJOR) src: turn embedder api overload into default argument (Alena Khineika) #43629
* [dabda03] - (SEMVER-MAJOR) src: per-environment time origin value (Chengzhong Wu) #43781
* [2b32985] - (SEMVER-MAJOR) stream: use null for the error argument (Luigi Pinca) #44312
* [57ff476] - (SEMVER-MAJOR) test: remove duplicate test (Luigi Pinca) #44051
* [77def91] - (SEMVER-MAJOR) tls,http2: send fatal alert on ALPN mismatch (Tobias Nießen) #44031

PR-URL: #44626
Co-authored-by: Ruy Adorno <[email protected]>
@mcollina
Copy link
Member

mcollina commented Oct 6, 2022

This PR must be backported / released together with #44820.

cc @nodejs/releasers

@mcollina mcollina removed dont-land-on-v18.x PRs that should not land on the v18.x-staging branch and should not be released in v18.x. dont-land-on-v19.x labels Oct 6, 2022
danielleadams pushed a commit that referenced this pull request Oct 11, 2022
Co-Authored-By: Matteo Collina <[email protected]>
Co-Authored-By: Livia Medeiros <[email protected]>
PR-URL: #44180
Reviewed-By: Robert Nagy <[email protected]>
Reviewed-By: Paolo Insogna <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: LiviaMedeiros <[email protected]>
danielleadams added a commit that referenced this pull request Oct 11, 2022
Notable changes:

* cli:
  * (SEMVER-MINOR) add `--watch` (Moshe Atlow) #44366
* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel) #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing) #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon) #44631
danielleadams added a commit that referenced this pull request Oct 11, 2022
Notable changes:

* cli:
  * (SEMVER-MINOR) add `--watch` (Moshe Atlow) #44366
* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel) #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing) #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon) #44631

PR-URL: #44968
danielleadams added a commit that referenced this pull request Oct 11, 2022
Notable changes:

* cli:
  * (SEMVER-MINOR) add `--watch` (Moshe Atlow) #44366
* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel)
  #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing)
  #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* lib:
  * (SEMVER-MINOR) refactor transferable AbortSignal (flakey5) #44048
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna
  Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon)
  #44631

PR-URL: #44968
RafaelGSS added a commit that referenced this pull request Oct 11, 2022
Notable Changes:

cli:
  * (SEMVER-MINOR) add `--watch` (Moshe Atlow) #44366
esm:
  * remove specifier resolution flag (Geoffrey Booth) #44859
  * convert `resolve` hook to synchronous (Jacob Smith) #43363
http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing) #44180
  * (SEMVER-MAJOR) use Keep-Alive by default in global agents (Paolo Insogna) #43522
build:
  * (SEMVER-MAJOR) remove dtrace & etw support (Ben Noordhuis) #43652
  * (SEMVER-MAJOR) remove systemtap support (Ben Noordhuis) #43651

Deprecation and Removals:

* (SEMVER-MAJOR) runtime deprecate exports double slash maps (Guy Bedford) #44495

Semver-Major Commits:

* [aa3a572] - (SEMVER-MAJOR) build: remove dtrace & etw support (Ben Noordhuis) #43652
* [38f1e27] - (SEMVER-MAJOR) build: remove systemtap support (Ben Noordhuis) #43651
* [2849283] - (SEMVER-MAJOR) crypto: remove non-standard `webcrypto.Crypto.prototype.CryptoKey` (Antoine du Hamel) #42083
* [a1653ac] - (SEMVER-MAJOR) crypto: do not allow to call setFips from the worker thread (Sergey Petushkov) #43624
* [a4fa526] - (SEMVER-MAJOR) fs: add directory autodetection to fsPromises.symlink() (Livia Medeiros) #42894
* [bb4891d] - (SEMVER-MAJOR) fs: add validateBuffer to improve error (Hirotaka Tagawa / wafuwafu13) #44769
* [950a441] - (SEMVER-MAJOR) fs: remove coercion to string in writing methods (Livia Medeiros) #42796
* [41a6d82] - (SEMVER-MAJOR) fs: harden fs.readSync(buffer, options) typecheck (LiviaMedeiros) #42772
* [2275faa] - (SEMVER-MAJOR) fs: harden fs.read(params, callback) typecheck (LiviaMedeiros) #42772
* [29953a0] - (SEMVER-MAJOR) fs: harden filehandle.read(params) typecheck (LiviaMedeiros) #42772
* [4267b92] - (SEMVER-MAJOR) http: use Keep-Alive by default in global agents (Paolo Insogna) #43522
* [f529f73] - (SEMVER-MAJOR) lib: brand check event handler property receivers (Chengzhong Wu) #44483
* [6de2673] - (SEMVER-MAJOR) lib: enable global WebCrypto by default (Antoine du Hamel) #42083
* [73ba883] - (SEMVER-MAJOR) lib: use private field in AbortController (Joyee Cheung) #43820
* [7dd2f41] - (SEMVER-MAJOR) module: runtime deprecate exports double slash maps (Guy Bedford) #44495
* [587367d] - (SEMVER-MAJOR) perf_hooks: expose webperf global scope interfaces (Chengzhong Wu) #44483
* [364c0e1] - (SEMVER-MAJOR) perf_hooks: fix webperf idlharness (Chengzhong Wu) #44483
* [e0ab8dd] - (SEMVER-MAJOR) process: make process.config read only (Sergey Petushkov) #43627
* [481a959] - (SEMVER-MAJOR) readline: remove `question` method from `InterfaceConstructor` (Antoine du Hamel) #44606
* [77e5856] - (SEMVER-MAJOR) src: turn embedder api overload into default argument (Alena Khineika) #43629
* [dabda03] - (SEMVER-MAJOR) src: per-environment time origin value (Chengzhong Wu) #43781
* [2b32985] - (SEMVER-MAJOR) stream: use null for the error argument (Luigi Pinca) #44312
* [57ff476] - (SEMVER-MAJOR) test: remove duplicate test (Luigi Pinca) #44051
* [77def91] - (SEMVER-MAJOR) tls,http2: send fatal alert on ALPN mismatch (Tobias Nießen) #44031

PR-URL: #44626
Co-authored-by: Ruy Adorno <[email protected]>
danielleadams added a commit that referenced this pull request Oct 12, 2022
watch mode (experimental):

Running in 'watch' mode using `node --watch` restarts the process when an
imported file is changed.

Contributed by Moshe Atlow in [#44366](#44366)

Other notable changes:

* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel)
  #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing)
  #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* lib:
  * (SEMVER-MINOR) refactor transferable AbortSignal (flakey5) #44048
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna
  Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon)
  #44631

PR-URL: #44968
danielleadams added a commit that referenced this pull request Oct 12, 2022
watch mode (experimental):

Running in 'watch' mode using `node --watch` restarts the process when an
imported file is changed.

Contributed by Moshe Atlow in [#44366](#44366)

Other notable changes:

* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel)
  #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing)
  #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* lib:
  * (SEMVER-MINOR) refactor transferable AbortSignal (flakey5) #44048
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna
  Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon)
  #44631

PR-URL: #44968
danielleadams added a commit that referenced this pull request Oct 13, 2022
watch mode (experimental):

Running in 'watch' mode using `node --watch` restarts the process when an
imported file is changed.

Contributed by Moshe Atlow in [#44366](#44366)

Other notable changes:

* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel)
  #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing)
  #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* lib:
  * (SEMVER-MINOR) refactor transferable AbortSignal (flakey5) #44048
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna
  Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon)
  #44631

PR-URL: #44968
danielleadams added a commit that referenced this pull request Oct 13, 2022
watch mode (experimental):

Running in 'watch' mode using `node --watch` restarts the process when an
imported file is changed.

Contributed by Moshe Atlow in [#44366](#44366)

Other notable changes:

* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel)
  #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing)
  #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* lib:
  * (SEMVER-MINOR) refactor transferable AbortSignal (flakey5) #44048
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna
  Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon)
  #44631

PR-URL: #44968
danielleadams added a commit that referenced this pull request Oct 13, 2022
watch mode (experimental):

Running in 'watch' mode using `node --watch` restarts the process when an
imported file is changed.

Contributed by Moshe Atlow in #44366

Other notable changes:

* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel)
  #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing)
  #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* lib:
  * (SEMVER-MINOR) refactor transferable AbortSignal (flakey5) #44048
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna
  Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon)
  #44631

PR-URL: #44968
danielleadams added a commit that referenced this pull request Oct 13, 2022
watch mode (experimental):

Running in 'watch' mode using `node --watch` restarts the process when an
imported file is changed.

Contributed by Moshe Atlow in #44366

Other notable changes:

* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel)
  #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing)
  #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* lib:
  * (SEMVER-MINOR) refactor transferable AbortSignal (flakey5) #44048
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna
  Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon)
  #44631

PR-URL: #44968
danielleadams added a commit that referenced this pull request Oct 13, 2022
watch mode (experimental):

Running in 'watch' mode using `node --watch` restarts the process when an
imported file is changed.

Contributed by Moshe Atlow in #44366

Other notable changes:

* fs:
  * (SEMVER-MINOR) add `FileHandle.prototype.readLines` (Antoine du Hamel)
  #42590
* http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing)
  #44180
* http2:
  * (SEMVER-MINOR) make early hints generic (Yagiz Nizipli) #44820
* lib:
  * (SEMVER-MINOR) refactor transferable AbortSignal (flakey5) #44048
* src:
  * (SEMVER-MINOR) add detailed embedder process initialization API (Anna
  Henningsen) #44121
* util:
  * (SEMVER-MINOR) add default value option to parsearg (Manuel Spigolon)
  #44631

PR-URL: #44968
RafaelGSS added a commit that referenced this pull request Oct 14, 2022
Notable Changes:

cli:
  * (SEMVER-MINOR) add `--watch` (Moshe Atlow) #44366
esm:
  * remove specifier resolution flag (Geoffrey Booth) #44859
  * convert `resolve` hook to synchronous (Jacob Smith) #43363
http:
  * (SEMVER-MINOR) add writeEarlyHints function to ServerResponse (Wing) #44180
  * (SEMVER-MAJOR) use Keep-Alive by default in global agents (Paolo Insogna) #43522
build:
  * (SEMVER-MAJOR) remove dtrace & etw support (Ben Noordhuis) #43652
  * (SEMVER-MAJOR) remove systemtap support (Ben Noordhuis) #43651

Deprecation and Removals:

* (SEMVER-MAJOR) runtime deprecate exports double slash maps (Guy Bedford) #44495

Semver-Major Commits:

* [aa3a572] - (SEMVER-MAJOR) build: remove dtrace & etw support (Ben Noordhuis) #43652
* [38f1e27] - (SEMVER-MAJOR) build: remove systemtap support (Ben Noordhuis) #43651
* [2849283] - (SEMVER-MAJOR) crypto: remove non-standard `webcrypto.Crypto.prototype.CryptoKey` (Antoine du Hamel) #42083
* [a1653ac] - (SEMVER-MAJOR) crypto: do not allow to call setFips from the worker thread (Sergey Petushkov) #43624
* [a4fa526] - (SEMVER-MAJOR) fs: add directory autodetection to fsPromises.symlink() (Livia Medeiros) #42894
* [bb4891d] - (SEMVER-MAJOR) fs: add validateBuffer to improve error (Hirotaka Tagawa / wafuwafu13) #44769
* [950a441] - (SEMVER-MAJOR) fs: remove coercion to string in writing methods (Livia Medeiros) #42796
* [41a6d82] - (SEMVER-MAJOR) fs: harden fs.readSync(buffer, options) typecheck (LiviaMedeiros) #42772
* [2275faa] - (SEMVER-MAJOR) fs: harden fs.read(params, callback) typecheck (LiviaMedeiros) #42772
* [29953a0] - (SEMVER-MAJOR) fs: harden filehandle.read(params) typecheck (LiviaMedeiros) #42772
* [4267b92] - (SEMVER-MAJOR) http: use Keep-Alive by default in global agents (Paolo Insogna) #43522
* [f529f73] - (SEMVER-MAJOR) lib: brand check event handler property receivers (Chengzhong Wu) #44483
* [6de2673] - (SEMVER-MAJOR) lib: enable global WebCrypto by default (Antoine du Hamel) #42083
* [73ba883] - (SEMVER-MAJOR) lib: use private field in AbortController (Joyee Cheung) #43820
* [7dd2f41] - (SEMVER-MAJOR) module: runtime deprecate exports double slash maps (Guy Bedford) #44495
* [587367d] - (SEMVER-MAJOR) perf_hooks: expose webperf global scope interfaces (Chengzhong Wu) #44483
* [364c0e1] - (SEMVER-MAJOR) perf_hooks: fix webperf idlharness (Chengzhong Wu) #44483
* [e0ab8dd] - (SEMVER-MAJOR) process: make process.config read only (Sergey Petushkov) #43627
* [481a959] - (SEMVER-MAJOR) readline: remove `question` method from `InterfaceConstructor` (Antoine du Hamel) #44606
* [77e5856] - (SEMVER-MAJOR) src: turn embedder api overload into default argument (Alena Khineika) #43629
* [dabda03] - (SEMVER-MAJOR) src: per-environment time origin value (Chengzhong Wu) #43781
* [2b32985] - (SEMVER-MAJOR) stream: use null for the error argument (Luigi Pinca) #44312
* [57ff476] - (SEMVER-MAJOR) test: remove duplicate test (Luigi Pinca) #44051
* [77def91] - (SEMVER-MAJOR) tls,http2: send fatal alert on ALPN mismatch (Tobias Nießen) #44031

PR-URL: #44626
Co-authored-by: Ruy Adorno <[email protected]>
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
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run. notable-change PRs with changes that should be highlighted in changelogs. semver-minor PRs that contain new features and should be released in the next minor version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.