Skip to content

berstend/straightforward

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

16 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🏴 straightforward npm bundle size

A straightforward forward-proxy written in Node.js

Goals

  • Extremely focused (~200 SLOC), no-fuzz forward proxy
  • Support HTTP, HTTPS, CONNECT & Websockets (wss)
  • Performant: By default all requests/responses are streamed
  • No external dependencies, small, self-contained, tested
  • Support both cli and extensible programmatic usage
  • Straightforward: no implicit magic or abstractions

What you can do with it

  • Start an explicit forwarding proxy in seconds that just works
  • Optionally use authentication
  • Mock responses to test code using a proxy
  • Allow others to surf with your IP address
  • Use it programmatically to do whatever you want

What this is not

Installation

# Use directly with no installation (npx is part of npm): ❯❯❯ npx straightforward --port 9191 # Or install globally: ❯❯❯ npm install -g straightforward

Usage (cli)

❯❯❯ straightforward --help Usage: straightforward --port 9191 [options] Options: --version Show version number [boolean] -p, --port Port to bind on [number] [default: 9191] -a, --auth Enable proxy authentication [string] -e, --echo Enable echo mode (mock all http responses) [boolean] -d, --debug Enabled debug output [boolean] -c, --cluster Run a cluster of proxies (using number of CPUs) [boolean] --cluster-count Specify how many cluster workers to spawn [number] -q, --quiet Suppress request logs [boolean] -s, --silent Don't print anything to stdout [boolean]  -h, --help Show help [boolean]  Examples:  straightforward --auth "user:pass" Require authentication  straightforward --echo Mock responses for all http requests  Use with cURL:  curl --proxy https://localhost:9191 'http://example.com' -v  curl --proxy https://user:pass@localhost:9191 'http://example.com' -v

Usage (code)

// ESM/TS: import { Straightforward, middleware } from "straightforward" const { Straightforward, middleware } = require("straightforward") ;(async () => { // Start proxy server const sf = new Straightforward() await sf.listen(9191) console.log(`Proxy listening on http://localhost:9191`) // Log http requests sf.onRequest.use(async ({ req, res }, next) => { console.log(`http request: ${req.url}`) // Note the common middleware pattern, use `next()` // to pass the request to the next handler. return next() }) // Log connect (https) requests sf.onConnect.use(async ({ req }, next) => { console.log(`connect request: ${req.url}`) return next() }) // Use built-in middleware for authentication sf.onRequest.use(middleware.auth({ user: "bob", pass: "alice" })) sf.onConnect.use(middleware.auth({ user: "bob", pass: "alice" })) // Use built-in middleware to mock responses for all http requests sf.onRequest.use(middleware.echo) })()

In action

❯❯❯ straightforward --port 9191

foobar

Example: Secure proxy on fresh server in 30 seconds

Let's say you have a fresh linux server and want to use it as an authenticated forward proxy quickly.

  • Make sure nvm is installed:
    • curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
  • Make sure a recent version of Node.js is installed:
    • nvm install node && nvm use node && node --version
  • Add forever (process manager) and straightforward:
    • npm install -g forever straightforward
  • Start proxy daemon:
    • forever start --id "proxy1" $( which straightforward ) --port 9191 --quiet --auth 'user:foobar'
  • Test your proxy from a different machine:
    • curl --proxy http://user:foobar@SERVER:9191/ http://canhazip.com
  • List all running forever services:
    • forever list
  • Stop our proxy service daemon:
    • forever stop proxy1

API

onRequest

Middlewares triggered when http requests occur

sf.onRequest.use(async ({ req, res }, next) => { console.log(`http request: ${req.url}`) // Note the common middleware pattern, use `next()` // to pass the request to the next handler. return next() })

Middlwares can be chained:

sf.onRequest.use( async ({ req, res }, next) => { console.log(`middleware1`) return next() }, async ({ req, res }, next) => { console.log(`middleware2`) res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }) res.end("Hello world") } )

onResponse

Middlewares triggered when http request responses are available

sf.onResponse.use(async ({ req, res, proxyRes }, next) => { console.log(`http response`) return next() })

onConnect

Middlewares triggered when https and wss requests occur

sf.onConnect.use(async ({ req, clientSocket, head }, next) => { console.log(`connect request`) return next() })

License

MIT

About

🏴 A straightforward forward-proxy written in Node.js.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors