Python socket with proxy. Authentication Error (407) - python

Thank you for reading.
I was able to make a request with a socket connected to a proxy. But, return a 407. That is, there is an error in authentication in the proxy.
I put a Headers ['proxy-yauthorization'], but it doesn't work. It is sent with Basic + "User: Pass" based64.
def http_proxy_connect(address, proxy = None, auth = None, headers = {}):
import socket
import base64
def valid_address(addr):
""" Verify that an IP/port tuple is valid """
return isinstance(addr, (list, tuple)) and len(addr) == 2 and isinstance(addr[0], str) and isinstance(addr[1], (int, int))
if not valid_address(address):
raise ValueError('Invalid target address')
if proxy == None:
s = socket.socket()
s.connect(address)
return s, 0, {}
if not valid_address(proxy):
raise ValueError('Invalid proxy address')
headers = {
'host': address[0]
}
headers['proxy-authorization'] = 'Basic ' + auth
headers['Proxy-Authorization'] = 'Basic ' + auth
headers['Proxy-Authenticate'] = 'Basic'
s = socket.socket()
s.connect(proxy)
fp = s.makefile('wr')
fp.write('CONNECT %s:%d HTTP/1.0\r\n' % address)
fp.write('\r\n'.join('%s: %s' % (k, v) for (k, v) in headers.items()) + '\r\n\r\n')
print('\r\n'.join('%s: %s' % (k, v) for (k, v) in headers.items()) + '\r\n\r\n')
fp.flush()
statusline = fp.readline().rstrip('\r\n')
if statusline.count(' ') < 2:
fp.close()
s.close()
raise IOError('Bad response')
version, status, statusmsg = statusline.split(' ', 2)
if not version in ('HTTP/1.0', 'HTTP/1.1'):
fp.close()
s.close()
raise IOError('Unsupported HTTP version')
try:
status = int(status)
except ValueError:
fp.close()
s.close()
raise IOError('Bad response')
response_headers = {}
while True:
tl = ''
l = fp.readline().rstrip('\r\n')
if l == '':
break
if not ':' in l:
continue
k, v = l.split(':', 1)
response_headers[k.strip().lower()] = v.strip()
fp.close()
return (s, status, response_headers)
print(http_proxy_connect(('xxxxx',80), ('xxxxx',50000), 'user:pass in base64!'));
I am currently sending in Headers ['proxy-yauthorization'], "Basic User: Pass" in base64.

Related

How to use proxy with Auth in socket (python) (make reflector ) [duplicate]

I'm on a network that requires me to connect through an authenticated HTTP proxy to access anything outside the network. What I need to do is basically to make a socket (or equivalent) to connect to the Internet, but sending all the data through the proxy instead of trying to send it directly. Any ideas as to how this could be done?
As I didn't find any actual modules or other code that I could use, I ended up writing my own function that connects through the proxy:
def http_proxy_connect(address, proxy = None, auth = None, headers = {}):
"""
Establish a socket connection through an HTTP proxy.
Arguments:
address (required) = The address of the target
proxy (def: None) = The address of the proxy server
auth (def: None) = A tuple of the username and password used for authentication
headers (def: {}) = A set of headers that will be sent to the proxy
Returns:
A 3-tuple of the format:
(socket, status_code, headers)
Where `socket' is the socket object, `status_code` is the HTTP status code that the server
returned and `headers` is a dict of headers that the server returned.
"""
import socket
import base64
def valid_address(addr):
""" Verify that an IP/port tuple is valid """
return isinstance(addr, (list, tuple)) and len(addr) == 2 and isinstance(addr[0], str) and isinstance(addr[1], (int, long))
if not valid_address(address):
raise ValueError('Invalid target address')
if proxy == None:
s = socket.socket()
s.connect(address)
return s, 0, {}
if not valid_address(proxy):
raise ValueError('Invalid proxy address')
headers = {
'host': address[0]
}
if auth != None:
if isinstance(auth, str):
headers['proxy-authorization'] = auth
elif auth and isinstance(auth, (tuple, list)):
if len(auth) == 1:
raise ValueError('Invalid authentication specification')
t = auth[0]
args = auth[1:]
if t.lower() == 'basic' and len(args) == 2:
headers['proxy-authorization'] = 'Basic ' + base64.b64encode('%s:%s' % args)
else:
raise ValueError('Invalid authentication specification')
else:
raise ValueError('Invalid authentication specification')
s = socket.socket()
s.connect(proxy)
fp = s.makefile('r+')
fp.write('CONNECT %s:%d HTTP/1.0\r\n' % address)
fp.write('\r\n'.join('%s: %s' % (k, v) for (k, v) in headers.items()) + '\r\n\r\n')
fp.flush()
statusline = fp.readline().rstrip('\r\n')
if statusline.count(' ') < 2:
fp.close()
s.close()
raise IOError('Bad response')
version, status, statusmsg = statusline.split(' ', 2)
if not version in ('HTTP/1.0', 'HTTP/1.1'):
fp.close()
s.close()
raise IOError('Unsupported HTTP version')
try:
status = int(status)
except ValueError:
fp.close()
s.close()
raise IOError('Bad response')
response_headers = {}
while True:
tl = ''
l = fp.readline().rstrip('\r\n')
if l == '':
break
if not ':' in l:
continue
k, v = l.split(':', 1)
response_headers[k.strip().lower()] = v.strip()
fp.close()
return (s, status, response_headers)
I'm not sure if this will be of much help, but have you taken a look to pycurl? This may help you to connect to the Proxy providing a username/password authentication system (see this and this)

argument for 's' must be a bytes object in Python 3.8

Why am I getting the error argument for 's' must be a bytes object when trying to run the lambda function? I'm following the usage example but I'm getting this error. Any explanation to this issue and how to resolve it?
{
"errorMessage": "Failed sending data.\nERROR: argument for 's' must be a bytes object",
"errorType": "Exception",
"stackTrace": [
" File \"/var/task/AlertMetricSender.py\", line 5, in lambda_handler\n sender.send()\n",
" File \"/var/task/modules/ZabbixSender.py\", line 91, in send\n self.__active_checks()\n",
" File \"/var/task/modules/ZabbixSender.py\", line 79, in __active_checks\n response = self.__request(request)\n",
" File \"/var/task/modules/ZabbixSender.py\", line 59, in __request\n raise Exception(\"Failed sending data.\\nERROR: %s\" % e)\n"
]
}
ZabbixSender.py:
#
# For sending metric value to zabbix server.
#
# You must create item as "zabbix trapper" on server.
# Because the server must be connected to agent:10050, if it is selected "zabbix agent".
#
# Usage:
# from modules.ZabbixSender import ZabbixSender
# ZABBIX_HOST = "zabbix.example.com"
# ZABBIX_PORT = 10051
# sender = ZabbixSender(ZABBIX_HOST, ZABBIX_PORT)
# sender.add("example-hostname-01", "healthcheck", 1)
# sender.add("example-hostname-01", "item.keyname", 0.123)
# sender.add("example-hostname-02", "item.keyname", 1234)
# sender.send()
#
import socket
import struct
import time
import json
class ZabbixSender:
log = True
def __init__(self, host='127.0.0.1', port=10051):
self.address = (host, port)
self.data = []
def __log(self, log):
if self.log: print(log)
def __connect(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.sock.connect(self.address)
except:
raise Exception("Can't connect server.")
def __close(self):
self.sock.close()
def __pack(self, request):
string = json.dumps(request)
header = struct.pack('<4sBQ', 'ZBXD', 1, len(string))
return header + string
def __unpack(self, response):
header, version, length = struct.unpack('<4sBQ', response[:13])
(data, ) = struct.unpack('<%ds'%length, response[13:13+length])
return json.loads(data)
def __request(self, request):
self.__connect()
try:
self.sock.sendall(self.__pack(request))
except Exception as e:
raise Exception("Failed sending data.\nERROR: %s" % e)
response = ''
while True:
data = self.sock.recv(4096)
if not data:
break
response += data
self.__close()
return self.__unpack(response)
def __active_checks(self):
hosts = set()
for d in self.data:
hosts.add(d['host'])
for h in hosts:
request = {"request":"active checks", "host":h}
self.__log("[active check] %s" % h)
response = self.__request(request)
if not response['response'] == 'success': self.__log("[host not found] %s" % h)
def add(self, host, key, value, clock=None):
if clock is None: clock = int(time.time())
self.data.append({"host":host, "key":key, "value":value, "clock":clock})
def send(self):
if not self.data:
self.__log("Not found sender data, end without sending.")
return False
self.__active_checks()
request = {"request":"sender data", "data":self.data}
response = self.__request(request)
result = True if response['response'] == 'success' else False
if result:
for d in self.data:
self.__log("[send data] %s" % d)
self.__log("[send result] %s" % response['info'])
else:
raise Exception("Failed send data.")
return result
if __name__ == '__main__':
sender = ZabbixSender()
sender.add("gedowfather-example-01", "healthcheck", 1)
sender.add("gedowfather-example-01", "gedow.item", 1111)
sender.send()
AlertMetricSender.py:
from modules.ZabbixSender import ZabbixSender
def lambda_handler(event, context):
sender = ZabbixSender("10.10.10.10", 10051)
sender.add("Zabbix server", "lambda.test", 5)
sender.send()
The error is coming from struct.pack. You're not seeing that, because of your blanket try/except.
All socket activity is done in byte strings, not Unicode strings. You need this:
def __pack(self, request):
string = json.dumps(request).encode('utf-8')
header = b'ZBXD' + struct.pack('<BQ', 1, len(string))
return header + string
One subtle thing about this: You must convert to a bytes string BEFORE you do len(string). It's quite possible for the conversion to UTF-8 to increase the number of characters in the string.
AND I absolutely need to comment on this:
result = True if response['response'] == 'success' else False
What led you to write that? This is exactly the same as the much more natural reading:
result = response['response'] == 'success'

Is there any way to repair this error with POST data in python?

I need to check the compatibility of the GPS device communication protocol with the logging server. The application allows you to perform a test that compares the sent frame with the protocols it supports and checks whether it is possible to read this frame by already supported protocols. For this purpose, I wanted to use the shared test, but I get an error.
https://github.com/traccar/traccar/blob/master/tools/test-integration.py
```
import sys
import os
import xml.etree.ElementTree
import urllib
import urllib.parse
import urllib.request as urllib2
import json
import socket
import time
messages = {
'gps103' : 'imei:123456789012345,help me,1201011201,,F,120100.000,A,6000.0000,N,13000.0000,E,0.00,;'
}
baseUrl = 'http://172.16.43.210:8082'
user = { 'email' : 'admin', 'password' : 'admin' }
debug = '-v' in sys.argv
def load_ports():
ports = {}
dir = os.path.dirname(os.path.abspath(__file__))
root = xml.etree.ElementTree.parse(dir + '\\default.xml').getroot()
for entry in root.findall('entry'):
key = entry.attrib['key']
if key.endswith('.port'):
ports[key[:-5]] = int(entry.text)
if debug:
print('\nports: %s\n' % repr(ports))
return ports
def login():
request = urllib2.Request(baseUrl + '/api/session')
response = urllib2.urlopen(request, urllib.parse.urlencode(user))
if debug:
print('\nlogin: %s\n' % repr(json.load(response)))
return response.headers.get('Set-Cookie')
def remove_devices(cookie):
request = urllib2.Request(baseUrl + '/api/devices')
request.add_header('Cookie', cookie)
response = urllib2.urlopen(request)
data = json.load(response)
if debug:
print ('\ndevices: %s\n' % repr(data))
for device in data:
request = urllib2.Request(baseUrl + '/api/devices/' + str(device['id']))
request.add_header('Cookie', cookie)
request.get_method = lambda: 'DELETE'
response = urllib2.urlopen(request)
def add_device(cookie, unique_id):
request = urllib2.Request(baseUrl + '/api/devices')
request.add_header('Cookie', cookie)
request.add_header('Content-Type', 'application/json')
device = { 'name' : unique_id, 'uniqueId' : unique_id }
response = urllib2.urlopen(request, json.dumps(device))
data = json.load(response)
return data['id']
def send_message(port, message):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', port))
s.send(message)
s.close()
def get_protocols(cookie, device_id):
params = { 'deviceId' : device_id, 'from' : '2000-01-01T00:00:00.000Z', 'to' : '2050-01-01T00:00:00.000Z' }
request = urllib2.Request(baseUrl + '/api/positions?' + urllib.urlencode(params))
request.add_header('Cookie', cookie)
request.add_header('Content-Type', 'application/json')
request.add_header('Accept', 'application/json')
response = urllib2.urlopen(request)
protocols = []
for position in json.load(response):
protocols.append(position['protocol'])
return protocols
ports = load_ports()
cookie = login()
remove_devices(cookie)
devices = {
'123456789012345' : add_device(cookie, '123456789012345'),
'123456789012' : add_device(cookie, '123456789012'),
'1234567890' : add_device(cookie, '1234567890'),
'123456' : add_device(cookie, '123456'),
'1234' : add_device(cookie, '1234')
}
all = set(ports.keys())
protocols = set(messages.keys())
print ('Total: %d' % len(all))
print ('Missing: %d' % len(all - protocols))
print ('Covered: %d' % len(protocols))
#if all - protocols:
# print '\nMissing: %s\n' % repr(list((all - protocols)))
for protocol in messages:
send_message(ports[protocol], messages[protocol])
time.sleep(10)
for device in devices:
protocols -= set(get_protocols(cookie, devices[device]))
print ('Success: %d' % (len(messages) - len(protocols)))
print ('Failed: %d' % len(protocols))
if protocols:
print ('\nFailed: %s' % repr(list(protocols)))
```
And i got this error:
File "C:\Users\ISUIT\Desktop\Ew.Prac\tt.py", line 159, in <module>
cookie = login()
File "C:\Users\ISUIT\Desktop\Ew.Prac\tt.py", line 112, in login
response = urllib2.urlopen(request, urllib.parse.urlencode(user))
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1776.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 214, in urlopen
return opener.open(url, data, timeout)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1776.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 514, in open
req = meth(req)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1776.0_x64__qbz5n2kfra8p0\lib\urllib\request.py", line 1277, in do_request_
raise TypeError(msg)
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
I try to use bytes(string, 'utf-8') but it doesn't work
Use string.encode('utf-8') to cast the type to bytes.

Python Server Logger

I need some help figuring out why this isn't working the way it should. The goal was to stand up a local python server (similar to SimpleHTTPServer) but have it log requests/responses to a file to get a better understanding of how browser DOM behaves. I want to be able to browse to localhost and have it react like a webserver would.
When using this it appears to be hanging at localhost and not redirecting it the 'sample.html' file. Any thoughts on why this might be happening?
Code:
import os, re, socket, thread, threading;
# Settings that you may want to change:
WEBSERVER_PORT = 28876;
LOGS_FOLDER = os.path.join(os.getcwd(), 'logs');
TEST_HTML = 'sample.html';
VERBOSE_OUTPUT = True;
# Settings that you may need to change if you add new file types:
DEFAULT_MIME_TYPE = 'application/octet-stream';
REGISTERED_MIME_TYPES = {
'text/html': ['htm', 'html'],
'text/javascript': ['js'],
'image/svg+xml': ['svg'],
'image/jpeg': ['jpg'],
};
def MimeType(path):
last_dot = path.rfind('.');
if last_dot != -1:
ext = path[last_dot + 1:].lower();
for mime_type, exts in REGISTERED_MIME_TYPES.items():
if ext in exts:
return mime_type;
return DEFAULT_MIME_TYPE;
def GenerateRedirect(new_path):
return (301, 'Moved permanently', \
['Location: http://localhost:%s%s' % (WEBSERVER_PORT, new_path)], \
'text/html', '%s' % (new_path, new_path));
def Reply404(path, query, data):
return 404, 'Not found', 'text/plain', 'The path %s was not found' % path;
def ReplyFile(path, query, data):
path = os.path.join(os.getcwd(), path[1:].replace(os.altsep, os.sep));
if os.path.isfile(path):
try:
data = open(path, 'rb').read();
except:
print ' Cannot open file %s' % path;
return 500, 'Internal server error', 'text/plain', \
'The path %s could not be read' % path;
if VERBOSE_OUTPUT:
print ' Reply = file %s' % path;
return 200, 'OK', MimeType(path), data;
print ' Cannot find file %s' % path;
return 404, 'Not found', 'text/plain', 'The path %s was not found' % path;
def ReplyLog(path, query, data):
path = os.path.join(LOGS_FOLDER, path[len('/logs/'):].replace('/', os.sep));
try:
open(path, 'ab').write(data + '\r\n');
except:
print ' Cannot write to log file %s' % path;
return 500, 'Internal server error', 'text/plain', \
'The path %s could not be read' % path;
if VERBOSE_OUTPUT:
print ' Wrote %s bytes to log file %s' % (len(data), path);
return 200, 'OK', 'text/plain', 'Log successful';
# Replies contains entries in one of two forms:
# "regexp": ("mimetype", "body"),
# "regexp": function,
# The first form causes the server to reply with "200 OK" and the given body and
# mimetype. The second form requires "function" to accept the HTTP request path
# as an argument and return a tuple containing the HTTP return code, HTTP reason
# message, mimetype and body.
replies = [
(r'^/$', GenerateRedirect('/' + TEST_HTML)),
(r'^/logs/.*$', ReplyLog),
(r'^.*$', ReplyFile),
];
def Main():
if not os.path.isdir(LOGS_FOLDER):
try:
os.mkdir(LOGS_FOLDER);
except:
print 'Cannot create logs folder %s' % LOGS_FOLDER;
return;
server_socket = socket.socket();
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
server_socket.bind(('', WEBSERVER_PORT));
server_socket.listen(1);
print 'Webserver running at http://localhost:%d/' % WEBSERVER_PORT;
print;
thread_counter = 1;
while 1:
client_socket, client_address = server_socket.accept();
thread = threading.Thread(target = ConnectionThread, \
args = (client_socket, client_address));
thread.start();
thread_counter += 1;
def ConnectionThread(client_socket, client_address):
try:
print '** Connection from %s:%s opened.' % client_address;
while 1:
try:
request_headers, request_content = ReadRequest(client_socket);
if request_headers is None:
break;
response = HandleRequest(request_headers, request_content);
try:
client_socket.send(response);
except socket.error, e:
raise ConnectionError('Cannot send response');
except ConnectionError, e:
print ' ConnectionError: %s' % e;
try:
client_socket.close();
except:
pass;
break;
print '** Connection from %s:%s closed' % client_address;
except:
thread.interrupt_main();
class ConnectionError(Exception):
def __init__(self, value):
self.value = value;
def __str__(self):
return self.value;
def GetContentLength(request_headers):
for request_header in request_headers:
if request_header.find(':') != -1:
name, value = request_header.split(':', 1);
if name.strip().lower() == 'content-length':
try:
return int(value);
except ValueError:
raise ConnectionError('Bad content-length value: %s' % value);
return None;
def ReadRequest(client_socket):
request = '';
request_headers = None;
request_headers_length = None;
if VERBOSE_OUTPUT:
print '>> Accepted request, reading headers...',;
while request_headers is None:
try:
request += client_socket.recv(256);
except socket.error, e:
if VERBOSE_OUTPUT:
print;
raise ConnectionError('Connection dropped while reading request headers.');
if len(request) == 0:
if VERBOSE_OUTPUT:
print;
# raise ConnectionError('Connection closed.');
return None, None;
request_headers_length = request.find('\r\n\r\n');
if request_headers_length != -1:
request_headers = request[:request_headers_length].split('\r\n')[:-1];
# One line breaks is part of the headers
request_headers_length += 2;
# The other is not part of the headers or the content:
request_content_length = GetContentLength(request_headers);
if request_content_length is None:
if VERBOSE_OUTPUT:
print '\r>> Accepted request, read %d bytes of headers and ' \
'no content.' % (request_headers_length);
return request_headers, None;
request_content = request[request_headers_length + 2:];
else:
if VERBOSE_OUTPUT:
print '\r>> Accepted request, read %d bytes of headers...' % \
len(request),;
while len(request_content) < request_content_length:
if VERBOSE_OUTPUT:
print '\r>> Accepted request, read %d bytes of headers and ' \
'%d/%d bytes of content...' % (request_headers_length, \
len(request_content), request_content_length),;
read_size = request_content_length - len(request_content);
try:
request_content += client_socket.recv(read_size);
except socket.error, e:
if VERBOSE_OUTPUT:
print;
raise ConnectionError('Connection dropped while reading request content.');
if VERBOSE_OUTPUT:
print '\r>> Accepted request, read %d bytes of headers and ' \
'%d bytes of content. %s' % (request_headers_length, \
len(request_content), ' ' * len(str(request_content_length)));
return request_headers, request_content;
def HandleRequest(request_headers, request_content):
end_method = request_headers[0].find(' ');
if end_method == -1:
raise ConnectionError('Bad request header; no method recognized');
method = request_headers[0][:end_method];
end_path = request_headers[0].find(' ', end_method + 1);
if end_path == -1:
raise ConnectionError('Bad request header; no path recognized');
path = request_headers[0][end_method + 1:end_path];
query = None;
start_query = path.find('?');
if start_query != -1:
query = path[start_query:];
path = path[:start_query];
if VERBOSE_OUTPUT:
print ' method=%s, path=%s, query=%s, %s headers' % \
(method, path, query, len(request_headers));
code, reason, mime_type, body = 404, 'Not found', 'text/plain', 'Not found';
response = None;
for path_regexp, response in replies:
if re.match(path_regexp, path):
if type(response) != tuple:
response = response(path, query, request_content);
break;
assert type(response) == tuple and len(response) in [2, 4, 5], \
'Invalid response tuple %s' % repr(response);
code, reason, headers, mime_type, body = 200, 'OK', [], 'text/plain', '';
if len(response) == 2:
mime_type, body = response;
elif len(response) == 4:
code, reason, mime_type, body = response;
else:
code, reason, headers, mime_type, body = response;
response_lines = [
'HTTP/1.1 %03d %s' % (code, reason),
'Content-Type: %s' % mime_type,
'Date: Sat Aug 28 1976 09:15:00 GMT',
'Expires: Sat Aug 28 1976 09:15:00 GMT',
'Cache-Control: no-cache, must-revalidate',
'Pragma: no-cache',
'Accept-Ranges: bytes',
'Content-Length: %d' % len(body),
] + headers + [
'',
body
];
response = '\r\n'.join(response_lines);
if VERBOSE_OUTPUT:
print '<< %s (%d bytes %s)' % \
(response.split('\r\n')[0], len(response), mime_type);
return response;
if __name__ == "__main__":
Main();
Any feedback would be greatly appreciated.
Thank you!

Establishing a TCP connection through an authenticated HTTP proxy?

I'm on a network that requires me to connect through an authenticated HTTP proxy to access anything outside the network. What I need to do is basically to make a socket (or equivalent) to connect to the Internet, but sending all the data through the proxy instead of trying to send it directly. Any ideas as to how this could be done?
As I didn't find any actual modules or other code that I could use, I ended up writing my own function that connects through the proxy:
def http_proxy_connect(address, proxy = None, auth = None, headers = {}):
"""
Establish a socket connection through an HTTP proxy.
Arguments:
address (required) = The address of the target
proxy (def: None) = The address of the proxy server
auth (def: None) = A tuple of the username and password used for authentication
headers (def: {}) = A set of headers that will be sent to the proxy
Returns:
A 3-tuple of the format:
(socket, status_code, headers)
Where `socket' is the socket object, `status_code` is the HTTP status code that the server
returned and `headers` is a dict of headers that the server returned.
"""
import socket
import base64
def valid_address(addr):
""" Verify that an IP/port tuple is valid """
return isinstance(addr, (list, tuple)) and len(addr) == 2 and isinstance(addr[0], str) and isinstance(addr[1], (int, long))
if not valid_address(address):
raise ValueError('Invalid target address')
if proxy == None:
s = socket.socket()
s.connect(address)
return s, 0, {}
if not valid_address(proxy):
raise ValueError('Invalid proxy address')
headers = {
'host': address[0]
}
if auth != None:
if isinstance(auth, str):
headers['proxy-authorization'] = auth
elif auth and isinstance(auth, (tuple, list)):
if len(auth) == 1:
raise ValueError('Invalid authentication specification')
t = auth[0]
args = auth[1:]
if t.lower() == 'basic' and len(args) == 2:
headers['proxy-authorization'] = 'Basic ' + base64.b64encode('%s:%s' % args)
else:
raise ValueError('Invalid authentication specification')
else:
raise ValueError('Invalid authentication specification')
s = socket.socket()
s.connect(proxy)
fp = s.makefile('r+')
fp.write('CONNECT %s:%d HTTP/1.0\r\n' % address)
fp.write('\r\n'.join('%s: %s' % (k, v) for (k, v) in headers.items()) + '\r\n\r\n')
fp.flush()
statusline = fp.readline().rstrip('\r\n')
if statusline.count(' ') < 2:
fp.close()
s.close()
raise IOError('Bad response')
version, status, statusmsg = statusline.split(' ', 2)
if not version in ('HTTP/1.0', 'HTTP/1.1'):
fp.close()
s.close()
raise IOError('Unsupported HTTP version')
try:
status = int(status)
except ValueError:
fp.close()
s.close()
raise IOError('Bad response')
response_headers = {}
while True:
tl = ''
l = fp.readline().rstrip('\r\n')
if l == '':
break
if not ':' in l:
continue
k, v = l.split(':', 1)
response_headers[k.strip().lower()] = v.strip()
fp.close()
return (s, status, response_headers)
I'm not sure if this will be of much help, but have you taken a look to pycurl? This may help you to connect to the Proxy providing a username/password authentication system (see this and this)

Categories