forked from kirm/sip.js
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathwebsocket-proxy.js
More file actions
94 lines (77 loc) · 2.19 KB
/
websocket-proxy.js
File metadata and controls
94 lines (77 loc) · 2.19 KB
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
var sip = require('./sip.js');
var contexts = {};
function makeContextId(msg) {
var v = msg.headers.via[0];
return [v.params.branch, v.protocol, v.host, v.port, msg.headers['call-id'], msg.headers.cseq.seq];
}
function Proxy(options, route) {
var self = this;
var trans;
self.stop = function() { if (trans) trans.stop(); delete trans; };
self.handler = function(req, rem) {
if (req.method === 'CANCEL') {
var ctx = contexts[makeContextId(req)];
if (ctx) {
trans.send(trans.makeResponse(req, 200));
ctx.cancelled = true;
if (ctx.cancellers)
Object.keys(ctx.cancellers).forEach(function(c) { ctx.cancellers[c](); });
}
else
trans.send(sip.makeResponse(req, 481));
return;
}
var id = makeContextId(req);
contexts[id] = { cancellers: {} };
try {
route(self, sip.copyMessage(req), rem);
} catch(e) {
delete contexts[id];
throw e;
}
}
self.send = function(msg, callback) {
var ctx = contexts[makeContextId(msg)];
if (!ctx) return trans.send.apply(trans, arguments);
return msg.method
? self.forwardRequest(ctx, msg, callback || self.defaultCallback)
: self.forwardResponse(ctx, msg);
}
self.forwardRequest = function(ctx, req, callback) {
self.send(req, function(res, rem) {
var via = res.headers.via[0];
if (+res.status < 200) {
ctx.cancellers[via.params.branch] = function() { self.sendCancel(req, via); };
if (ctx.cancelled) self.sendCancel(req, via);
}
else
delete ctx.cancellers[via.params.branch];
callback(res, rem);
});
}
self.forwardResponse = function(ctx, res, callback) {
if (+res.status >= 200) delete contexts[makeContextId(res)];
trans.send(res);
}
self.defaultCallback = function(res) {
res.headers.via.shift();
self.send(res);
}
self.sendCancel = function(req, via) {
trans.send({
method : 'CANCEL',
uri : req.uri,
headers : {
via : [via],
to : req.headers.to,
from : req.headers.from,
'call-id': req.headers['call-id'],
cseq : {method: 'CANCEL', seq: req.headers.cseq.seq}
}
});
}
trans = sip.create({ws:true, tcp:false, udp:false, address:options.address, port:options.port},
self.handler);
self.trans = trans;
}
module.exports = Proxy;