Skip to content

Commit 7ead980

Browse files
author
Claudio
committed
updating socks version to support squid proxy
1 parent 982c872 commit 7ead980

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

socks.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@
4343
import socket
4444
import struct
4545
import sys
46+
import logging
4647

4748
PROXY_TYPE_SOCKS4 = 1
4849
PROXY_TYPE_SOCKS5 = 2
4950
PROXY_TYPE_HTTP = 3
51+
PROXY_TYPE_HTTP_NO_TUNNEL = 4
5052

5153
_defaultproxy = None
5254
_orgsocket = socket.socket
@@ -123,6 +125,7 @@ def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _soc
123125
self.__proxy = (None, None, None, None, None, None)
124126
self.__proxysockname = None
125127
self.__proxypeername = None
128+
self.__httptunnel = True
126129

127130
def __recvall(self, count):
128131
"""__recvall(count) -> data
@@ -136,6 +139,34 @@ def __recvall(self, count):
136139
data = data + d
137140
return data
138141

142+
def sendall(self, bytes):
143+
if 'encode' in dir(bytes):
144+
bytes = bytes.encode()
145+
if not self.__httptunnel:
146+
bytes = self.__rewriteproxy(bytes)
147+
socket.socket.sendall(self, bytes)
148+
149+
def __rewriteproxy(self, header):
150+
""" rewrite HTTP request headers to support non-tunneling proxies
151+
(i.e. thos which do not support the CONNECT method).
152+
This only works for HTTP (not HTTPS) since HTTPS requires tunneling.
153+
"""
154+
host, endpt = None, None
155+
hdrs = header.split("\r\n")
156+
for hdr in hdrs:
157+
if hdr.lower().startswith("host:"):
158+
host = hdr
159+
elif hdr.lower().startswith("get") or hdr.lower().startswith("post"):
160+
endpt = hdr
161+
if host and endpt:
162+
hdrs.remove(host)
163+
hdrs.remove(endpt)
164+
host = host.split(" ")[1]
165+
endpt = endpt.split(" ")
166+
hdrs.insert(0, "%s http://%s%s %s" % (endpt[0], host, endpt[1], endpt[2]))
167+
return "\r\n".join(hdrs)
168+
169+
139170
def setproxy(self, proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
140171
"""setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
141172
Sets the proxy to be used.
@@ -376,6 +407,17 @@ def connect(self, destpair):
376407
portnum = 8080
377408
_orgsocket.connect(self,(self.__proxy[1], portnum))
378409
self.__negotiatehttp(destpair[0], destpair[1])
410+
elif self.__proxy[0] == PROXY_TYPE_HTTP_NO_TUNNEL:
411+
if self.__proxy[2] != None:
412+
portnum = self.__proxy[2]
413+
else:
414+
portnum = 8080
415+
_orgsocket.connect(self,(self.__proxy[1],portnum))
416+
if 443 == destpair[1]:
417+
logging.warn("SSL connections (generally on port 443) require the use of tunneling - failing back to PROXY_TYPE_HTTP")
418+
self.__negotiatehttp(destpair[0],destpair[1])
419+
else:
420+
self.httptunnel = False
379421
elif self.__proxy[0] == None:
380422
_orgsocket.connect(self, (destpair[0], destpair[1]))
381423
else:

0 commit comments

Comments
 (0)