blob: 41eb3b0560232d966fbdd1322e3e59e3fd5f2b5f [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",
Jeremy Hylton7c75c992002-06-28 23:38:14 +000081 "UnknownTransferEncoding", "UnimplementedFileMode",
82 "IncompleteRead", "InvalidURL", "ImproperConnectionState",
83 "CannotSendRequest", "CannotSendHeader", "ResponseNotReady",
84 "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 Hyltond46aa372002-07-06 18:48:07 +000098
99 # strict: If true, raise BadStatusLine if the status line can't be
100 # parsed as a valid HTTP/1.0 or 1.1 status line. By default it is
101 # false because it prvents clients from talking to HTTP/0.9
102 # servers. Note that a response with a sufficiently corrupted
103 # status line will look like an HTTP/0.9 response.
104
105 # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
106
107 def __init__(self, sock, debuglevel=0, strict=0):
Greg Steindd6eefb2000-07-18 09:09:48 +0000108 self.fp = sock.makefile('rb', 0)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000109 self.debuglevel = debuglevel
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000110 self.strict = strict
Greg Stein5e0fa402000-06-26 08:28:01 +0000111
Greg Steindd6eefb2000-07-18 09:09:48 +0000112 self.msg = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000113
Greg Steindd6eefb2000-07-18 09:09:48 +0000114 # from the Status-Line of the response
Tim Peters07e99cb2001-01-14 23:47:14 +0000115 self.version = _UNKNOWN # HTTP-Version
116 self.status = _UNKNOWN # Status-Code
117 self.reason = _UNKNOWN # Reason-Phrase
Greg Stein5e0fa402000-06-26 08:28:01 +0000118
Tim Peters07e99cb2001-01-14 23:47:14 +0000119 self.chunked = _UNKNOWN # is "chunked" being used?
120 self.chunk_left = _UNKNOWN # bytes left to read in current chunk
121 self.length = _UNKNOWN # number of bytes left in response
122 self.will_close = _UNKNOWN # conn will close at end of response
Greg Stein5e0fa402000-06-26 08:28:01 +0000123
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000124 def _read_status(self):
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000125 # Initialize with Simple-Response defaults
Greg Stein5e0fa402000-06-26 08:28:01 +0000126 line = self.fp.readline()
Jeremy Hylton30f86742000-09-18 22:50:38 +0000127 if self.debuglevel > 0:
128 print "reply:", repr(line)
Greg Steindd6eefb2000-07-18 09:09:48 +0000129 try:
Guido van Rossum34735a62000-12-15 15:09:42 +0000130 [version, status, reason] = line.split(None, 2)
Greg Steindd6eefb2000-07-18 09:09:48 +0000131 except ValueError:
132 try:
Guido van Rossum34735a62000-12-15 15:09:42 +0000133 [version, status] = line.split(None, 1)
Greg Steindd6eefb2000-07-18 09:09:48 +0000134 reason = ""
135 except ValueError:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000136 # empty version will cause next test to fail and status
137 # will be treated as 0.9 response.
138 version = ""
139 if not version.startswith('HTTP/'):
140 if self.strict:
141 self.close()
142 raise BadStatusLine(line)
143 else:
144 # assume it's a Simple-Response from an 0.9 server
145 self.fp = LineAndFileWrapper(line, self.fp)
146 return "HTTP/0.9", 200, ""
Greg Stein5e0fa402000-06-26 08:28:01 +0000147
Jeremy Hylton23d40472001-04-13 14:57:08 +0000148 # The status code is a three-digit number
149 try:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000150 status = int(status)
Jeremy Hylton23d40472001-04-13 14:57:08 +0000151 if status < 100 or status > 999:
152 raise BadStatusLine(line)
153 except ValueError:
154 raise BadStatusLine(line)
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000155 return version, status, reason
Greg Stein5e0fa402000-06-26 08:28:01 +0000156
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000157 def _begin(self):
158 if self.msg is not None:
159 # we've already started reading the response
160 return
161
162 # read until we get a non-100 response
163 while 1:
164 version, status, reason = self._read_status()
165 if status != 100:
166 break
167 # skip the header from the 100 response
168 while 1:
169 skip = self.fp.readline().strip()
170 if not skip:
171 break
172 if self.debuglevel > 0:
173 print "header:", skip
174
175 self.status = status
176 self.reason = reason.strip()
Greg Steindd6eefb2000-07-18 09:09:48 +0000177 if version == 'HTTP/1.0':
178 self.version = 10
Jeremy Hylton110941a2000-10-12 19:58:36 +0000179 elif version.startswith('HTTP/1.'):
Tim Peters07e99cb2001-01-14 23:47:14 +0000180 self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1
Jeremy Hylton110941a2000-10-12 19:58:36 +0000181 elif version == 'HTTP/0.9':
182 self.version = 9
Greg Steindd6eefb2000-07-18 09:09:48 +0000183 else:
184 raise UnknownProtocol(version)
Greg Stein5e0fa402000-06-26 08:28:01 +0000185
Jeremy Hylton110941a2000-10-12 19:58:36 +0000186 if self.version == 9:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000187 self.chunked = 0
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000188 self.will_close = 1
Jeremy Hylton110941a2000-10-12 19:58:36 +0000189 self.msg = mimetools.Message(StringIO())
190 return
191
Greg Steindd6eefb2000-07-18 09:09:48 +0000192 self.msg = mimetools.Message(self.fp, 0)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000193 if self.debuglevel > 0:
194 for hdr in self.msg.headers:
195 print "header:", hdr,
Greg Stein5e0fa402000-06-26 08:28:01 +0000196
Greg Steindd6eefb2000-07-18 09:09:48 +0000197 # don't let the msg keep an fp
198 self.msg.fp = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000199
Greg Steindd6eefb2000-07-18 09:09:48 +0000200 # are we using the chunked-style of transfer encoding?
201 tr_enc = self.msg.getheader('transfer-encoding')
202 if tr_enc:
Guido van Rossum34735a62000-12-15 15:09:42 +0000203 if tr_enc.lower() != 'chunked':
Greg Steindd6eefb2000-07-18 09:09:48 +0000204 raise UnknownTransferEncoding()
205 self.chunked = 1
206 self.chunk_left = None
207 else:
208 self.chunked = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000209
Greg Steindd6eefb2000-07-18 09:09:48 +0000210 # will the connection close at the end of the response?
211 conn = self.msg.getheader('connection')
212 if conn:
Guido van Rossum34735a62000-12-15 15:09:42 +0000213 conn = conn.lower()
Greg Steindd6eefb2000-07-18 09:09:48 +0000214 # a "Connection: close" will always close the connection. if we
215 # don't see that and this is not HTTP/1.1, then the connection will
216 # close unless we see a Keep-Alive header.
Guido van Rossum34735a62000-12-15 15:09:42 +0000217 self.will_close = conn.find('close') != -1 or \
Greg Steindd6eefb2000-07-18 09:09:48 +0000218 ( self.version != 11 and \
219 not self.msg.getheader('keep-alive') )
220 else:
221 # for HTTP/1.1, the connection will always remain open
222 # otherwise, it will remain open IFF we see a Keep-Alive header
223 self.will_close = self.version != 11 and \
224 not self.msg.getheader('keep-alive')
Greg Stein5e0fa402000-06-26 08:28:01 +0000225
Greg Steindd6eefb2000-07-18 09:09:48 +0000226 # do we have a Content-Length?
227 # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
228 length = self.msg.getheader('content-length')
229 if length and not self.chunked:
Jeremy Hylton30a81812000-09-14 20:34:27 +0000230 try:
231 self.length = int(length)
232 except ValueError:
233 self.length = None
Greg Steindd6eefb2000-07-18 09:09:48 +0000234 else:
235 self.length = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000236
Greg Steindd6eefb2000-07-18 09:09:48 +0000237 # does the body have a fixed length? (of zero)
Tim Peters07e99cb2001-01-14 23:47:14 +0000238 if (status == 204 or # No Content
239 status == 304 or # Not Modified
240 100 <= status < 200): # 1xx codes
Greg Steindd6eefb2000-07-18 09:09:48 +0000241 self.length = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000242
Greg Steindd6eefb2000-07-18 09:09:48 +0000243 # if the connection remains open, and we aren't using chunked, and
244 # a content-length was not provided, then assume that the connection
245 # WILL close.
246 if not self.will_close and \
247 not self.chunked and \
248 self.length is None:
249 self.will_close = 1
Greg Stein5e0fa402000-06-26 08:28:01 +0000250
Greg Steindd6eefb2000-07-18 09:09:48 +0000251 def close(self):
252 if self.fp:
253 self.fp.close()
254 self.fp = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000255
Greg Steindd6eefb2000-07-18 09:09:48 +0000256 def isclosed(self):
257 # NOTE: it is possible that we will not ever call self.close(). This
258 # case occurs when will_close is TRUE, length is None, and we
259 # read up to the last byte, but NOT past it.
260 #
261 # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
262 # called, meaning self.isclosed() is meaningful.
263 return self.fp is None
264
265 def read(self, amt=None):
266 if self.fp is None:
267 return ''
268
269 if self.chunked:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000270 assert self.chunked != _UNKNOWN
Greg Steindd6eefb2000-07-18 09:09:48 +0000271 chunk_left = self.chunk_left
272 value = ''
273 while 1:
274 if chunk_left is None:
275 line = self.fp.readline()
Guido van Rossum34735a62000-12-15 15:09:42 +0000276 i = line.find(';')
Greg Steindd6eefb2000-07-18 09:09:48 +0000277 if i >= 0:
Tim Peters07e99cb2001-01-14 23:47:14 +0000278 line = line[:i] # strip chunk-extensions
Guido van Rossum34735a62000-12-15 15:09:42 +0000279 chunk_left = int(line, 16)
Greg Steindd6eefb2000-07-18 09:09:48 +0000280 if chunk_left == 0:
281 break
282 if amt is None:
283 value = value + self._safe_read(chunk_left)
284 elif amt < chunk_left:
285 value = value + self._safe_read(amt)
286 self.chunk_left = chunk_left - amt
287 return value
288 elif amt == chunk_left:
289 value = value + self._safe_read(amt)
Tim Peters07e99cb2001-01-14 23:47:14 +0000290 self._safe_read(2) # toss the CRLF at the end of the chunk
Greg Steindd6eefb2000-07-18 09:09:48 +0000291 self.chunk_left = None
292 return value
293 else:
294 value = value + self._safe_read(chunk_left)
295 amt = amt - chunk_left
296
297 # we read the whole chunk, get another
Tim Peters07e99cb2001-01-14 23:47:14 +0000298 self._safe_read(2) # toss the CRLF at the end of the chunk
Greg Steindd6eefb2000-07-18 09:09:48 +0000299 chunk_left = None
300
301 # read and discard trailer up to the CRLF terminator
302 ### note: we shouldn't have any trailers!
303 while 1:
304 line = self.fp.readline()
305 if line == '\r\n':
306 break
307
308 # we read everything; close the "file"
309 self.close()
310
311 return value
312
313 elif amt is None:
314 # unbounded read
315 if self.will_close:
316 s = self.fp.read()
317 else:
318 s = self._safe_read(self.length)
Tim Peters07e99cb2001-01-14 23:47:14 +0000319 self.close() # we read everything
Greg Steindd6eefb2000-07-18 09:09:48 +0000320 return s
321
322 if self.length is not None:
323 if amt > self.length:
324 # clip the read to the "end of response"
325 amt = self.length
326 self.length = self.length - amt
327
328 # we do not use _safe_read() here because this may be a .will_close
329 # connection, and the user is reading more bytes than will be provided
330 # (for example, reading in 1k chunks)
331 s = self.fp.read(amt)
332
Greg Steindd6eefb2000-07-18 09:09:48 +0000333 return s
334
335 def _safe_read(self, amt):
336 """Read the number of bytes requested, compensating for partial reads.
337
338 Normally, we have a blocking socket, but a read() can be interrupted
339 by a signal (resulting in a partial read).
340
341 Note that we cannot distinguish between EOF and an interrupt when zero
342 bytes have been read. IncompleteRead() will be raised in this
343 situation.
344
345 This function should be used when <amt> bytes "should" be present for
346 reading. If the bytes are truly not available (due to EOF), then the
347 IncompleteRead exception can be used to detect the problem.
348 """
349 s = ''
350 while amt > 0:
351 chunk = self.fp.read(amt)
352 if not chunk:
353 raise IncompleteRead(s)
354 s = s + chunk
355 amt = amt - len(chunk)
356 return s
357
358 def getheader(self, name, default=None):
359 if self.msg is None:
360 raise ResponseNotReady()
361 return self.msg.getheader(name, default)
Greg Stein5e0fa402000-06-26 08:28:01 +0000362
363
364class HTTPConnection:
365
Greg Steindd6eefb2000-07-18 09:09:48 +0000366 _http_vsn = 11
367 _http_vsn_str = 'HTTP/1.1'
Greg Stein5e0fa402000-06-26 08:28:01 +0000368
Greg Steindd6eefb2000-07-18 09:09:48 +0000369 response_class = HTTPResponse
370 default_port = HTTP_PORT
371 auto_open = 1
Jeremy Hylton30f86742000-09-18 22:50:38 +0000372 debuglevel = 0
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000373 strict = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000374
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000375 def __init__(self, host, port=None, strict=None):
Greg Steindd6eefb2000-07-18 09:09:48 +0000376 self.sock = None
377 self.__response = None
378 self.__state = _CS_IDLE
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000379
Greg Steindd6eefb2000-07-18 09:09:48 +0000380 self._set_hostport(host, port)
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000381 if strict is not None:
382 self.strict = strict
Greg Stein5e0fa402000-06-26 08:28:01 +0000383
Greg Steindd6eefb2000-07-18 09:09:48 +0000384 def _set_hostport(self, host, port):
385 if port is None:
Guido van Rossum34735a62000-12-15 15:09:42 +0000386 i = host.find(':')
Greg Steindd6eefb2000-07-18 09:09:48 +0000387 if i >= 0:
Skip Montanaro9d389972002-03-24 16:53:50 +0000388 try:
389 port = int(host[i+1:])
390 except ValueError:
Jeremy Hyltonfbd79942002-07-02 20:19:08 +0000391 raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
Greg Steindd6eefb2000-07-18 09:09:48 +0000392 host = host[:i]
393 else:
394 port = self.default_port
395 self.host = host
396 self.port = port
Greg Stein5e0fa402000-06-26 08:28:01 +0000397
Jeremy Hylton30f86742000-09-18 22:50:38 +0000398 def set_debuglevel(self, level):
399 self.debuglevel = level
400
Greg Steindd6eefb2000-07-18 09:09:48 +0000401 def connect(self):
402 """Connect to the host and port specified in __init__."""
Martin v. Löwis2ad25692001-07-31 08:40:21 +0000403 msg = "getaddrinfo returns an empty list"
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000404 for res in socket.getaddrinfo(self.host, self.port, 0,
405 socket.SOCK_STREAM):
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000406 af, socktype, proto, canonname, sa = res
407 try:
408 self.sock = socket.socket(af, socktype, proto)
409 if self.debuglevel > 0:
410 print "connect: (%s, %s)" % (self.host, self.port)
411 self.sock.connect(sa)
412 except socket.error, msg:
413 if self.debuglevel > 0:
414 print 'connect fail:', (self.host, self.port)
Martin v. Löwis322c0d12001-10-07 08:53:32 +0000415 if self.sock:
416 self.sock.close()
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000417 self.sock = None
418 continue
419 break
420 if not self.sock:
421 raise socket.error, msg
Greg Stein5e0fa402000-06-26 08:28:01 +0000422
Greg Steindd6eefb2000-07-18 09:09:48 +0000423 def close(self):
424 """Close the connection to the HTTP server."""
425 if self.sock:
Tim Peters07e99cb2001-01-14 23:47:14 +0000426 self.sock.close() # close it manually... there may be other refs
Greg Steindd6eefb2000-07-18 09:09:48 +0000427 self.sock = None
428 if self.__response:
429 self.__response.close()
430 self.__response = None
431 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000432
Greg Steindd6eefb2000-07-18 09:09:48 +0000433 def send(self, str):
434 """Send `str' to the server."""
435 if self.sock is None:
436 if self.auto_open:
437 self.connect()
438 else:
439 raise NotConnected()
Greg Stein5e0fa402000-06-26 08:28:01 +0000440
Greg Steindd6eefb2000-07-18 09:09:48 +0000441 # send the data to the server. if we get a broken pipe, then close
442 # the socket. we want to reconnect when somebody tries to send again.
443 #
444 # NOTE: we DO propagate the error, though, because we cannot simply
445 # ignore the error... the caller will know if they can retry.
Jeremy Hylton30f86742000-09-18 22:50:38 +0000446 if self.debuglevel > 0:
447 print "send:", repr(str)
Greg Steindd6eefb2000-07-18 09:09:48 +0000448 try:
Martin v. Löwise12454f2002-02-16 23:06:19 +0000449 self.sock.sendall(str)
Greg Steindd6eefb2000-07-18 09:09:48 +0000450 except socket.error, v:
Tim Peters07e99cb2001-01-14 23:47:14 +0000451 if v[0] == 32: # Broken pipe
Greg Steindd6eefb2000-07-18 09:09:48 +0000452 self.close()
453 raise
Greg Stein5e0fa402000-06-26 08:28:01 +0000454
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000455 def putrequest(self, method, url, skip_host=0):
Greg Steindd6eefb2000-07-18 09:09:48 +0000456 """Send a request to the server.
Greg Stein5e0fa402000-06-26 08:28:01 +0000457
Greg Steindd6eefb2000-07-18 09:09:48 +0000458 `method' specifies an HTTP request method, e.g. 'GET'.
459 `url' specifies the object being requested, e.g. '/index.html'.
460 """
Greg Stein5e0fa402000-06-26 08:28:01 +0000461
Greg Steindd6eefb2000-07-18 09:09:48 +0000462 # check if a prior response has been completed
463 if self.__response and self.__response.isclosed():
464 self.__response = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000465
Greg Steindd6eefb2000-07-18 09:09:48 +0000466 #
467 # in certain cases, we cannot issue another request on this connection.
468 # this occurs when:
469 # 1) we are in the process of sending a request. (_CS_REQ_STARTED)
470 # 2) a response to a previous request has signalled that it is going
471 # to close the connection upon completion.
472 # 3) the headers for the previous response have not been read, thus
473 # we cannot determine whether point (2) is true. (_CS_REQ_SENT)
474 #
475 # if there is no prior response, then we can request at will.
476 #
477 # if point (2) is true, then we will have passed the socket to the
478 # response (effectively meaning, "there is no prior response"), and
479 # will open a new one when a new request is made.
480 #
481 # Note: if a prior response exists, then we *can* start a new request.
482 # We are not allowed to begin fetching the response to this new
483 # request, however, until that prior response is complete.
484 #
485 if self.__state == _CS_IDLE:
486 self.__state = _CS_REQ_STARTED
487 else:
488 raise CannotSendRequest()
Greg Stein5e0fa402000-06-26 08:28:01 +0000489
Greg Steindd6eefb2000-07-18 09:09:48 +0000490 if not url:
491 url = '/'
492 str = '%s %s %s\r\n' % (method, url, self._http_vsn_str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000493
Greg Steindd6eefb2000-07-18 09:09:48 +0000494 try:
495 self.send(str)
496 except socket.error, v:
497 # trap 'Broken pipe' if we're allowed to automatically reconnect
498 if v[0] != 32 or not self.auto_open:
499 raise
500 # try one more time (the socket was closed; this will reopen)
501 self.send(str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000502
Greg Steindd6eefb2000-07-18 09:09:48 +0000503 if self._http_vsn == 11:
504 # Issue some standard headers for better HTTP/1.1 compliance
Greg Stein5e0fa402000-06-26 08:28:01 +0000505
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000506 if not skip_host:
507 # this header is issued *only* for HTTP/1.1
508 # connections. more specifically, this means it is
509 # only issued when the client uses the new
510 # HTTPConnection() class. backwards-compat clients
511 # will be using HTTP/1.0 and those clients may be
512 # issuing this header themselves. we should NOT issue
513 # it twice; some web servers (such as Apache) barf
514 # when they see two Host: headers
Guido van Rossumf6922aa2001-01-14 21:03:01 +0000515
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000516 # If we need a non-standard port,include it in the
517 # header. If the request is going through a proxy,
518 # but the host of the actual URL, not the host of the
519 # proxy.
Jeremy Hylton8acf1e02002-03-08 19:35:51 +0000520
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000521 netloc = ''
522 if url.startswith('http'):
523 nil, netloc, nil, nil, nil = urlsplit(url)
524
525 if netloc:
526 self.putheader('Host', netloc)
527 elif self.port == HTTP_PORT:
528 self.putheader('Host', self.host)
529 else:
530 self.putheader('Host', "%s:%s" % (self.host, self.port))
Greg Stein5e0fa402000-06-26 08:28:01 +0000531
Greg Steindd6eefb2000-07-18 09:09:48 +0000532 # note: we are assuming that clients will not attempt to set these
533 # headers since *this* library must deal with the
534 # consequences. this also means that when the supporting
535 # libraries are updated to recognize other forms, then this
536 # code should be changed (removed or updated).
Greg Stein5e0fa402000-06-26 08:28:01 +0000537
Greg Steindd6eefb2000-07-18 09:09:48 +0000538 # we only want a Content-Encoding of "identity" since we don't
539 # support encodings such as x-gzip or x-deflate.
540 self.putheader('Accept-Encoding', 'identity')
Greg Stein5e0fa402000-06-26 08:28:01 +0000541
Greg Steindd6eefb2000-07-18 09:09:48 +0000542 # we can accept "chunked" Transfer-Encodings, but no others
543 # NOTE: no TE header implies *only* "chunked"
544 #self.putheader('TE', 'chunked')
Greg Stein5e0fa402000-06-26 08:28:01 +0000545
Greg Steindd6eefb2000-07-18 09:09:48 +0000546 # if TE is supplied in the header, then it must appear in a
547 # Connection header.
548 #self.putheader('Connection', 'TE')
Greg Stein5e0fa402000-06-26 08:28:01 +0000549
Greg Steindd6eefb2000-07-18 09:09:48 +0000550 else:
551 # For HTTP/1.0, the server will assume "not chunked"
552 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000553
Greg Steindd6eefb2000-07-18 09:09:48 +0000554 def putheader(self, header, value):
555 """Send a request header line to the server.
Greg Stein5e0fa402000-06-26 08:28:01 +0000556
Greg Steindd6eefb2000-07-18 09:09:48 +0000557 For example: h.putheader('Accept', 'text/html')
558 """
559 if self.__state != _CS_REQ_STARTED:
560 raise CannotSendHeader()
Greg Stein5e0fa402000-06-26 08:28:01 +0000561
Greg Steindd6eefb2000-07-18 09:09:48 +0000562 str = '%s: %s\r\n' % (header, value)
563 self.send(str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000564
Greg Steindd6eefb2000-07-18 09:09:48 +0000565 def endheaders(self):
566 """Indicate that the last header line has been sent to the server."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000567
Greg Steindd6eefb2000-07-18 09:09:48 +0000568 if self.__state == _CS_REQ_STARTED:
569 self.__state = _CS_REQ_SENT
570 else:
571 raise CannotSendHeader()
Greg Stein5e0fa402000-06-26 08:28:01 +0000572
Greg Steindd6eefb2000-07-18 09:09:48 +0000573 self.send('\r\n')
Greg Stein5e0fa402000-06-26 08:28:01 +0000574
Greg Steindd6eefb2000-07-18 09:09:48 +0000575 def request(self, method, url, body=None, headers={}):
576 """Send a complete request to the server."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000577
Greg Steindd6eefb2000-07-18 09:09:48 +0000578 try:
579 self._send_request(method, url, body, headers)
580 except socket.error, v:
581 # trap 'Broken pipe' if we're allowed to automatically reconnect
582 if v[0] != 32 or not self.auto_open:
583 raise
584 # try one more time
585 self._send_request(method, url, body, headers)
Greg Stein5e0fa402000-06-26 08:28:01 +0000586
Greg Steindd6eefb2000-07-18 09:09:48 +0000587 def _send_request(self, method, url, body, headers):
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000588 # If headers already contains a host header, then define the
589 # optional skip_host argument to putrequest(). The check is
590 # harder because field names are case insensitive.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000591 if 'Host' in (headers
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000592 or [k for k in headers.iterkeys() if k.lower() == "host"]):
593 self.putrequest(method, url, skip_host=1)
594 else:
595 self.putrequest(method, url)
Greg Stein5e0fa402000-06-26 08:28:01 +0000596
Greg Steindd6eefb2000-07-18 09:09:48 +0000597 if body:
598 self.putheader('Content-Length', str(len(body)))
599 for hdr, value in headers.items():
600 self.putheader(hdr, value)
601 self.endheaders()
Greg Stein5e0fa402000-06-26 08:28:01 +0000602
Greg Steindd6eefb2000-07-18 09:09:48 +0000603 if body:
604 self.send(body)
Greg Stein5e0fa402000-06-26 08:28:01 +0000605
Greg Steindd6eefb2000-07-18 09:09:48 +0000606 def getresponse(self):
607 "Get the response from the server."
Greg Stein5e0fa402000-06-26 08:28:01 +0000608
Greg Steindd6eefb2000-07-18 09:09:48 +0000609 # check if a prior response has been completed
610 if self.__response and self.__response.isclosed():
611 self.__response = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000612
Greg Steindd6eefb2000-07-18 09:09:48 +0000613 #
614 # if a prior response exists, then it must be completed (otherwise, we
615 # cannot read this response's header to determine the connection-close
616 # behavior)
617 #
618 # note: if a prior response existed, but was connection-close, then the
619 # socket and response were made independent of this HTTPConnection
620 # object since a new request requires that we open a whole new
621 # connection
622 #
623 # this means the prior response had one of two states:
624 # 1) will_close: this connection was reset and the prior socket and
625 # response operate independently
626 # 2) persistent: the response was retained and we await its
627 # isclosed() status to become true.
628 #
629 if self.__state != _CS_REQ_SENT or self.__response:
630 raise ResponseNotReady()
Greg Stein5e0fa402000-06-26 08:28:01 +0000631
Jeremy Hylton30f86742000-09-18 22:50:38 +0000632 if self.debuglevel > 0:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000633 response = self.response_class(self.sock, self.debuglevel,
634 strict=self.strict)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000635 else:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000636 response = self.response_class(self.sock, strict=self.strict)
Greg Stein5e0fa402000-06-26 08:28:01 +0000637
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000638 response._begin()
639 assert response.will_close != _UNKNOWN
Greg Steindd6eefb2000-07-18 09:09:48 +0000640 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000641
Greg Steindd6eefb2000-07-18 09:09:48 +0000642 if response.will_close:
643 # this effectively passes the connection to the response
644 self.close()
645 else:
646 # remember this, so we can tell when it is complete
647 self.__response = response
Greg Stein5e0fa402000-06-26 08:28:01 +0000648
Greg Steindd6eefb2000-07-18 09:09:48 +0000649 return response
Greg Stein5e0fa402000-06-26 08:28:01 +0000650
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000651class SSLFile:
652 """File-like object wrapping an SSL socket."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000653
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000654 BUFSIZE = 8192
655
656 def __init__(self, sock, ssl, bufsize=None):
657 self._sock = sock
658 self._ssl = ssl
659 self._buf = ''
660 self._bufsize = bufsize or self.__class__.BUFSIZE
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000661
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000662 def _read(self):
663 buf = ''
664 # put in a loop so that we retry on transient errors
Greg Steindd6eefb2000-07-18 09:09:48 +0000665 while 1:
666 try:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000667 buf = self._ssl.read(self._bufsize)
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000668 except socket.sslerror, err:
669 if (err[0] == socket.SSL_ERROR_WANT_READ
Neal Norwitz22c5d772002-02-11 17:59:51 +0000670 or err[0] == socket.SSL_ERROR_WANT_WRITE):
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000671 continue
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000672 if (err[0] == socket.SSL_ERROR_ZERO_RETURN
673 or err[0] == socket.SSL_ERROR_EOF):
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000674 break
675 raise
676 except socket.error, err:
Tim Petersf3623f32001-10-11 18:15:51 +0000677 if err[0] == errno.EINTR:
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000678 continue
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000679 if err[0] == errno.EBADF:
680 # XXX socket was closed?
681 break
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000682 raise
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000683 else:
Jeremy Hylton42dd01a2001-02-01 23:35:20 +0000684 break
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000685 return buf
686
687 def read(self, size=None):
688 L = [self._buf]
689 avail = len(self._buf)
690 while size is None or avail < size:
691 s = self._read()
692 if s == '':
693 break
694 L.append(s)
695 avail += len(s)
696 all = "".join(L)
697 if size is None:
698 self._buf = ''
699 return all
700 else:
701 self._buf = all[size:]
702 return all[:size]
703
704 def readline(self):
705 L = [self._buf]
706 self._buf = ''
707 while 1:
708 i = L[-1].find("\n")
709 if i >= 0:
710 break
711 s = self._read()
712 if s == '':
713 break
714 L.append(s)
715 if i == -1:
716 # loop exited because there is no more data
717 return "".join(L)
718 else:
719 all = "".join(L)
720 # XXX could do enough bookkeeping not to do a 2nd search
721 i = all.find("\n") + 1
722 line = all[:i]
723 self._buf = all[i:]
724 return line
725
726 def close(self):
727 self._sock.close()
728
729class FakeSocket:
730 def __init__(self, sock, ssl):
731 self.__sock = sock
732 self.__ssl = ssl
733
734 def makefile(self, mode, bufsize=None):
735 if mode != 'r' and mode != 'rb':
736 raise UnimplementedFileMode()
737 return SSLFile(self.__sock, self.__ssl, bufsize)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000738
Greg Steindd6eefb2000-07-18 09:09:48 +0000739 def send(self, stuff, flags = 0):
740 return self.__ssl.write(stuff)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000741
Andrew M. Kuchlinga3c0b932002-03-18 22:51:48 +0000742 def sendall(self, stuff, flags = 0):
743 return self.__ssl.write(stuff)
744
Greg Steindd6eefb2000-07-18 09:09:48 +0000745 def recv(self, len = 1024, flags = 0):
746 return self.__ssl.read(len)
Guido van Rossum23acc951994-02-21 16:36:04 +0000747
Greg Steindd6eefb2000-07-18 09:09:48 +0000748 def __getattr__(self, attr):
749 return getattr(self.__sock, attr)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000750
Guido van Rossum23acc951994-02-21 16:36:04 +0000751
Greg Stein5e0fa402000-06-26 08:28:01 +0000752class HTTPSConnection(HTTPConnection):
Greg Steindd6eefb2000-07-18 09:09:48 +0000753 "This class allows communication via SSL."
Greg Stein5e0fa402000-06-26 08:28:01 +0000754
Greg Steindd6eefb2000-07-18 09:09:48 +0000755 default_port = HTTPS_PORT
Greg Stein5e0fa402000-06-26 08:28:01 +0000756
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000757 def __init__(self, host, port=None, key_file=None, cert_file=None,
758 strict=None):
759 HTTPConnection.__init__(self, host, port, strict)
Jeremy Hylton7c75c992002-06-28 23:38:14 +0000760 self.key_file = key_file
761 self.cert_file = cert_file
Greg Stein5e0fa402000-06-26 08:28:01 +0000762
Greg Steindd6eefb2000-07-18 09:09:48 +0000763 def connect(self):
764 "Connect to a host on a given (SSL) port."
Greg Stein5e0fa402000-06-26 08:28:01 +0000765
Greg Steindd6eefb2000-07-18 09:09:48 +0000766 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
767 sock.connect((self.host, self.port))
Guido van Rossum0aee7222000-12-11 20:32:20 +0000768 realsock = sock
769 if hasattr(sock, "_sock"):
770 realsock = sock._sock
771 ssl = socket.ssl(realsock, self.key_file, self.cert_file)
Greg Steindd6eefb2000-07-18 09:09:48 +0000772 self.sock = FakeSocket(sock, ssl)
Greg Stein5e0fa402000-06-26 08:28:01 +0000773
774
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000775class HTTP:
Greg Steindd6eefb2000-07-18 09:09:48 +0000776 "Compatibility class with httplib.py from 1.5."
Greg Stein5e0fa402000-06-26 08:28:01 +0000777
Greg Steindd6eefb2000-07-18 09:09:48 +0000778 _http_vsn = 10
779 _http_vsn_str = 'HTTP/1.0'
Greg Stein5e0fa402000-06-26 08:28:01 +0000780
Greg Steindd6eefb2000-07-18 09:09:48 +0000781 debuglevel = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000782
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000783 _connection_class = HTTPConnection
784
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000785 def __init__(self, host='', port=None, strict=None):
Greg Steindd6eefb2000-07-18 09:09:48 +0000786 "Provide a default host, since the superclass requires one."
Greg Stein5e0fa402000-06-26 08:28:01 +0000787
Greg Steindd6eefb2000-07-18 09:09:48 +0000788 # some joker passed 0 explicitly, meaning default port
789 if port == 0:
790 port = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000791
Greg Steindd6eefb2000-07-18 09:09:48 +0000792 # Note that we may pass an empty string as the host; this will throw
793 # an error when we attempt to connect. Presumably, the client code
794 # will call connect before then, with a proper host.
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000795 self._setup(self._connection_class(host, port, strict))
Greg Stein5e0fa402000-06-26 08:28:01 +0000796
Greg Stein81937a42001-08-18 09:20:23 +0000797 def _setup(self, conn):
798 self._conn = conn
799
800 # set up delegation to flesh out interface
801 self.send = conn.send
802 self.putrequest = conn.putrequest
803 self.endheaders = conn.endheaders
804 self.set_debuglevel = conn.set_debuglevel
805
806 conn._http_vsn = self._http_vsn
807 conn._http_vsn_str = self._http_vsn_str
Greg Stein5e0fa402000-06-26 08:28:01 +0000808
Greg Steindd6eefb2000-07-18 09:09:48 +0000809 self.file = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000810
Greg Steindd6eefb2000-07-18 09:09:48 +0000811 def connect(self, host=None, port=None):
812 "Accept arguments to set the host/port, since the superclass doesn't."
Greg Stein5e0fa402000-06-26 08:28:01 +0000813
Greg Steindd6eefb2000-07-18 09:09:48 +0000814 if host is not None:
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000815 self._conn._set_hostport(host, port)
816 self._conn.connect()
Greg Stein5e0fa402000-06-26 08:28:01 +0000817
Greg Steindd6eefb2000-07-18 09:09:48 +0000818 def getfile(self):
819 "Provide a getfile, since the superclass' does not use this concept."
820 return self.file
Greg Stein5e0fa402000-06-26 08:28:01 +0000821
Greg Steindd6eefb2000-07-18 09:09:48 +0000822 def putheader(self, header, *values):
823 "The superclass allows only one value argument."
Guido van Rossum34735a62000-12-15 15:09:42 +0000824 self._conn.putheader(header, '\r\n\t'.join(values))
Greg Stein5e0fa402000-06-26 08:28:01 +0000825
Greg Steindd6eefb2000-07-18 09:09:48 +0000826 def getreply(self):
827 """Compat definition since superclass does not define it.
Greg Stein5e0fa402000-06-26 08:28:01 +0000828
Greg Steindd6eefb2000-07-18 09:09:48 +0000829 Returns a tuple consisting of:
830 - server status code (e.g. '200' if all goes well)
831 - server "reason" corresponding to status code
832 - any RFC822 headers in the response from the server
833 """
834 try:
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000835 response = self._conn.getresponse()
Greg Steindd6eefb2000-07-18 09:09:48 +0000836 except BadStatusLine, e:
837 ### hmm. if getresponse() ever closes the socket on a bad request,
838 ### then we are going to have problems with self.sock
Greg Stein5e0fa402000-06-26 08:28:01 +0000839
Greg Steindd6eefb2000-07-18 09:09:48 +0000840 ### should we keep this behavior? do people use it?
841 # keep the socket open (as a file), and return it
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000842 self.file = self._conn.sock.makefile('rb', 0)
Greg Stein5e0fa402000-06-26 08:28:01 +0000843
Greg Steindd6eefb2000-07-18 09:09:48 +0000844 # close our socket -- we want to restart after any protocol error
845 self.close()
Greg Stein5e0fa402000-06-26 08:28:01 +0000846
Greg Steindd6eefb2000-07-18 09:09:48 +0000847 self.headers = None
848 return -1, e.line, None
Greg Stein5e0fa402000-06-26 08:28:01 +0000849
Greg Steindd6eefb2000-07-18 09:09:48 +0000850 self.headers = response.msg
851 self.file = response.fp
852 return response.status, response.reason, response.msg
Greg Stein5e0fa402000-06-26 08:28:01 +0000853
Greg Steindd6eefb2000-07-18 09:09:48 +0000854 def close(self):
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000855 self._conn.close()
Greg Stein5e0fa402000-06-26 08:28:01 +0000856
Greg Steindd6eefb2000-07-18 09:09:48 +0000857 # note that self.file == response.fp, which gets closed by the
858 # superclass. just clear the object ref here.
859 ### hmm. messy. if status==-1, then self.file is owned by us.
860 ### well... we aren't explicitly closing, but losing this ref will
861 ### do it
862 self.file = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000863
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000864if hasattr(socket, 'ssl'):
865 class HTTPS(HTTP):
866 """Compatibility with 1.5 httplib interface
867
868 Python 1.5.2 did not have an HTTPS class, but it defined an
869 interface for sending http requests that is also useful for
Tim Peters5ceadc82001-01-13 19:16:21 +0000870 https.
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +0000871 """
872
Martin v. Löwisd7bf9742000-09-21 22:09:47 +0000873 _connection_class = HTTPSConnection
Tim Peters5ceadc82001-01-13 19:16:21 +0000874
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000875 def __init__(self, host='', port=None, key_file=None, cert_file=None,
876 strict=None):
Greg Stein81937a42001-08-18 09:20:23 +0000877 # provide a default host, pass the X509 cert info
878
879 # urf. compensate for bad input.
880 if port == 0:
881 port = None
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000882 self._setup(self._connection_class(host, port, key_file,
883 cert_file, strict))
Greg Stein81937a42001-08-18 09:20:23 +0000884
885 # we never actually use these for anything, but we keep them
886 # here for compatibility with post-1.5.2 CVS.
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000887 self.key_file = key_file
888 self.cert_file = cert_file
Greg Stein81937a42001-08-18 09:20:23 +0000889
Greg Stein5e0fa402000-06-26 08:28:01 +0000890
891class HTTPException(Exception):
Jeremy Hylton12f4f352002-07-06 18:55:01 +0000892 # Subclasses that define an __init__ must call Exception.__init__
893 # or define self.args. Otherwise, str() will fail.
Greg Steindd6eefb2000-07-18 09:09:48 +0000894 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000895
896class NotConnected(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000897 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000898
Skip Montanaro9d389972002-03-24 16:53:50 +0000899class InvalidURL(HTTPException):
900 pass
901
Greg Stein5e0fa402000-06-26 08:28:01 +0000902class UnknownProtocol(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000903 def __init__(self, version):
Jeremy Hylton12f4f352002-07-06 18:55:01 +0000904 self.args = version,
Greg Steindd6eefb2000-07-18 09:09:48 +0000905 self.version = version
Greg Stein5e0fa402000-06-26 08:28:01 +0000906
907class UnknownTransferEncoding(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000908 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000909
Greg Stein5e0fa402000-06-26 08:28:01 +0000910class UnimplementedFileMode(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000911 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000912
913class IncompleteRead(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000914 def __init__(self, partial):
Jeremy Hylton12f4f352002-07-06 18:55:01 +0000915 self.args = partial,
Greg Steindd6eefb2000-07-18 09:09:48 +0000916 self.partial = partial
Greg Stein5e0fa402000-06-26 08:28:01 +0000917
918class ImproperConnectionState(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000919 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000920
921class CannotSendRequest(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +0000922 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000923
924class CannotSendHeader(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +0000925 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000926
927class ResponseNotReady(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +0000928 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000929
930class BadStatusLine(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +0000931 def __init__(self, line):
Jeremy Hylton12f4f352002-07-06 18:55:01 +0000932 self.args = line,
Greg Steindd6eefb2000-07-18 09:09:48 +0000933 self.line = line
Greg Stein5e0fa402000-06-26 08:28:01 +0000934
935# for backwards compatibility
936error = HTTPException
937
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000938class LineAndFileWrapper:
939 """A limited file-like object for HTTP/0.9 responses."""
940
941 # The status-line parsing code calls readline(), which normally
942 # get the HTTP status line. For a 0.9 response, however, this is
943 # actually the first line of the body! Clients need to get a
944 # readable file object that contains that line.
945
946 def __init__(self, line, file):
947 self._line = line
948 self._file = file
949 self._line_consumed = 0
950 self._line_offset = 0
951 self._line_left = len(line)
952
953 def __getattr__(self, attr):
954 return getattr(self._file, attr)
955
956 def _done(self):
957 # called when the last byte is read from the line. After the
958 # call, all read methods are delegated to the underlying file
959 # obhect.
960 self._line_consumed = 1
961 self.read = self._file.read
962 self.readline = self._file.readline
963 self.readlines = self._file.readlines
964
965 def read(self, amt=None):
966 assert not self._line_consumed and self._line_left
967 if amt is None or amt > self._line_left:
968 s = self._line[self._line_offset:]
969 self._done()
970 if amt is None:
971 return s + self._file.read()
972 else:
973 return s + self._file.read(amt - len(s))
974 else:
975 assert amt <= self._line_left
976 i = self._line_offset
977 j = i + amt
978 s = self._line[i:j]
979 self._line_offset = j
980 self._line_left -= amt
981 if self._line_left == 0:
982 self._done()
983 return s
984
985 def readline(self):
986 s = self._line[self._line_offset:]
987 self._done()
988 return s
989
990 def readlines(self, size=None):
991 L = [self._line[self._line_offset:]]
992 self._done()
993 if size is None:
994 return L + self._file.readlines()
995 else:
996 return L + self._file.readlines(size)
Greg Stein5e0fa402000-06-26 08:28:01 +0000997
998#
999# snarfed from httplib.py for now...
1000#
Guido van Rossum23acc951994-02-21 16:36:04 +00001001def test():
Guido van Rossum41999c11997-12-09 00:12:23 +00001002 """Test this module.
1003
1004 The test consists of retrieving and displaying the Python
1005 home page, along with the error code and error string returned
1006 by the www.python.org server.
Guido van Rossum41999c11997-12-09 00:12:23 +00001007 """
Greg Stein5e0fa402000-06-26 08:28:01 +00001008
Guido van Rossum41999c11997-12-09 00:12:23 +00001009 import sys
1010 import getopt
1011 opts, args = getopt.getopt(sys.argv[1:], 'd')
1012 dl = 0
1013 for o, a in opts:
1014 if o == '-d': dl = dl + 1
1015 host = 'www.python.org'
1016 selector = '/'
1017 if args[0:]: host = args[0]
1018 if args[1:]: selector = args[1]
1019 h = HTTP()
1020 h.set_debuglevel(dl)
1021 h.connect(host)
1022 h.putrequest('GET', selector)
1023 h.endheaders()
Greg Stein5e0fa402000-06-26 08:28:01 +00001024 status, reason, headers = h.getreply()
1025 print 'status =', status
1026 print 'reason =', reason
Guido van Rossum41999c11997-12-09 00:12:23 +00001027 print
1028 if headers:
Guido van Rossum34735a62000-12-15 15:09:42 +00001029 for header in headers.headers: print header.strip()
Guido van Rossum41999c11997-12-09 00:12:23 +00001030 print
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001031 print "read", len(h.getfile().read())
Greg Stein5e0fa402000-06-26 08:28:01 +00001032
Jeremy Hylton8acf1e02002-03-08 19:35:51 +00001033 # minimal test that code to extract host from url works
1034 class HTTP11(HTTP):
1035 _http_vsn = 11
1036 _http_vsn_str = 'HTTP/1.1'
1037
1038 h = HTTP11('www.python.org')
1039 h.putrequest('GET', 'http://www.python.org/~jeremy/')
1040 h.endheaders()
1041 h.getreply()
1042 h.close()
1043
Greg Stein5e0fa402000-06-26 08:28:01 +00001044 if hasattr(socket, 'ssl'):
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001045 host = 'sourceforge.net'
Jeremy Hylton42dd01a2001-02-01 23:35:20 +00001046 selector = '/projects/python'
Greg Steindd6eefb2000-07-18 09:09:48 +00001047 hs = HTTPS()
1048 hs.connect(host)
1049 hs.putrequest('GET', selector)
1050 hs.endheaders()
1051 status, reason, headers = hs.getreply()
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001052 # XXX why does this give a 302 response?
Greg Steindd6eefb2000-07-18 09:09:48 +00001053 print 'status =', status
1054 print 'reason =', reason
1055 print
1056 if headers:
Guido van Rossum34735a62000-12-15 15:09:42 +00001057 for header in headers.headers: print header.strip()
Greg Steindd6eefb2000-07-18 09:09:48 +00001058 print
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001059 print "read", len(hs.getfile().read())
Guido van Rossum23acc951994-02-21 16:36:04 +00001060
Guido van Rossuma0dfc7a1995-09-07 19:28:19 +00001061
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001062 # Test a buggy server -- returns garbled status line.
1063 # http://www.yahoo.com/promotions/mom_com97/supermom.html
1064 c = HTTPConnection("promotions.yahoo.com")
1065 c.set_debuglevel(1)
1066 c.connect()
1067 c.request("GET", "/promotions/mom_com97/supermom.html")
1068 r = c.getresponse()
1069 print r.status, r.version
1070 lines = r.read().split("\n")
1071 print "\n".join(lines[:5])
1072
1073 c = HTTPConnection("promotions.yahoo.com", strict=1)
1074 c.set_debuglevel(1)
1075 c.connect()
1076 c.request("GET", "/promotions/mom_com97/supermom.html")
1077 try:
1078 r = c.getresponse()
1079 except BadStatusLine, err:
1080 print "strict mode failed as expected"
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001081 print err
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001082 else:
1083 print "XXX strict mode should have failed"
1084
1085 for strict in 0, 1:
1086 h = HTTP(strict=strict)
1087 h.connect("promotions.yahoo.com")
1088 h.putrequest('GET', "/promotions/mom_com97/supermom.html")
1089 h.endheaders()
1090 status, reason, headers = h.getreply()
1091 assert (strict and status == -1) or status == 200, (strict, status)
1092
Guido van Rossum23acc951994-02-21 16:36:04 +00001093if __name__ == '__main__':
Guido van Rossum41999c11997-12-09 00:12:23 +00001094 test()