You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.8 KiB
101 lines
3.8 KiB
"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
|