httplib_proxy.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. '''
  2. Created on Jan 11, 2012
  3. @author: philipkershaw
  4. '''
  5. import socket
  6. from httplib import HTTPConnection as _HTTPConnection
  7. from httplib import HTTPException
  8. # maximal line length when calling readline().
  9. _MAXLINE = 65536
  10. class LineTooLong(HTTPException):
  11. def __init__(self, line_type):
  12. HTTPException.__init__(self, "got more than %d bytes when reading %s"
  13. % (_MAXLINE, line_type))
  14. class HTTPConnection(_HTTPConnection):
  15. NDG_HTTPSCLIENT = True
  16. def __init__(self, *arg, **kwarg):
  17. self._tunnel_host = None
  18. self._tunnel_port = None
  19. self._tunnel_headers = {}
  20. _HTTPConnection.__init__(self, *arg, **kwarg)
  21. def set_tunnel(self, host, port=None, headers=None):
  22. """ Sets up the host and the port for the HTTP CONNECT Tunnelling.
  23. The headers argument should be a mapping of extra HTTP headers
  24. to send with the CONNECT request.
  25. """
  26. self._tunnel_host = host
  27. self._tunnel_port = port
  28. if headers:
  29. self._tunnel_headers = headers
  30. else:
  31. self._tunnel_headers.clear()
  32. def _tunnel(self):
  33. self._set_hostport(self._tunnel_host, self._tunnel_port)
  34. self.send("CONNECT %s:%d HTTP/1.0\r\n" % (self.host, self.port))
  35. for header, value in self._tunnel_headers.iteritems():
  36. self.send("%s: %s\r\n" % (header, value))
  37. self.send("\r\n")
  38. response = self.response_class(self.sock, strict = self.strict,
  39. method = self._method)
  40. (version, code, message) = response._read_status()
  41. if code != 200:
  42. self.close()
  43. raise socket.error("Tunnel connection failed: %d %s" % (code,
  44. message.strip()))
  45. while True:
  46. line = response.fp.readline(_MAXLINE + 1)
  47. if len(line) > _MAXLINE:
  48. raise LineTooLong("header line")
  49. if line == '\r\n': break
  50. def connect(self):
  51. """Connect to the host and port specified in __init__."""
  52. _HTTPConnection.connect(self)
  53. if self._tunnel_host:
  54. self._tunnel()