npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

http-host-proxy

v1.0.0

Published

HTTP(s) proxy with host based routing to front servers, with optional SSL or authentication

Downloads

29

Readme

HTTP Host Proxy

HTTP(s) proxy with host based routing to front servers, with optional SSL or authentication

NOTE: as of version 1.0.0 this module no longer uses Passhash for user authentication - it has been replaced with HashP which has a different file format that is not backwards compatible.

Installation

First, install Node.js. Then:

[sudo] npm install -g http-host-proxy

Example

First create a router file

example-router.json

{
  "test1.com": "localhost:8080",
  "test2.com": "127.0.0.1:8081",
  "test3.com": {
    "host": "192.168.1.15",
    "port": 8000
  },
  "daveeddy.com": "daveeddy.com",
  "google.com": "google.com:80",
  "github.com": {
    "host": "github.com",
    "port": 80
  }
}

This file maps incoming host headers, to the endpoint the server will proxy. Any of the above forms are permitted in the config.

Basic

Now, we can fire up the server:

$ http-host-proxy -r example-router.json
listening on http://0.0.0.0:8080

By default, the server listens on HTTP, host 0.0.0.0, port 8080

In a second terminal, we can trigger some requests to the server

$ curl -i localhost:8080
HTTP/1.1 404 Not Found
Date: Thu, 14 Nov 2013 22:14:59 GMT
Connection: keep-alive
Transfer-Encoding: chunked

no route found for host: localhost:8080
$ curl -i -H 'host: daveeddy.com' localhost:8080
HTTP/1.1 200 OK
server: nginx
date: Thu, 14 Nov 2013 22:15:12 GMT
content-type: text/html
content-length: 18692
last-modified: Tue, 12 Nov 2013 23:58:31 GMT
connection: keep-alive
accept-ranges: bytes

<!doctype html>
<html>
.... SNIPPED ....

In the first request, you can see that we are thrown a 404 from the proxy itself, because it doesn't have a route defined for the host header localhost:8080. In the second request however a manual host header is set to daveeddy.com, which matches a route in the router. The request is proxied to http://www.daveeddy.com, and the response headers and the body are delivered directly through the proxy.

On the server end, you can see Apache style logs, prefixed with the host header.

$ http-host-proxy -r example-router.json
listening on http://0.0.0.0:8080
[localhost:8080] 127.0.0.1 - - [14/Nov/2013:17:14:59 -0500] "GET / HTTP/1.1" 404 - "-" "curl/7.30.0"
[daveeddy.com] 127.0.0.1 - - [14/Nov/2013:17:15:12 -0500] "GET / HTTP/1.1" 200 18692 "-" "curl/7.30.0"

Default Route

You can specify the following in the router file to create a default route for unmatched host headers:

{
  "*": "google.com"
}

With the above in place, any successful request will be proxied to google

SSL

Enabling ssl is easy. You need to already have a certificate and key file, or generate your own. To generate your own you can run:

openssl genrsa -out my.key 4096
openssl req -new -x509 -days 1826 -key my.key -out my.crt

These 2 commands will create my.key and my.crt in your current directory. Now, just fire up the server with the following options to listen securely.

$ http-host-proxy -r example-router.json --ssl -k my.key -c my.crt
listening on https://0.0.0.0:8080
[daveeddy.com] 127.0.0.1 - - [14/Nov/2013:17:25:19 -0500] "GET / HTTPS/1.1" 200 18692 "-" "curl/7.30.0"

And to generate a request, just change curl to use https, and supply -k if the certificate is self-signed.

$ curl -k -i -H 'host: daveeddy.com' https://localhost:8080
HTTP/1.1 200 OK
server: nginx
date: Thu, 14 Nov 2013 22:26:03 GMT
content-type: text/html
content-length: 18692
last-modified: Tue, 12 Nov 2013 23:58:31 GMT
connection: keep-alive
accept-ranges: bytes

<!doctype html>
<html>
.... SNIPPED ....

Authentication

Authentication can also be done by the proxy; It will use basic HTTP auth before proxying any requests. The file format for the authentication database file can be thought of as a stronger version of htpasswd, and can be found in the HashP Node Module.

First, we can create a passhash authentication database by running the following commands:

$ npm install -g hashp
$ echo -n 'password' | hashp username > passhash.txt
$ cat passhash.txt
username:QLZ6oPKVhm:swQfzk8F6gVhPrA3k2/1CTzitYo+LdZ8Qx+pmwBV7CFk/pZwsiunjYxmgzkXpJK+22mF4fvqI7t3neFXBi6SpQ==:89

