@schoolofmotion/rocket-booster
v1.4.2-s1
Published
Serverless reverse proxy and load balancing library built for Cloudflare Workers.
Downloads
2
Maintainers
Readme
📦 Releases | 📔 Examples | ⚙️ Options | 🌎 Contributing
🚀 rocket-booster is a lightweight and scalable reverse proxy and load balancing library built for Cloudflare Workers. It sits in front of web servers (e.g. web application, storage platform, or RESTful API), forwards HTTP requests or WebSocket traffics from clients to upstream servers and transforms responses with several optimizations to improve page loading time.
- ⚡ Serverless: Deploy instantly to the auto-scaling serverless platform built by Cloudflare. No virtual machines, servers, or containers to manage.
- ✈️ Load Balancing: Distribute incoming traffics evenly among different upstream services.
- ⚙️ Hackable: Deliver unique content based on visitor attributes, conduct A/B testing, or build custom middleware to hook into the lifecycle. (Experimental)
- 📄 TypeScript: Extensive type declaration with TSDoc.
📦 Build and Deploy
Start with templates
- Install Wrangler CLI and generate a project from the rocket-booster-template
npm install -g @cloudflare/wrangler
wrangler generate booster-app https://github.com/booster-labs/rocket-booster-template
- Install dependencies and edit the options in
src/index.ts
cd booster-app
npm install
- Login and publish to Cloudflare Workers
wrangler login
wrangler publish
Integrate with existing project
- Install the
rocket-booster
package
npm install --save rocket-booster
- Import the
useProxy
function fromrocket-booster
. The function returns an object with theuse()
method, which maps route patterns to configuration objects, andapply()
method, which takes the inbound Request to the Worker, and returns the Response fetched from the upstream service.
import useProxy from 'rocket-booster';
addEventListener('fetch', (event) => {
const proxy = useProxy();
proxy.use('/', {
upstream: {
domain: 'example.com',
protocol: 'https',
},
});
const response = proxy.apply(event.request);
event.respondWith(response);
});
- Edit the options object to change the request and response. For example, the options below will add the header
Access-Control-Allow-Origin: *
to each response from the upstream service, which allows any origin to access the service.
proxy.use('/', {
upstream: {
domain: 'example.com',
protocol: 'https',
},
cors: {
origin: '*',
},
});
- Build and publish to Cloudflare Workers
wrangler build
wrangler publish
📔 Examples
MDN Web Docs Mirror
Set up a reverse proxy for https://developer.mozilla.org:
proxy.use('/', {
upstream: {
domain: 'developer.mozilla.org',
protocol: 'https',
},
});
WebSocket Proxy
rocket-booster
could proxy WebSocket traffic to upstream services. Set up a reverse proxy for wss://echo.websocket.org:
proxy.use('/', {
upstream: {
domain: 'echo.websocket.org',
protocol: 'https',
},
});
S3 Bucket with custom response behavior
rocket-booster
could set custom headers to request and response, add CORS header, or add basic authentication. Set up a reverse proxy for https://example.s3.amazonaws.com:
proxy.use('/', {
upstream: {
domain: 'example.s3.amazonaws.com',
protocol: 'https',
},
header: {
response: {
'x-response-header': 'Hello from rocket-booster',
},
},
cors: {
origin: ['https://www.example.com'],
methods: ['GET', 'POST'],
credentials: true,
},
});
⚙️ Options
Routing
The proxy
object provides a use
function that maps URL patterns to different options. The options object has an optional methods
property that accepts a list of HTTP methods, which specifies the request methods the route will handle.
// Matches all requests
proxy.use('/', { /* ... */ });
// Matches GET and POST requests with path starting with `/api`
proxy.use('/api', {
methods: ['GET', 'POST'],
});
// Matches GET requests with path ending with `.json` in `/data`
proxy.use('/data/*.json', {
methods: ['GET'],
});
Upstream
domain
: The domain name of the upstream server.protocol
: The protocol scheme of the upstream server. (optional, defaults to'https'
)port
: The port of the upstream server. (optional, defaults to80
or443
based onprotocol
)timeout
: The maximum wait time on a request to the upstream server. (optional, defaults to10000
)weight
: The weight of the server that will be accounted as part of the load balancing decision. (optional, defaults to1
)
proxy.use('/', {
upstream: {
domain: 'httpbin.org',
protocol: 'https',
port: 443,
timeout: 10000,
weight: 1,
},
/* ... */
});
Load Balancing
To load balance HTTP traffic to a group of servers, pass an array of server configurations to upstream
. The load balancer will forward the request to an upstream server based on the loadBalancing.policy
option.
random
: The load balancer will select a random upstream server from the server group. The optionalweight
parameter in the server configuration could influence the load balancing algorithm.ip-hash
: The client's IP address is used as a hashing key to select the upstream server from the server group. It ensures that the requests from the same client will always be directed to the same server.
proxy.use('/', {
loadBalancing: {
policy: 'random',
},
upstream: [
{
domain: 's1.example.com',
protocol: 'https',
weight: 20,
},
{
domain: 's2.example.com',
protocol: 'https',
weight: 30,
},
{
domain: 's3.example.com',
protocol: 'https',
weight: 50,
},
],
/* ... */
});
Firewall
Each incoming request is inspected against the firewall rules defined in the firewall
property of the options object. The request will be blocked if it matches at least one firewall rule.
field
: The property of the incoming request to be inspectedasn
: The ASN number of the incoming request. (number
)ip
: The IP address of the incoming request, e.g.1.1.1.1
. (string
)hostname
: The content of thehost
header, e.g.github.com
. (string | undefined
)user-agent
: The content of theuser-agent
header, e.g.Mozilla/5.0
. (string | undefined
)country
: The two-letter country code in the request, e.g.US
. (string | undefined
)continent
: The continent of the incoming request, e.g.NA
. (string | undefined
)
value
: The value of the firewall ruleoperator
: The operator to be used to determine if the request is blockedequal
: Block the request iffield
is equal tovalue
not equal
: Block the request iffield
is not equal tovalue
match
: Block the request ifvalue
matchesfield
(Expectfield
to bestring
andvalue
to beRegExp
)not match
: Block the request ifvalue
doesn't matchfield
(Expectfield
to bestring
andvalue
to beRegExp
)in
: Block the request iffield
is invalue
(Expectvalue
to beArray
)not in
: Block the request iffield
is not invalue
(Expectvalue
to beArray
)contain
: Block the request iffield
containsvalue
(Expectfield
andvalue
to bestring
)not contain
: Block the request iffield
doesn't containvalue
(Expectfield
andvalue
to bestring
)greater
: Block the request iffield
is greater thanvalue
(Expectfield
andvalue
to benumber
)less
: Block the request iffield
is less thanvalue
(Expectfield
andvalue
to benumber
)
proxy.use('/', {
/* ... */
firewall: [
{
field: 'ip',
operator: 'in',
value: ['1.1.1.1', '1.0.0.1'],
},
{
field: 'user-agent',
operator: 'match',
value: /Chrome/,
}
],
});
Rewrite
location
: Rewrite thelocation
header for responses with 3xx or 201 status if exists. (optional, defaults tofalse
)
proxy.use('/', {
/* ... */
rewrite: {
path: {
'/api/user': '/user'
},
},
});
Headers
request
: Sets request header going upstream to the backend. Accepts an object. (optional, defaults to{}
)response
: Sets response header coming downstream to the client. Accepts an object. (optional, defaults to{}
)
proxy.use('/', {
/* ... */
headers: {
request: {
'x-example-header': 'hello server',
},
response: {
'x-example-header': 'hello client',
},
},
});
Cross-Origin Resource Sharing (CORS)
origin
: Configures theAccess-Control-Allow-Origin
CORS header. (optional, defaults tofalse
)boolean
: set totrue
to reflect the origin of the request, or set tofalse
to disable CORS.string[]
: an array of acceptable origins.*
: allow any origin to access the resource.
methods
: Configures theAccess-Control-Allow-Methods
CORS header. Expects an array of valid HTTP methods or*
. (optional, defaults to reflecting the method specified in the request’sAccess-Control-Request-Method
header)allowedHeaders
: Configures theAccess-Control-Allow-Headers
CORS header. Expects an array of HTTP headers or *. (optional, defaults to reflecting the headers specified in the request’sAccess-Control-Request-Headers
header.)exposedHeaders
: Configures theAccess-Control-Expose-Headers
CORS header. Expects an array of HTTP headers or*
. (optional, defaults to[]
)credentials
: Configures theAccess-Control-Allow-Credentials
CORS header. Set to true to pass the header, otherwise it is omitted. (optional, defaults tofalse
)maxAge
: Configures theAccess-Control-Max-Age
CORS header. Set to an integer to pass the header, otherwise it is omitted. (optional)
proxy.use('/', {
/* ... */
cors: {
origin: true,
methods: [
'GET',
'POST',
],
allowHeaders: [
'Example-Header',
],
exposeHeaders: [
'Example-Header',
],
credentials: true,
maxAge: 86400,
},
});
Optimization
Cloudflare Workers provides several optimization by default.
- Brotli: Speed up page load times for visitor’s HTTPS traffic by applying Brotli compression.
- HTTP/2: Improve page load time by connection multiplexing, header compression, and server push.
- HTTP/3 with QUIC: Accelerate HTTP requests by using QUIC, which provides encryption and performance improvements compared to TCP and TLS.
- 0-RTT Connection Resumption: Improve performance for clients who have previously connected to the website.
🌎 Contributing
- Request a feature: Create an issue with the Feature request template.
- Report bugs: Create an issue with the Bug report template.
- Add new feature or fix bugs: Fork this repository, edit code, and send a pull request.