| "use strict"; |
| var __importDefault = (this && this.__importDefault) || function (mod) { |
| return (mod && mod.__esModule) ? mod : { "default": mod }; |
| }; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| exports.parseProxyResponse = void 0; |
| const debug_1 = __importDefault(require("debug")); |
| const debug = (0, debug_1.default)('https-proxy-agent:parse-proxy-response'); |
| function parseProxyResponse(socket) { |
| return new Promise((resolve, reject) => { |
| // we need to buffer any HTTP traffic that happens with the proxy before we get |
| // the CONNECT response, so that if the response is anything other than an "200" |
| // response code, then we can re-play the "data" events on the socket once the |
| // HTTP parser is hooked up... |
| let buffersLength = 0; |
| const buffers = []; |
| function read() { |
| const b = socket.read(); |
| if (b) |
| ondata(b); |
| else |
| socket.once('readable', read); |
| } |
| function cleanup() { |
| socket.removeListener('end', onend); |
| socket.removeListener('error', onerror); |
| socket.removeListener('readable', read); |
| } |
| function onend() { |
| cleanup(); |
| debug('onend'); |
| reject(new Error('Proxy connection ended before receiving CONNECT response')); |
| } |
| function onerror(err) { |
| cleanup(); |
| debug('onerror %o', err); |
| reject(err); |
| } |
| function ondata(b) { |
| buffers.push(b); |
| buffersLength += b.length; |
| const buffered = Buffer.concat(buffers, buffersLength); |
| const endOfHeaders = buffered.indexOf('\r\n\r\n'); |
| if (endOfHeaders === -1) { |
| // keep buffering |
| debug('have not received end of HTTP headers yet...'); |
| read(); |
| return; |
| } |
| const headerParts = buffered |
| .slice(0, endOfHeaders) |
| .toString('ascii') |
| .split('\r\n'); |
| const firstLine = headerParts.shift(); |
| if (!firstLine) { |
| socket.destroy(); |
| return reject(new Error('No header received from proxy CONNECT response')); |
| } |
| const firstLineParts = firstLine.split(' '); |
| const statusCode = +firstLineParts[1]; |
| const statusText = firstLineParts.slice(2).join(' '); |
| const headers = {}; |
| for (const header of headerParts) { |
| if (!header) |
| continue; |
| const firstColon = header.indexOf(':'); |
| if (firstColon === -1) { |
| socket.destroy(); |
| return reject(new Error(`Invalid header from proxy CONNECT response: "${header}"`)); |
| } |
| const key = header.slice(0, firstColon).toLowerCase(); |
| const value = header.slice(firstColon + 1).trimStart(); |
| const current = headers[key]; |
| if (typeof current === 'string') { |
| headers[key] = [current, value]; |
| } |
| else if (Array.isArray(current)) { |
| current.push(value); |
| } |
| else { |
| headers[key] = value; |
| } |
| } |
| debug('got proxy server response: %o %o', firstLine, headers); |
| cleanup(); |
| resolve({ |
| connect: { |
| statusCode, |
| statusText, |
| headers, |
| }, |
| buffered, |
| }); |
| } |
| socket.on('error', onerror); |
| socket.on('end', onend); |
| read(); |
| }); |
| } |
| exports.parseProxyResponse = parseProxyResponse; |
| //# sourceMappingURL=parse-proxy-response.js.map |