"""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('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()
