"""HTTP client class

See the following URL for a description of the HTTP/1.0 protocol:
http://www.w3.org/hypertext/WWW/Protocols/
(I actually implemented it from a much earlier draft.)

Example:

>>> from httplib import HTTP
>>> h = HTTP('www.python.org')
>>> h.putrequest('GET', '/index.html')
>>> h.putheader('Host', 'www.python.org')
>>> h.putheader('Accept', 'text/html')
>>> h.putheader('Accept', 'text/plain')
>>> h.endheaders()
>>> errcode, errmsg, headers = h.getreply()
>>> if errcode == 200:
...     f = h.getfile()
...     print f.read() # Print the raw HTML
...
<HEAD>
<TITLE>Python Language Home Page</TITLE>
[...many more lines...]
>>>

Note that an HTTP object is used for a single request -- to issue a
second request to the same server, you create a new HTTP object.
(This is in accordance with the protocol, which uses a new TCP
connection for each request.)
"""

import os
import socket
import string
import mimetools

try:
    from cStringIO import StringIO
except:
    from StringIO import StringIO

HTTP_VERSION = 'HTTP/1.0'
HTTP_PORT = 80
HTTPS_PORT = 443

class FakeSocket:
    def __init__(self, sock, ssl):
        self.__sock = sock
        self.__ssl = ssl
        return

    def makefile(self, mode):           # hopefully, never have to write
        msgbuf = ""
        while 1:
            try:
                msgbuf = msgbuf + self.__ssl.read()
            except socket.sslerror, msg:
                break
        return StringIO(msgbuf)

    def send(self, stuff, flags = 0):
        return self.__ssl.write(stuff)

    def recv(self, len = 1024, flags = 0):
        return self.__ssl.read(len)

    def __getattr__(self, attr):
        return getattr(self.__sock, attr)

class HTTP:
    """This class manages a connection to an HTTP server."""

    def __init__(self, host = '', port = 0, **x509):
        """Initialize a new instance.

        If specified, `host' is the name of the remote host to which
        to connect.  If specified, `port' specifies the port to which
        to connect.  By default, httplib.HTTP_PORT is used.

        """
        self.key_file = x509.get('key_file')
        self.cert_file = x509.get('cert_file')
        self.debuglevel = 0
        self.file = None
        if host: self.connect(host, port)

    def set_debuglevel(self, debuglevel):
        """Set the debug output level.

        A non-false value results in debug messages for connection and
        for all messages sent to and received from the server.

        """
        self.debuglevel = debuglevel

    def connect(self, host, port = 0):
        """Connect to a host on a given port.

        Note:  This method is automatically invoked by __init__,
        if a host is specified during instantiation.

        """
        if not port:
            i = string.find(host, ':')
            if i >= 0:
                host, port = host[:i], host[i+1:]
                try: port = string.atoi(port)
                except string.atoi_error:
                    raise socket.error, "nonnumeric port"
        if not port: port = HTTP_PORT
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if self.debuglevel > 0: print 'connect:', (host, port)
        self.sock.connect((host, port))

    def send(self, str):
        """Send `str' to the server."""
        if self.debuglevel > 0: print 'send:', `str`
        self.sock.send(str)

    def putrequest(self, request, selector):
        """Send a request to the server.

        `request' specifies an HTTP request method, e.g. 'GET'.
        `selector' specifies the object being requested, e.g.
        '/index.html'.

        """
        if not selector: selector = '/'
        str = '%s %s %s\r\n' % (request, selector, HTTP_VERSION)
        self.send(str)

    def putheader(self, header, *args):
        """Send a request header line to the server.

        For example: h.putheader('Accept', 'text/html')

        """
        str = '%s: %s\r\n' % (header, string.joinfields(args,'\r\n\t'))
        self.send(str)

    def endheaders(self):
        """Indicate that the last header line has been sent to the server."""
        self.send('\r\n')

    def getreply(self):
        """Get a reply from the server.

        Returns a tuple consisting of:
        - server response code (e.g. '200' if all goes well)
        - server response string corresponding to response code
        - any RFC822 headers in the response from the server

        """
        self.file = self.sock.makefile('rb')
        line = self.file.readline()
        if self.debuglevel > 0: print 'reply:', `line`
        try:
            [ver, code, msg] = string.split(line, None, 2)
        except ValueError:
          try:
              [ver, code] = string.split(line, None, 1)
              msg = ""
          except ValueError:
              self.headers = None
              return -1, line, self.headers
        if ver[:5] != 'HTTP/':
            self.headers = None
            return -1, line, self.headers
        errcode = string.atoi(code)
        errmsg = string.strip(msg)
        self.headers = mimetools.Message(self.file, 0)
        return errcode, errmsg, self.headers

    def getfile(self):
        """Get a file object from which to receive data from the HTTP server.

        NOTE:  This method must not be invoked until getreplies
        has been invoked.

        """
        return self.file

    def close(self):
        """Close the connection to the HTTP server."""
        if self.file:
            self.file.close()
        self.file = None
        if self.sock:
            self.sock.close()
        self.sock = None

if hasattr(socket, "ssl"):
    class HTTPS(HTTP):
        """This class allows communication via SSL."""

        def connect(self, host, port = 0):
            """Connect to a host on a given port.

            Note:  This method is automatically invoked by __init__,
            if a host is specified during instantiation.

            """
            if not port:
                i = string.find(host, ':')
                if i >= 0:
                    host, port = host[:i], host[i+1:]
                    try: port = string.atoi(port)
                    except string.atoi_error:
                        raise socket.error, "nonnumeric port"
            if not port: port = HTTPS_PORT
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            if self.debuglevel > 0: print 'connect:', (host, port)
            sock.connect((host, port))
            ssl = socket.ssl(sock, self.key_file, self.cert_file)
            self.sock = FakeSocket(sock, ssl)


def test():
    """Test this module.

    The test consists of retrieving and displaying the Python
    home page, along with the error code and error string returned
    by the www.python.org server.

    """
    import sys
    import getopt
    opts, args = getopt.getopt(sys.argv[1:], 'd')
    dl = 0
    for o, a in opts:
        if o == '-d': dl = dl + 1
    print "testing HTTP..."
    host = 'www.python.org'
    selector = '/'
    if args[0:]: host = args[0]
    if args[1:]: selector = args[1]
    h = HTTP()
    h.set_debuglevel(dl)
    h.connect(host)
    h.putrequest('GET', selector)
    h.endheaders()
    errcode, errmsg, headers = h.getreply()
    print 'errcode =', errcode
    print 'errmsg  =', errmsg
    print
    if headers:
        for header in headers.headers: print string.strip(header)
    print
    print h.getfile().read()
    if hasattr(socket, "ssl"):
        print "-"*40
        print "testing HTTPS..."
        host = 'synergy.as.cmu.edu'
        selector = '/~geek/'
        if args[0:]: host = args[0]
        if args[1:]: selector = args[1]
        h = HTTPS()
        h.set_debuglevel(dl)
        h.connect(host)
        h.putrequest('GET', selector)
        h.endheaders()
        errcode, errmsg, headers = h.getreply()
        print 'errcode =', errcode
        print 'errmsg  =', errmsg
        print
        if headers:
            for header in headers.headers: print string.strip(header)
        print
        print h.getfile().read()


if __name__ == '__main__':
    test()
