"""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 socket
import string
import mimetools

HTTP_VERSION = 'HTTP/1.0'
HTTP_PORT = 80

class HTTP:
    """This class manages a connection to an HTTP server."""
    
    def __init__(self, host = '', port = 0):
        """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.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:
            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


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
    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 __name__ == '__main__':
    test()
