Add simple unittests for ganeti.http
[ganeti-local] / lib / http / __init__.py
1 #
2 #
3
4 # Copyright (C) 2007, 2008 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21 """HTTP module.
22
23 """
24
25 import logging
26 import mimetools
27 import OpenSSL
28 import select
29 import socket
30 import errno
31
32 from cStringIO import StringIO
33
34 from ganeti import constants
35 from ganeti import serializer
36 from ganeti import utils
37
38
39 HTTP_GANETI_VERSION = "Ganeti %s" % constants.RELEASE_VERSION
40
41 HTTP_OK = 200
42 HTTP_NO_CONTENT = 204
43 HTTP_NOT_MODIFIED = 304
44
45 HTTP_0_9 = "HTTP/0.9"
46 HTTP_1_0 = "HTTP/1.0"
47 HTTP_1_1 = "HTTP/1.1"
48
49 HTTP_GET = "GET"
50 HTTP_HEAD = "HEAD"
51 HTTP_POST = "POST"
52 HTTP_PUT = "PUT"
53 HTTP_DELETE = "DELETE"
54
55 HTTP_ETAG = "ETag"
56 HTTP_HOST = "Host"
57 HTTP_SERVER = "Server"
58 HTTP_DATE = "Date"
59 HTTP_USER_AGENT = "User-Agent"
60 HTTP_CONTENT_TYPE = "Content-Type"
61 HTTP_CONTENT_LENGTH = "Content-Length"
62 HTTP_CONNECTION = "Connection"
63 HTTP_KEEP_ALIVE = "Keep-Alive"
64
65 _SSL_UNEXPECTED_EOF = "Unexpected EOF"
66
67 # Socket operations
68 (SOCKOP_SEND,
69  SOCKOP_RECV,
70  SOCKOP_SHUTDOWN,
71  SOCKOP_HANDSHAKE) = range(4)
72
73 # send/receive quantum
74 SOCK_BUF_SIZE = 32768
75
76
77 class HttpError(Exception):
78   """Internal exception for HTTP errors.
79
80   This should only be used for internal error reporting.
81
82   """
83
84
85 class HttpConnectionClosed(Exception):
86   """Internal exception for a closed connection.
87
88   This should only be used for internal error reporting. Only use
89   it if there's no other way to report this condition.
90
91   """
92
93
94 class HttpSessionHandshakeUnexpectedEOF(HttpError):
95   """Internal exception for errors during SSL handshake.
96
97   This should only be used for internal error reporting.
98
99   """
100
101
102 class HttpSocketTimeout(Exception):
103   """Internal exception for socket timeouts.
104
105   This should only be used for internal error reporting.
106
107   """
108
109
110 class HttpException(Exception):
111   code = None
112   message = None
113
114   def __init__(self, message=None):
115     Exception.__init__(self)
116     if message is not None:
117       self.message = message
118
119
120 class HttpBadRequest(HttpException):
121   code = 400
122
123
124 class HttpForbidden(HttpException):
125   code = 403
126
127
128 class HttpNotFound(HttpException):
129   code = 404
130
131
132 class HttpGone(HttpException):
133   code = 410
134
135
136 class HttpLengthRequired(HttpException):
137   code = 411
138
139
140 class HttpInternalError(HttpException):
141   code = 500
142
143
144 class HttpNotImplemented(HttpException):
145   code = 501
146
147
148 class HttpServiceUnavailable(HttpException):
149   code = 503
150
151
152 class HttpVersionNotSupported(HttpException):
153   code = 505
154
155
156 class HttpJsonConverter:
157   CONTENT_TYPE = "application/json"
158
159   def Encode(self, data):
160     return serializer.DumpJson(data)
161
162   def Decode(self, data):
163     return serializer.LoadJson(data)
164
165
166 def WaitForSocketCondition(poller, sock, event, timeout):
167   """Waits for a condition to occur on the socket.
168
169   @type poller: select.Poller
170   @param poller: Poller object as created by select.poll()
171   @type sock: socket
172   @param sock: Wait for events on this socket
173   @type event: int
174   @param event: ORed condition (see select module)
175   @type timeout: float or None
176   @param timeout: Timeout in seconds
177   @rtype: int or None
178   @return: None for timeout, otherwise occured conditions
179
180   """
181   check = (event | select.POLLPRI |
182            select.POLLNVAL | select.POLLHUP | select.POLLERR)
183
184   if timeout is not None:
185     # Poller object expects milliseconds
186     timeout *= 1000
187
188   poller.register(sock, event)
189   try:
190     while True:
191       # TODO: If the main thread receives a signal and we have no timeout, we
192       # could wait forever. This should check a global "quit" flag or
193       # something every so often.
194       io_events = poller.poll(timeout)
195       if not io_events:
196         # Timeout
197         return None
198       for (evfd, evcond) in io_events:
199         if evcond & check:
200           return evcond
201   finally:
202     poller.unregister(sock)
203
204
205 def SocketOperation(poller, sock, op, arg1, timeout):
206   """Wrapper around socket functions.
207
208   This function abstracts error handling for socket operations, especially
209   for the complicated interaction with OpenSSL.
210
211   @type poller: select.Poller
212   @param poller: Poller object as created by select.poll()
213   @type sock: socket
214   @param sock: Socket for the operation
215   @type op: int
216   @param op: Operation to execute (SOCKOP_* constants)
217   @type arg1: any
218   @param arg1: Parameter for function (if needed)
219   @type timeout: None or float
220   @param timeout: Timeout in seconds or None
221   @return: Return value of socket function
222
223   """
224   # TODO: event_poll/event_check/override
225   if op in (SOCKOP_SEND, SOCKOP_HANDSHAKE):
226     event_poll = select.POLLOUT
227     event_check = select.POLLOUT
228
229   elif op == SOCKOP_RECV:
230     event_poll = select.POLLIN
231     event_check = select.POLLIN | select.POLLPRI
232
233   elif op == SOCKOP_SHUTDOWN:
234     event_poll = None
235     event_check = None
236
237     # The timeout is only used when OpenSSL requests polling for a condition.
238     # It is not advisable to have no timeout for shutdown.
239     assert timeout
240
241   else:
242     raise AssertionError("Invalid socket operation")
243
244   # Handshake is only supported by SSL sockets
245   if (op == SOCKOP_HANDSHAKE and
246       not isinstance(sock, OpenSSL.SSL.ConnectionType)):
247     return
248
249   # No override by default
250   event_override = 0
251
252   while True:
253     # Poll only for certain operations and when asked for by an override
254     if event_override or op in (SOCKOP_SEND, SOCKOP_RECV, SOCKOP_HANDSHAKE):
255       if event_override:
256         wait_for_event = event_override
257       else:
258         wait_for_event = event_poll
259
260       event = WaitForSocketCondition(poller, sock, wait_for_event, timeout)
261       if event is None:
262         raise HttpSocketTimeout()
263
264       if (op == SOCKOP_RECV and
265           event & (select.POLLNVAL | select.POLLHUP | select.POLLERR)):
266         return ""
267
268       if not event & wait_for_event:
269         continue
270
271     # Reset override
272     event_override = 0
273
274     try:
275       try:
276         if op == SOCKOP_SEND:
277           return sock.send(arg1)
278
279         elif op == SOCKOP_RECV:
280           return sock.recv(arg1)
281
282         elif op == SOCKOP_SHUTDOWN:
283           if isinstance(sock, OpenSSL.SSL.ConnectionType):
284             # PyOpenSSL's shutdown() doesn't take arguments
285             return sock.shutdown()
286           else:
287             return sock.shutdown(arg1)
288
289         elif op == SOCKOP_HANDSHAKE:
290           return sock.do_handshake()
291
292       except OpenSSL.SSL.WantWriteError:
293         # OpenSSL wants to write, poll for POLLOUT
294         event_override = select.POLLOUT
295         continue
296
297       except OpenSSL.SSL.WantReadError:
298         # OpenSSL wants to read, poll for POLLIN
299         event_override = select.POLLIN | select.POLLPRI
300         continue
301
302       except OpenSSL.SSL.WantX509LookupError:
303         continue
304
305       except OpenSSL.SSL.ZeroReturnError, err:
306         # SSL Connection has been closed. In SSL 3.0 and TLS 1.0, this only
307         # occurs if a closure alert has occurred in the protocol, i.e. the
308         # connection has been closed cleanly. Note that this does not
309         # necessarily mean that the transport layer (e.g. a socket) has been
310         # closed.
311         if op == SOCKOP_SEND:
312           # Can happen during a renegotiation
313           raise HttpConnectionClosed(err.args)
314         elif op == SOCKOP_RECV:
315           return ""
316
317         # SSL_shutdown shouldn't return SSL_ERROR_ZERO_RETURN
318         raise socket.error(err.args)
319
320       except OpenSSL.SSL.SysCallError, err:
321         if op == SOCKOP_SEND:
322           # arg1 is the data when writing
323           if err.args and err.args[0] == -1 and arg1 == "":
324             # errors when writing empty strings are expected
325             # and can be ignored
326             return 0
327
328         if err.args == (-1, _SSL_UNEXPECTED_EOF):
329           if op == SOCKOP_RECV:
330             return ""
331           elif op == SOCKOP_HANDSHAKE:
332             # Can happen if peer disconnects directly after the connection is
333             # opened.
334             raise HttpSessionHandshakeUnexpectedEOF(err.args)
335
336         raise socket.error(err.args)
337
338       except OpenSSL.SSL.Error, err:
339         raise socket.error(err.args)
340
341     except socket.error, err:
342       if err.args and err.args[0] == errno.EAGAIN:
343         # Ignore EAGAIN
344         continue
345
346       raise
347
348
349 def ShutdownConnection(poller, sock, close_timeout, write_timeout, msgreader,
350                        force):
351   """Closes the connection.
352
353   @type poller: select.Poller
354   @param poller: Poller object as created by select.poll()
355   @type sock: socket
356   @param sock: Socket to be shut down
357   @type close_timeout: float
358   @param close_timeout: How long to wait for the peer to close the connection
359   @type write_timeout: float
360   @param write_timeout: Write timeout for shutdown
361   @type msgreader: http.HttpMessageReader
362   @param msgreader: Request message reader, used to determine whether peer
363                     should close connection
364   @type force: bool
365   @param force: Whether to forcibly close the connection without waiting
366                 for peer
367
368   """
369   poller = select.poll()
370
371   #print msgreader.peer_will_close, force
372   if msgreader and msgreader.peer_will_close and not force:
373     # Wait for peer to close
374     try:
375       # Check whether it's actually closed
376       if not SocketOperation(poller, sock, SOCKOP_RECV, 1, close_timeout):
377         return
378     except (socket.error, HttpError, HttpSocketTimeout):
379       # Ignore errors at this stage
380       pass
381
382   # Close the connection from our side
383   try:
384     # We don't care about the return value, see NOTES in SSL_shutdown(3).
385     SocketOperation(poller, sock, SOCKOP_SHUTDOWN, socket.SHUT_RDWR,
386                     write_timeout)
387   except HttpSocketTimeout:
388     raise HttpError("Timeout while shutting down connection")
389   except socket.error, err:
390     raise HttpError("Error while shutting down connection: %s" % err)
391
392
393 def Handshake(poller, sock, write_timeout):
394   """Shakes peer's hands.
395
396   @type poller: select.Poller
397   @param poller: Poller object as created by select.poll()
398   @type sock: socket
399   @param sock: Socket to be shut down
400   @type write_timeout: float
401   @param write_timeout: Write timeout for handshake
402
403   """
404   try:
405     return SocketOperation(poller, sock, SOCKOP_HANDSHAKE, None, write_timeout)
406   except HttpSocketTimeout:
407     raise HttpError("Timeout during SSL handshake")
408   except socket.error, err:
409     raise HttpError("Error in SSL handshake: %s" % err)
410
411
412 class HttpSslParams(object):
413   """Data class for SSL key and certificate.
414
415   """
416   def __init__(self, ssl_key_path, ssl_cert_path):
417     """Initializes this class.
418
419     @type ssl_key_path: string
420     @param ssl_key_path: Path to file containing SSL key in PEM format
421     @type ssl_cert_path: string
422     @param ssl_cert_path: Path to file containing SSL certificate in PEM format
423
424     """
425     self.ssl_key_pem = utils.ReadFile(ssl_key_path)
426     self.ssl_cert_pem = utils.ReadFile(ssl_cert_path)
427
428   def GetKey(self):
429     return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
430                                           self.ssl_key_pem)
431
432   def GetCertificate(self):
433     return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
434                                            self.ssl_cert_pem)
435
436
437 class HttpBase(object):
438   """Base class for HTTP server and client.
439
440   """
441   def __init__(self):
442     self.using_ssl = None
443     self._ssl_params = None
444     self._ssl_key = None
445     self._ssl_cert = None
446
447   def _CreateSocket(self, ssl_params, ssl_verify_peer):
448     """Creates a TCP socket and initializes SSL if needed.
449
450     @type ssl_params: HttpSslParams
451     @param ssl_params: SSL key and certificate
452     @type ssl_verify_peer: bool
453     @param ssl_verify_peer: Whether to require client certificate and compare
454                             it with our certificate
455
456     """
457     self._ssl_params = ssl_params
458
459     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
460
461     # Should we enable SSL?
462     self.using_ssl = ssl_params is not None
463
464     if not self.using_ssl:
465       return sock
466
467     self._ssl_key = ssl_params.GetKey()
468     self._ssl_cert = ssl_params.GetCertificate()
469
470     ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
471     ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2)
472
473     ctx.use_privatekey(self._ssl_key)
474     ctx.use_certificate(self._ssl_cert)
475     ctx.check_privatekey()
476
477     if ssl_verify_peer:
478       ctx.set_verify(OpenSSL.SSL.VERIFY_PEER |
479                      OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
480                      self._SSLVerifyCallback)
481
482     return OpenSSL.SSL.Connection(ctx, sock)
483
484   def _SSLVerifyCallback(self, conn, cert, errnum, errdepth, ok):
485     """Verify the certificate provided by the peer
486
487     We only compare fingerprints. The client must use the same certificate as
488     we do on our side.
489
490     """
491     assert self._ssl_params, "SSL not initialized"
492
493     return (self._ssl_cert.digest("sha1") == cert.digest("sha1") and
494             self._ssl_cert.digest("md5") == cert.digest("md5"))
495
496
497 class HttpMessage(object):
498   """Data structure for HTTP message.
499
500   """
501   def __init__(self):
502     self.start_line = None
503     self.headers = None
504     self.body = None
505     self.decoded_body = None
506
507
508 class HttpClientToServerStartLine(object):
509   """Data structure for HTTP request start line.
510
511   """
512   def __init__(self, method, path, version):
513     self.method = method
514     self.path = path
515     self.version = version
516
517   def __str__(self):
518     return "%s %s %s" % (self.method, self.path, self.version)
519
520
521 class HttpServerToClientStartLine(object):
522   """Data structure for HTTP response start line.
523
524   """
525   def __init__(self, version, code, reason):
526     self.version = version
527     self.code = code
528     self.reason = reason
529
530   def __str__(self):
531     return "%s %s %s" % (self.version, self.code, self.reason)
532
533
534 class HttpMessageWriter(object):
535   """Writes an HTTP message to a socket.
536
537   """
538   def __init__(self, sock, msg, write_timeout):
539     """Initializes this class and writes an HTTP message to a socket.
540
541     @type sock: socket
542     @param sock: Socket to be written to
543     @type msg: http.HttpMessage
544     @param msg: HTTP message to be written
545     @type write_timeout: float
546     @param write_timeout: Write timeout for socket
547
548     """
549     self._msg = msg
550
551     self._PrepareMessage()
552
553     buf = self._FormatMessage()
554
555     poller = select.poll()
556
557     pos = 0
558     end = len(buf)
559     while pos < end:
560       # Send only SOCK_BUF_SIZE bytes at a time
561       data = buf[pos:(pos + SOCK_BUF_SIZE)]
562
563       sent = SocketOperation(poller, sock, SOCKOP_SEND, data,
564                              write_timeout)
565
566       # Remove sent bytes
567       pos += sent
568
569     assert pos == end, "Message wasn't sent completely"
570
571   def _PrepareMessage(self):
572     """Prepares the HTTP message by setting mandatory headers.
573
574     """
575     # RFC2616, section 4.3: "The presence of a message-body in a request is
576     # signaled by the inclusion of a Content-Length or Transfer-Encoding header
577     # field in the request's message-headers."
578     if self._msg.body:
579       self._msg.headers[HTTP_CONTENT_LENGTH] = len(self._msg.body)
580
581   def _FormatMessage(self):
582     """Serializes the HTTP message into a string.
583
584     """
585     buf = StringIO()
586
587     # Add start line
588     buf.write(str(self._msg.start_line))
589     buf.write("\r\n")
590
591     # Add headers
592     if self._msg.start_line.version != HTTP_0_9:
593       for name, value in self._msg.headers.iteritems():
594         buf.write("%s: %s\r\n" % (name, value))
595
596     buf.write("\r\n")
597
598     # Add message body if needed
599     if self.HasMessageBody():
600       buf.write(self._msg.body)
601
602     elif self._msg.body:
603       logging.warning("Ignoring message body")
604
605     return buf.getvalue()
606
607   def HasMessageBody(self):
608     """Checks whether the HTTP message contains a body.
609
610     Can be overriden by subclasses.
611
612     """
613     return bool(self._msg.body)
614
615
616 class HttpMessageReader(object):
617   """Reads HTTP message from socket.
618
619   """
620   # Length limits
621   START_LINE_LENGTH_MAX = None
622   HEADER_LENGTH_MAX = None
623
624   # Parser state machine
625   PS_START_LINE = "start-line"
626   PS_HEADERS = "headers"
627   PS_BODY = "entity-body"
628   PS_COMPLETE = "complete"
629
630   def __init__(self, sock, msg, read_timeout):
631     """Reads an HTTP message from a socket.
632
633     @type sock: socket
634     @param sock: Socket to be read from
635     @type msg: http.HttpMessage
636     @param msg: Object for the read message
637     @type read_timeout: float
638     @param read_timeout: Read timeout for socket
639
640     """
641     self.sock = sock
642     self.msg = msg
643
644     self.poller = select.poll()
645     self.start_line_buffer = None
646     self.header_buffer = StringIO()
647     self.body_buffer = StringIO()
648     self.parser_status = self.PS_START_LINE
649     self.content_length = None
650     self.peer_will_close = None
651
652     buf = ""
653     eof = False
654     while self.parser_status != self.PS_COMPLETE:
655       # TODO: Don't read more than necessary (Content-Length), otherwise
656       # data might be lost and/or an error could occur
657       data = SocketOperation(self.poller, sock, SOCKOP_RECV, SOCK_BUF_SIZE,
658                              read_timeout)
659
660       if data:
661         buf += data
662       else:
663         eof = True
664
665       # Do some parsing and error checking while more data arrives
666       buf = self._ContinueParsing(buf, eof)
667
668       # Must be done only after the buffer has been evaluated
669       # TODO: Connection-length < len(data read) and connection closed
670       if (eof and
671           self.parser_status in (self.PS_START_LINE,
672                                  self.PS_HEADERS)):
673         raise HttpError("Connection closed prematurely")
674
675     # Parse rest
676     buf = self._ContinueParsing(buf, True)
677
678     assert self.parser_status == self.PS_COMPLETE
679     assert not buf, "Parser didn't read full response"
680
681     msg.body = self.body_buffer.getvalue()
682
683     # TODO: Content-type, error handling
684     if msg.body:
685       msg.decoded_body = HttpJsonConverter().Decode(msg.body)
686     else:
687       msg.decoded_body = None
688
689     if msg.decoded_body:
690       logging.debug("Message body: %s", msg.decoded_body)
691
692   def _ContinueParsing(self, buf, eof):
693     """Main function for HTTP message state machine.
694
695     @type buf: string
696     @param buf: Receive buffer
697     @type eof: bool
698     @param eof: Whether we've reached EOF on the socket
699     @rtype: string
700     @return: Updated receive buffer
701
702     """
703     # TODO: Use offset instead of slicing when possible
704     if self.parser_status == self.PS_START_LINE:
705       # Expect start line
706       while True:
707         idx = buf.find("\r\n")
708
709         # RFC2616, section 4.1: "In the interest of robustness, servers SHOULD
710         # ignore any empty line(s) received where a Request-Line is expected.
711         # In other words, if the server is reading the protocol stream at the
712         # beginning of a message and receives a CRLF first, it should ignore
713         # the CRLF."
714         if idx == 0:
715           # TODO: Limit number of CRLFs/empty lines for safety?
716           buf = buf[:2]
717           continue
718
719         if idx > 0:
720           self.start_line_buffer = buf[:idx]
721
722           self._CheckStartLineLength(len(self.start_line_buffer))
723
724           # Remove status line, including CRLF
725           buf = buf[idx + 2:]
726
727           self.msg.start_line = self.ParseStartLine(self.start_line_buffer)
728
729           self.parser_status = self.PS_HEADERS
730         else:
731           # Check whether incoming data is getting too large, otherwise we just
732           # fill our read buffer.
733           self._CheckStartLineLength(len(buf))
734
735         break
736
737     # TODO: Handle messages without headers
738     if self.parser_status == self.PS_HEADERS:
739       # Wait for header end
740       idx = buf.find("\r\n\r\n")
741       if idx >= 0:
742         self.header_buffer.write(buf[:idx + 2])
743
744         self._CheckHeaderLength(self.header_buffer.tell())
745
746         # Remove headers, including CRLF
747         buf = buf[idx + 4:]
748
749         self._ParseHeaders()
750
751         self.parser_status = self.PS_BODY
752       else:
753         # Check whether incoming data is getting too large, otherwise we just
754         # fill our read buffer.
755         self._CheckHeaderLength(len(buf))
756
757     if self.parser_status == self.PS_BODY:
758       # TODO: Implement max size for body_buffer
759       self.body_buffer.write(buf)
760       buf = ""
761
762       # Check whether we've read everything
763       #
764       # RFC2616, section 4.4: "When a message-body is included with a message,
765       # the transfer-length of that body is determined by one of the following
766       # [...] 5. By the server closing the connection. (Closing the connection
767       # cannot be used to indicate the end of a request body, since that would
768       # leave no possibility for the server to send back a response.)"
769       #
770       # TODO: Error when buffer length > Content-Length header
771       if (eof or
772           self.content_length is None or
773           (self.content_length is not None and
774            self.body_buffer.tell() >= self.content_length)):
775         self.parser_status = self.PS_COMPLETE
776
777     return buf
778
779   def _CheckStartLineLength(self, length):
780     """Limits the start line buffer size.
781
782     @type length: int
783     @param length: Buffer size
784
785     """
786     if (self.START_LINE_LENGTH_MAX is not None and
787         length > self.START_LINE_LENGTH_MAX):
788       raise HttpError("Start line longer than %d chars" %
789                        self.START_LINE_LENGTH_MAX)
790
791   def _CheckHeaderLength(self, length):
792     """Limits the header buffer size.
793
794     @type length: int
795     @param length: Buffer size
796
797     """
798     if (self.HEADER_LENGTH_MAX is not None and
799         length > self.HEADER_LENGTH_MAX):
800       raise HttpError("Headers longer than %d chars" % self.HEADER_LENGTH_MAX)
801
802   def ParseStartLine(self, start_line):
803     """Parses the start line of a message.
804
805     Must be overriden by subclass.
806
807     @type start_line: string
808     @param start_line: Start line string
809
810     """
811     raise NotImplementedError()
812
813   def _WillPeerCloseConnection(self):
814     """Evaluate whether peer will close the connection.
815
816     @rtype: bool
817     @return: Whether peer will close the connection
818
819     """
820     # RFC2616, section 14.10: "HTTP/1.1 defines the "close" connection option
821     # for the sender to signal that the connection will be closed after
822     # completion of the response. For example,
823     #
824     #        Connection: close
825     #
826     # in either the request or the response header fields indicates that the
827     # connection SHOULD NOT be considered `persistent' (section 8.1) after the
828     # current request/response is complete."
829
830     hdr_connection = self.msg.headers.get(HTTP_CONNECTION, None)
831     if hdr_connection:
832       hdr_connection = hdr_connection.lower()
833
834     # An HTTP/1.1 server is assumed to stay open unless explicitly closed.
835     if self.msg.start_line.version == HTTP_1_1:
836       return (hdr_connection and "close" in hdr_connection)
837
838     # Some HTTP/1.0 implementations have support for persistent connections,
839     # using rules different than HTTP/1.1.
840
841     # For older HTTP, Keep-Alive indicates persistent connection.
842     if self.msg.headers.get(HTTP_KEEP_ALIVE):
843       return False
844
845     # At least Akamai returns a "Connection: Keep-Alive" header, which was
846     # supposed to be sent by the client.
847     if hdr_connection and "keep-alive" in hdr_connection:
848       return False
849
850     return True
851
852   def _ParseHeaders(self):
853     """Parses the headers.
854
855     This function also adjusts internal variables based on header values.
856
857     RFC2616, section 4.3: "The presence of a message-body in a request is
858     signaled by the inclusion of a Content-Length or Transfer-Encoding header
859     field in the request's message-headers."
860
861     """
862     # Parse headers
863     self.header_buffer.seek(0, 0)
864     self.msg.headers = mimetools.Message(self.header_buffer, 0)
865
866     self.peer_will_close = self._WillPeerCloseConnection()
867
868     # Do we have a Content-Length header?
869     hdr_content_length = self.msg.headers.get(HTTP_CONTENT_LENGTH, None)
870     if hdr_content_length:
871       try:
872         self.content_length = int(hdr_content_length)
873       except ValueError:
874         self.content_length = None
875       if self.content_length is not None and self.content_length < 0:
876         self.content_length = None
877
878     # if the connection remains open and a content-length was not provided,
879     # then assume that the connection WILL close.
880     if self.content_length is None:
881       self.peer_will_close = True