blob: c1c4fe18c46bad0ff7af7fb34ee6b1831ffa580f [file] [log] [blame]
Greg Stein5e0fa402000-06-26 08:28:01 +00001"""HTTP/1.1 client library
Guido van Rossum41999c11997-12-09 00:12:23 +00002
Greg Stein5e0fa402000-06-26 08:28:01 +00003<intro stuff goes here>
4<other stuff, too>
Guido van Rossum41999c11997-12-09 00:12:23 +00005
Greg Stein5e0fa402000-06-26 08:28:01 +00006HTTPConnection go through a number of "states", which defines when a client
7may legally make another request or fetch the response for a particular
8request. This diagram details these state transitions:
Guido van Rossum41999c11997-12-09 00:12:23 +00009
Greg Stein5e0fa402000-06-26 08:28:01 +000010 (null)
11 |
12 | HTTPConnection()
13 v
14 Idle
15 |
16 | putrequest()
17 v
18 Request-started
19 |
20 | ( putheader() )* endheaders()
21 v
22 Request-sent
23 |
24 | response = getresponse()
25 v
26 Unread-response [Response-headers-read]
27 |\____________________
Tim Peters5ceadc82001-01-13 19:16:21 +000028 | |
29 | response.read() | putrequest()
30 v v
31 Idle Req-started-unread-response
32 ______/|
33 / |
34 response.read() | | ( putheader() )* endheaders()
35 v v
36 Request-started Req-sent-unread-response
37 |
38 | response.read()
39 v
40 Request-sent
Greg Stein5e0fa402000-06-26 08:28:01 +000041
42This diagram presents the following rules:
43 -- a second request may not be started until {response-headers-read}
44 -- a response [object] cannot be retrieved until {request-sent}
45 -- there is no differentiation between an unread response body and a
46 partially read response body
47
48Note: this enforcement is applied by the HTTPConnection class. The
49 HTTPResponse class does not enforce this state machine, which
50 implies sophisticated clients may accelerate the request/response
51 pipeline. Caution should be taken, though: accelerating the states
52 beyond the above pattern may imply knowledge of the server's
53 connection-close behavior for certain requests. For example, it
54 is impossible to tell whether the server will close the connection
55 UNTIL the response headers have been read; this means that further
56 requests cannot be placed into the pipeline until it is known that
57 the server will NOT be closing the connection.
58
59Logical State __state __response
60------------- ------- ----------
61Idle _CS_IDLE None
62Request-started _CS_REQ_STARTED None
63Request-sent _CS_REQ_SENT None
64Unread-response _CS_IDLE <response_class>
65Req-started-unread-response _CS_REQ_STARTED <response_class>
66Req-sent-unread-response _CS_REQ_SENT <response_class>
Guido van Rossum41999c11997-12-09 00:12:23 +000067"""
Guido van Rossum23acc951994-02-21 16:36:04 +000068
Jeremy Hylton6459c8d2001-10-11 17:47:22 +000069import errno
Guido van Rossum65ab98c1995-08-07 20:13:02 +000070import mimetools
Jeremy Hylton6459c8d2001-10-11 17:47:22 +000071import socket
Jeremy Hylton8acf1e02002-03-08 19:35:51 +000072from urlparse import urlsplit
Guido van Rossum23acc951994-02-21 16:36:04 +000073
Guido van Rossum09c8b6c1999-12-07 21:37:17 +000074try:
Greg Steindd6eefb2000-07-18 09:09:48 +000075 from cStringIO import StringIO
Greg Stein5e0fa402000-06-26 08:28:01 +000076except ImportError:
Greg Steindd6eefb2000-07-18 09:09:48 +000077 from StringIO import StringIO
Guido van Rossum09c8b6c1999-12-07 21:37:17 +000078
Skip Montanaro951a8842001-06-01 16:25:38 +000079__all__ = ["HTTP", "HTTPResponse", "HTTPConnection", "HTTPSConnection",
80 "HTTPException", "NotConnected", "UnknownProtocol",
81 "UnknownTransferEncoding", "IllegalKeywordArgument",
Skip Montanarof3f87f72002-03-24 16:56:45 +000082 "UnimplementedFileMode", "IncompleteRead", "InvalidURL",
Skip Montanaro951a8842001-06-01 16:25:38 +000083 "ImproperConnectionState", "CannotSendRequest", "CannotSendHeader",
84 "ResponseNotReady", "BadStatusLine", "error"]
Skip Montanaro2dd42762001-01-23 15:35:05 +000085
Guido van Rossum23acc951994-02-21 16:36:04 +000086HTTP_PORT = 80
Guido van Rossum09c8b6c1999-12-07 21:37:17 +000087HTTPS_PORT = 443
88
Greg Stein5e0fa402000-06-26 08:28:01 +000089_UNKNOWN = 'UNKNOWN'
90
91# connection states
92_CS_IDLE = 'Idle'
93_CS_REQ_STARTED = 'Request-started'
94_CS_REQ_SENT = 'Request-sent'
95
96
97class HTTPResponse:
Jeremy Hylton30f86742000-09-18 22:50:38 +000098 def __init__(self, sock, debuglevel=0):
Greg Steindd6eefb2000-07-18 09:09:48 +000099 self.fp = sock.makefile('rb', 0)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000100 self.debuglevel = debuglevel
Greg Stein5e0fa402000-06-26 08:28:01 +0000101
Greg Steindd6eefb2000-07-18 09:09:48 +0000102 self.msg = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000103
Greg Steindd6eefb2000-07-18 09:09:48 +0000104 # from the Status-Line of the response
Tim Peters07e99cb2001-01-14 23:47:14 +0000105 self.version = _UNKNOWN # HTTP-Version
106 self.status = _UNKNOWN # Status-Code
107 self.reason = _UNKNOWN # Reason-Phrase
Greg Stein5e0fa402000-06-26 08:28:01 +0000108
Tim Peters07e99cb2001-01-14 23:47:14 +0000109 self.chunked = _UNKNOWN # is "chunked" being used?
110 self.chunk_left = _UNKNOWN # bytes left to read in current chunk
111 self.length = _UNKNOWN # number of bytes left in response
112 self.will_close = _UNKNOWN # conn will close at end of response
Greg Stein5e0fa402000-06-26 08:28:01 +0000113
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000114 def _read_status(self):
Greg Stein5e0fa402000-06-26 08:28:01 +0000115 line = self.fp.readline()
Jeremy Hylton30f86742000-09-18 22:50:38 +0000116 if self.debuglevel > 0:
117 print "reply:", repr(line)
Greg Steindd6eefb2000-07-18 09:09:48 +0000118 try:
Guido van Rossum34735a62000-12-15 15:09:42 +0000119 [version, status, reason] = line.split(None, 2)
Greg Steindd6eefb2000-07-18 09:09:48 +0000120 except ValueError:
121 try:
Guido van Rossum34735a62000-12-15 15:09:42 +0000122 [version, status] = line.split(None, 1)
Greg Steindd6eefb2000-07-18 09:09:48 +0000123 reason = ""
124 except ValueError:
Jeremy Hylton110941a2000-10-12 19:58:36 +0000125 version = "HTTP/0.9"
126 status = "200"
127 reason = ""
Greg Steindd6eefb2000-07-18 09:09:48 +0000128 if version[:5] != 'HTTP/':
129 self.close()
130 raise BadStatusLine(line)
Greg Stein5e0fa402000-06-26 08:28:01 +0000131
Jeremy Hylton23d40472001-04-13 14:57:08 +0000132 # The status code is a three-digit number
133 try:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000134 status = int(status)
Jeremy Hylton23d40472001-04-13 14:57:08 +0000135 if status < 100 or status > 999:
136 raise BadStatusLine(line)
137 except ValueError:
138 raise BadStatusLine(line)
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000139 return version, status, reason
Greg Stein5e0fa402000-06-26 08:28:01 +0000140
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000141 def _begin(self):
142 if self.msg is not None:
143 # we've already started reading the response
144 return
145
146 # read until we get a non-100 response
147 while 1:
148 version, status, reason = self._read_status()
149 if status != 100:
150 break
151 # skip the header from the 100 response
152 while 1:
153 skip = self.fp.readline().strip()
154 if not skip:
155 break
156 if self.debuglevel > 0:
157 print "header:", skip
158
159 self.status = status
160 self.reason = reason.strip()
Greg Steindd6eefb2000-07-18 09:09:48 +0000161 if version == 'HTTP/1.0':
162 self.version = 10
Jeremy Hylton110941a2000-10-12 19:58:36 +0000163 elif version.startswith('HTTP/1.'):
Tim Peters07e99cb2001-01-14 23:47:14 +0000164 self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1
Jeremy Hylton110941a2000-10-12 19:58:36 +0000165 elif version == 'HTTP/0.9':
166 self.version = 9
Greg Steindd6eefb2000-07-18 09:09:48 +0000167 else:
168 raise UnknownProtocol(version)
Greg Stein5e0fa402000-06-26 08:28:01 +0000169
Jeremy Hylton110941a2000-10-12 19:58:36 +0000170 if self.version == 9:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000171 self.chunked = 0
Jeremy Hylton110941a2000-10-12 19:58:36 +0000172 self.msg = mimetools.Message(StringIO())
173 return
174
Greg Steindd6eefb2000-07-18 09:09:48 +0000175 self.msg = mimetools.Message(self.fp, 0)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000176 if self.debuglevel > 0:
177 for hdr in self.msg.headers:
178 print "header:", hdr,
Greg Stein5e0fa402000-06-26 08:28:01 +0000179
Greg Steindd6eefb2000-07-18 09:09:48 +0000180 # don't let the msg keep an fp
181 self.msg.fp = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000182
Greg Steindd6eefb2000-07-18 09:09:48 +0000183 # are we using the chunked-style of transfer encoding?
184 tr_enc = self.msg.getheader('transfer-encoding')
185 if tr_enc:
Guido van Rossum34735a62000-12-15 15:09:42 +0000186 if tr_enc.lower() != 'chunked':
Greg Steindd6eefb2000-07-18 09:09:48 +0000187 raise UnknownTransferEncoding()
188 self.chunked = 1
189 self.chunk_left = None
190 else:
191 self.chunked = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000192
Greg Steindd6eefb2000-07-18 09:09:48 +0000193 # will the connection close at the end of the response?
194 conn = self.msg.getheader('connection')
195 if conn:
Guido van Rossum34735a62000-12-15 15:09:42 +0000196 conn = conn.lower()
Greg Steindd6eefb2000-07-18 09:09:48 +0000197 # a "Connection: close" will always close the connection. if we
198 # don't see that and this is not HTTP/1.1, then the connection will
199 # close unless we see a Keep-Alive header.
Guido van Rossum34735a62000-12-15 15:09:42 +0000200 self.will_close = conn.find('close') != -1 or \
Greg Steindd6eefb2000-07-18 09:09:48 +0000201 ( self.version != 11 and \
202 not self.msg.getheader('keep-alive') )
203 else:
204 # for HTTP/1.1, the connection will always remain open
205 # otherwise, it will remain open IFF we see a Keep-Alive header
206 self.will_close = self.version != 11 and \
207 not self.msg.getheader('keep-alive')
Greg Stein5e0fa402000-06-26 08:28:01 +0000208
Greg Steindd6eefb2000-07-18 09:09:48 +0000209 # do we have a Content-Length?
210 # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
211 length = self.msg.getheader('content-length')
212 if length and not self.chunked:
Jeremy Hylton30a81812000-09-14 20:34:27 +0000213 try:
214 self.length = int(length)
215 except ValueError:
216 self.length = None
Greg Steindd6eefb2000-07-18 09:09:48 +0000217 else:
218 self.length = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000219
Greg Steindd6eefb2000-07-18 09:09:48 +0000220 # does the body have a fixed length? (of zero)
Tim Peters07e99cb2001-01-14 23:47:14 +0000221 if (status == 204 or # No Content
222 status == 304 or # Not Modified
223 100 <= status < 200): # 1xx codes
Greg Steindd6eefb2000-07-18 09:09:48 +0000224 self.length = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000225
Greg Steindd6eefb2000-07-18 09:09:48 +0000226 # if the connection remains open, and we aren't using chunked, and
227 # a content-length was not provided, then assume that the connection
228 # WILL close.
229 if not self.will_close and \
230 not self.chunked and \
231 self.length is None:
232 self.will_close = 1
Greg Stein5e0fa402000-06-26 08:28:01 +0000233
Greg Steindd6eefb2000-07-18 09:09:48 +0000234 def close(self):
235 if self.fp:
236 self.fp.close()
237 self.fp = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000238
Greg Steindd6eefb2000-07-18 09:09:48 +0000239 def isclosed(self):
240 # NOTE: it is possible that we will not ever call self.close(). This
241 # case occurs when will_close is TRUE, length is None, and we
242 # read up to the last byte, but NOT past it.
243 #
244 # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
245 # called, meaning self.isclosed() is meaningful.
246 return self.fp is None
247
248 def read(self, amt=None):
249 if self.fp is None:
250 return ''
251
252 if self.chunked:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000253 assert self.chunked != _UNKNOWN
Greg Steindd6eefb2000-07-18 09:09:48 +0000254 chunk_left = self.chunk_left
255 value = ''
256 while 1:
257 if chunk_left is None:
258 line = self.fp.readline()
Guido van Rossum34735a62000-12-15 15:09:42 +0000259 i = line.find(';')
Greg Steindd6eefb2000-07-18 09:09:48 +0000260 if i >= 0:
Tim Peters07e99cb2001-01-14 23:47:14 +0000261 line = line[:i] # strip chunk-extensions
Guido van Rossum34735a62000-12-15 15:09:42 +0000262 chunk_left = int(line, 16)
Greg Steindd6eefb2000-07-18 09:09:48 +0000263 if chunk_left == 0:
264 break
265 if amt is None:
266 value = value + self._safe_read(chunk_left)
267 elif amt < chunk_left:
268 value = value + self._safe_read(amt)
269 self.chunk_left = chunk_left - amt
270 return value
271 elif amt == chunk_left:
272 value = value + self._safe_read(amt)
Tim Peters07e99cb2001-01-14 23:47:14 +0000273 self._safe_read(2) # toss the CRLF at the end of the chunk
Greg Steindd6eefb2000-07-18 09:09:48 +0000274 self.chunk_left = None
275 return value
276 else:
277 value = value + self._safe_read(chunk_left)
278 amt = amt - chunk_left
279
280 # we read the whole chunk, get another
Tim Peters07e99cb2001-01-14 23:47:14 +0000281 self._safe_read(2) # toss the CRLF at the end of the chunk
Greg Steindd6eefb2000-07-18 09:09:48 +0000282 chunk_left = None
283
284 # read and discard trailer up to the CRLF terminator
285 ### note: we shouldn't have any trailers!
286 while 1:
287 line = self.fp.readline()
288 if line == '\r\n':
289 break
290
291 # we read everything; close the "file"
292 self.close()
293
294 return value
295
296 elif amt is None:
297 # unbounded read
298 if self.will_close:
299 s = self.fp.read()
300 else:
301 s = self._safe_read(self.length)
Tim Peters07e99cb2001-01-14 23:47:14 +0000302 self.close() # we read everything
Greg Steindd6eefb2000-07-18 09:09:48 +0000303 return s
304
305 if self.length is not None:
306 if amt > self.length:
307 # clip the read to the "end of response"
308 amt = self.length
309 self.length = self.length - amt
310
311 # we do not use _safe_read() here because this may be a .will_close
312 # connection, and the user is reading more bytes than will be provided
313 # (for example, reading in 1k chunks)
314 s = self.fp.read(amt)
315
Greg Steindd6eefb2000-07-18 09:09:48 +0000316 return s
317
318 def _safe_read(self, amt):
319 """Read the number of bytes requested, compensating for partial reads.
320
321 Normally, we have a blocking socket, but a read() can be interrupted
322 by a signal (resulting in a partial read).
323
324 Note that we cannot distinguish between EOF and an interrupt when zero
325 bytes have been read. IncompleteRead() will be raised in this
326 situation.
327
328 This function should be used when <amt> bytes "should" be present for
329 reading. If the bytes are truly not available (due to EOF), then the
330 IncompleteRead exception can be used to detect the problem.
331 """
332 s = ''
333 while amt > 0:
334 chunk = self.fp.read(amt)
335 if not chunk:
336 raise IncompleteRead(s)
337 s = s + chunk
338 amt = amt - len(chunk)
339 return s
340
341 def getheader(self, name, default=None):
342 if self.msg is None:
343 raise ResponseNotReady()
344 return self.msg.getheader(name, default)
Greg Stein5e0fa402000-06-26 08:28:01 +0000345
346
347class HTTPConnection:
348
Greg Steindd6eefb2000-07-18 09:09:48 +0000349 _http_vsn = 11
350 _http_vsn_str = 'HTTP/1.1'
Greg Stein5e0fa402000-06-26 08:28:01 +0000351
Greg Steindd6eefb2000-07-18 09:09:48 +0000352 response_class = HTTPResponse
353 default_port = HTTP_PORT
354 auto_open = 1
Jeremy Hylton30f86742000-09-18 22:50:38 +0000355 debuglevel = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000356
Greg Steindd6eefb2000-07-18 09:09:48 +0000357 def __init__(self, host, port=None):
358 self.sock = None
359 self.__response = None
360 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000361
Greg Steindd6eefb2000-07-18 09:09:48 +0000362 self._set_hostport(host, port)
Greg Stein5e0fa402000-06-26 08:28:01 +0000363
Greg Steindd6eefb2000-07-18 09:09:48 +0000364 def _set_hostport(self, host, port):
365 if port is None:
Guido van Rossum34735a62000-12-15 15:09:42 +0000366 i = host.find(':')
Greg Steindd6eefb2000-07-18 09:09:48 +0000367 if i >= 0:
Skip Montanaro9d389972002-03-24 16:53:50 +0000368 try:
369 port = int(host[i+1:])
370 except ValueError:
371 raise InvalidURL, "nonnumeric port: '%s'"%host[i+1:]
Greg Steindd6eefb2000-07-18 09:09:48 +0000372 host = host[:i]
373 else:
374 port = self.default_port
375 self.host = host
376 self.port = port
Greg Stein5e0fa402000-06-26 08:28:01 +0000377
Jeremy Hylton30f86742000-09-18 22:50:38 +0000378 def set_debuglevel(self, level):
379 self.debuglevel = level
380
Greg Steindd6eefb2000-07-18 09:09:48 +0000381 def connect(self):
382 """Connect to the host and port specified in __init__."""
Martin v. Löwis2ad25692001-07-31 08:40:21 +0000383 msg = "getaddrinfo returns an empty list"
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000384 for res in socket.getaddrinfo(self.host, self.port, 0,
385 socket.SOCK_STREAM):
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000386 af, socktype, proto, canonname, sa = res
387 try:
388 self.sock = socket.socket(af, socktype, proto)
389 if self.debuglevel > 0:
390 print "connect: (%s, %s)" % (self.host, self.port)
391 self.sock.connect(sa)
392 except socket.error, msg:
393 if self.debuglevel > 0:
394 print 'connect fail:', (self.host, self.port)
Martin v. Löwis322c0d12001-10-07 08:53:32 +0000395 if self.sock:
396 self.sock.close()
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000397 self.sock = None
398 continue
399 break
400 if not self.sock:
401 raise socket.error, msg
Greg Stein5e0fa402000-06-26 08:28:01 +0000402
Greg Steindd6eefb2000-07-18 09:09:48 +0000403 def close(self):
404 """Close the connection to the HTTP server."""
405 if self.sock:
Tim Peters07e99cb2001-01-14 23:47:14 +0000406 self.sock.close() # close it manually... there may be other refs
Greg Steindd6eefb2000-07-18 09:09:48 +0000407 self.sock = None
408 if self.__response:
409 self.__response.close()
410 self.__response = None
411 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000412
Greg Steindd6eefb2000-07-18 09:09:48 +0000413 def send(self, str):
414 """Send `str' to the server."""
415 if self.sock is None:
416 if self.auto_open:
417 self.connect()
418 else:
419 raise NotConnected()
Greg Stein5e0fa402000-06-26 08:28:01 +0000420
Greg Steindd6eefb2000-07-18 09:09:48 +0000421 # send the data to the server. if we get a broken pipe, then close
422 # the socket. we want to reconnect when somebody tries to send again.
423 #
424 # NOTE: we DO propagate the error, though, because we cannot simply
425 # ignore the error... the caller will know if they can retry.
Jeremy Hylton30f86742000-09-18 22:50:38 +0000426 if self.debuglevel > 0:
427 print "send:", repr(str)
Greg Steindd6eefb2000-07-18 09:09:48 +0000428 try:
Martin v. Löwise12454f2002-02-16 23:06:19 +0000429 self.sock.sendall(str)
Greg Steindd6eefb2000-07-18 09:09:48 +0000430 except socket.error, v:
Tim Peters07e99cb2001-01-14 23:47:14 +0000431 if v[0] == 32: # Broken pipe
Greg Steindd6eefb2000-07-18 09:09:48 +0000432 self.close()
433 raise
Greg Stein5e0fa402000-06-26 08:28:01 +0000434
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000435 def putrequest(self, method, url, skip_host=0):
Greg Steindd6eefb2000-07-18 09:09:48 +0000436 """Send a request to the server.
Greg Stein5e0fa402000-06-26 08:28:01 +0000437
Greg Steindd6eefb2000-07-18 09:09:48 +0000438 `method' specifies an HTTP request method, e.g. 'GET'.
439 `url' specifies the object being requested, e.g. '/index.html'.
440 """
Greg Stein5e0fa402000-06-26 08:28:01 +0000441
Greg Steindd6eefb2000-07-18 09:09:48 +0000442 # check if a prior response has been completed
443 if self.__response and self.__response.isclosed():
444 self.__response = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000445
Greg Steindd6eefb2000-07-18 09:09:48 +0000446 #
447 # in certain cases, we cannot issue another request on this connection.
448 # this occurs when:
449 # 1) we are in the process of sending a request. (_CS_REQ_STARTED)
450 # 2) a response to a previous request has signalled that it is going
451 # to close the connection upon completion.
452 # 3) the headers for the previous response have not been read, thus
453 # we cannot determine whether point (2) is true. (_CS_REQ_SENT)
454 #
455 # if there is no prior response, then we can request at will.
456 #
457 # if point (2) is true, then we will have passed the socket to the
458 # response (effectively meaning, "there is no prior response"), and
459 # will open a new one when a new request is made.
460 #
461 # Note: if a prior response exists, then we *can* start a new request.
462 # We are not allowed to begin fetching the response to this new
463 # request, however, until that prior response is complete.
464 #
465 if self.__state == _CS_IDLE:
466 self.__state = _CS_REQ_STARTED
467 else:
468 raise CannotSendRequest()
Greg Stein5e0fa402000-06-26 08:28:01 +0000469
Greg Steindd6eefb2000-07-18 09:09:48 +0000470 if not url:
471 url = '/'
472 str = '%s %s %s\r\n' % (method, url, self._http_vsn_str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000473
Greg Steindd6eefb2000-07-18 09:09:48 +0000474 try:
475 self.send(str)
476 except socket.error, v:
477 # trap 'Broken pipe' if we're allowed to automatically reconnect
478 if v[0] != 32 or not self.auto_open:
479 raise
480 # try one more time (the socket was closed; this will reopen)
481 self.send(str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000482
Greg Steindd6eefb2000-07-18 09:09:48 +0000483 if self._http_vsn == 11:
484 # Issue some standard headers for better HTTP/1.1 compliance
Greg Stein5e0fa402000-06-26 08:28:01 +0000485
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000486 if not skip_host:
487 # this header is issued *only* for HTTP/1.1
488 # connections. more specifically, this means it is
489 # only issued when the client uses the new
490 # HTTPConnection() class. backwards-compat clients
491 # will be using HTTP/1.0 and those clients may be
492 # issuing this header themselves. we should NOT issue
493 # it twice; some web servers (such as Apache) barf
494 # when they see two Host: headers
Guido van Rossumf6922aa2001-01-14 21:03:01 +0000495
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000496 # If we need a non-standard port,include it in the
497 # header. If the request is going through a proxy,
498 # but the host of the actual URL, not the host of the
499 # proxy.
Jeremy Hylton8acf1e02002-03-08 19:35:51 +0000500
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000501 netloc = ''
502 if url.startswith('http'):
503 nil, netloc, nil, nil, nil = urlsplit(url)
504
505 if netloc:
506 self.putheader('Host', netloc)
507 elif self.port == HTTP_PORT:
508 self.putheader('Host', self.host)
509 else:
510 self.putheader('Host', "%s:%s" % (self.host, self.port))
Greg Stein5e0fa402000-06-26 08:28:01 +0000511
Greg Steindd6eefb2000-07-18 09:09:48 +0000512 # note: we are assuming that clients will not attempt to set these
513 # headers since *this* library must deal with the
514 # consequences. this also means that when the supporting
515 # libraries are updated to recognize other forms, then this
516 # code should be changed (removed or updated).
Greg Stein5e0fa402000-06-26 08:28:01 +0000517
Greg Steindd6eefb2000-07-18 09:09:48 +0000518 # we only want a Content-Encoding of "identity" since we don't
519 # support encodings such as x-gzip or x-deflate.
520 self.putheader('Accept-Encoding', 'identity')
Greg Stein5e0fa402000-06-26 08:28:01 +0000521
Greg Steindd6eefb2000-07-18 09:09:48 +0000522 # we can accept "chunked" Transfer-Encodings, but no others
523 # NOTE: no TE header implies *only* "chunked"
524 #self.putheader('TE', 'chunked')
Greg Stein5e0fa402000-06-26 08:28:01 +0000525
Greg Steindd6eefb2000-07-18 09:09:48 +0000526 # if TE is supplied in the header, then it must appear in a
527 # Connection header.
528 #self.putheader('Connection', 'TE')
Greg Stein5e0fa402000-06-26 08:28:01 +0000529
Greg Steindd6eefb2000-07-18 09:09:48 +0000530 else:
531 # For HTTP/1.0, the server will assume "not chunked"
532 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000533
Greg Steindd6eefb2000-07-18 09:09:48 +0000534 def putheader(self, header, value):
535 """Send a request header line to the server.
Greg Stein5e0fa402000-06-26 08:28:01 +0000536
Greg Steindd6eefb2000-07-18 09:09:48 +0000537 For example: h.putheader('Accept', 'text/html')
538 """
539 if self.__state != _CS_REQ_STARTED:
540 raise CannotSendHeader()
Greg Stein5e0fa402000-06-26 08:28:01 +0000541
Greg Steindd6eefb2000-07-18 09:09:48 +0000542 str = '%s: %s\r\n' % (header, value)
543 self.send(str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000544
Greg Steindd6eefb2000-07-18 09:09:48 +0000545 def endheaders(self):
546 """Indicate that the last header line has been sent to the server."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000547
Greg Steindd6eefb2000-07-18 09:09:48 +0000548 if self.__state == _CS_REQ_STARTED:
549 self.__state = _CS_REQ_SENT
550 else:
551 raise CannotSendHeader()
Greg Stein5e0fa402000-06-26 08:28:01 +0000552
Greg Steindd6eefb2000-07-18 09:09:48 +0000553 self.send('\r\n')
Greg Stein5e0fa402000-06-26 08:28:01 +0000554
Greg Steindd6eefb2000-07-18 09:09:48 +0000555 def request(self, method, url, body=None, headers={}):
556 """Send a complete request to the server."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000557
Greg Steindd6eefb2000-07-18 09:09:48 +0000558 try:
559 self._send_request(method, url, body, headers)
560 except socket.error, v:
561 # trap 'Broken pipe' if we're allowed to automatically reconnect
562 if v[0] != 32 or not self.auto_open:
563 raise
564 # try one more time
565 self._send_request(method, url, body, headers)
Greg Stein5e0fa402000-06-26 08:28:01 +0000566
Greg Steindd6eefb2000-07-18 09:09:48 +0000567 def _send_request(self, method, url, body, headers):
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000568 # If headers already contains a host header, then define the
569 # optional skip_host argument to putrequest(). The check is
570 # harder because field names are case insensitive.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000571 if 'Host' in (headers
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000572 or [k for k in headers.iterkeys() if k.lower() == "host"]):
573 self.putrequest(method, url, skip_host=1)
574 else:
575 self.putrequest(method, url)
Greg Stein5e0fa402000-06-26 08:28:01 +0000576
Greg Steindd6eefb2000-07-18 09:09:48 +0000577 if body:
578 self.putheader('Content-Length', str(len(body)))
579 for hdr, value in headers.items():
580 self.putheader(hdr, value)
581 self.endheaders()
Greg Stein5e0fa402000-06-26 08:28:01 +0000582
Greg Steindd6eefb2000-07-18 09:09:48 +0000583 if body:
584 self.send(body)
Greg Stein5e0fa402000-06-26 08:28:01 +0000585
Greg Steindd6eefb2000-07-18 09:09:48 +0000586 def getresponse(self):
587 "Get the response from the server."
Greg Stein5e0fa402000-06-26 08:28:01 +0000588
Greg Steindd6eefb2000-07-18 09:09:48 +0000589 # check if a prior response has been completed
590 if self.__response and self.__response.isclosed():
591 self.__response = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000592
Greg Steindd6eefb2000-07-18 09:09:48 +0000593 #
594 # if a prior response exists, then it must be completed (otherwise, we
595 # cannot read this response's header to determine the connection-close
596 # behavior)
597 #
598 # note: if a prior response existed, but was connection-close, then the
599 # socket and response were made independent of this HTTPConnection
600 # object since a new request requires that we open a whole new
601 # connection
602 #
603 # this means the prior response had one of two states:
604 # 1) will_close: this connection was reset and the prior socket and
605 # response operate independently
606 # 2) persistent: the response was retained and we await its
607 # isclosed() status to become true.
608 #
609 if self.__state != _CS_REQ_SENT or self.__response:
610 raise ResponseNotReady()
Greg Stein5e0fa402000-06-26 08:28:01 +0000611
Jeremy Hylton30f86742000-09-18 22:50:38 +0000612 if self.debuglevel > 0:
613 response = self.response_class(self.sock, self.debuglevel)
614 else:
615 response = self.response_class(self.sock)
Greg Stein5e0fa402000-06-26 08:28:01 +0000616
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000617 response._begin()
618 assert response.will_close != _UNKNOWN
Greg Steindd6eefb2000-07-18 09:09:48 +0000619 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000620
Greg Steindd6eefb2000-07-18 09:09:48 +0000621 if response.will_close:
622 # this effectively passes the connection to the response
623 self.close()
624 else:
625 # remember this, so we can tell when it is complete
626 self.__response = response
Greg Stein5e0fa402000-06-26 08:28:01 +0000627
Greg Steindd6eefb2000-07-18 09:09:48 +0000628 return response
Greg Stein5e0fa402000-06-26 08:28:01 +0000629
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000630class SSLFile:
631 """File-like object wrapping an SSL socket."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000632
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000633 BUFSIZE = 8192
634
635 def __init__(self, sock, ssl, bufsize=None):
636 self._sock = sock
637 self._ssl = ssl
638 self._buf = ''
639 self._bufsize = bufsize or self.__class__.BUFSIZE
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000640
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000641 def _read(self):
642 buf = ''
643 # put in a loop so that we retry on transient errors
Greg Steindd6eefb2000-07-18 09:09:48 +0000644 while 1:
645 try:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000646 buf = self._ssl.read(self._bufsize)
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000647 except socket.sslerror, err:
648 if (err[0] == socket.SSL_ERROR_WANT_READ
Neal Norwitz22c5d772002-02-11 17:59:51 +0000649 or err[0] == socket.SSL_ERROR_WANT_WRITE):
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000650 continue
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000651 if (err[0] == socket.SSL_ERROR_ZERO_RETURN
652 or err[0] == socket.SSL_ERROR_EOF):
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000653 break
654 raise
655 except socket.error, err:
Tim Petersf3623f32001-10-11 18:15:51 +0000656 if err[0] == errno.EINTR:
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000657 continue
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000658 if err[0] == errno.EBADF:
659 # XXX socket was closed?
660 break
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000661 raise
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000662 else:
Jeremy Hylton42dd01a2001-02-01 23:35:20 +0000663 break
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000664 return buf
665
666 def read(self, size=None):
667 L = [self._buf]
668 avail = len(self._buf)
669 while size is None or avail < size:
670 s = self._read()
671 if s == '':
672 break
673 L.append(s)
674 avail += len(s)
675 all = "".join(L)
676 if size is None:
677 self._buf = ''
678 return all
679 else:
680 self._buf = all[size:]
681 return all[:size]
682
683 def readline(self):
684 L = [self._buf]
685 self._buf = ''
686 while 1:
687 i = L[-1].find("\n")
688 if i >= 0:
689 break
690 s = self._read()
691 if s == '':
692 break
693 L.append(s)
694 if i == -1:
695 # loop exited because there is no more data
696 return "".join(L)
697 else:
698 all = "".join(L)
699 # XXX could do enough bookkeeping not to do a 2nd search
700 i = all.find("\n") + 1
701 line = all[:i]
702 self._buf = all[i:]
703 return line
704
705 def close(self):
706 self._sock.close()
707
708class FakeSocket:
709 def __init__(self, sock, ssl):
710 self.__sock = sock
711 self.__ssl = ssl
712
713 def makefile(self, mode, bufsize=None):
714 if mode != 'r' and mode != 'rb':
715 raise UnimplementedFileMode()
716 return SSLFile(self.__sock, self.__ssl, bufsize)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000717
Greg Steindd6eefb2000-07-18 09:09:48 +0000718 def send(self, stuff, flags = 0):
719 return self.__ssl.write(stuff)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000720
Andrew M. Kuchlinga3c0b932002-03-18 22:51:48 +0000721 def sendall(self, stuff, flags = 0):
722 return self.__ssl.write(stuff)
723
Greg Steindd6eefb2000-07-18 09:09:48 +0000724 def recv(self, len = 1024, flags = 0):
725 return self.__ssl.read(len)
Guido van Rossum23acc951994-02-21 16:36:04 +0000726
Greg Steindd6eefb2000-07-18 09:09:48 +0000727 def __getattr__(self, attr):
728 return getattr(self.__sock, attr)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000729
Guido van Rossum23acc951994-02-21 16:36:04 +0000730
Greg Stein5e0fa402000-06-26 08:28:01 +0000731class HTTPSConnection(HTTPConnection):
Greg Steindd6eefb2000-07-18 09:09:48 +0000732 "This class allows communication via SSL."
Greg Stein5e0fa402000-06-26 08:28:01 +0000733
Greg Steindd6eefb2000-07-18 09:09:48 +0000734 default_port = HTTPS_PORT
Greg Stein5e0fa402000-06-26 08:28:01 +0000735
Greg Steindd6eefb2000-07-18 09:09:48 +0000736 def __init__(self, host, port=None, **x509):
737 keys = x509.keys()
738 try:
739 keys.remove('key_file')
740 except ValueError:
741 pass
742 try:
743 keys.remove('cert_file')
744 except ValueError:
745 pass
746 if keys:
747 raise IllegalKeywordArgument()
748 HTTPConnection.__init__(self, host, port)
749 self.key_file = x509.get('key_file')
750 self.cert_file = x509.get('cert_file')
Greg Stein5e0fa402000-06-26 08:28:01 +0000751
Greg Steindd6eefb2000-07-18 09:09:48 +0000752 def connect(self):
753 "Connect to a host on a given (SSL) port."
Greg Stein5e0fa402000-06-26 08:28:01 +0000754
Greg Steindd6eefb2000-07-18 09:09:48 +0000755 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
756 sock.connect((self.host, self.port))
Guido van Rossum0aee7222000-12-11 20:32:20 +0000757 realsock = sock
758 if hasattr(sock, "_sock"):
759 realsock = sock._sock
760 ssl = socket.ssl(realsock, self.key_file, self.cert_file)
Greg Steindd6eefb2000-07-18 09:09:48 +0000761 self.sock = FakeSocket(sock, ssl)
Greg Stein5e0fa402000-06-26 08:28:01 +0000762
763
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000764class HTTP:
Greg Steindd6eefb2000-07-18 09:09:48 +0000765 "Compatibility class with httplib.py from 1.5."
Greg Stein5e0fa402000-06-26 08:28:01 +0000766
Greg Steindd6eefb2000-07-18 09:09:48 +0000767 _http_vsn = 10
768 _http_vsn_str = 'HTTP/1.0'
Greg Stein5e0fa402000-06-26 08:28:01 +0000769
Greg Steindd6eefb2000-07-18 09:09:48 +0000770 debuglevel = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000771
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000772 _connection_class = HTTPConnection
773
Greg Stein81937a42001-08-18 09:20:23 +0000774 def __init__(self, host='', port=None):
Greg Steindd6eefb2000-07-18 09:09:48 +0000775 "Provide a default host, since the superclass requires one."
Greg Stein5e0fa402000-06-26 08:28:01 +0000776
Greg Steindd6eefb2000-07-18 09:09:48 +0000777 # some joker passed 0 explicitly, meaning default port
778 if port == 0:
779 port = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000780
Greg Steindd6eefb2000-07-18 09:09:48 +0000781 # Note that we may pass an empty string as the host; this will throw
782 # an error when we attempt to connect. Presumably, the client code
783 # will call connect before then, with a proper host.
Greg Stein81937a42001-08-18 09:20:23 +0000784 self._setup(self._connection_class(host, port))
Greg Stein5e0fa402000-06-26 08:28:01 +0000785
Greg Stein81937a42001-08-18 09:20:23 +0000786 def _setup(self, conn):
787 self._conn = conn
788
789 # set up delegation to flesh out interface
790 self.send = conn.send
791 self.putrequest = conn.putrequest
792 self.endheaders = conn.endheaders
793 self.set_debuglevel = conn.set_debuglevel
794
795 conn._http_vsn = self._http_vsn
796 conn._http_vsn_str = self._http_vsn_str
Greg Stein5e0fa402000-06-26 08:28:01 +0000797
Greg Steindd6eefb2000-07-18 09:09:48 +0000798 self.file = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000799
Greg Steindd6eefb2000-07-18 09:09:48 +0000800 def connect(self, host=None, port=None):
801 "Accept arguments to set the host/port, since the superclass doesn't."
Greg Stein5e0fa402000-06-26 08:28:01 +0000802
Greg Steindd6eefb2000-07-18 09:09:48 +0000803 if host is not None:
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000804 self._conn._set_hostport(host, port)
805 self._conn.connect()
Greg Stein5e0fa402000-06-26 08:28:01 +0000806
Greg Steindd6eefb2000-07-18 09:09:48 +0000807 def getfile(self):
808 "Provide a getfile, since the superclass' does not use this concept."
809 return self.file
Greg Stein5e0fa402000-06-26 08:28:01 +0000810
Greg Steindd6eefb2000-07-18 09:09:48 +0000811 def putheader(self, header, *values):
812 "The superclass allows only one value argument."
Guido van Rossum34735a62000-12-15 15:09:42 +0000813 self._conn.putheader(header, '\r\n\t'.join(values))
Greg Stein5e0fa402000-06-26 08:28:01 +0000814
Greg Steindd6eefb2000-07-18 09:09:48 +0000815 def getreply(self):
816 """Compat definition since superclass does not define it.
Greg Stein5e0fa402000-06-26 08:28:01 +0000817
Greg Steindd6eefb2000-07-18 09:09:48 +0000818 Returns a tuple consisting of:
819 - server status code (e.g. '200' if all goes well)
820 - server "reason" corresponding to status code
821 - any RFC822 headers in the response from the server
822 """
823 try:
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000824 response = self._conn.getresponse()
Greg Steindd6eefb2000-07-18 09:09:48 +0000825 except BadStatusLine, e:
826 ### hmm. if getresponse() ever closes the socket on a bad request,
827 ### then we are going to have problems with self.sock
Greg Stein5e0fa402000-06-26 08:28:01 +0000828
Greg Steindd6eefb2000-07-18 09:09:48 +0000829 ### should we keep this behavior? do people use it?
830 # keep the socket open (as a file), and return it
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000831 self.file = self._conn.sock.makefile('rb', 0)
Greg Stein5e0fa402000-06-26 08:28:01 +0000832
Greg Steindd6eefb2000-07-18 09:09:48 +0000833 # close our socket -- we want to restart after any protocol error
834 self.close()
Greg Stein5e0fa402000-06-26 08:28:01 +0000835
Greg Steindd6eefb2000-07-18 09:09:48 +0000836 self.headers = None
837 return -1, e.line, None
Greg Stein5e0fa402000-06-26 08:28:01 +0000838
Greg Steindd6eefb2000-07-18 09:09:48 +0000839 self.headers = response.msg
840 self.file = response.fp
841 return response.status, response.reason, response.msg
Greg Stein5e0fa402000-06-26 08:28:01 +0000842
Greg Steindd6eefb2000-07-18 09:09:48 +0000843 def close(self):
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000844 self._conn.close()
Greg Stein5e0fa402000-06-26 08:28:01 +0000845
Greg Steindd6eefb2000-07-18 09:09:48 +0000846 # note that self.file == response.fp, which gets closed by the
847 # superclass. just clear the object ref here.
848 ### hmm. messy. if status==-1, then self.file is owned by us.
849 ### well... we aren't explicitly closing, but losing this ref will
850 ### do it
851 self.file = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000852
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000853if hasattr(socket, 'ssl'):
854 class HTTPS(HTTP):
855 """Compatibility with 1.5 httplib interface
856
857 Python 1.5.2 did not have an HTTPS class, but it defined an
858 interface for sending http requests that is also useful for
Tim Peters5ceadc82001-01-13 19:16:21 +0000859 https.
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000860 """
861
Martin v. Löwisd7bf9742000-09-21 22:09:47 +0000862 _connection_class = HTTPSConnection
Tim Peters5ceadc82001-01-13 19:16:21 +0000863
Greg Stein81937a42001-08-18 09:20:23 +0000864 def __init__(self, host='', port=None, **x509):
865 # provide a default host, pass the X509 cert info
866
867 # urf. compensate for bad input.
868 if port == 0:
869 port = None
870 self._setup(self._connection_class(host, port, **x509))
871
872 # we never actually use these for anything, but we keep them
873 # here for compatibility with post-1.5.2 CVS.
874 self.key_file = x509.get('key_file')
875 self.cert_file = x509.get('cert_file')
876
Greg Stein5e0fa402000-06-26 08:28:01 +0000877
878class HTTPException(Exception):
Greg Steindd6eefb2000-07-18 09:09:48 +0000879 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000880
881class NotConnected(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000882 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000883
Skip Montanaro9d389972002-03-24 16:53:50 +0000884class InvalidURL(HTTPException):
885 pass
886
Greg Stein5e0fa402000-06-26 08:28:01 +0000887class UnknownProtocol(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000888 def __init__(self, version):
889 self.version = version
Greg Stein5e0fa402000-06-26 08:28:01 +0000890
891class UnknownTransferEncoding(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000892 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000893
894class IllegalKeywordArgument(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000895 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000896
897class UnimplementedFileMode(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000898 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000899
900class IncompleteRead(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000901 def __init__(self, partial):
902 self.partial = partial
Greg Stein5e0fa402000-06-26 08:28:01 +0000903
904class ImproperConnectionState(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000905 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000906
907class CannotSendRequest(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +0000908 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000909
910class CannotSendHeader(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +0000911 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000912
913class ResponseNotReady(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +0000914 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000915
916class BadStatusLine(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000917 def __init__(self, line):
918 self.line = line
Greg Stein5e0fa402000-06-26 08:28:01 +0000919
920# for backwards compatibility
921error = HTTPException
922
923
924#
925# snarfed from httplib.py for now...
926#
Guido van Rossum23acc951994-02-21 16:36:04 +0000927def test():
Guido van Rossum41999c11997-12-09 00:12:23 +0000928 """Test this module.
929
930 The test consists of retrieving and displaying the Python
931 home page, along with the error code and error string returned
932 by the www.python.org server.
Guido van Rossum41999c11997-12-09 00:12:23 +0000933 """
Greg Stein5e0fa402000-06-26 08:28:01 +0000934
Guido van Rossum41999c11997-12-09 00:12:23 +0000935 import sys
936 import getopt
937 opts, args = getopt.getopt(sys.argv[1:], 'd')
938 dl = 0
939 for o, a in opts:
940 if o == '-d': dl = dl + 1
941 host = 'www.python.org'
942 selector = '/'
943 if args[0:]: host = args[0]
944 if args[1:]: selector = args[1]
945 h = HTTP()
946 h.set_debuglevel(dl)
947 h.connect(host)
948 h.putrequest('GET', selector)
949 h.endheaders()
Greg Stein5e0fa402000-06-26 08:28:01 +0000950 status, reason, headers = h.getreply()
951 print 'status =', status
952 print 'reason =', reason
Guido van Rossum41999c11997-12-09 00:12:23 +0000953 print
954 if headers:
Guido van Rossum34735a62000-12-15 15:09:42 +0000955 for header in headers.headers: print header.strip()
Guido van Rossum41999c11997-12-09 00:12:23 +0000956 print
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000957 print "read", len(h.getfile().read())
Greg Stein5e0fa402000-06-26 08:28:01 +0000958
Jeremy Hylton8acf1e02002-03-08 19:35:51 +0000959 # minimal test that code to extract host from url works
960 class HTTP11(HTTP):
961 _http_vsn = 11
962 _http_vsn_str = 'HTTP/1.1'
963
964 h = HTTP11('www.python.org')
965 h.putrequest('GET', 'http://www.python.org/~jeremy/')
966 h.endheaders()
967 h.getreply()
968 h.close()
969
Greg Stein5e0fa402000-06-26 08:28:01 +0000970 if hasattr(socket, 'ssl'):
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000971 host = 'sourceforge.net'
Jeremy Hylton42dd01a2001-02-01 23:35:20 +0000972 selector = '/projects/python'
Greg Steindd6eefb2000-07-18 09:09:48 +0000973 hs = HTTPS()
974 hs.connect(host)
975 hs.putrequest('GET', selector)
976 hs.endheaders()
977 status, reason, headers = hs.getreply()
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000978 # XXX why does this give a 302 response?
Greg Steindd6eefb2000-07-18 09:09:48 +0000979 print 'status =', status
980 print 'reason =', reason
981 print
982 if headers:
Guido van Rossum34735a62000-12-15 15:09:42 +0000983 for header in headers.headers: print header.strip()
Greg Steindd6eefb2000-07-18 09:09:48 +0000984 print
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000985 print "read", len(hs.getfile().read())
Guido van Rossum23acc951994-02-21 16:36:04 +0000986
Guido van Rossuma0dfc7a1995-09-07 19:28:19 +0000987
Guido van Rossum23acc951994-02-21 16:36:04 +0000988if __name__ == '__main__':
Guido van Rossum41999c11997-12-09 00:12:23 +0000989 test()