UNPKG

koa-even-better-http-proxy

Version:
93 lines (78 loc) 2.87 kB
import chunkLength from '../../lib/chunkLength'; let timeoutDuration = null; let abortRequest = null; // "secureConnect" includes time taken for "lookup" (dns), "connect" and // "ready" events, as well as tls handshake. const getEventListener = (isSecure) => (isSecure ? 'secureConnect' : 'connect'); const onError = (ctx, container, err, resolve, reject) => { if (err.code === 'ECONNRESET') { ctx.set( 'X-Timout-Reason', `The proxy timed out your request after ${timeoutDuration}ms.` ); ctx.set('Content-Type', 'text/plain'); ctx.status = 504; resolve(container); } else { reject(err); } }; const onSocketOpen = (container, socket) => { const { options } = container; const { isSecure } = container.proxy; const { timeout, connectTimeout } = options; if (connectTimeout) { timeoutDuration = connectTimeout; socket.setTimeout(connectTimeout, abortRequest); socket.on(getEventListener(isSecure), () => { if (timeout) { timeoutDuration = timeout; socket.setTimeout(timeout, abortRequest); } else { // 0 to reset to the default of no timeout for the rest of the request socket.setTimeout(0); } }); } else if (timeout) { timeoutDuration = timeout; socket.setTimeout(timeout, abortRequest); } }; const getProxyReq = (container, resolve, reject) => { const { proxy } = container; const reqOpt = proxy.reqBuilder; return proxy.requestModule.request(reqOpt, (rsp) => { const chunks = []; rsp.on('data', (chunk) => chunks.push(chunk)); rsp.on('end', () => { proxy.res = rsp; proxy.resData = Buffer.concat(chunks, chunkLength(chunks)); resolve(container); }); rsp.on('error', reject); }); }; export default (Container) => { const { ctx } = Container.user; const { bodyContent } = Container.proxy; const { options } = Container; return new Promise((resolve, reject) => { const proxyReq = getProxyReq(Container, resolve, reject); abortRequest = () => proxyReq.abort(); proxyReq.on('socket', (socket) => onSocketOpen(Container, socket)); proxyReq.on('error', (err) => onError(ctx, Container, err, resolve, reject) ); // this guy should go elsewhere, down the chain if (options.parseReqBody) { if (bodyContent.length) { proxyReq.write(bodyContent); } proxyReq.end(); } else { // Pipe will call end when it has completely read from the request. ctx.req.pipe(proxyReq); } ctx.req.on('aborted', () => proxyReq.abort()); // reject? }); };