OpenStack
OpenStack

Reputation: 5596

Creating a NodeJS based web server to take advantage of HTTP2 on windows platform

I am using windows 2012 server and want to host some static HTML/CSS/JS/image files on a nodejs based web server. I do not want to use IIS as I want to take advantages of HTTP2 & want to push files from server to client. I looked at Using node.js as a simple web server which talks about how to create a node based webserver. Another option is to use http-server node package.

My question is:

  1. These solutions are over two year old. Do we have a better option available now?
  2. Does any of these two options supports HTTP2?

I would prefer using a existing node module rather then reinventing the wheel.

Upvotes: 1

Views: 423

Answers (3)

robbie-mac
robbie-mac

Reputation: 1

I know this is a fairly old question, but I thought I would give an answer for those that come here looking for info.

Node now has a native http2 module and there are some examples on the web that show exactly how to implement a static web server.

NOTE: At the time of this answer Node 9.6.1 is current and the native module is still experimental

Example https://dexecure.com/blog/how-to-create-http2-static-file-server-nodejs-with-examples/

NOTE: I have no affiliation to the author of the example

Upvotes: 0

Barry Pollard
Barry Pollard

Reputation: 46040

If you want to use Node then this article seems to cover the basics: https://webapplog.com/http2-server-push-node-express/ and it seems the node-spdy module is the best option (it includes support for HTTP/2 despite the name). There is a node-http2 module but it seems much less well maintained and doesn't support Express (the most popular HTTP framework for Node).

However, as discussed in the comments, while not the question you asked, I recommend running a traditional web server (e.g. Apache, Nginx or IIS) in front of NodeJS or any other traditionally back end server. While NodeJS is very flexible and most (if not all) of the functionality of a webserver can be added to it, a traditional web server comes out of the box with a lot of functionality and requires just configuration rather than programming and/or pulling in multiple other modules to set it up properly.

For just serving static files Node seems the wrong solution to me so, for the rest of my answer I'll discuss not not using Node directly for the reasons given above but instead using a front end webserver.

I don't know IIS too well but from a quick Google it seems HTTP/2 was only introduced in IIS 10 and, as far as I know, even IIS 10 doesn't support Push except through API calls so I agree with your decision not to use that for now.

Nginx could be installed instead of IIS, as suggested, and while it supports HTTP/2 it doesn't yet support HTTP/2 (though Cloudflare have added it and run on Nginx so imagine it won't be long coming).

Apache fully supports HTTP/2 including server push. Packaged windows versions of Apache can be downloaded from Apache Lounge so is probably the easiest way of supporting HTTP/2 push on Windows Server and would be my recommendation for the scenario you've given.

While I mostly use Apache on Linux boxes I've a number of servers on Windows and have quite happily been running Apache on that as a Service (so it automatically restarts on server reboot) with no issues so not sure what "bad experience" you had previously but it really is quite stable to me.

To set up Apache on a Windows Server use the following steps:

  1. Download the last version from Apache Lounge.
  2. Unzip the files and save them to C:\ (or C:\Program Files\ if you prefer but update all the config to change the default C:\apache24 to C:\Program Files\)
  3. Edit the conf\httpd.conf file to check ServerRoot, DocumentRoot and any Directory values are set to where you want it (C:\Apache24 by default).
  4. Run a DOS->Command Prompt as Administrator
  5. In the Administrator CD to the Apache location and the bin director.
  6. Run httpd.exe and deal with any error messages (note port 80 must be free so stop anything else running on that report).
  7. Check you get the default "It works!" message on http://localhost/
  8. Install Apache as a service by killing the httpd.exe process and instead running httpd.exe -install.
  9. Start the Apache24 service and again verify you get the "It works!" message on http://localhost/

To add HTTP/2 and HTTPS (necessary for HTTP/2 on all browsers), uncomment the following lines from httpd.conf:

 LoadModule http2_module modules/mod_http2.so
 ...
 LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
 ...
 LoadModule ssl_module modules/mod_ssl.so
 ...
 Include conf/extra/httpd-ssl.conf

Install a cert and key to conf/server.crt and conf/server.key - note Apache 2.4 expects the cert file to include the cert plus any intermediary certs in X509 Base 64 DER format so should look something like this when opened in a text editor:

-----BEGIN CERTIFICATE-----
MII...etc.
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MII...etc.
-----END CERTIFICATE-----

Where the first cert is the server cert and the 2nd and subsequent certs are the intermediaries.

You should make sure you're running good HTTPS config (the defaults in Apache are very poor), but the defaults will do for now. I've a blog post on that here.

Restart Apache in the service menu and check you can access https://localhost (ignoring any cert error assuming your cert does not cover localhost).

To add HTTP/2 to Apache

Edit the conf/extra/httpd-ssl.conf file to add the following near the top (e.g. after the Listen 443 line):

Protocols h2 http/1.1

Restart Apache in the service menu and check you can access https://localhost (ignoring any cert error assuming your cert does not cover localhost) and you should see h2 as the protocol in the developer tools of your web browser.

To use HTTP/2 push in Apache add the following to push a style sheet:

Header add Link "</path/to/css/styles.css>;rel=preload;as=style" env=!cssloaded

And you should see it pushed to your page in developer tools. Again, I've a blog post on that if you want more information on this.

If you do want to use Node for some (or all) of your calls you can uncomment the following line from conf/httpd.conf:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

And then add the following config:

ProxyPass /nodecontent http://127.0.0.1:8000/

Which will send any of those requests to node service running on port 8000. Restart to pick up this config.

If your node service adds any HTTP headers like this:

link:</path/to/style/styles.css>;rel=preload;as=style

Then Apache should pick them up and push them too. For example if using Express you can use the following to set the headers:

app.get('/test/', function (req, res) {
  res.header('link','</path/to/style.css>;rel=preload;as=style');
  res.send('This is a test page which also uses Apache to push a CSS file!\n');
});

Finally, while on the subject of HTTP/2 push this article includes a lot of interesting food for thought: https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/

Upvotes: 0

licitdev
licitdev

Reputation: 319

You could try NGINX, it can support HTTP/2. http://nginx.org/en/docs/windows.html

Run your node applications by using default node, nodemon, pm2... Then use NGINX as a static web server and you can reverse proxy your node apps.

Upvotes: 1

Related Questions