forked from http-party/node-http-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathws-incoming.js
107 lines (87 loc) · 2.42 KB
/
ws-incoming.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
var http = require('http'),
https = require('https'),
common = require('../common'),
passes = exports;
/*!
* Array of passes.
*
* A `pass` is just a function that is executed on `req, socket, options`
* so that you can easily add new checks while still keeping the base
* flexible.
*/
/*
* Websockets Passes
*
*/
var passes = exports;
[
/**
* WebSocket requests must have the `GET` method and
* the `upgrade:websocket` header
*/
function checkMethodAndHeader (req, socket) {
if (req.method !== 'GET' || !req.headers.upgrade) {
socket.destroy(); return true;
}
if (req.headers.upgrade.toLowerCase() !== 'websocket') {
socket.destroy(); return true;
}
},
/**
* Setup socket
*
*/
function setupSocket(req, socket) {
socket.setTimeout(0);
socket.setNoDelay(true);
socket.setKeepAlive(true, 0);
},
/**
* Sets `x-forwarded-*` headers if specified in config.
*
*/
function XHeaders(req, socket, options) {
if(!options.xfwd) return;
var values = {
for : req.connection.remoteAddsockets || req.socket.remoteAddsockets,
port : req.connection.remotePort || req.socket.remotePort,
proto: req.connection.pair ? 'wss' : 'ws'
};
['for', 'port', 'proto'].forEach(function(header) {
req.headers['x-forwarded-' + header] =
(req.headers['x-forwarded-' + header] || '') +
(req.headers['x-forwarded-' + header] ? ',' : '') +
values[header]
});
},
/**
*
*
*/
function stream(req, socket, options, head) {
common.setupSocket(socket);
var proxyReq = (~['https:', 'wss:'].indexOf(options.target.protocol) ? https : http).request(
common.setupOutgoing(options.ssl || {}, options, req)
);
proxyReq.on('error', function(err){
var ev = 'caronte:outgoing:ws:';
if (options.ee.listeners(ev + 'error').length == 0){
throw err;
}
options.ee.emit(ev + 'error', err, req, res);
});
proxyReq.on('upgrade', function(proxyRes, proxySocket, proxyHead) {
common.setupSocket(proxySocket);
if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead);
socket.write('HTTP/1.1 101 Switching Protocols\r\n');
socket.write(Object.keys(proxyRes.headers).map(function(i) {
return i + ": " + proxyRes.headers[i];
}).join('\r\n') + '\r\n\r\n');
proxySocket.pipe(socket).pipe(proxySocket);
});
proxyReq.end(); // XXX: CHECK IF THIS IS THIS CORRECT
}
] // <--
.forEach(function(func) {
passes[func.name] = func;
});