Statistics
| Branch: | Tag: | Revision:

root / lib / http / __init__.py @ 5a9c3f46

History | View | Annotate | Download (21.8 kB)

1 a43f68dc Michael Hanselmann
#
2 a43f68dc Michael Hanselmann
#
3 4ce6007f Michael Hanselmann
4 4ce6007f Michael Hanselmann
# Copyright (C) 2007, 2008 Google Inc.
5 4ce6007f Michael Hanselmann
#
6 a43f68dc Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 a43f68dc Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 a43f68dc Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 a43f68dc Michael Hanselmann
# (at your option) any later version.
10 a43f68dc Michael Hanselmann
#
11 a43f68dc Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 a43f68dc Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a43f68dc Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a43f68dc Michael Hanselmann
# General Public License for more details.
15 a43f68dc Michael Hanselmann
#
16 a43f68dc Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 a43f68dc Michael Hanselmann
# along with this program; if not, write to the Free Software
18 a43f68dc Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a43f68dc Michael Hanselmann
# 02110-1301, USA.
20 a43f68dc Michael Hanselmann
21 02cab3e7 Michael Hanselmann
"""HTTP module.
22 a43f68dc Michael Hanselmann

23 a43f68dc Michael Hanselmann
"""
24 a43f68dc Michael Hanselmann
25 42242313 Michael Hanselmann
import logging
26 42242313 Michael Hanselmann
import mimetools
27 a43f68dc Michael Hanselmann
import OpenSSL
28 42242313 Michael Hanselmann
import select
29 42242313 Michael Hanselmann
import socket
30 8a0b06d2 Michael Hanselmann
import errno
31 8a0b06d2 Michael Hanselmann
32 8a0b06d2 Michael Hanselmann
from cStringIO import StringIO
33 a43f68dc Michael Hanselmann
34 42242313 Michael Hanselmann
from ganeti import constants
35 a43f68dc Michael Hanselmann
from ganeti import serializer
36 f2a6fc9e Michael Hanselmann
from ganeti import utils
37 a43f68dc Michael Hanselmann
38 a43f68dc Michael Hanselmann
39 8a9f9060 Michael Hanselmann
HTTP_GANETI_VERSION = "Ganeti %s" % constants.RELEASE_VERSION
40 8a9f9060 Michael Hanselmann
41 42242313 Michael Hanselmann
HTTP_OK = 200
42 42242313 Michael Hanselmann
HTTP_NO_CONTENT = 204
43 42242313 Michael Hanselmann
HTTP_NOT_MODIFIED = 304
44 42242313 Michael Hanselmann
45 42242313 Michael Hanselmann
HTTP_0_9 = "HTTP/0.9"
46 42242313 Michael Hanselmann
HTTP_1_0 = "HTTP/1.0"
47 42242313 Michael Hanselmann
HTTP_1_1 = "HTTP/1.1"
48 42242313 Michael Hanselmann
49 42242313 Michael Hanselmann
HTTP_GET = "GET"
50 42242313 Michael Hanselmann
HTTP_HEAD = "HEAD"
51 8a9f9060 Michael Hanselmann
HTTP_POST = "POST"
52 8a9f9060 Michael Hanselmann
HTTP_PUT = "PUT"
53 99b5ef90 Michael Hanselmann
HTTP_DELETE = "DELETE"
54 8a9f9060 Michael Hanselmann
55 713faea6 Oleksiy Mishchenko
HTTP_ETAG = "ETag"
56 8a9f9060 Michael Hanselmann
HTTP_HOST = "Host"
57 8a9f9060 Michael Hanselmann
HTTP_SERVER = "Server"
58 8a9f9060 Michael Hanselmann
HTTP_DATE = "Date"
59 8a9f9060 Michael Hanselmann
HTTP_USER_AGENT = "User-Agent"
60 8a9f9060 Michael Hanselmann
HTTP_CONTENT_TYPE = "Content-Type"
61 8a9f9060 Michael Hanselmann
HTTP_CONTENT_LENGTH = "Content-Length"
62 8a9f9060 Michael Hanselmann
HTTP_CONNECTION = "Connection"
63 8a9f9060 Michael Hanselmann
HTTP_KEEP_ALIVE = "Keep-Alive"
64 42242313 Michael Hanselmann
65 d7bace1b Michael Hanselmann
_SSL_UNEXPECTED_EOF = "Unexpected EOF"
66 d7bace1b Michael Hanselmann
67 73a59d9e Michael Hanselmann
# Socket operations
68 73a59d9e Michael Hanselmann
(SOCKOP_SEND,
69 73a59d9e Michael Hanselmann
 SOCKOP_RECV,
70 73a59d9e Michael Hanselmann
 SOCKOP_SHUTDOWN) = range(3)
71 73a59d9e Michael Hanselmann
72 b18dd019 Iustin Pop
# send/receive quantum
73 b18dd019 Iustin Pop
SOCK_BUF_SIZE = 32768
74 42242313 Michael Hanselmann
75 13b63666 Michael Hanselmann
76 02cab3e7 Michael Hanselmann
class HttpError(Exception):
77 02cab3e7 Michael Hanselmann
  """Internal exception for HTTP errors.
78 02cab3e7 Michael Hanselmann

79 02cab3e7 Michael Hanselmann
  This should only be used for internal error reporting.
80 02cab3e7 Michael Hanselmann

81 02cab3e7 Michael Hanselmann
  """
82 02cab3e7 Michael Hanselmann
83 02cab3e7 Michael Hanselmann
84 c9d0fa8a Michael Hanselmann
class HttpSocketTimeout(Exception):
85 73a59d9e Michael Hanselmann
  """Internal exception for socket timeouts.
86 73a59d9e Michael Hanselmann

87 73a59d9e Michael Hanselmann
  This should only be used for internal error reporting.
88 73a59d9e Michael Hanselmann

89 73a59d9e Michael Hanselmann
  """
90 8a0b06d2 Michael Hanselmann
91 8a0b06d2 Michael Hanselmann
92 84f2756e Michael Hanselmann
class HttpException(Exception):
93 a43f68dc Michael Hanselmann
  code = None
94 a43f68dc Michael Hanselmann
  message = None
95 a43f68dc Michael Hanselmann
96 a43f68dc Michael Hanselmann
  def __init__(self, message=None):
97 42242313 Michael Hanselmann
    Exception.__init__(self)
98 a43f68dc Michael Hanselmann
    if message is not None:
99 a43f68dc Michael Hanselmann
      self.message = message
100 a43f68dc Michael Hanselmann
101 a43f68dc Michael Hanselmann
102 84f2756e Michael Hanselmann
class HttpBadRequest(HttpException):
103 a43f68dc Michael Hanselmann
  code = 400
104 a43f68dc Michael Hanselmann
105 a43f68dc Michael Hanselmann
106 84f2756e Michael Hanselmann
class HttpForbidden(HttpException):
107 a43f68dc Michael Hanselmann
  code = 403
108 a43f68dc Michael Hanselmann
109 a43f68dc Michael Hanselmann
110 84f2756e Michael Hanselmann
class HttpNotFound(HttpException):
111 a43f68dc Michael Hanselmann
  code = 404
