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

feat: Implement a way to expose static files from a directory (similar to Python SimpleHttpServer) #45079

Open
ErickWendel opened this issue Oct 19, 2022 · 25 comments · May be fixed by #45096
Open
Assignees
Labels
feature request Issues that request new features to be added to Node.js. never-stale Mark issue so that it is never considered stale tools Issues and PRs related to the tools directory.

Comments

@ErickWendel
Copy link
Member

ErickWendel commented Oct 19, 2022

What is the problem this feature will solve?

HTTP Server is a very popular package with 1M+ weekly downloads used to expose static files from a directory.

Node.js doesn't have any native way to expose static files in a directory from a single command.

This is an idea given by @ruyadorno during a session on Tooling WG at nodejs/tooling#164 which he suggested I implement it.

What is the feature you are proposing to solve the problem?

In Python, they have the SimpleHTTPServer a native module meant for the development environment and has basic security checks.

The idea is not to replace the HTTP Server package, as it's a robust package, but to have a similar implementation to Python's SimpleHTTPServer exposing directory files.

Adding something like:

node --serve directory -p 3000

or

node --serve . 
#with a default port

What alternatives have you considered?

No response

@ErickWendel ErickWendel added the feature request Issues that request new features to be added to Node.js. label Oct 19, 2022
@ErickWendel ErickWendel changed the title feat: Implement SimpleHttp server (similar to Python SimpleHttp) feat: Implement a way to expose static files from a directory (similar to Python SimpleHttpServer) Oct 19, 2022
@ErickWendel ErickWendel self-assigned this Oct 19, 2022
@ErickWendel ErickWendel added the tools Issues and PRs related to the tools directory. label Oct 19, 2022
@richardlau
Copy link
Member

FWIW we use the Python equivalent for the docserve target in our Makefile:

node/Makefile

Lines 835 to 837 in eb298df

.PHONY: docserve
docserve: $(apidocs_html) $(apiassets)
@$(PYTHON) -m http.server 8000 --bind 127.0.0.1 --directory out/doc/api

@ErickWendel
Copy link
Member Author

FWIW we use the Python equivalent for the docserve target in our Makefile:

node/Makefile

Lines 835 to 837 in eb298df

.PHONY: docserve
docserve: $(apidocs_html) $(apiassets)
@$(PYTHON) -m http.server 8000 --bind 127.0.0.1 --directory out/doc/api

Nice! this way we can move from Python and use Node only for it 🤩

@DominusKelvin
Copy link

This looks great. I'm interested in seeing how the implementation goes.

@Trott
Copy link
Member

Trott commented Oct 20, 2022

@nodejs/tsc @nodejs/http

@ShogunPanda
Copy link
Contributor

Same here, really interested in this. Let me know if I can help with the implementation.

@GeoffreyBooth
Copy link
Member

The maintainers of http-server should be consulted regarding this. It's considered impolite for Node to supplant a popular public package without doing outreach first.

@DominusKelvin
Copy link

DominusKelvin commented Oct 20, 2022

Good point at @GeoffreyBooth.

@ErickWendel how much overlap will there be with the http-server package as you mentioned the plan is not to replace it completely?

@mcollina
Copy link
Member

I don't think we should be implementing https://www.npmjs.com/package/http-server in core.
I believe that we should bring https://npm.im/send in and make it significantly faster, ideally with some parts implemented in C++ to bypass some of the problems.

@targos
Copy link
Member

targos commented Oct 20, 2022

I don't think we should be implementing https://www.npmjs.com/package/http-server in core.

You mean http-server specifically, or the feature it provides (a simple way to spawn a local file server)?
If it's the latter, why?

@mcollina
Copy link
Member

I think we should offer the functionality to serve static files in core, ideally with a superior implementation than send(). Serving files in JavaScript is highly inefficient.

@jasnell did some part of the work for http/2, however, it lacks quite a few features to be complete (etags, ranges, directories, etc).

We might also provide some utility that could enable us to do:

node -e "require('http').createStaticServe({ path: './static' }).listen(3000)"

I don't think we should offer a --serve flag because there are a lot of possible configuration options for a web server. Moreover, http-server offers additional features such as a full-blown reverse proxy. Those latter functionalities are pretty helpful and I do not think we should compete with the ecosystem on this.

@Trott
Copy link
Member

Trott commented Oct 20, 2022

Serving files in JavaScript is highly inefficient.
...
I don't think we should offer a --serve flag because there are a lot of possible configuration options for a web server.

What if we choose not to worry about configurability or efficiency? For example, what if it:

  • Only serves on localhost.
  • Is not configurable beyond specifying a port number and maybe a few other narrow and obvious things. It serves a directory, maybe knows about the usual relevant MIME types for file extensions, etc. No fiddling with keep-alive, TLS, etc. No reverse-proxy. And so on.
  • Is documented with a very big warning about how it is not a production-ready web server, is inefficient, insecure, for testing and development only, etc.,

Valid use cases would be:

  • I have built a static web site and want to look at it and/or test it locally before deploying it.
  • I have a docs directory that I want to look at in a web browser.
  • I want to set up a web server locally for a static directory so I can run a link checker locally.

Invalid use cases would be:

  • I want to serve a static directory to others in a production environment.
  • I need to test performance and efficiency using different server options.
  • I need a reverse-proxy.

@ErickWendel
Copy link
Member Author

ErickWendel commented Oct 20, 2022

Serving files in JavaScript is highly inefficient.
...
I don't think we should offer a --serve flag because there are a lot of possible configuration options for a web server.

