101 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"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
 |