# net.py -- Connection, HttpProxyConnection classes
#
# Copyright (C) 2003 Manish Jethani (manish_jethani AT yahoo.com)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import socket
import httplib
from string import split,join
class Connection: # generic tcp connection wrapper
def __init__(self, server):
self.socket = None
self.server = server
def establish(self):
if self.socket == None:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = (self.server[0], int(self.server[1]))
s.connect(server)
self.socket = s
return self.socket
def send_data(self, buf):
return self.socket.send(buf)
def receive_data(self, bufsize):
return self.socket.recv(bufsize)
def send_data_all(self, buf):
total = len(buf)
sent = 0
while sent < total:
sent = sent + self.send_data(buf[sent:])
return sent
def send_data_line(self, line):
# print "C:" + line #XXX
return self.send_data_all(line) + self.send_data_all('\r\n')
def receive_data_line(self):
cnt = 0
buf = ''
while 1:
in_byte = self.receive_data(1)
if in_byte == '':
return None
if in_byte == '\r':
cnt = 1
elif in_byte == '\n' and cnt == 1:
cnt = 2
else:
cnt = 0
buf = buf + in_byte
if cnt == 2:
# print "S:" + buf #XXX
return buf
def break_(self):
self.socket.shutdown(2)
self.socket.close()
self.socket = None
class HttpProxyConnection(Connection): # http tunnelling
def __init__(self, server, proxy):
Connection.__init__(self, server)
self.proxy = proxy
def establish(self):
tmp = self.server
self.server = self.proxy
try:
Connection.establish(self)
finally:
self.server = tmp
connect_str = 'CONNECT ' + self.server[0] \
+ ':' + str(self.server[1]) \
+ ' HTTP/1.0\r\n'
self.send_data_all(connect_str)
self.send_data_all('User-Agent: msnp.py\r\n')
self.send_data_all('Host: ' + self.server[0] + '\r\n')
self.send_data_all('\r\n')
status = -1
while 1:
buf = self.receive_data_line()
if status == -1:
resp = split(buf, ' ', 2)
if len(resp) > 1:
status = int(resp[1])
else:
status = 0
if buf == '\r\n':
break
if status != 200:
self.socket = None
return self.socket
class HTTPSConnection(httplib.HTTPSConnection):
# httplib.HTTPSConnection with HTTP proxy support
def __init__(self, host, port = None, key_file = None, cert_file = None,
strict = None, http_proxy = None):
httplib.HTTPSConnection.__init__(self, host, port, key_file, cert_file,
strict)
self.http_proxy = http_proxy
def connect(self):
if self.http_proxy:
conn = HttpProxyConnection((self.host, self.port), self.http_proxy)
conn.establish()
sock = conn.socket
ssl = socket.ssl(sock, self.key_file, self.cert_file)
self.sock = httplib.FakeSocket(sock, ssl)
else:
httplib.HTTPSConnection.connect(self)
# vim: set ts=4 sw=4 et tw=79 :
|