What if we choose not to worry about configurability or efficiency? For example, what if it:

  • Only serves on localhost.
  • Is not configurable beyond specifying a port number and maybe a few other narrow and obvious things. It serves a directory, maybe knows about the usual relevant MIME types for file extensions, etc. No fiddling with keep-alive, TLS, etc. No reverse-proxy. And so on.
  • Is documented with a very big warning about how it is not a production-ready web server, is inefficient, insecure, for testing and development only, etc.,

Valid use cases would be:

  • I have built a static web site and want to look at it and/or test it locally before deploying it.
  • I have a docs directory that I want to look at in a web browser.
  • I want to set up a web server locally for a static directory so I can run a link checker locally.

Invalid use cases would be:

  • I want to serve a static directory to others in a production environment.
  • I need to test performance and efficiency using different server options.
  • I need a reverse-proxy.

That's exactly what I meant. Python's SimpleHTTPServer does the same. They have a big disclaimer saying that this module is just a util module for a development environment.

Edited by Trott to preserve formatting in quoted material.

@tniessen
Copy link
Member

HTTP Server is a very popular package with 1M+ weekly downloads used to expose static files from a directory.

Node.js doesn't have any native way to expose static files in a directory from a single command.

We've had this discussion before (even though I can't find it right now). I frequently use npx -y http-server myself and I don't know how much better (or worse) the experience would be if this was moved into core.

@aduh95
Copy link
Contributor

aduh95 commented Oct 20, 2022

We might also provide some utility that could enable us to do:

node -e "require('http').createStaticServe({ path: './static' }).listen(3000)"

I don't think we should offer a --serve flag because there are a lot of possible configuration options for a web server. Moreover, http-server offers additional features such as a full-blown reverse proxy. Those latter functionalities are pretty helpful and I do not think we should compete with the ecosystem on this.

Maybe node -r node:http/server would be a doable shortcut, I agree having a flag is not useful here. But then, we need to ask ourselves if it's really an improvement over npx -y http-server.

@targos
Copy link
Member

targos commented Oct 20, 2022

But then, we need to ask ourselves if it's really an improvement over npx -y http-server.

npx -y http-server installs 39 different packages. If nothing else, the improvement is less supply-chain security risk and no need for an internet connection.

@GeoffreyBooth
Copy link
Member

I believe that we should bring https://npm.im/send in and make it significantly faster, ideally with some parts implemented in C++ to bypass some of the problems.

I agree with this approach. One of the reasons to bring something into core is if the experience can be improved by having the feature in core. Implementing the serving in C++ would achieve that, because it's a hassle to work with packages that require compilation. I also think our goal should be something that could be used in production. The dev use case is already well handled by ecosystem packages that have more features than we're likely to want to add (hot module reload etc).

@jasnell
Copy link
Member

jasnell commented Oct 20, 2022

A key challenge is the fact that sending a file efficiently varies across http1, http2, and http3. A sendfile like approach only really works with http1, where we are capable of writing directly to the socket, or can rely on the kernel to efficiently send the data from an fd. For http2 and http3 the situation is a lot different. We have to rely on the underlying nghttp2 and nghttp3 state model to determine exactly how and when to send various chunks of the file. It can be made very efficient, yes, but there's not a one impl fits all approach that is going to work.

The suggestion of using something like node --serve directory -p 3000 just isn't going to be workable given the current situation unless we limit it specifically to http1 or http2.

I think before we do anything further here, we should work on finishing up landing the quic/http3 implementation, then work on normalizing the http1, 2, and 3 implementations as much as possible, identifying an API approach that will allow a consistent UX/DX for sending files.

@aduh95 aduh95 linked a pull request Oct 20, 2022 that will close this issue
@aduh95
Copy link
Contributor

aduh95 commented Oct 20, 2022

FWIW I have an HTTP 1.1 implementation in #45096.

@ruyadorno
Copy link
Member

I believe the syntax proposed in #45096 might solve the compat issue mentioned by @jasnell with regards to http2, http3 since these can be supported under diff modules.

While I would prefer seeing a C++ implementation with performance in mind as mentioned by @mcollina I'd be very much +1 to land an experimental JS implementation first and progress from there. Thanks @ErickWendel for bringing it up, it's great to see the momentum it managed to gather and would love to see that landing @aduh95 ❤️

@tniessen
Copy link
Member

+1 to planning for HTTP/2 and QUIC support ahead of time.

@ErickWendel
Copy link
Member Author

ErickWendel commented Oct 21, 2022

Well, as @aduh95 already implemented a draft I'll jump to something else.

@mcollina do you think it'll be worth it for me to start a draft implementing a better send and adding this utility function you mentioned?

node -e "require('http').createStaticServe({ path: './static' }).listen(3000)"

@mcollina
Copy link
Member

@mcollina do you think it'll be worth it for me to start a draft implementing a better send

I think this deserves its own issue. The goal for this is faster file sending in the native layer, as send is a good JS implementation already.

@github-actions
Copy link
Contributor

There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.

For more information on how the project manages feature requests, please consult the feature request management document.

@github-actions github-actions bot added the stale label Apr 21, 2023
@github-actions
Copy link
Contributor

There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.

For more information on how the project manages feature requests, please consult the feature request management document.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale May 21, 2023
@aduh95 aduh95 reopened this Apr 4, 2024
@github-actions github-actions bot removed the stale label Apr 5, 2024
Copy link
Contributor

github-actions bot commented Oct 2, 2024

There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the never-stale Mark issue so that it is never considered stale label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.

@github-actions github-actions bot added the stale label Oct 2, 2024
@ruyadorno ruyadorno added never-stale Mark issue so that it is never considered stale and removed stale labels Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js. never-stale Mark issue so that it is never considered stale tools Issues and PRs related to the tools directory.
Projects
Status: Awaiting Triage
Development

Successfully merging a pull request may close this issue.