This commit was manufactured by cvs2svn to create tag 'cnrisync'.
[python/dscho.git] / Lib / httplib.py
blobca431ab4cb218ada054d2f33b7cb3a8f50fd0a10
1 # HTTP client class
3 # See the following URL for a description of the HTTP/1.0 protocol:
4 # http://www.w3.org/hypertext/WWW/Protocols/
5 # (I actually implemented it from a much earlier draft.)
7 # Example:
9 # >>> from httplib import HTTP
10 # >>> h = HTTP('www.python.org')
11 # >>> h.putrequest('GET', '/index.html')
12 # >>> h.putheader('Accept', 'text/html')
13 # >>> h.putheader('Accept', 'text/plain')
14 # >>> h.endheaders()
15 # >>> errcode, errmsg, headers = h.getreply()
16 # >>> if errcode == 200:
17 # ... f = h.getfile()
18 # ... print f.read() # Print the raw HTML
19 # ...
20 # <HEAD>
21 # <TITLE>Python Language Home Page</TITLE>
22 # [...many more lines...]
23 # >>>
25 # Note that an HTTP object is used for a single request -- to issue a
26 # second request to the same server, you create a new HTTP object.
27 # (This is in accordance with the protocol, which uses a new TCP
28 # connection for each request.)
31 import os
32 import socket
33 import string
34 import regex
35 import regsub
36 import mimetools
38 HTTP_VERSION = 'HTTP/1.0'
39 HTTP_PORT = 80
41 replypat = regsub.gsub('\\.', '\\\\.', HTTP_VERSION) + \
42 '[ \t]+\([0-9][0-9][0-9]\)\(.*\)'
43 replyprog = regex.compile(replypat)
45 class HTTP:
47 def __init__(self, host = '', port = 0):
48 self.debuglevel = 0
49 self.file = None
50 if host: self.connect(host, port)
52 def set_debuglevel(self, debuglevel):
53 self.debuglevel = debuglevel
55 def connect(self, host, port = 0):
56 if not port:
57 i = string.find(host, ':')
58 if i >= 0:
59 host, port = host[:i], host[i+1:]
60 try: port = string.atoi(port)
61 except string.atoi_error:
62 raise socket.error, "nonnumeric port"
63 if not port: port = HTTP_PORT
64 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
65 if self.debuglevel > 0: print 'connect:', (host, port)
66 self.sock.connect(host, port)
68 def send(self, str):
69 if self.debuglevel > 0: print 'send:', `str`
70 self.sock.send(str)
72 def putrequest(self, request, selector):
73 if not selector: selector = '/'
74 str = '%s %s %s\r\n' % (request, selector, HTTP_VERSION)
75 self.send(str)
77 def putheader(self, header, *args):
78 str = '%s: %s\r\n' % (header, string.joinfields(args,'\r\n\t'))
79 self.send(str)
81 def endheaders(self):
82 self.send('\r\n')
84 def getreply(self):
85 self.file = self.sock.makefile('rb')
86 self.sock = None
87 line = self.file.readline()
88 if self.debuglevel > 0: print 'reply:', `line`
89 if replyprog.match(line) < 0:
90 self.headers = None
91 return -1, line, self.headers
92 errcode, errmsg = replyprog.group(1, 2)
93 errcode = string.atoi(errcode)
94 errmsg = string.strip(errmsg)
95 self.headers = mimetools.Message(self.file, 0)
96 return errcode, errmsg, self.headers
98 def getfile(self):
99 return self.file
101 def close(self):
102 if self.file:
103 self.file.close()
104 self.file = None
107 def test():
108 import sys
109 import getopt
110 opts, args = getopt.getopt(sys.argv[1:], 'd')
111 dl = 0
112 for o, a in opts:
113 if o == '-d': dl = dl + 1
114 host = 'www.python.org'
115 selector = '/'
116 if args[0:]: host = args[0]
117 if args[1:]: selector = args[1]
118 h = HTTP()
119 h.set_debuglevel(dl)
120 h.connect(host)
121 h.putrequest('GET', selector)
122 h.endheaders()
123 errcode, errmsg, headers = h.getreply()
124 print 'errcode =', errcode
125 print 'errmsg =', errmsg
126 print
127 if headers:
128 for header in headers.headers: print string.strip(header)
129 print
130 print h.getfile().read()
133 if __name__ == '__main__':
134 test()