Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aggvpn
GitHub Repository: aggvpn/ws
Path: blob/main/websocket-python/cdn-ssl.py
567 views
1
import socket, threading, thread, select, signal, sys, time, getopt
2
3
# Listen
4
LISTENING_ADDR = '127.0.0.1'
5
if sys.argv[1:]:
6
LISTENING_PORT = sys.argv[1]
7
else:
8
LISTENING_PORT = 700
9
#Pass
10
PASS = ''
11
12
# CONST
13
BUFLEN = 4096 * 4
14
TIMEOUT = 60
15
DEFAULT_HOST = '127.0.0.1:69'
16
RESPONSE = 'HTTP/1.1 101 Script By Virtual\r\n\r\n'
17
#RESPONSE = 'HTTP/1.1 200 Hello_World!\r\nContent-length: 0\r\n\r\nHTTP/1.1 200 Connection established\r\n\r\n' # lint:ok
18
19
class Server(threading.Thread):
20
def __init__(self, host, port):
21
threading.Thread.__init__(self)
22
self.running = False
23
self.host = host
24
self.port = port
25
self.threads = []
26
self.threadsLock = threading.Lock()
27
self.logLock = threading.Lock()
28
29
def run(self):
30
self.soc = socket.socket(socket.AF_INET)
31
self.soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
32
self.soc.settimeout(2)
33
intport = int(self.port)
34
self.soc.bind((self.host, intport))
35
self.soc.listen(0)
36
self.running = True
37
38
try:
39
while self.running:
40
try:
41
c, addr = self.soc.accept()
42
c.setblocking(1)
43
except socket.timeout:
44
continue
45
46
conn = ConnectionHandler(c, self, addr)
47
conn.start()
48
self.addConn(conn)
49
finally:
50
self.running = False
51
self.soc.close()
52
53
def printLog(self, log):
54
self.logLock.acquire()
55
print log
56
self.logLock.release()
57
58
def addConn(self, conn):
59
try:
60
self.threadsLock.acquire()
61
if self.running:
62
self.threads.append(conn)
63
finally:
64
self.threadsLock.release()
65
66
def removeConn(self, conn):
67
try:
68
self.threadsLock.acquire()
69
self.threads.remove(conn)
70
finally:
71
self.threadsLock.release()
72
73
def close(self):
74
try:
75
self.running = False
76
self.threadsLock.acquire()
77
78
threads = list(self.threads)
79
for c in threads:
80
c.close()
81
finally:
82
self.threadsLock.release()
83
84
85
class ConnectionHandler(threading.Thread):
86
def __init__(self, socClient, server, addr):
87
threading.Thread.__init__(self)
88
self.clientClosed = False
89
self.targetClosed = True
90
self.client = socClient
91
self.client_buffer = ''
92
self.server = server
93
self.log = 'Connection: ' + str(addr)
94
95
def close(self):
96
try:
97
if not self.clientClosed:
98
self.client.shutdown(socket.SHUT_RDWR)
99
self.client.close()
100
except:
101
pass
102
finally:
103
self.clientClosed = True
104
105
try:
106
if not self.targetClosed:
107
self.target.shutdown(socket.SHUT_RDWR)
108
self.target.close()
109
except:
110
pass
111
finally:
112
self.targetClosed = True
113
114
def run(self):
115
try:
116
self.client_buffer = self.client.recv(BUFLEN)
117
118
hostPort = self.findHeader(self.client_buffer, 'X-Real-Host')
119
120
if hostPort == '':
121
hostPort = DEFAULT_HOST
122
123
split = self.findHeader(self.client_buffer, 'X-Split')
124
125
if split != '':
126
self.client.recv(BUFLEN)
127
128
if hostPort != '':
129
passwd = self.findHeader(self.client_buffer, 'X-Pass')
130
131
if len(PASS) != 0 and passwd == PASS:
132
self.method_CONNECT(hostPort)
133
elif len(PASS) != 0 and passwd != PASS:
134
self.client.send('HTTP/1.1 400 WrongPass!\r\n\r\n')
135
elif hostPort.startswith('127.0.0.1') or hostPort.startswith('localhost'):
136
self.method_CONNECT(hostPort)
137
else:
138
self.client.send('HTTP/1.1 403 Forbidden!\r\n\r\n')
139
else:
140
print '- No X-Real-Host!'
141
self.client.send('HTTP/1.1 400 NoXRealHost!\r\n\r\n')
142
143
except Exception as e:
144
self.log += ' - error: ' + e.strerror
145
self.server.printLog(self.log)
146
pass
147
finally:
148
self.close()
149
self.server.removeConn(self)
150
151
def findHeader(self, head, header):
152
aux = head.find(header + ': ')
153
154
if aux == -1:
155
return ''
156
157
aux = head.find(':', aux)
158
head = head[aux+2:]
159
aux = head.find('\r\n')
160
161
if aux == -1:
162
return ''
163
164
return head[:aux];
165
166
def connect_target(self, host):
167
i = host.find(':')
168
if i != -1:
169
port = int(host[i+1:])
170
host = host[:i]
171
else:
172
if self.method=='CONNECT':
173
port = 443
174
else:
175
port = sys.argv[1]
176
177
(soc_family, soc_type, proto, _, address) = socket.getaddrinfo(host, port)[0]
178
179
self.target = socket.socket(soc_family, soc_type, proto)
180
self.targetClosed = False
181
self.target.connect(address)
182
183
def method_CONNECT(self, path):
184
self.log += ' - CONNECT ' + path
185
186
self.connect_target(path)
187
self.client.sendall(RESPONSE)
188
self.client_buffer = ''
189
190
self.server.printLog(self.log)
191
self.doCONNECT()
192
193
def doCONNECT(self):
194
socs = [self.client, self.target]
195
count = 0
196
error = False
197
while True:
198
count += 1
199
(recv, _, err) = select.select(socs, [], socs, 3)
200
if err:
201
error = True
202
if recv:
203
for in_ in recv:
204
try:
205
data = in_.recv(BUFLEN)
206
if data:
207
if in_ is self.target:
208
self.client.send(data)
209
else:
210
while data:
211
byte = self.target.send(data)
212
data = data[byte:]
213
214
count = 0
215
else:
216
break
217
except:
218
error = True
219
break
220
if count == TIMEOUT:
221
error = True
222
if error:
223
break
224
225
226
def print_usage():
227
print 'Usage: proxy.py -p <port>'
228
print ' proxy.py -b <bindAddr> -p <port>'
229
print ' proxy.py -b 0.0.0.0 -p 80'
230
231
def parse_args(argv):
232
global LISTENING_ADDR
233
global LISTENING_PORT
234
235
try:
236
opts, args = getopt.getopt(argv,"hb:p:",["bind=","port="])
237
except getopt.GetoptError:
238
print_usage()
239
sys.exit(2)
240
for opt, arg in opts:
241
if opt == '-h':
242
print_usage()
243
sys.exit()
244
elif opt in ("-b", "--bind"):
245
LISTENING_ADDR = arg
246
elif opt in ("-p", "--port"):
247
LISTENING_PORT = int(arg)
248
249
250
def main(host=LISTENING_ADDR, port=LISTENING_PORT):
251
print "\n:-------PythonProxy-------:\n"
252
print "Listening addr: " + LISTENING_ADDR
253
print "Listening port: " + str(LISTENING_PORT) + "\n"
254
print ":-------------------------:\n"
255
server = Server(LISTENING_ADDR, LISTENING_PORT)
256
server.start()
257
while True:
258
try:
259
time.sleep(2)
260
except KeyboardInterrupt:
261
print 'Stopping...'
262
server.close()
263
break
264
265
####### parse_args(sys.argv[1:])
266
if __name__ == '__main__':
267
main()
268
269