@schoolofmotion/rocket-booster
Version:
Serverless reverse proxy and load balancing library built for Cloudflare Workers.
80 lines (68 loc) • 1.54 kB
text/typescript
import { Middleware } from '../types/middleware';
import { UpstreamOptions } from '../types/upstream';
export const cloneRequest = (
url: string,
request: Request,
): Request => {
const requestInit: CfRequestInit = {
body: request.body,
method: request.method,
headers: request.headers,
};
return new Request(url, requestInit);
};
export const getURL = (
url: string,
upstream: UpstreamOptions,
): string => {
const cloneURL = new URL(url);
const {
domain,
port,
protocol,
} = upstream;
cloneURL.hostname = domain;
if (port !== undefined) {
cloneURL.port = port.toString();
}
if (protocol !== undefined) {
cloneURL.protocol = `${protocol}:`;
}
return cloneURL.href;
};
export const sendRequest = async (
request: Request,
upstream: UpstreamOptions,
): Promise<Response> => {
const timeout = upstream.timeout || 10000;
const redirect = upstream.redirect || 'manual';
const timeoutId = setTimeout(() => {
throw new Error('Fetch Timeout');
}, timeout);
const response = await fetch(request, { redirect });
clearTimeout(timeoutId);
return response;
};
export const useUpstream: Middleware = async (
context,
next,
) => {
const { request, upstream } = context;
if (upstream === null) {
await next();
return;
}
const url = getURL(
request.url,
upstream,
);
const upstreamRequest = cloneRequest(
url,
request,
);
context.response = await sendRequest(
upstreamRequest,
upstream,
);
await next();
};