Or optionally visiting http://bahamas10.github.io/node-hashp/

Now, we start the server with this file

$ http-host-proxy -r example-router.json -a passhash.txt
listening on http://0.0.0.0:8080

Make a few requests, first without authorization, then with it supplied

 $ curl -i -H 'host: daveeddy.com' localhost:8080
 HTTP/1.1 401 Unauthorized
 WWW-Authenticate: Basic realm="Auth Required"
 Date: Thu, 14 Nov 2013 22:51:30 GMT
 Connection: keep-alive
 Transfer-Encoding: chunked

 $ curl -i -H 'host: daveeddy.com' --user username:password localhost:8080
 HTTP/1.1 200 OK
 server: nginx
 date: Thu, 14 Nov 2013 22:51:42 GMT
 content-type: text/html
 content-length: 18692
 last-modified: Tue, 12 Nov 2013 23:58:31 GMT
 connection: keep-alive
 accept-ranges: bytes

 <!doctype html>
 <html>
 .... SNIPPED ....

And on the server we see:

$ http-host-proxy -r example-router.json -a passhash.txt
listening on http://0.0.0.0:8080
[<empty>@daveeddy.com] 127.0.0.1 - - [14/Nov/2013:17:51:30 -0500] "GET / HTTP/1.1" 401 - "-" "curl/7.30.0"
[[email protected]] 127.0.0.1 - - [14/Nov/2013:17:51:42 -0500] "GET / HTTP/1.1" 200 18692 "-" "curl/7.30.0"

In the logs you can see [email protected], the username is automatically prepended to the host header when authentication is enabled.

NOTE: The authorization header is stripped out by the proxy before being sent to the destination.

Usage

usage: http-host-proxy [options] -r routefile.json

HTTP(s) proxy with host based routing to front servers, with optional SSL or authentication

required options
  -r, --routes <file.json>      [env HTTPHOSTPROXY_ROUTES] a JSON file of host based routes

authentication options
  -a, --auth <authfile>         [env HTTPHOSTPROXY_AUTH] enable basic http authorization
                                and use <authfile> as the `hashp` file
  -f, --fail-delay <seconds>    [env HTTPHOSTPROXY_FAIL_DELAY] delay, in seconds, before sending a response to a client
                                that failed authentication, defaults to 2

ssl options
  -c, --cert <certfile>         [env HTTPHOSTPROXY_CERT] the SSL cert file to use when `--ssl` is switched on
  -k, --key <keyfile>           [env HTTPHOSTPROXY_KEY] the SSL key file to use when `--ssl` is switched on
  -s, --ssl                     [env HTTPHOSTPROXY_SSL] enable ssl, requires `--key` and `--cert` be specified

socket options
  -H, --host <host>             [env HTTPHOSTPROXY_HOST] the host address on which to listen, defaults to 0.0.0.0
  -p, --port <port>             [env HTTPHOSTPROXY_PORT] the port on which to listen, defaults to 8080

options
  -b, --buffer                  [env HTTPHOSTPROXY_BUFFER] buffer log output, useful if this webserver is heavily used
  -d, --debug                   [env HTTPHOSTPROXY_DEBUG] print verbose logs, defaults to false
  -h, --help                    print this message and exit
  -u, --updates                 check for available updates on npm
  -v, --version                 print the version number and exit

Configuration

  • process.env.HTTPHOSTPROXY_AUTH - same as -a or --auth
  • process.env.HTTPHOSTPROXY_BUFFER - same as -b or --buffer
  • process.env.HTTPHOSTPROXY_CERT - same as -c or --cert
  • process.env.HTTPHOSTPROXY_DEBUG - same as -d or --debug
  • process.env.HTTPHOSTPROXY_FAIL_DELAY - same as -f or --fail-delay
  • process.env.HTTPHOSTPROXY_GID - group ID to drop privileges to after server has started
  • process.env.HTTPHOSTPROXY_HOST - same as -H or --host
  • process.env.HTTPHOSTPROXY_KEY - same as -k or --key
  • process.env.HTTPHOSTPROXY_PORT - same as -p or --port
  • process.env.HTTPHOSTPROXY_ROUTES - same as -r or --routes
  • process.env.HTTPHOSTPROXY_SSL - same as -s or --ssl
  • process.env.HTTPHOSTPROXY_UID - group ID to drop privileges to after server has started

Send a SIGHUP to the process to reload the router file

Authors

License

MIT License