112 a43f68dc Michael Hanselmann
113 a43f68dc Michael Hanselmann
114 84f2756e Michael Hanselmann
class HttpGone(HttpException):
115 a43f68dc Michael Hanselmann
  code = 410
116 a43f68dc Michael Hanselmann
117 a43f68dc Michael Hanselmann
118 84f2756e Michael Hanselmann
class HttpLengthRequired(HttpException):
119 a43f68dc Michael Hanselmann
  code = 411
120 a43f68dc Michael Hanselmann
121 a43f68dc Michael Hanselmann
122 84f2756e Michael Hanselmann
class HttpInternalError(HttpException):
123 a43f68dc Michael Hanselmann
  code = 500
124 a43f68dc Michael Hanselmann
125 a43f68dc Michael Hanselmann
126 84f2756e Michael Hanselmann
class HttpNotImplemented(HttpException):
127 a43f68dc Michael Hanselmann
  code = 501
128 a43f68dc Michael Hanselmann
129 a43f68dc Michael Hanselmann
130 84f2756e Michael Hanselmann
class HttpServiceUnavailable(HttpException):
131 a43f68dc Michael Hanselmann
  code = 503
132 a43f68dc Michael Hanselmann
133 a43f68dc Michael Hanselmann
134 84f2756e Michael Hanselmann
class HttpVersionNotSupported(HttpException):
135 42242313 Michael Hanselmann
  code = 505
136 42242313 Michael Hanselmann
137 42242313 Michael Hanselmann
138 84f2756e Michael Hanselmann
class HttpJsonConverter:
139 a43f68dc Michael Hanselmann
  CONTENT_TYPE = "application/json"
140 a43f68dc Michael Hanselmann
141 a43f68dc Michael Hanselmann
  def Encode(self, data):
142 a43f68dc Michael Hanselmann
    return serializer.DumpJson(data)
143 a43f68dc Michael Hanselmann
144 a43f68dc Michael Hanselmann
  def Decode(self, data):
145 a43f68dc Michael Hanselmann
    return serializer.LoadJson(data)
146 a43f68dc Michael Hanselmann
147 a43f68dc Michael Hanselmann
148 73a59d9e Michael Hanselmann
def WaitForSocketCondition(poller, sock, event, timeout):
149 f22c1cea Michael Hanselmann
  """Waits for a condition to occur on the socket.
150 f22c1cea Michael Hanselmann

151 f22c1cea Michael Hanselmann
  @type poller: select.Poller
152 f22c1cea Michael Hanselmann
  @param poller: Poller object as created by select.poll()
153 73a59d9e Michael Hanselmann
  @type sock: socket
154 358a8811 Michael Hanselmann
  @param sock: Wait for events on this socket
155 f22c1cea Michael Hanselmann
  @type event: int
156 f22c1cea Michael Hanselmann
  @param event: ORed condition (see select module)
157 f22c1cea Michael Hanselmann
  @type timeout: float or None
158 f22c1cea Michael Hanselmann
  @param timeout: Timeout in seconds
159 f22c1cea Michael Hanselmann
  @rtype: int or None
160 f22c1cea Michael Hanselmann
  @return: None for timeout, otherwise occured conditions
161 f22c1cea Michael Hanselmann

162 f22c1cea Michael Hanselmann
  """
163 f22c1cea Michael Hanselmann
  check = (event | select.POLLPRI |
164 f22c1cea Michael Hanselmann
           select.POLLNVAL | select.POLLHUP | select.POLLERR)
165 f22c1cea Michael Hanselmann
166 f22c1cea Michael Hanselmann
  if timeout is not None:
167 f22c1cea Michael Hanselmann
    # Poller object expects milliseconds
168 f22c1cea Michael Hanselmann
    timeout *= 1000
169 f22c1cea Michael Hanselmann
170 f22c1cea Michael Hanselmann
  poller.register(sock, event)
171 f22c1cea Michael Hanselmann
  try:
172 f22c1cea Michael Hanselmann
    while True:
173 f22c1cea Michael Hanselmann
      # TODO: If the main thread receives a signal and we have no timeout, we
174 f22c1cea Michael Hanselmann
      # could wait forever. This should check a global "quit" flag or
175 f22c1cea Michael Hanselmann
      # something every so often.
176 f22c1cea Michael Hanselmann
      io_events = poller.poll(timeout)
177 f22c1cea Michael Hanselmann
      if not io_events:
178 f22c1cea Michael Hanselmann
        # Timeout
179 f22c1cea Michael Hanselmann
        return None
180 f22c1cea Michael Hanselmann
      for (evfd, evcond) in io_events:
181 f22c1cea Michael Hanselmann
        if evcond & check:
182 f22c1cea Michael Hanselmann
          return evcond
183 f22c1cea Michael Hanselmann
  finally:
184 f22c1cea Michael Hanselmann
    poller.unregister(sock)
185 f22c1cea Michael Hanselmann
186 f22c1cea Michael Hanselmann
187 73a59d9e Michael Hanselmann
def SocketOperation(poller, sock, op, arg1, timeout):
188 73a59d9e Michael Hanselmann
  """Wrapper around socket functions.
189 73a59d9e Michael Hanselmann

190 73a59d9e Michael Hanselmann
  This function abstracts error handling for socket operations, especially
191 73a59d9e Michael Hanselmann
  for the complicated interaction with OpenSSL.
192 73a59d9e Michael Hanselmann

193 73a59d9e Michael Hanselmann
  @type poller: select.Poller
194 73a59d9e Michael Hanselmann
  @param poller: Poller object as created by select.poll()
195 73a59d9e Michael Hanselmann
  @type sock: socket
196 358a8811 Michael Hanselmann
  @param sock: Socket for the operation
197 73a59d9e Michael Hanselmann
  @type op: int
198 73a59d9e Michael Hanselmann
  @param op: Operation to execute (SOCKOP_* constants)
199 73a59d9e Michael Hanselmann
  @type arg1: any
200 73a59d9e Michael Hanselmann
  @param arg1: Parameter for function (if needed)
201 73a59d9e Michael Hanselmann
  @type timeout: None or float
202 73a59d9e Michael Hanselmann
  @param timeout: Timeout in seconds or None
203 358a8811 Michael Hanselmann
  @return: Return value of socket function
204 73a59d9e Michael Hanselmann

205 73a59d9e Michael Hanselmann
  """
206 73a59d9e Michael Hanselmann
  # TODO: event_poll/event_check/override
207 73a59d9e Michael Hanselmann
  if op == SOCKOP_SEND:
208 73a59d9e Michael Hanselmann
    event_poll = select.POLLOUT
209 73a59d9e Michael Hanselmann
    event_check = select.POLLOUT
210 73a59d9e Michael Hanselmann
211 73a59d9e Michael Hanselmann
  elif op == SOCKOP_RECV:
212 73a59d9e Michael Hanselmann
    event_poll = select.POLLIN
213 73a59d9e Michael Hanselmann
    event_check = select.POLLIN | select.POLLPRI
214 73a59d9e Michael Hanselmann
215 73a59d9e Michael Hanselmann
  elif op == SOCKOP_SHUTDOWN:
216 73a59d9e Michael Hanselmann
    event_poll = None
