Running a Standalone HTTP Server

When developing and testing a new HTML page, it can be accessed locally by opening it as a file from a browser. But Chrome and Firefox will issue an error if the Javascript in the page tries to make an AJAX call (due to enforcement of browser sandbox security). To work around this there are some simple HTTP servers that can be run from the command line, serving content from the current directory. Serving the page via the “http:” protocol avoids the stricter security that is applied to the “file:” protocol when a file is opened directly in the browser.

Node.js: http-server

If you have npm and Node.js installed you can install the “http-server” package:

% npm install http-server -g   ## 5.9 MB "node_modules" directory
% npm list --depth 1
/Users/curious1/server-test
|-+ http-server@0.10.0
  |-- colors@1.0.3
  |-- corser@2.0.1
  |-- ecstatic@2.2.1
  |-- http-proxy@1.16.2
  |-- opener@1.4.3
  |-- optimist@0.6.1
  |-- portfinder@1.0.13
  |-- union@0.4.6
% du -skh node_modules/
5.9M	node_modules/

…and then run it like this:

% node_modules/.bin/http-server 
Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
  http://192.168.1.6:8080
Hit CTRL-C to stop the server
[Mon Aug 21 2017 11:48:15 GMT-0400 (EDT)] "GET /" "TestAgent (For standalone server; Version 0.0)"

(as an alternative, install http-server once globally with ‘npm install -g http-server’, which will put it on the command PATH)

The ‘http-server’ server can be started on a different port number by specifying ‘-p NNNN’ on the command line, where NNNN is the port number (such as 8000, whatever you like).

The ‘http-server’ server reports each access to the server on standard output – one example line is shown above (the “GET /” entry). This is an abbreviated form of the standard HTTP common log access format that most web servers use to report page requests.

I made a request to this server from another terminal window, using the ‘curl’ utility like this:

$ curl -v -A "TestAgent (For standalone server; Version 0.0)" localhost:8080

The “-v” option shows the HTTP headers that are returned in the ‘curl’ request:

...request text omitted...
< HTTP/1.1 200 OK
< server: ecstatic-2.2.1
< last-modified: Mon, 21 Aug 2017 15:46:44 GMT
< etag: "107525095-93-"2017-08-21T15:46:44.000Z""
< cache-control: max-age=3600
< content-length: 93
< content-type: text/html; charset=UTF-8
< Date: Mon, 21 Aug 2017 15:52:38 GMT
< Connection: keep-alive
< 
<title>Hello, World!</title>
This is some content that's served by a standalone HTTP server.

A minor point of interest here is the “server:” header, which reports the name of the server that’s responding to the request (“ecstatic-2.2.1” in this case). This will be different for each server that is tested below.

Python SimpleHTTPServer Module

Python 2 comes with a built-in SimpleHTTPServer:

% python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
127.0.0.1 - - [21/Aug/2017 11:58:49] "GET / HTTP/1.1" 200 -

(the “-m” option simply specifies the Python code module to run)

The server name is reported as “SimpleHTTP/0.6 Python/2.7.10”. Note also that the HTTP response code is logged by this server, “200” (OK) in this case (meaning that the requested HTML was served OK). The response code can be useful in debugging issues with the page being tested. A “404” error, for example, means that the requested file wasn’t found. It could be a CSS or Javascript file – a line of output is generated for any file requested as part of the total HTML page.

Python 2.x, selecting another port:

% python -m SimpleHTTPServer 8888
Serving HTTP on 0.0.0.0 port 8888 ...

In Python 3 there is a similar built-in web server:

% python3 -m http.server 8888

PHP Built-in Server

If you have PHP installed you could use:

% php -S localhost:8888
PHP 5.5.38 Development Server started at Fri Aug 18 11:47:37 2017
Listening on http://localhost:8888
Document root is /Users/curious1/server-test
Press Ctrl-C to quit.
[Mon Aug 21 12:06:47 2017] ::1:63614 [200]: /

For this PHP server, the port number is required; entering just ‘php -S localhost’ will fail with an error (“Invalid address: localhost”). And the server does not report any server type (no “server:” header is returned).

Other Options for HTTP Servers

In the Java ecosystem, Tomcat and Jetty are two HTTP servers that can be easily installed and run (but out of the box they don’t work on content in the current directory).

The Maven package management system comes with a built-in HTTP server, ‘cargo’ which can be run with the Maven command ‘mvn -P cargo.run’ (if a project has already been built with the Maven “maven-archetype-webapp” archetype.

Ruby on Rails comes with a variety of simple HTTP servers built in, part of the command line interface for managing the lifecycle of a Rails app.

WebStorm, the front-end development IDE from JetBrains (makers of IntelliJ) comes with an internal server; in an editor window that has a HTML file open, hover the
mouse in the upper right corner: logos will appear for each of the browsers currently installed on the system. Click a logo and the HTML will be loaded in the selected browser.

TL; DR

Running various kinds of simple HTTP servers from the command line:

% http-server -p 8888   ## node/Javascript
% python -m SimpleHTTPServer 8888
% python3 -m http.server 8888
% php -S localhost:8888

‘http-server’ and the built-in php server respond with the HTTP/1.1 protocol; the python v2 server responds with HTTP/1.0.

Server types reported by the different servers:
‘http-server’: “ecstatic-2.2.1”
‘python -m SimpleHTTPServer’: “SimpleHTTP/0.6 Python/2.7.10”
‘php -s’: nothing reported

Differences in the access log output:

http-server: "[Mon Aug 21 2017 11:48:15 GMT-0400 (EDT)] "GET /" "TestAgent (For standalone server; Version 0.0)""
python -m SimpleHTTPServer: "127.0.0.1 - - [21/Aug/2017 11:58:49] "GET / HTTP/1.1" 200 -"
php -s: "[Mon Aug 21 12:06:47 2017] ::1:63614 [200]: /"

All servers except the Node.js http-server return the status code as part of the access log output (“200” means OK – success serving the page, “404” means Not Found, something is missing).

References

http-server – NodeJS
SimpleHTTPServer — Simple HTTP request handler — Python 2.7.14 documentation
PHP: Options – Manual
Log Files – Apache HTTP Server
(a good detailed discussion of common log format)
HTTP response status codes – HTTP | MDN

Versions


$ node -v
v5.0.0
$ python -V
Python 2.7.10
$ php -v
PHP 5.5.38 (cli) (built: Aug 21 2016 21:48:49)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies