UNPKG

http2.js-client

Version:

Patch http2-client to use custom http2.js (node-http2)

111 lines (110 loc) 4.65 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const import_locals_1 = __importDefault(require("import-locals")); const patcher = new import_locals_1.default(module); patcher.export('http2-client/lib/request', 'HEADERS_TO_REMOVE'); const request_1 = require("http2-client/lib/request"); const http2_js_1 = require("http2.js"); const endpoint_1 = require("http2.js/lib/protocol/endpoint"); const noop_1 = require("./noop"); class PatchedClass { holdConnectionToIdentification(clientKey, requestOptions, cb) { const topic = `identify-${clientKey}`; if (this._events[topic]) { this.once(topic, cb); return; } const socket = this.identifyConnection(requestOptions, (type) => { const options = { createConnection() { return socket; } }; if (type === 'h2' && this.http2Support) { const endpoint = new endpoint_1.Endpoint(noop_1.noopLog, 'CLIENT' /* settings */); endpoint.socket = socket; endpoint.pipe(endpoint.socket).pipe(endpoint); this.setHttp2Client(clientKey, endpoint); } else { this.cachedHTTP1Result[clientKey] = Date.now(); } cb(options); this.emit(topic, options); }); } makeHttp2Request(clientKey, inStream, endpoint, requestOptions, cb) { const http2Debouncer = this.http2Debouncer; http2Debouncer.pause(clientKey); const stream = endpoint.createStream(); const req = new http2_js_1.OutgoingRequest(noop_1.noopLog); req.stream = stream; req.options = requestOptions; req.endpoint = endpoint; for (const [name, value] of Object.entries(requestOptions.headers || {})) { req.setHeader(name, value); } const headers = req._headers; for (const name of request_1.HEADERS_TO_REMOVE) delete headers[name]; if (!headers[':authority']) { headers[':authority'] = requestOptions.hostname || requestOptions.host; if (requestOptions.port) { headers[':authority'] += `:${requestOptions.port}`; } } if (!headers[':method']) { headers[':method'] = (requestOptions.method || 'GET').toUpperCase(); } if (!headers[':path']) { headers[':path'] = requestOptions.path || '/'; } if (!headers[':scheme']) { headers[':scheme'] = requestOptions.protocol.slice(0, -1) || 'https'; } if (!headers['accept-encoding']) { headers['accept-encoding'] = 'gzip'; } if (requestOptions.auth) { headers.authorization = 'Basic ' + Buffer.from(requestOptions.auth).toString('base64'); } requestOptions.headers = headers; stream.headers(headers); inStream.emit('socket', requestOptions.createConnection()); let maxContentLength = 0; let currentContent = 0; stream.on('data', data => { currentContent += data.length; if (currentContent >= maxContentLength) { http2Debouncer.unpauseAndTime(clientKey); } }); const res = new http2_js_1.IncomingResponse(stream); res.req = req; res.once('ready', () => stream.emit('response', res.headers)); inStream.take(stream); const onResponse = $headers => { maxContentLength = +$headers['content-length']; if (isNaN(maxContentLength) || maxContentLength <= 0) { http2Debouncer.unpauseAndTime(clientKey); } request_1.HttpRequestManager.httpCompatibleResponse(res, requestOptions, $headers); inStream.emit('http1.response', res); if (cb) cb(res); }; stream.on('response', Object.assign(onResponse, { http2Safe: true })); if (['GET', 'HEAD', 'DELETE'].includes(headers[':method'])) stream.end(); } } if (!request_1.HttpRequestManager.$patched) { request_1.HttpRequestManager.$patched = true; for (const [name, value] of Object.entries(PatchedClass.prototype)) { request_1.HttpRequestManager.prototype[name] = value; } }