217 73a59d9e Michael Hanselmann
    event_check = None
218 73a59d9e Michael Hanselmann
219 73a59d9e Michael Hanselmann
    # The timeout is only used when OpenSSL requests polling for a condition.
220 73a59d9e Michael Hanselmann
    # It is not advisable to have no timeout for shutdown.
221 73a59d9e Michael Hanselmann
    assert timeout
222 73a59d9e Michael Hanselmann
223 73a59d9e Michael Hanselmann
  else:
224 73a59d9e Michael Hanselmann
    raise AssertionError("Invalid socket operation")
225 73a59d9e Michael Hanselmann
226 73a59d9e Michael Hanselmann
  # No override by default
227 73a59d9e Michael Hanselmann
  event_override = 0
228 73a59d9e Michael Hanselmann
229 73a59d9e Michael Hanselmann
  while True:
230 73a59d9e Michael Hanselmann
    # Poll only for certain operations and when asked for by an override
231 73a59d9e Michael Hanselmann
    if event_override or op in (SOCKOP_SEND, SOCKOP_RECV):
232 73a59d9e Michael Hanselmann
      if event_override:
233 73a59d9e Michael Hanselmann
        wait_for_event = event_override
234 73a59d9e Michael Hanselmann
      else:
235 73a59d9e Michael Hanselmann
        wait_for_event = event_poll
236 73a59d9e Michael Hanselmann
237 73a59d9e Michael Hanselmann
      event = WaitForSocketCondition(poller, sock, wait_for_event, timeout)
238 73a59d9e Michael Hanselmann
      if event is None:
239 c9d0fa8a Michael Hanselmann
        raise HttpSocketTimeout()
240 73a59d9e Michael Hanselmann
241 73a59d9e Michael Hanselmann
      if (op == SOCKOP_RECV and
242 73a59d9e Michael Hanselmann
          event & (select.POLLNVAL | select.POLLHUP | select.POLLERR)):
243 73a59d9e Michael Hanselmann
        return ""
244 73a59d9e Michael Hanselmann
245 73a59d9e Michael Hanselmann
      if not event & wait_for_event:
246 73a59d9e Michael Hanselmann
        continue
247 73a59d9e Michael Hanselmann
248 73a59d9e Michael Hanselmann
    # Reset override
249 73a59d9e Michael Hanselmann
    event_override = 0
250 73a59d9e Michael Hanselmann
251 73a59d9e Michael Hanselmann
    try:
252 73a59d9e Michael Hanselmann
      try:
253 73a59d9e Michael Hanselmann
        if op == SOCKOP_SEND:
254 73a59d9e Michael Hanselmann
          return sock.send(arg1)
255 73a59d9e Michael Hanselmann
256 73a59d9e Michael Hanselmann
        elif op == SOCKOP_RECV:
257 73a59d9e Michael Hanselmann
          return sock.recv(arg1)
258 73a59d9e Michael Hanselmann
259 73a59d9e Michael Hanselmann
        elif op == SOCKOP_SHUTDOWN:
260 73a59d9e Michael Hanselmann
          if isinstance(sock, OpenSSL.SSL.ConnectionType):
261 73a59d9e Michael Hanselmann
            # PyOpenSSL's shutdown() doesn't take arguments
262 73a59d9e Michael Hanselmann
            return sock.shutdown()
263 73a59d9e Michael Hanselmann
          else:
264 73a59d9e Michael Hanselmann
            return sock.shutdown(arg1)
265 73a59d9e Michael Hanselmann
266 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantWriteError:
267 73a59d9e Michael Hanselmann
        # OpenSSL wants to write, poll for POLLOUT
268 73a59d9e Michael Hanselmann
        event_override = select.POLLOUT
269 73a59d9e Michael Hanselmann
        continue
270 73a59d9e Michael Hanselmann
271 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantReadError:
272 73a59d9e Michael Hanselmann
        # OpenSSL wants to read, poll for POLLIN
273 73a59d9e Michael Hanselmann
        event_override = select.POLLIN | select.POLLPRI
274 73a59d9e Michael Hanselmann
        continue
275 73a59d9e Michael Hanselmann
276 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantX509LookupError:
277 73a59d9e Michael Hanselmann
        continue
278 73a59d9e Michael Hanselmann
279 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.SysCallError, err:
280 73a59d9e Michael Hanselmann
        if op == SOCKOP_SEND:
281 73a59d9e Michael Hanselmann
          # arg1 is the data when writing
282 73a59d9e Michael Hanselmann
          if err.args and err.args[0] == -1 and arg1 == "":
283 73a59d9e Michael Hanselmann
            # errors when writing empty strings are expected
284 73a59d9e Michael Hanselmann
            # and can be ignored
285 73a59d9e Michael Hanselmann
            return 0
286 73a59d9e Michael Hanselmann
287 73a59d9e Michael Hanselmann
        elif op == SOCKOP_RECV:
288 73a59d9e Michael Hanselmann
          if err.args == (-1, _SSL_UNEXPECTED_EOF):
289 73a59d9e Michael Hanselmann
            return ""
290 73a59d9e Michael Hanselmann
291 73a59d9e Michael Hanselmann
        raise socket.error(err.args)
292 73a59d9e Michael Hanselmann
293 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.Error, err:
294 73a59d9e Michael Hanselmann
        raise socket.error(err.args)
295 73a59d9e Michael Hanselmann
296 73a59d9e Michael Hanselmann
    except socket.error, err:
297 73a59d9e Michael Hanselmann
      if err.args and err.args[0] == errno.EAGAIN:
298 73a59d9e Michael Hanselmann
        # Ignore EAGAIN
299 73a59d9e Michael Hanselmann
        continue
300 73a59d9e Michael Hanselmann
301 73a59d9e Michael Hanselmann
      raise
302 73a59d9e Michael Hanselmann
303 73a59d9e Michael Hanselmann
304 02cab3e7 Michael Hanselmann
def ShutdownConnection(poller, sock, close_timeout, write_timeout, msgreader,
305 02cab3e7 Michael Hanselmann
                       force):
306 02cab3e7 Michael Hanselmann
  """Closes the connection.
307 02cab3e7 Michael Hanselmann

308 358a8811 Michael Hanselmann
  @type poller: select.Poller
309 358a8811 Michael Hanselmann
  @param poller: Poller object as created by select.poll()
310 358a8811 Michael Hanselmann
  @type sock: socket
311 358a8811 Michael Hanselmann
  @param sock: Socket to be shut down
312 358a8811 Michael Hanselmann
  @type close_timeout: float
313 358a8811 Michael Hanselmann
  @param close_timeout: How long to wait for the peer to close the connection
314 358a8811 Michael Hanselmann
  @type write_timeout: float
315 358a8811 Michael Hanselmann
  @param write_timeout: Write timeout for shutdown
316 358a8811 Michael Hanselmann
  @type msgreader: http.HttpMessageReader
317 358a8811 Michael Hanselmann
  @param msgreader: Request message reader, used to determine whether peer
318 358a8811 Michael Hanselmann
                    should close connection
319 358a8811 Michael Hanselmann
  @type force: bool
320 358a8811 Michael Hanselmann
  @param force: Whether to forcibly close the connection without waiting
321 358a8811 Michael Hanselmann
                for peer
322 358a8811 Michael Hanselmann

323 02cab3e7 Michael Hanselmann
  """
