@thgh/tunnelmole
Version:
Tunnelmole, an open source ngrok alternative. Instant public URLs for any http/https based application. Available as a command line application or as an NPM dependency for your code. Stable and maintained. Good test coverage. Works behind firewalls
67 lines (57 loc) • 2.44 kB
text/typescript
import HostipWebSocket from "../websocket/host-ip-websocket.js"
import ForwardedRequestMessage from "../messages/forwarded-request-message.js"
import http from 'http';
import ForwardedResponseMessage from "../messages/forwarded-response-message.js"
import { forwardedResponse } from "../messages/types.js"
import log from "../logging/log.js"
import { Options } from "../options.js";
export default async function forwardedRequest(forwardedRequestMessage: ForwardedRequestMessage, websocket: HostipWebSocket, options : Options) {
const port = options.port;
const { requestId, url, headers } = forwardedRequestMessage;
// Prevent issue with gzip encoding
delete headers['Accept-Encoding']
delete headers['accept-encoding']
// @todo: Once GET is working, add support for all HTTP methods
const requestOptions : http.RequestOptions = {
hostname: '127.0.0.1',
method: forwardedRequestMessage.method,
port: port,
path: url,
headers
};
const request = http.request(requestOptions, (response : http.IncomingMessage) => {
let responseBody : Buffer;
response.on('data', (chunk: Buffer) => {
if (typeof responseBody === 'undefined') {
responseBody = chunk;
} else {
responseBody = Buffer.concat([responseBody, chunk]);
}
});
/**
* If you see this callback being called more than once, this is probably normal especially if a browser initiated the request
* Most browsers will make more than one request, for example an extra one for favicon.ico
*/
response.on('end', () => {
//@ts-ignore
const forwardedResponseMessage : ForwardedResponseMessage = {
type: forwardedResponse,
requestId,
statusCode: response.statusCode,
url,
headers: response.headers,
body: ''
}
if (Buffer.isBuffer(responseBody)) {
forwardedResponseMessage.body = responseBody.toString('base64');
}
websocket.sendMessage(forwardedResponseMessage);
})
});
const requestBody : Buffer = Buffer.from(forwardedRequestMessage.body, 'base64');
request.write(requestBody);
request.on('error', (error : any) => {
log(error);
});
request.end();
}