-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathclient.js
More file actions
145 lines (100 loc) · 3.25 KB
/
client.js
File metadata and controls
145 lines (100 loc) · 3.25 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env node
let net = require('net');
let conf = require('./config.js');
let proxy;
let tasks = {};
let createConnection = function (buf, taskId) {
let tcpConn = tasks[taskId] = net.connect(conf.shared.port, conf.shared.host, function () {
console.log('Connected to target #%d %s:%s', taskId, conf.shared.host, conf.shared.port);
tcpConn.write(buf);
});
tcpConn.on('error', function (error) {
console.log('Proxy-to-site connection #' + taskId + ' Error: ' + error.toString());
// tcpConn.end();
if (tasks[taskId]) {
let buf = Buffer.alloc(6);
buf.writeUInt16BE(taskId, 0);
buf.writeUInt32BE(0, 2);
proxy.write(buf);
delete tasks[taskId];
}
});
tcpConn.on('close', function () {
console.log('Connection closed target #' + taskId);
// tcpConn.end(buf);
if (tasks[taskId]) {
let buf = Buffer.alloc(6);
buf.writeUInt16BE(taskId, 0);
buf.writeUInt32BE(0, 2);
proxy.write(buf);
delete tasks[taskId];
}
});
tcpConn.on('data', function (data) {
console.log('Send data back for target #' + taskId + ', len=' + data.length);
let buf = Buffer.alloc(6);
buf.writeUInt16BE(taskId, 0);
buf.writeUInt32BE(data.length, 2);
buf = Buffer.concat([buf, data]);
proxy.write(buf);
});
};
function connect() {
if (proxy) {
proxy.destroy();
}
proxy = net.connect(conf.upstream.port, conf.upstream.host, function () {
console.log('Proxy connected to %s:%s', conf.upstream.host, conf.upstream.port);
});
proxy.on('error', function (error) {
console.log('proxy upstream Connection Error: ' + error.toString());
// if (error.errno === 'ECONNRESET')
// setTimeout(connect, 1000);
});
proxy.on('close', function () {
console.log('proxy upstream Connection Closed');
Object.keys(tasks).forEach(function (task) {
tasks[task].end();
});
setTimeout(connect, 1000);
});
let buf = Buffer.alloc(0);
proxy.on('data', function (data) {
buf = Buffer.concat([buf, data]);
while (buf.length >= 6) {
let taskId = buf.readInt16BE(0);
let size = buf.readInt32BE(2);
// Upstream informs - user close connection
if (!size) {
if (tasks[taskId]) {
console.log('Closing connection for request #%d', taskId);
tasks[taskId].end();
delete tasks[taskId];
}
buf = buf.slice(6);
}
else {
// Check completed frames in buffer
if (6 + size <= buf.length) {
console.log('New data from upsteam #%d, len=%d', taskId, size);
// If no such TaskId connection - create it!
if (!tasks[taskId]) {
// Make separate data since first send in callback - data buf may change
let bufLocal = buf.slice(6, size + 6);
createConnection(bufLocal, taskId);
}
else {
console.log('Send data to target #' + taskId);
tasks[taskId].write(buf.slice(6, size + 6));
}
buf = buf.slice(6 + size);
}
else {
// console.log('There are some partial data for request #' + taskId + ', len=' + (buf.length - 6) + ', needs=' + size);
break;
}
}
}
});
}
connect();