324 02cab3e7 Michael Hanselmann
  poller = select.poll()
325 02cab3e7 Michael Hanselmann
326 02cab3e7 Michael Hanselmann
  #print msgreader.peer_will_close, force
327 02cab3e7 Michael Hanselmann
  if msgreader and msgreader.peer_will_close and not force:
328 02cab3e7 Michael Hanselmann
    # Wait for peer to close
329 02cab3e7 Michael Hanselmann
    try:
330 02cab3e7 Michael Hanselmann
      # Check whether it's actually closed
331 02cab3e7 Michael Hanselmann
      if not SocketOperation(poller, sock, SOCKOP_RECV, 1, close_timeout):
332 02cab3e7 Michael Hanselmann
        return
333 02cab3e7 Michael Hanselmann
    except (socket.error, HttpError, HttpSocketTimeout):
334 02cab3e7 Michael Hanselmann
      # Ignore errors at this stage
335 02cab3e7 Michael Hanselmann
      pass
336 02cab3e7 Michael Hanselmann
337 02cab3e7 Michael Hanselmann
  # Close the connection from our side
338 02cab3e7 Michael Hanselmann
  try:
339 02cab3e7 Michael Hanselmann
    SocketOperation(poller, sock, SOCKOP_SHUTDOWN, socket.SHUT_RDWR,
340 02cab3e7 Michael Hanselmann
                    write_timeout)
341 02cab3e7 Michael Hanselmann
  except HttpSocketTimeout:
342 02cab3e7 Michael Hanselmann
    raise HttpError("Timeout while shutting down connection")
343 02cab3e7 Michael Hanselmann
  except socket.error, err:
344 02cab3e7 Michael Hanselmann
    raise HttpError("Error while shutting down connection: %s" % err)
345 02cab3e7 Michael Hanselmann
346 02cab3e7 Michael Hanselmann
347 f20cbea2 Michael Hanselmann
class HttpSslParams(object):
348 f20cbea2 Michael Hanselmann
  """Data class for SSL key and certificate.
349 f20cbea2 Michael Hanselmann

350 f20cbea2 Michael Hanselmann
  """
351 f20cbea2 Michael Hanselmann
  def __init__(self, ssl_key_path, ssl_cert_path):
352 f20cbea2 Michael Hanselmann
    """Initializes this class.
353 f20cbea2 Michael Hanselmann

354 f20cbea2 Michael Hanselmann
    @type ssl_key_path: string
355 f20cbea2 Michael Hanselmann
    @param ssl_key_path: Path to file containing SSL key in PEM format
356 f20cbea2 Michael Hanselmann
    @type ssl_cert_path: string
357 f20cbea2 Michael Hanselmann
    @param ssl_cert_path: Path to file containing SSL certificate in PEM format
358 f20cbea2 Michael Hanselmann

359 f20cbea2 Michael Hanselmann
    """
360 65c6b8e0 Michael Hanselmann
    self.ssl_key_pem = utils.ReadFile(ssl_key_path)
361 65c6b8e0 Michael Hanselmann
    self.ssl_cert_pem = utils.ReadFile(ssl_cert_path)
362 f20cbea2 Michael Hanselmann
363 65c6b8e0 Michael Hanselmann
  def GetKey(self):
364 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
365 65c6b8e0 Michael Hanselmann
                                          self.ssl_key_pem)
366 65c6b8e0 Michael Hanselmann
367 65c6b8e0 Michael Hanselmann
  def GetCertificate(self):
368 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
369 65c6b8e0 Michael Hanselmann
                                           self.ssl_cert_pem)
370 f20cbea2 Michael Hanselmann
371 f20cbea2 Michael Hanselmann
372 f4322a1e Michael Hanselmann
class HttpBase(object):
373 b14f759e Michael Hanselmann
  """Base class for HTTP server and client.
374 b14f759e Michael Hanselmann

375 b14f759e Michael Hanselmann
  """
376 b14f759e Michael Hanselmann
  def __init__(self):
377 22692e48 Michael Hanselmann
    self.using_ssl = None
378 f20cbea2 Michael Hanselmann
    self._ssl_params = None
379 65c6b8e0 Michael Hanselmann
    self._ssl_key = None
380 65c6b8e0 Michael Hanselmann
    self._ssl_cert = None
381 b14f759e Michael Hanselmann
382 f20cbea2 Michael Hanselmann
  def _CreateSocket(self, ssl_params, ssl_verify_peer):
383 b14f759e Michael Hanselmann
    """Creates a TCP socket and initializes SSL if needed.
384 b14f759e Michael Hanselmann

385 f20cbea2 Michael Hanselmann
    @type ssl_params: HttpSslParams
386 f20cbea2 Michael Hanselmann
    @param ssl_params: SSL key and certificate
387 b14f759e Michael Hanselmann
    @type ssl_verify_peer: bool
388 b14f759e Michael Hanselmann
    @param ssl_verify_peer: Whether to require client certificate and compare
389 b14f759e Michael Hanselmann
                            it with our certificate
390 b14f759e Michael Hanselmann

391 b14f759e Michael Hanselmann
    """
392 f20cbea2 Michael Hanselmann
    self._ssl_params = ssl_params
393 f20cbea2 Michael Hanselmann
394 b14f759e Michael Hanselmann
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
395 b14f759e Michael Hanselmann
396 b14f759e Michael Hanselmann
    # Should we enable SSL?
397 22692e48 Michael Hanselmann
    self.using_ssl = ssl_params is not None
398 b14f759e Michael Hanselmann
399 22692e48 Michael Hanselmann
    if not self.using_ssl:
400 b14f759e Michael Hanselmann
      return sock
401 b14f759e Michael Hanselmann
402 65c6b8e0 Michael Hanselmann
    self._ssl_key = ssl_params.GetKey()
403 65c6b8e0 Michael Hanselmann
    self._ssl_cert = ssl_params.GetCertificate()
404 65c6b8e0 Michael Hanselmann
405 b14f759e Michael Hanselmann
    ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
406 b14f759e Michael Hanselmann
    ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2)
407 b14f759e Michael Hanselmann
408 65c6b8e0 Michael Hanselmann
    ctx.use_privatekey(self._ssl_key)
409 65c6b8e0 Michael Hanselmann
    ctx.use_certificate(self._ssl_cert)
410 b14f759e Michael Hanselmann
    ctx.check_privatekey()
411 b14f759e Michael Hanselmann
412 b14f759e Michael Hanselmann
    if ssl_verify_peer:
413 b14f759e Michael Hanselmann
      ctx.set_verify(OpenSSL.SSL.VERIFY_PEER |
414 b14f759e Michael Hanselmann
                     OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
415 b14f759e Michael Hanselmann
                     self._SSLVerifyCallback)
416 b14f759e Michael Hanselmann
417 b14f759e Michael Hanselmann
    return OpenSSL.SSL.Connection(ctx, sock)
