UNPKG

@fastify/reply-from

Version:

forward your HTTP request to another server, for fastify

195 lines (174 loc) 5.29 kB
import fastify, { FastifyReply, FastifyRequest, RawServerBase, RequestGenericInterface, RouteGenericInterface } from 'fastify' import * as http from 'node:http' import { IncomingHttpHeaders } from 'node:http2' import * as https from 'node:https' import { AddressInfo } from 'node:net' import { expectType } from 'tsd' import { Agent, Client, Dispatcher, Pool } from 'undici' import replyFrom, { FastifyReplyFromOptions, RawServerResponse } from '..' // @ts-ignore import tap from 'tap' const fullOptions: FastifyReplyFromOptions = { base: 'http://example2.com', http: { agentOptions: { keepAliveMsecs: 60 * 1000, maxFreeSockets: 2048, maxSockets: 2048 }, requestOptions: { timeout: 1000 }, agents: { 'http:': new http.Agent({}), 'https:': new https.Agent({}) } }, http2: { sessionTimeout: 1000, requestTimeout: 1000, sessionOptions: { rejectUnauthorized: true }, requestOptions: { endStream: true } }, cacheURLs: 100, disableCache: false, undici: { connections: 100, pipelining: 10, proxy: 'http://example2.com:8080' }, contentTypesToEncode: ['application/x-www-form-urlencoded'], retryMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'], maxRetriesOn503: 10, disableRequestLogging: false, globalAgent: false, destroyAgent: true } async function main () { const server = fastify() server.register(replyFrom) server.register(replyFrom, {}) server.register(replyFrom, { http2: true }) server.register(replyFrom, fullOptions) server.register(replyFrom, { undici: { proxy: new URL('http://example2.com:8080') } }) server.register(replyFrom, { undici: { proxy: { uri: 'http://example2.com:8080' } } }) server.get('/v1', (_request, reply) => { expectType<FastifyReply>(reply.from()) }) server.get('/v3', (_request, reply) => { reply.from('/v3', { timeout: 1000, body: { hello: 'world' }, rewriteRequestHeaders (req, headers) { expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(req) return headers }, getUpstream (req, base) { expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(req) return base }, onResponse (request, reply, res) { expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(request) expectType<FastifyReply<RouteGenericInterface, RawServerBase>>(reply) expectType<RawServerResponse<RawServerBase>>(res) expectType<number>(res.statusCode) } }) }) // http2 const instance = fastify({ http2: true }) // @ts-ignore tap.tearDown(instance.close.bind(instance)) const target = fastify({ http2: true }) // @ts-ignore tap.tearDown(target.close.bind(target)) instance.get('/', (_request, reply) => { reply.from() }) instance.get('/http2', (_request, reply) => { reply.from('/', { method: 'POST', retryDelay: ({ req, res, err, attempt, getDefaultDelay }) => { const defaultDelay = getDefaultDelay(req, res, err, attempt) if (defaultDelay) return defaultDelay if (res && res.statusCode === 500 && req.method === 'GET') { return 300 } return null }, rewriteHeaders (headers) { return headers }, rewriteRequestHeaders (_req, headers: IncomingHttpHeaders) { return headers }, getUpstream (_req, base) { return base }, onError (reply: FastifyReply<RouteGenericInterface, RawServerBase>, error) { return reply.send(error.error) }, queryString (search, reqUrl, request) { expectType<string | undefined>(search) expectType<string>(reqUrl) expectType<FastifyRequest<RequestGenericInterface, RawServerBase>>(request) return '' }, }) }) await target.listen({ port: 0 }) const port = (target.server.address() as AddressInfo).port instance.register(replyFrom, { base: `http://localhost:${port}`, http2: { sessionOptions: { rejectUnauthorized: false, }, }, }) instance.register(replyFrom, { base: `http://localhost:${port}`, http2: true, }) await instance.listen({ port: 0 }) const undiciInstance = fastify() undiciInstance.register(replyFrom, { base: 'http://example2.com', undici: { pipelining: 10, connections: 10 } }) await undiciInstance.ready() const undiciInstanceAgent = fastify() undiciInstance.register(replyFrom, { base: 'http://example2.com', undici: new Agent() }) await undiciInstanceAgent.ready() const undiciInstancePool = fastify() undiciInstance.register(replyFrom, { base: 'http://example2.com', undici: new Pool('http://example2.com') }) await undiciInstancePool.ready() const undiciInstanceClient = fastify() undiciInstance.register(replyFrom, { base: 'http://example2.com', undici: new Client('http://example2.com') }) await undiciInstanceClient.ready() const undiciInstanceDispatcher = fastify() undiciInstance.register(replyFrom, { base: 'http://example2.com', undici: new Dispatcher() }) await undiciInstanceDispatcher.ready() tap.pass('done') tap.end() } main()