-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathproxy.py
More file actions
83 lines (69 loc) · 2.13 KB
/
proxy.py
File metadata and controls
83 lines (69 loc) · 2.13 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
# -*- coding: utf-8 -*-
from gevent.monkey import patch_all
patch_all()
import time
import socket
import sys
import signal
import gevent
from wsgiref.handlers import format_date_time
from gevent.server import StreamServer
from gevent.socket import (
create_connection,
gethostbyname,
)
LISTEN_PORT = 1235
SS_PORT = 9876
BUFFER_SIZE = 1024
class MixedTCPServer(StreamServer):
def __init__(self, listen_port, tcp_forward_port, **kwargs):
super().__init__('0.0.0.0:{}'.format(listen_port), **kwargs)
self.tcp_service = '127.0.0.1:{}'.format(tcp_forward_port)
def handle(self, source, address):
init_data = source.recv(BUFFER_SIZE)
try:
if len(init_data) > 3 and init_data[:3] == b'GET':
source.sendall(b'HTTP/1.1 200 OK\r\n' + format_date_time(time.time()).encode() + b'\r\n\r\nOK')
return
else:
dest = create_connection(self.tcp_service)
except IOError as ex:
sys.stderr.write('Error on create connection: {}'.format(ex))
return
forwarders = (
gevent.spawn(forward, source, dest, self),
gevent.spawn(forward, dest, source, self),
)
gevent.joinall(forwarders)
def close(self):
if not self.closed:
sys.stderr.write('Closing...')
super().close()
def forward(source, dest, server):
try:
while True:
try:
data = source.recv(BUFFER_SIZE)
if not data:
break
dest.sendall(data)
except KeyboardInterrupt:
if not server.closed:
server.close()
break
except socket.error:
if not server.closed:
server.close()
break
finally:
source.close()
dest.close()
server = None
def main():
server = MixedTCPServer(LISTEN_PORT, SS_PORT)
gevent.signal(signal.SIGTERM, server.close)
gevent.signal(signal.SIGINT, server.close)
server.start()
gevent.wait()
if __name__ == '__main__':
main()