418 b14f759e Michael Hanselmann
419 b14f759e Michael Hanselmann
  def _SSLVerifyCallback(self, conn, cert, errnum, errdepth, ok):
420 b14f759e Michael Hanselmann
    """Verify the certificate provided by the peer
421 b14f759e Michael Hanselmann

422 b14f759e Michael Hanselmann
    We only compare fingerprints. The client must use the same certificate as
423 b14f759e Michael Hanselmann
    we do on our side.
424 b14f759e Michael Hanselmann

425 b14f759e Michael Hanselmann
    """
426 f20cbea2 Michael Hanselmann
    assert self._ssl_params, "SSL not initialized"
427 b14f759e Michael Hanselmann
428 65c6b8e0 Michael Hanselmann
    return (self._ssl_cert.digest("sha1") == cert.digest("sha1") and
429 65c6b8e0 Michael Hanselmann
            self._ssl_cert.digest("md5") == cert.digest("md5"))
430 b14f759e Michael Hanselmann
431 b14f759e Michael Hanselmann
432 02cab3e7 Michael Hanselmann
class HttpMessage(object):
433 02cab3e7 Michael Hanselmann
  """Data structure for HTTP message.
434 02cab3e7 Michael Hanselmann

435 02cab3e7 Michael Hanselmann
  """
436 02cab3e7 Michael Hanselmann
  def __init__(self):
437 02cab3e7 Michael Hanselmann
    self.start_line = None
438 02cab3e7 Michael Hanselmann
    self.headers = None
439 02cab3e7 Michael Hanselmann
    self.body = None
440 02cab3e7 Michael Hanselmann
    self.decoded_body = None
441 02cab3e7 Michael Hanselmann
442 02cab3e7 Michael Hanselmann
443 02cab3e7 Michael Hanselmann
class HttpClientToServerStartLine(object):
444 02cab3e7 Michael Hanselmann
  """Data structure for HTTP request start line.
445 02cab3e7 Michael Hanselmann

446 02cab3e7 Michael Hanselmann
  """
447 02cab3e7 Michael Hanselmann
  def __init__(self, method, path, version):
448 02cab3e7 Michael Hanselmann
    self.method = method
449 02cab3e7 Michael Hanselmann
    self.path = path
450 02cab3e7 Michael Hanselmann
    self.version = version
451 02cab3e7 Michael Hanselmann
452 02cab3e7 Michael Hanselmann
  def __str__(self):
453 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.method, self.path, self.version)
454 02cab3e7 Michael Hanselmann
455 02cab3e7 Michael Hanselmann
456 02cab3e7 Michael Hanselmann
class HttpServerToClientStartLine(object):
457 02cab3e7 Michael Hanselmann
  """Data structure for HTTP response start line.
458 02cab3e7 Michael Hanselmann

459 02cab3e7 Michael Hanselmann
  """
460 02cab3e7 Michael Hanselmann
  def __init__(self, version, code, reason):
461 02cab3e7 Michael Hanselmann
    self.version = version
462 02cab3e7 Michael Hanselmann
    self.code = code
463 02cab3e7 Michael Hanselmann
    self.reason = reason
464 02cab3e7 Michael Hanselmann
465 02cab3e7 Michael Hanselmann
  def __str__(self):
466 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.version, self.code, self.reason)
467 02cab3e7 Michael Hanselmann
468 02cab3e7 Michael Hanselmann
469 02cab3e7 Michael Hanselmann
class HttpMessageWriter(object):
470 02cab3e7 Michael Hanselmann
  """Writes an HTTP message to a socket.
471 02cab3e7 Michael Hanselmann

472 02cab3e7 Michael Hanselmann
  """
473 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, write_timeout):
474 358a8811 Michael Hanselmann
    """Initializes this class and writes an HTTP message to a socket.
475 358a8811 Michael Hanselmann

476 358a8811 Michael Hanselmann
    @type sock: socket
477 358a8811 Michael Hanselmann
    @param sock: Socket to be written to
478 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
479 358a8811 Michael Hanselmann
    @param msg: HTTP message to be written
480 358a8811 Michael Hanselmann
    @type write_timeout: float
481 358a8811 Michael Hanselmann
    @param write_timeout: Write timeout for socket
482 358a8811 Michael Hanselmann

483 358a8811 Michael Hanselmann
    """
484 02cab3e7 Michael Hanselmann
    self._msg = msg
485 02cab3e7 Michael Hanselmann
486 02cab3e7 Michael Hanselmann
    self._PrepareMessage()
487 02cab3e7 Michael Hanselmann
488 02cab3e7 Michael Hanselmann
    buf = self._FormatMessage()
489 02cab3e7 Michael Hanselmann
490 02cab3e7 Michael Hanselmann
    poller = select.poll()
491 b18dd019 Iustin Pop
492 b18dd019 Iustin Pop
    pos = 0
493 b18dd019 Iustin Pop
    end = len(buf)
494 b18dd019 Iustin Pop
    while pos < end:
495 b18dd019 Iustin Pop
      # Send only SOCK_BUF_SIZE bytes at a time
496 358a8811 Michael Hanselmann
      data = buf[pos:(pos + SOCK_BUF_SIZE)]
497 02cab3e7 Michael Hanselmann
498 02cab3e7 Michael Hanselmann
      sent = SocketOperation(poller, sock, SOCKOP_SEND, data,
499 02cab3e7 Michael Hanselmann
                             write_timeout)
500 02cab3e7 Michael Hanselmann
501 02cab3e7 Michael Hanselmann
      # Remove sent bytes
502 b18dd019 Iustin Pop
      pos += sent
503 02cab3e7 Michael Hanselmann
504 b18dd019 Iustin Pop
    assert pos == end, "Message wasn't sent completely"
505 02cab3e7 Michael Hanselmann
506 02cab3e7 Michael Hanselmann
  def _PrepareMessage(self):
507 02cab3e7 Michael Hanselmann
    """Prepares the HTTP message by setting mandatory headers.
508 02cab3e7 Michael Hanselmann

509 02cab3e7 Michael Hanselmann
    """
510 02cab3e7 Michael Hanselmann
    # RFC2616, section 4.3: "The presence of a message-body in a request is
511 02cab3e7 Michael Hanselmann
    # signaled by the inclusion of a Content-Length or Transfer-Encoding header
512 02cab3e7 Michael Hanselmann
    # field in the request's message-headers."
513 02cab3e7 Michael Hanselmann
    if self._msg.body:
514 02cab3e7 Michael Hanselmann
      self._msg.headers[HTTP_CONTENT_LENGTH] = len(self._msg.body)
515 02cab3e7 Michael Hanselmann
516 02cab3e7 Michael Hanselmann
  def _FormatMessage(self):
517 02cab3e7 Michael Hanselmann
    """Serializes the HTTP message into a string.
518 02cab3e7 Michael Hanselmann

519 02cab3e7 Michael Hanselmann
    """
520 02cab3e7 Michael Hanselmann
    buf = StringIO()
521 02cab3e7 Michael Hanselmann
522 02cab3e7 Michael Hanselmann
    # Add start line
523 02cab3e7 Michael Hanselmann
    buf.write(str(self._msg.start_line))
524 02cab3e7 Michael Hanselmann
    buf.write("\r\n")
