-
Notifications
You must be signed in to change notification settings - Fork 30k
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 http.createStaticServer
#45096
base: main
Are you sure you want to change the base?
Conversation
doc/api/http.md
Outdated
node -r node:http/server # starts serving the cwd on a random port | ||
|
||
# To start serving on the port 8080 using /path/to/dir as the root: | ||
node -r node:http/server /path/to/dir --port 8080 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really a fan of building in a preload like this. Someone can easily use the -pe
syntax to achieve this if they wanted, e.g. node -pe "require('http').createStaticServer(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One reason to use -r
is you can get autocomplete when selecting the root directory, and it's easier to offer shorter versions of flags (i.e. I'd rather type node -r http/server . -p 8080 -h 0.0.0.0
than node -e 'http.createStaticServer({port: 8080, host: '0.0.0.0'})'
). Currently this PR offers both syntax, so I guess I should also document that, and folks can chose the syntax they prefer, wdyt?
lib/http/server.js
Outdated
|
||
emitExperimentalWarning('http/server'); | ||
|
||
if (module.isPreloading) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is dangerous. If someone has their own preload module and happens to require('http/server')
within it, this part will be run while they may not expect it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs tests.
I would also recommend we implement:
- partial responses (Ranges)
- conditional-GET negotiation (If-Match, If-Unmodified-Since, If-None-Match, If-Modified-Since) - this includes etag generation.
It's not necessary that those are implemented now, however we should note those are not implemented in the docs.
lib/http/server.js
Outdated
stream.on('error', reject); | ||
stream.on('close', resolve); | ||
stream.pipe(res); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should use stream.pipeline
instead if this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pipeline
implementation seems overly complicated in comparison of what's needed here (we don't need any AbortSignal
support, etc.), and tries to do more that we want (i.e. it closes the request in case of error before we can send a 404 status).
Tests have been added, this is ready for reviews. There's a discussion regarding the name of the module ( |
There are a few CI failures that need to be taken care of in separate PRs, converting this one back to draft. |
lib/http/static.js
Outdated
const { validateFunction, validatePort } = require('internal/validators'); | ||
|
||
if (module.isPreloading) { | ||
const requiredModules = getOptionValue('--require'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still very much not a fan of building preload into this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep in mind, for instance, that -r is permitted in the NODE_OPTIONS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have in mind what changes we would want to bring before we're happy with this pattern? Or do you think the pattern itself is undesirable? Personally I quite like the UX of it, and I think it's better than coming up with another built-in flag, but I'm happy to withdraw it if I'm in the minority.
@mcollina are you still blocking this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Co-authored-by: Michaël Zasso <targos@protonmail.com> Co-authored-by: Tobias Nießen <tniessen@tnie.de>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking comments, just things to make it a little bit faster.
|
||
try { | ||
try { | ||
const stream = createReadStream(url, { emitClose: false }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know is a nitpick but I think you can cache this object to avoid creating every time.
Also, maybe expose the highWaterMark
to the user configure is a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand what you mean, do you mean cache the stream? We're going to need a different stream for each request, I think, so I don't see how it'd be useful 🤔 could you send an example maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caching { emitClose: false }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
The
notable-change
Please suggest a text for the release notes if you'd like to include a more detailed summary, then proceed to update the PR description with the text or a link to the notable change suggested text comment. Otherwise, the commit will be placed in the Other Notable Changes section. |
Should there be a note about security in the docs? Specifically, I am wondering what would constitute a vulnerability here. |
@aduh95 heads up, please update the usage example in the body so that releasers & other collaborators can potentially refer to it. |
This PR adds a small utility to spawns a really simple HTTP 1.1 server to serve a local directory. The server is not meant to be secure or extremely performant, it's meant to be minimal and a useful replacement for
python -m http.server
. This should never be used in production of course.Usage:
Semver-major if we want to release it without requiring thenode:
prefix.EDIT: I've removed the
node:http/static
module from this PR, it can be discussed in a separate PR.Fixes: #45079