525 02cab3e7 Michael Hanselmann
526 02cab3e7 Michael Hanselmann
    # Add headers
527 02cab3e7 Michael Hanselmann
    if self._msg.start_line.version != HTTP_0_9:
528 02cab3e7 Michael Hanselmann
      for name, value in self._msg.headers.iteritems():
529 02cab3e7 Michael Hanselmann
        buf.write("%s: %s\r\n" % (name, value))
530 02cab3e7 Michael Hanselmann
531 02cab3e7 Michael Hanselmann
    buf.write("\r\n")
532 02cab3e7 Michael Hanselmann
533 02cab3e7 Michael Hanselmann
    # Add message body if needed
534 02cab3e7 Michael Hanselmann
    if self.HasMessageBody():
535 02cab3e7 Michael Hanselmann
      buf.write(self._msg.body)
536 02cab3e7 Michael Hanselmann
537 02cab3e7 Michael Hanselmann
    elif self._msg.body:
538 02cab3e7 Michael Hanselmann
      logging.warning("Ignoring message body")
539 02cab3e7 Michael Hanselmann
540 02cab3e7 Michael Hanselmann
    return buf.getvalue()
541 02cab3e7 Michael Hanselmann
542 02cab3e7 Michael Hanselmann
  def HasMessageBody(self):
543 02cab3e7 Michael Hanselmann
    """Checks whether the HTTP message contains a body.
544 02cab3e7 Michael Hanselmann

545 02cab3e7 Michael Hanselmann
    Can be overriden by subclasses.
546 02cab3e7 Michael Hanselmann

547 02cab3e7 Michael Hanselmann
    """
548 02cab3e7 Michael Hanselmann
    return bool(self._msg.body)
549 02cab3e7 Michael Hanselmann
550 02cab3e7 Michael Hanselmann
551 02cab3e7 Michael Hanselmann
class HttpMessageReader(object):
552 02cab3e7 Michael Hanselmann
  """Reads HTTP message from socket.
553 02cab3e7 Michael Hanselmann

554 02cab3e7 Michael Hanselmann
  """
555 02cab3e7 Michael Hanselmann
  # Length limits
556 02cab3e7 Michael Hanselmann
  START_LINE_LENGTH_MAX = None
557 02cab3e7 Michael Hanselmann
  HEADER_LENGTH_MAX = None
558 02cab3e7 Michael Hanselmann
559 02cab3e7 Michael Hanselmann
  # Parser state machine
560 02cab3e7 Michael Hanselmann
  PS_START_LINE = "start-line"
561 02cab3e7 Michael Hanselmann
  PS_HEADERS = "headers"
562 02cab3e7 Michael Hanselmann
  PS_BODY = "entity-body"
563 02cab3e7 Michael Hanselmann
  PS_COMPLETE = "complete"
564 02cab3e7 Michael Hanselmann
565 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, read_timeout):
566 358a8811 Michael Hanselmann
    """Reads an HTTP message from a socket.
567 358a8811 Michael Hanselmann

568 358a8811 Michael Hanselmann
    @type sock: socket
569 358a8811 Michael Hanselmann
    @param sock: Socket to be read from
570 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
571 358a8811 Michael Hanselmann
    @param msg: Object for the read message
572 358a8811 Michael Hanselmann
    @type read_timeout: float
573 358a8811 Michael Hanselmann
    @param read_timeout: Read timeout for socket
574 358a8811 Michael Hanselmann

575 358a8811 Michael Hanselmann
    """
576 02cab3e7 Michael Hanselmann
    self.sock = sock
577 02cab3e7 Michael Hanselmann
    self.msg = msg
578 02cab3e7 Michael Hanselmann
579 02cab3e7 Michael Hanselmann
    self.poller = select.poll()
580 02cab3e7 Michael Hanselmann
    self.start_line_buffer = None
581 02cab3e7 Michael Hanselmann
    self.header_buffer = StringIO()
582 02cab3e7 Michael Hanselmann
    self.body_buffer = StringIO()
583 02cab3e7 Michael Hanselmann
    self.parser_status = self.PS_START_LINE
584 02cab3e7 Michael Hanselmann
    self.content_length = None
585 02cab3e7 Michael Hanselmann
    self.peer_will_close = None
586 02cab3e7 Michael Hanselmann
587 02cab3e7 Michael Hanselmann
    buf = ""
588 02cab3e7 Michael Hanselmann
    eof = False
589 02cab3e7 Michael Hanselmann
    while self.parser_status != self.PS_COMPLETE:
590 b18dd019 Iustin Pop
      data = SocketOperation(self.poller, sock, SOCKOP_RECV, SOCK_BUF_SIZE,
591 02cab3e7 Michael Hanselmann
                             read_timeout)
592 02cab3e7 Michael Hanselmann
593 02cab3e7 Michael Hanselmann
      if data:
594 02cab3e7 Michael Hanselmann
        buf += data
595 02cab3e7 Michael Hanselmann
      else:
596 02cab3e7 Michael Hanselmann
        eof = True
597 02cab3e7 Michael Hanselmann
598 02cab3e7 Michael Hanselmann
      # Do some parsing and error checking while more data arrives
599 02cab3e7 Michael Hanselmann
      buf = self._ContinueParsing(buf, eof)
600 02cab3e7 Michael Hanselmann
601 02cab3e7 Michael Hanselmann
      # Must be done only after the buffer has been evaluated
602 02cab3e7 Michael Hanselmann
      # TODO: Connection-length < len(data read) and connection closed
603 02cab3e7 Michael Hanselmann
      if (eof and
604 02cab3e7 Michael Hanselmann
          self.parser_status in (self.PS_START_LINE,
605 02cab3e7 Michael Hanselmann
                                 self.PS_HEADERS)):
606 02cab3e7 Michael Hanselmann
        raise HttpError("Connection closed prematurely")
607 02cab3e7 Michael Hanselmann
608 02cab3e7 Michael Hanselmann
    # Parse rest
609 02cab3e7 Michael Hanselmann
    buf = self._ContinueParsing(buf, True)
610 02cab3e7 Michael Hanselmann
611 02cab3e7 Michael Hanselmann
    assert self.parser_status == self.PS_COMPLETE
612 02cab3e7 Michael Hanselmann
    assert not buf, "Parser didn't read full response"
613 02cab3e7 Michael Hanselmann
614 02cab3e7 Michael Hanselmann
    msg.body = self.body_buffer.getvalue()
615 02cab3e7 Michael Hanselmann
616 02cab3e7 Michael Hanselmann
    # TODO: Content-type, error handling
617 02cab3e7 Michael Hanselmann
    if msg.body:
618 02cab3e7 Michael Hanselmann
      msg.decoded_body = HttpJsonConverter().Decode(msg.body)
619 02cab3e7 Michael Hanselmann
    else:
620 02cab3e7 Michael Hanselmann
      msg.decoded_body = None
621 02cab3e7 Michael Hanselmann
622 02cab3e7 Michael Hanselmann
    if msg.decoded_body:
623 02cab3e7 Michael Hanselmann
      logging.debug("Message body: %s", msg.decoded_body)
624 02cab3e7 Michael Hanselmann
625 02cab3e7 Michael Hanselmann
  def _ContinueParsing(self, buf, eof):
626 02cab3e7 Michael Hanselmann
    """Main function for HTTP message state machine.
627 02cab3e7 Michael Hanselmann

628 02cab3e7 Michael Hanselmann
    @type buf: string
629 02cab3e7 Michael Hanselmann
    @param buf: Receive buffer
630 02cab3e7 Michael Hanselmann
    @type eof: bool
631 02cab3e7 Michael Hanselmann
    @param eof: Whether we've reached EOF on the socket
632 02cab3e7 Michael Hanselmann
    @rtype: string
633 02cab3e7 Michael Hanselmann
    @return: Updated receive buffer
634 02cab3e7 Michael Hanselmann

635 02cab3e7 Michael Hanselmann
    """
636 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_START_LINE:
637 02cab3e7 Michael Hanselmann
      # Expect start line
638 02cab3e7 Michael Hanselmann
      while True:
639 02cab3e7 Michael Hanselmann
        idx = buf.find("\r\n")
640 02cab3e7 Michael Hanselmann
641 02cab3e7 Michael Hanselmann
        # RFC2616, section 4.1: "In the interest of robustness, servers SHOULD
642 02cab3e7 Michael Hanselmann
        # ignore any empty line(s) received where a Request-Line is expected.
643 02cab3e7 Michael Hanselmann
        # In other words, if the server is reading the protocol stream at the
644 02cab3e7 Michael Hanselmann
        # beginning of a message and receives a CRLF first, it should ignore
645 02cab3e7 Michael Hanselmann
        # the CRLF."
646 02cab3e7 Michael Hanselmann
        if idx == 0:
647 358a8811 Michael Hanselmann
          # TODO: Limit number of CRLFs/empty lines for safety?
648 02cab3e7 Michael Hanselmann
          buf = buf[:2]
649 02cab3e7 Michael Hanselmann
          continue
650 02cab3e7 Michael Hanselmann
651 02cab3e7 Michael Hanselmann
        if idx > 0:
652 02cab3e7 Michael Hanselmann
          self.start_line_buffer = buf[:idx]
653 02cab3e7 Michael Hanselmann
654 02cab3e7 Michael Hanselmann
          self._CheckStartLineLength(len(self.start_line_buffer))
655 02cab3e7 Michael Hanselmann
656 02cab3e7 Michael Hanselmann
          # Remove status line, including CRLF
657 02cab3e7 Michael Hanselmann
          buf = buf[idx + 2:]
658 02cab3e7 Michael Hanselmann
659 02cab3e7 Michael Hanselmann
          self.msg.start_line = self.ParseStartLine(self.start_line_buffer)
660 02cab3e7 Michael Hanselmann
661 02cab3e7 Michael Hanselmann
          self.parser_status = self.PS_HEADERS
662 02cab3e7 Michael Hanselmann
        else:
663 02cab3e7 Michael Hanselmann
          # Check whether incoming data is getting too large, otherwise we just
664 02cab3e7 Michael Hanselmann
          # fill our read buffer.
665 02cab3e7 Michael Hanselmann
          self._CheckStartLineLength(len(buf))
666 02cab3e7 Michael Hanselmann
667 02cab3e7 Michael Hanselmann
        break
668 02cab3e7 Michael Hanselmann
669 02cab3e7 Michael Hanselmann
    # TODO: Handle messages without headers
670 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_HEADERS:
671 02cab3e7 Michael Hanselmann
      # Wait for header end
672 02cab3e7 Michael Hanselmann
      idx = buf.find("\r\n\r\n")
673 02cab3e7 Michael Hanselmann
      if idx >= 0:
674 02cab3e7 Michael Hanselmann
        self.header_buffer.write(buf[:idx + 2])
675 02cab3e7 Michael Hanselmann
676 02cab3e7 Michael Hanselmann
        self._CheckHeaderLength(self.header_buffer.tell())
677 02cab3e7 Michael Hanselmann
678 02cab3e7 Michael Hanselmann
        # Remove headers, including CRLF
679 02cab3e7 Michael Hanselmann
        buf = buf[idx + 4:]
680 02cab3e7 Michael Hanselmann
681 02cab3e7 Michael Hanselmann
        self._ParseHeaders()
682 02cab3e7 Michael Hanselmann
683 02cab3e7 Michael Hanselmann
        self.parser_status = self.PS_BODY
684 02cab3e7 Michael Hanselmann
      else:
685 02cab3e7 Michael Hanselmann
        # Check whether incoming data is getting too large, otherwise we just
686 02cab3e7 Michael Hanselmann
        # fill our read buffer.
687 02cab3e7 Michael Hanselmann
        self._CheckHeaderLength(len(buf))
688 02cab3e7 Michael Hanselmann
689 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_BODY:
690 02cab3e7 Michael Hanselmann
      # TODO: Implement max size for body_buffer
691 02cab3e7 Michael Hanselmann
      self.body_buffer.write(buf)
692 02cab3e7 Michael Hanselmann
      buf = ""
693 02cab3e7 Michael Hanselmann
694 02cab3e7 Michael Hanselmann
      # Check whether we've read everything
695 02cab3e7 Michael Hanselmann
      #
696 02cab3e7 Michael Hanselmann
      # RFC2616, section 4.4: "When a message-body is included with a message,
697 02cab3e7 Michael Hanselmann
      # the transfer-length of that body is determined by one of the following
698 02cab3e7 Michael Hanselmann
      # [...] 5. By the server closing the connection. (Closing the connection
699 02cab3e7 Michael Hanselmann
      # cannot be used to indicate the end of a request body, since that would
700 02cab3e7 Michael Hanselmann
      # leave no possibility for the server to send back a response.)"
701 02cab3e7 Michael Hanselmann
      if (eof or
702 02cab3e7 Michael Hanselmann
          self.content_length is None or
703 02cab3e7 Michael Hanselmann
          (self.content_length is not None and
704 02cab3e7 Michael Hanselmann
           self.body_buffer.tell() >= self.content_length)):
705 02cab3e7 Michael Hanselmann
        self.parser_status = self.PS_COMPLETE
706 02cab3e7 Michael Hanselmann
707 02cab3e7 Michael Hanselmann
    return buf
708 02cab3e7 Michael Hanselmann
709 02cab3e7 Michael Hanselmann
  def _CheckStartLineLength(self, length):
710 02cab3e7 Michael Hanselmann
    """Limits the start line buffer size.
711 02cab3e7 Michael Hanselmann

712 02cab3e7 Michael Hanselmann
    @type length: int
713 02cab3e7 Michael Hanselmann
    @param length: Buffer size
714 02cab3e7 Michael Hanselmann

715 02cab3e7 Michael Hanselmann
    """
716 02cab3e7 Michael Hanselmann
    if (self.START_LINE_LENGTH_MAX is not None and
717 02cab3e7 Michael Hanselmann
        length > self.START_LINE_LENGTH_MAX):
718 02cab3e7 Michael Hanselmann
      raise HttpError("Start line longer than %d chars" %
719 02cab3e7 Michael Hanselmann
                       self.START_LINE_LENGTH_MAX)
720 02cab3e7 Michael Hanselmann
721 02cab3e7 Michael Hanselmann
  def _CheckHeaderLength(self, length):
722 02cab3e7 Michael Hanselmann
    """Limits the header buffer size.
723 02cab3e7 Michael Hanselmann

724 02cab3e7 Michael Hanselmann
    @type length: int
725 02cab3e7 Michael Hanselmann
    @param length: Buffer size
726 02cab3e7 Michael Hanselmann

727 02cab3e7 Michael Hanselmann
    """
728 02cab3e7 Michael Hanselmann
    if (self.HEADER_LENGTH_MAX is not None and
729 02cab3e7 Michael Hanselmann
        length > self.HEADER_LENGTH_MAX):
730 02cab3e7 Michael Hanselmann
      raise HttpError("Headers longer than %d chars" % self.HEADER_LENGTH_MAX)
731 02cab3e7 Michael Hanselmann
732 02cab3e7 Michael Hanselmann
  def ParseStartLine(self, start_line):
733 02cab3e7 Michael Hanselmann
    """Parses the start line of a message.
734 02cab3e7 Michael Hanselmann

735 02cab3e7 Michael Hanselmann
    Must be overriden by subclass.
736 02cab3e7 Michael Hanselmann

737 02cab3e7 Michael Hanselmann
    @type start_line: string
738 02cab3e7 Michael Hanselmann
    @param start_line: Start line string
739 02cab3e7 Michael Hanselmann

740 02cab3e7 Michael Hanselmann
    """
741 02cab3e7 Michael Hanselmann
    raise NotImplementedError()
742 02cab3e7 Michael Hanselmann
743 02cab3e7 Michael Hanselmann
  def _WillPeerCloseConnection(self):
744 02cab3e7 Michael Hanselmann
    """Evaluate whether peer will close the connection.
745 02cab3e7 Michael Hanselmann

746 02cab3e7 Michael Hanselmann
    @rtype: bool
747 02cab3e7 Michael Hanselmann
    @return: Whether peer will close the connection
748 02cab3e7 Michael Hanselmann

749 02cab3e7 Michael Hanselmann
    """
750 02cab3e7 Michael Hanselmann
    # RFC2616, section 14.10: "HTTP/1.1 defines the "close" connection option
751 02cab3e7 Michael Hanselmann
    # for the sender to signal that the connection will be closed after
752 02cab3e7 Michael Hanselmann
    # completion of the response. For example,
753 02cab3e7 Michael Hanselmann
    #
754 02cab3e7 Michael Hanselmann
    #        Connection: close
755 02cab3e7 Michael Hanselmann
    #
756 02cab3e7 Michael Hanselmann
    # in either the request or the response header fields indicates that the
757 02cab3e7 Michael Hanselmann
    # connection SHOULD NOT be considered `persistent' (section 8.1) after the
758 02cab3e7 Michael Hanselmann
    # current request/response is complete."
759 02cab3e7 Michael Hanselmann
760 02cab3e7 Michael Hanselmann
    hdr_connection = self.msg.headers.get(HTTP_CONNECTION, None)
761 02cab3e7 Michael Hanselmann
    if hdr_connection:
762 02cab3e7 Michael Hanselmann
      hdr_connection = hdr_connection.lower()
763 02cab3e7 Michael Hanselmann
764 02cab3e7 Michael Hanselmann
    # An HTTP/1.1 server is assumed to stay open unless explicitly closed.
765 02cab3e7 Michael Hanselmann
    if self.msg.start_line.version == HTTP_1_1:
766 02cab3e7 Michael Hanselmann
      return (hdr_connection and "close" in hdr_connection)
767 02cab3e7 Michael Hanselmann
768 02cab3e7 Michael Hanselmann
    # Some HTTP/1.0 implementations have support for persistent connections,
769 02cab3e7 Michael Hanselmann
    # using rules different than HTTP/1.1.
770 02cab3e7 Michael Hanselmann
771 02cab3e7 Michael Hanselmann
    # For older HTTP, Keep-Alive indicates persistent connection.
772 02cab3e7 Michael Hanselmann
    if self.msg.headers.get(HTTP_KEEP_ALIVE):
773 02cab3e7 Michael Hanselmann
      return False
774 02cab3e7 Michael Hanselmann
775 02cab3e7 Michael Hanselmann
    # At least Akamai returns a "Connection: Keep-Alive" header, which was
776 02cab3e7 Michael Hanselmann
    # supposed to be sent by the client.
777 02cab3e7 Michael Hanselmann
    if hdr_connection and "keep-alive" in hdr_connection:
778 02cab3e7 Michael Hanselmann
      return False
779 02cab3e7 Michael Hanselmann
780 02cab3e7 Michael Hanselmann
    return True
781 02cab3e7 Michael Hanselmann
782 02cab3e7 Michael Hanselmann
  def _ParseHeaders(self):
783 02cab3e7 Michael Hanselmann
    """Parses the headers.
784 02cab3e7 Michael Hanselmann

785 02cab3e7 Michael Hanselmann
    This function also adjusts internal variables based on header values.
786 02cab3e7 Michael Hanselmann

787 02cab3e7 Michael Hanselmann
    RFC2616, section 4.3: "The presence of a message-body in a request is
788 02cab3e7 Michael Hanselmann
    signaled by the inclusion of a Content-Length or Transfer-Encoding header
789 02cab3e7 Michael Hanselmann
    field in the request's message-headers."
790 02cab3e7 Michael Hanselmann

791 02cab3e7 Michael Hanselmann
    """
792 02cab3e7 Michael Hanselmann
    # Parse headers
793 02cab3e7 Michael Hanselmann
    self.header_buffer.seek(0, 0)
794 02cab3e7 Michael Hanselmann
    self.msg.headers = mimetools.Message(self.header_buffer, 0)
795 02cab3e7 Michael Hanselmann
796 02cab3e7 Michael Hanselmann
    self.peer_will_close = self._WillPeerCloseConnection()
797 02cab3e7 Michael Hanselmann
798 02cab3e7 Michael Hanselmann
    # Do we have a Content-Length header?
799 02cab3e7 Michael Hanselmann
    hdr_content_length = self.msg.headers.get(HTTP_CONTENT_LENGTH, None)
800 02cab3e7 Michael Hanselmann
    if hdr_content_length:
801 02cab3e7 Michael Hanselmann
      try:
802 02cab3e7 Michael Hanselmann
        self.content_length = int(hdr_content_length)
803 02cab3e7 Michael Hanselmann
      except ValueError:
804 02cab3e7 Michael Hanselmann
        self.content_length = None
805 02cab3e7 Michael Hanselmann
      if self.content_length is not None and self.content_length < 0:
806 02cab3e7 Michael Hanselmann
        self.content_length = None
807 02cab3e7 Michael Hanselmann
808 02cab3e7 Michael Hanselmann
    # if the connection remains open and a content-length was not provided,
809 02cab3e7 Michael Hanselmann
    # then assume that the connection WILL close.
810 02cab3e7 Michael Hanselmann
    if self.content_length is None:
811 02cab3e7 Michael Hanselmann
      self.peer_will_close = True