Statistics
| Branch: | Tag: | Revision:

root / lib / http / __init__.py @ d7fa9982

History | View | Annotate | Download (23.9 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 d7fa9982 Michael Hanselmann
 SOCKOP_SHUTDOWN,
71 d7fa9982 Michael Hanselmann
 SOCKOP_HANDSHAKE) = range(4)
72 73a59d9e Michael Hanselmann
73 b18dd019 Iustin Pop
# send/receive quantum
74 b18dd019 Iustin Pop
SOCK_BUF_SIZE = 32768
75 42242313 Michael Hanselmann
76 13b63666 Michael Hanselmann
77 02cab3e7 Michael Hanselmann
class HttpError(Exception):
78 02cab3e7 Michael Hanselmann
  """Internal exception for HTTP errors.
79 02cab3e7 Michael Hanselmann

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

82 02cab3e7 Michael Hanselmann
  """
83 02cab3e7 Michael Hanselmann
84 02cab3e7 Michael Hanselmann
85 39cfc25b Michael Hanselmann
class HttpConnectionClosed(Exception):
86 39cfc25b Michael Hanselmann
  """Internal exception for a closed connection.
87 39cfc25b Michael Hanselmann

88 39cfc25b Michael Hanselmann
  This should only be used for internal error reporting. Only use
89 39cfc25b Michael Hanselmann
  it if there's no other way to report this condition.
90 39cfc25b Michael Hanselmann

91 39cfc25b Michael Hanselmann
  """
92 39cfc25b Michael Hanselmann
93 39cfc25b Michael Hanselmann
94 d7fa9982 Michael Hanselmann
class HttpSessionHandshakeUnexpectedEOF(HttpError):
95 d7fa9982 Michael Hanselmann
  """Internal exception for errors during SSL handshake.
96 d7fa9982 Michael Hanselmann

97 d7fa9982 Michael Hanselmann
  This should only be used for internal error reporting.
98 d7fa9982 Michael Hanselmann

99 d7fa9982 Michael Hanselmann
  """
100 d7fa9982 Michael Hanselmann
101 d7fa9982 Michael Hanselmann
102 c9d0fa8a Michael Hanselmann
class HttpSocketTimeout(Exception):
103 73a59d9e Michael Hanselmann
  """Internal exception for socket timeouts.
104 73a59d9e Michael Hanselmann

105 73a59d9e Michael Hanselmann
  This should only be used for internal error reporting.
106 73a59d9e Michael Hanselmann

107 73a59d9e Michael Hanselmann
  """
108 8a0b06d2 Michael Hanselmann
109 8a0b06d2 Michael Hanselmann
110 84f2756e Michael Hanselmann
class HttpException(Exception):
111 a43f68dc Michael Hanselmann
  code = None
112 a43f68dc Michael Hanselmann
  message = None
113 a43f68dc Michael Hanselmann
114 a43f68dc Michael Hanselmann
  def __init__(self, message=None):
115 42242313 Michael Hanselmann
    Exception.__init__(self)
116 a43f68dc Michael Hanselmann
    if message is not None:
117 a43f68dc Michael Hanselmann
      self.message = message
118 a43f68dc Michael Hanselmann
119 a43f68dc Michael Hanselmann
120 84f2756e Michael Hanselmann
class HttpBadRequest(HttpException):
121 a43f68dc Michael Hanselmann
  code = 400
122 a43f68dc Michael Hanselmann
123 a43f68dc Michael Hanselmann
124 84f2756e Michael Hanselmann
class HttpForbidden(HttpException):
125 a43f68dc Michael Hanselmann
  code = 403
126 a43f68dc Michael Hanselmann
127 a43f68dc Michael Hanselmann
128 84f2756e Michael Hanselmann
class HttpNotFound(HttpException):
129 a43f68dc Michael Hanselmann
  code = 404
130 a43f68dc Michael Hanselmann
131 a43f68dc Michael Hanselmann
132 84f2756e Michael Hanselmann
class HttpGone(HttpException):
133 a43f68dc Michael Hanselmann
  code = 410
134 a43f68dc Michael Hanselmann
135 a43f68dc Michael Hanselmann
136 84f2756e Michael Hanselmann
class HttpLengthRequired(HttpException):
137 a43f68dc Michael Hanselmann
  code = 411
138 a43f68dc Michael Hanselmann
139 a43f68dc Michael Hanselmann
140 84f2756e Michael Hanselmann
class HttpInternalError(HttpException):
141 a43f68dc Michael Hanselmann
  code = 500
142 a43f68dc Michael Hanselmann
143 a43f68dc Michael Hanselmann
144 84f2756e Michael Hanselmann
class HttpNotImplemented(HttpException):
145 a43f68dc Michael Hanselmann
  code = 501
146 a43f68dc Michael Hanselmann
147 a43f68dc Michael Hanselmann
148 84f2756e Michael Hanselmann
class HttpServiceUnavailable(HttpException):
149 a43f68dc Michael Hanselmann
  code = 503
150 a43f68dc Michael Hanselmann
151 a43f68dc Michael Hanselmann
152 84f2756e Michael Hanselmann
class HttpVersionNotSupported(HttpException):
153 42242313 Michael Hanselmann
  code = 505
154 42242313 Michael Hanselmann
155 42242313 Michael Hanselmann
156 84f2756e Michael Hanselmann
class HttpJsonConverter:
157 a43f68dc Michael Hanselmann
  CONTENT_TYPE = "application/json"
158 a43f68dc Michael Hanselmann
159 a43f68dc Michael Hanselmann
  def Encode(self, data):
160 a43f68dc Michael Hanselmann
    return serializer.DumpJson(data)
161 a43f68dc Michael Hanselmann
162 a43f68dc Michael Hanselmann
  def Decode(self, data):
163 a43f68dc Michael Hanselmann
    return serializer.LoadJson(data)
164 a43f68dc Michael Hanselmann
165 a43f68dc Michael Hanselmann
166 73a59d9e Michael Hanselmann
def WaitForSocketCondition(poller, sock, event, timeout):
167 f22c1cea Michael Hanselmann
  """Waits for a condition to occur on the socket.
168 f22c1cea Michael Hanselmann

169 f22c1cea Michael Hanselmann
  @type poller: select.Poller
170 f22c1cea Michael Hanselmann
  @param poller: Poller object as created by select.poll()
171 73a59d9e Michael Hanselmann
  @type sock: socket
172 358a8811 Michael Hanselmann
  @param sock: Wait for events on this socket
173 f22c1cea Michael Hanselmann
  @type event: int
174 f22c1cea Michael Hanselmann
  @param event: ORed condition (see select module)
175 f22c1cea Michael Hanselmann
  @type timeout: float or None
176 f22c1cea Michael Hanselmann
  @param timeout: Timeout in seconds
177 f22c1cea Michael Hanselmann
  @rtype: int or None
178 f22c1cea Michael Hanselmann
  @return: None for timeout, otherwise occured conditions
179 f22c1cea Michael Hanselmann

180 f22c1cea Michael Hanselmann
  """
181 f22c1cea Michael Hanselmann
  check = (event | select.POLLPRI |
182 f22c1cea Michael Hanselmann
           select.POLLNVAL | select.POLLHUP | select.POLLERR)
183 f22c1cea Michael Hanselmann
184 f22c1cea Michael Hanselmann
  if timeout is not None:
185 f22c1cea Michael Hanselmann
    # Poller object expects milliseconds
186 f22c1cea Michael Hanselmann
    timeout *= 1000
187 f22c1cea Michael Hanselmann
188 f22c1cea Michael Hanselmann
  poller.register(sock, event)
189 f22c1cea Michael Hanselmann
  try:
190 f22c1cea Michael Hanselmann
    while True:
191 f22c1cea Michael Hanselmann
      # TODO: If the main thread receives a signal and we have no timeout, we
192 f22c1cea Michael Hanselmann
      # could wait forever. This should check a global "quit" flag or
193 f22c1cea Michael Hanselmann
      # something every so often.
194 f22c1cea Michael Hanselmann
      io_events = poller.poll(timeout)
195 f22c1cea Michael Hanselmann
      if not io_events:
196 f22c1cea Michael Hanselmann
        # Timeout
197 f22c1cea Michael Hanselmann
        return None
198 f22c1cea Michael Hanselmann
      for (evfd, evcond) in io_events:
199 f22c1cea Michael Hanselmann
        if evcond & check:
200 f22c1cea Michael Hanselmann
          return evcond
201 f22c1cea Michael Hanselmann
  finally:
202 f22c1cea Michael Hanselmann
    poller.unregister(sock)
203 f22c1cea Michael Hanselmann
204 f22c1cea Michael Hanselmann
205 73a59d9e Michael Hanselmann
def SocketOperation(poller, sock, op, arg1, timeout):
206 73a59d9e Michael Hanselmann
  """Wrapper around socket functions.
207 73a59d9e Michael Hanselmann

208 73a59d9e Michael Hanselmann
  This function abstracts error handling for socket operations, especially
209 73a59d9e Michael Hanselmann
  for the complicated interaction with OpenSSL.
210 73a59d9e Michael Hanselmann

211 73a59d9e Michael Hanselmann
  @type poller: select.Poller
212 73a59d9e Michael Hanselmann
  @param poller: Poller object as created by select.poll()
213 73a59d9e Michael Hanselmann
  @type sock: socket
214 358a8811 Michael Hanselmann
  @param sock: Socket for the operation
215 73a59d9e Michael Hanselmann
  @type op: int
216 73a59d9e Michael Hanselmann
  @param op: Operation to execute (SOCKOP_* constants)
217 73a59d9e Michael Hanselmann
  @type arg1: any
218 73a59d9e Michael Hanselmann
  @param arg1: Parameter for function (if needed)
219 73a59d9e Michael Hanselmann
  @type timeout: None or float
220 73a59d9e Michael Hanselmann
  @param timeout: Timeout in seconds or None
221 358a8811 Michael Hanselmann
  @return: Return value of socket function
222 73a59d9e Michael Hanselmann

223 73a59d9e Michael Hanselmann
  """
224 73a59d9e Michael Hanselmann
  # TODO: event_poll/event_check/override
225 d7fa9982 Michael Hanselmann
  if op in (SOCKOP_SEND, SOCKOP_HANDSHAKE):
226 73a59d9e Michael Hanselmann
    event_poll = select.POLLOUT
227 73a59d9e Michael Hanselmann
    event_check = select.POLLOUT
228 73a59d9e Michael Hanselmann
229 73a59d9e Michael Hanselmann
  elif op == SOCKOP_RECV:
230 73a59d9e Michael Hanselmann
    event_poll = select.POLLIN
231 73a59d9e Michael Hanselmann
    event_check = select.POLLIN | select.POLLPRI
232 73a59d9e Michael Hanselmann
233 73a59d9e Michael Hanselmann
  elif op == SOCKOP_SHUTDOWN:
234 73a59d9e Michael Hanselmann
    event_poll = None
235 73a59d9e Michael Hanselmann
    event_check = None
236 73a59d9e Michael Hanselmann
237 73a59d9e Michael Hanselmann
    # The timeout is only used when OpenSSL requests polling for a condition.
238 73a59d9e Michael Hanselmann
    # It is not advisable to have no timeout for shutdown.
239 73a59d9e Michael Hanselmann
    assert timeout
240 73a59d9e Michael Hanselmann
241 73a59d9e Michael Hanselmann
  else:
242 73a59d9e Michael Hanselmann
    raise AssertionError("Invalid socket operation")
243 73a59d9e Michael Hanselmann
244 d7fa9982 Michael Hanselmann
  # Handshake is only supported by SSL sockets
245 d7fa9982 Michael Hanselmann
  if (op == SOCKOP_HANDSHAKE and
246 d7fa9982 Michael Hanselmann
      not isinstance(sock, OpenSSL.SSL.ConnectionType)):
247 d7fa9982 Michael Hanselmann
    return
248 d7fa9982 Michael Hanselmann
249 73a59d9e Michael Hanselmann
  # No override by default
250 73a59d9e Michael Hanselmann
  event_override = 0
251 73a59d9e Michael Hanselmann
252 73a59d9e Michael Hanselmann
  while True:
253 73a59d9e Michael Hanselmann
    # Poll only for certain operations and when asked for by an override
254 d7fa9982 Michael Hanselmann
    if event_override or op in (SOCKOP_SEND, SOCKOP_RECV, SOCKOP_HANDSHAKE):
255 73a59d9e Michael Hanselmann
      if event_override:
256 73a59d9e Michael Hanselmann
        wait_for_event = event_override
257 73a59d9e Michael Hanselmann
      else:
258 73a59d9e Michael Hanselmann
        wait_for_event = event_poll
259 73a59d9e Michael Hanselmann
260 73a59d9e Michael Hanselmann
      event = WaitForSocketCondition(poller, sock, wait_for_event, timeout)
261 73a59d9e Michael Hanselmann
      if event is None:
262 c9d0fa8a Michael Hanselmann
        raise HttpSocketTimeout()
263 73a59d9e Michael Hanselmann
264 73a59d9e Michael Hanselmann
      if (op == SOCKOP_RECV and
265 73a59d9e Michael Hanselmann
          event & (select.POLLNVAL | select.POLLHUP | select.POLLERR)):
266 73a59d9e Michael Hanselmann
        return ""
267 73a59d9e Michael Hanselmann
268 73a59d9e Michael Hanselmann
      if not event & wait_for_event:
269 73a59d9e Michael Hanselmann
        continue
270 73a59d9e Michael Hanselmann
271 73a59d9e Michael Hanselmann
    # Reset override
272 73a59d9e Michael Hanselmann
    event_override = 0
273 73a59d9e Michael Hanselmann
274 73a59d9e Michael Hanselmann
    try:
275 73a59d9e Michael Hanselmann
      try:
276 73a59d9e Michael Hanselmann
        if op == SOCKOP_SEND:
277 73a59d9e Michael Hanselmann
          return sock.send(arg1)
278 73a59d9e Michael Hanselmann
279 73a59d9e Michael Hanselmann
        elif op == SOCKOP_RECV:
280 73a59d9e Michael Hanselmann
          return sock.recv(arg1)
281 73a59d9e Michael Hanselmann
282 73a59d9e Michael Hanselmann
        elif op == SOCKOP_SHUTDOWN:
283 73a59d9e Michael Hanselmann
          if isinstance(sock, OpenSSL.SSL.ConnectionType):
284 73a59d9e Michael Hanselmann
            # PyOpenSSL's shutdown() doesn't take arguments
285 73a59d9e Michael Hanselmann
            return sock.shutdown()
286 73a59d9e Michael Hanselmann
          else:
287 73a59d9e Michael Hanselmann
            return sock.shutdown(arg1)
288 73a59d9e Michael Hanselmann
289 d7fa9982 Michael Hanselmann
        elif op == SOCKOP_HANDSHAKE:
290 d7fa9982 Michael Hanselmann
          return sock.do_handshake()
291 d7fa9982 Michael Hanselmann
292 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantWriteError:
293 73a59d9e Michael Hanselmann
        # OpenSSL wants to write, poll for POLLOUT
294 73a59d9e Michael Hanselmann
        event_override = select.POLLOUT
295 73a59d9e Michael Hanselmann
        continue
296 73a59d9e Michael Hanselmann
297 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantReadError:
298 73a59d9e Michael Hanselmann
        # OpenSSL wants to read, poll for POLLIN
299 73a59d9e Michael Hanselmann
        event_override = select.POLLIN | select.POLLPRI
300 73a59d9e Michael Hanselmann
        continue
301 73a59d9e Michael Hanselmann
302 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantX509LookupError:
303 73a59d9e Michael Hanselmann
        continue
304 73a59d9e Michael Hanselmann
305 39cfc25b Michael Hanselmann
      except OpenSSL.SSL.ZeroReturnError, err:
306 39cfc25b Michael Hanselmann
        # SSL Connection has been closed. In SSL 3.0 and TLS 1.0, this only
307 39cfc25b Michael Hanselmann
        # occurs if a closure alert has occurred in the protocol, i.e. the
308 39cfc25b Michael Hanselmann
        # connection has been closed cleanly. Note that this does not
309 39cfc25b Michael Hanselmann
        # necessarily mean that the transport layer (e.g. a socket) has been
310 39cfc25b Michael Hanselmann
        # closed.
311 39cfc25b Michael Hanselmann
        if op == SOCKOP_SEND:
312 39cfc25b Michael Hanselmann
          # Can happen during a renegotiation
313 39cfc25b Michael Hanselmann
          raise HttpConnectionClosed(err.args)
314 39cfc25b Michael Hanselmann
        elif op == SOCKOP_RECV:
315 39cfc25b Michael Hanselmann
          return ""
316 39cfc25b Michael Hanselmann
317 39cfc25b Michael Hanselmann
        # SSL_shutdown shouldn't return SSL_ERROR_ZERO_RETURN
318 39cfc25b Michael Hanselmann
        raise socket.error(err.args)
319 39cfc25b Michael Hanselmann
320 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.SysCallError, err:
321 73a59d9e Michael Hanselmann
        if op == SOCKOP_SEND:
322 73a59d9e Michael Hanselmann
          # arg1 is the data when writing
323 73a59d9e Michael Hanselmann
          if err.args and err.args[0] == -1 and arg1 == "":
324 73a59d9e Michael Hanselmann
            # errors when writing empty strings are expected
325 73a59d9e Michael Hanselmann
            # and can be ignored
326 73a59d9e Michael Hanselmann
            return 0
327 73a59d9e Michael Hanselmann
328 d7fa9982 Michael Hanselmann
        if err.args == (-1, _SSL_UNEXPECTED_EOF):
329 d7fa9982 Michael Hanselmann
          if op == SOCKOP_RECV:
330 73a59d9e Michael Hanselmann
            return ""
331 d7fa9982 Michael Hanselmann
          elif op == SOCKOP_HANDSHAKE:
332 d7fa9982 Michael Hanselmann
            # Can happen if peer disconnects directly after the connection is
333 d7fa9982 Michael Hanselmann
            # opened.
334 d7fa9982 Michael Hanselmann
            raise HttpSessionHandshakeUnexpectedEOF(err.args)
335 73a59d9e Michael Hanselmann
336 73a59d9e Michael Hanselmann
        raise socket.error(err.args)
337 73a59d9e Michael Hanselmann
338 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.Error, err:
339 73a59d9e Michael Hanselmann
        raise socket.error(err.args)
340 73a59d9e Michael Hanselmann
341 73a59d9e Michael Hanselmann
    except socket.error, err:
342 73a59d9e Michael Hanselmann
      if err.args and err.args[0] == errno.EAGAIN:
343 73a59d9e Michael Hanselmann
        # Ignore EAGAIN
344 73a59d9e Michael Hanselmann
        continue
345 73a59d9e Michael Hanselmann
346 73a59d9e Michael Hanselmann
      raise
347 73a59d9e Michael Hanselmann
348 73a59d9e Michael Hanselmann
349 02cab3e7 Michael Hanselmann
def ShutdownConnection(poller, sock, close_timeout, write_timeout, msgreader,
350 02cab3e7 Michael Hanselmann
                       force):
351 02cab3e7 Michael Hanselmann
  """Closes the connection.
352 02cab3e7 Michael Hanselmann

353 358a8811 Michael Hanselmann
  @type poller: select.Poller
354 358a8811 Michael Hanselmann
  @param poller: Poller object as created by select.poll()
355 358a8811 Michael Hanselmann
  @type sock: socket
356 358a8811 Michael Hanselmann
  @param sock: Socket to be shut down
357 358a8811 Michael Hanselmann
  @type close_timeout: float
358 358a8811 Michael Hanselmann
  @param close_timeout: How long to wait for the peer to close the connection
359 358a8811 Michael Hanselmann
  @type write_timeout: float
360 358a8811 Michael Hanselmann
  @param write_timeout: Write timeout for shutdown
361 358a8811 Michael Hanselmann
  @type msgreader: http.HttpMessageReader
362 358a8811 Michael Hanselmann
  @param msgreader: Request message reader, used to determine whether peer
363 358a8811 Michael Hanselmann
                    should close connection
364 358a8811 Michael Hanselmann
  @type force: bool
365 358a8811 Michael Hanselmann
  @param force: Whether to forcibly close the connection without waiting
366 358a8811 Michael Hanselmann
                for peer
367 358a8811 Michael Hanselmann

368 02cab3e7 Michael Hanselmann
  """
369 02cab3e7 Michael Hanselmann
  poller = select.poll()
370 02cab3e7 Michael Hanselmann
371 02cab3e7 Michael Hanselmann
  #print msgreader.peer_will_close, force
372 02cab3e7 Michael Hanselmann
  if msgreader and msgreader.peer_will_close and not force:
373 02cab3e7 Michael Hanselmann
    # Wait for peer to close
374 02cab3e7 Michael Hanselmann
    try:
375 02cab3e7 Michael Hanselmann
      # Check whether it's actually closed
376 02cab3e7 Michael Hanselmann
      if not SocketOperation(poller, sock, SOCKOP_RECV, 1, close_timeout):
377 02cab3e7 Michael Hanselmann
        return
378 02cab3e7 Michael Hanselmann
    except (socket.error, HttpError, HttpSocketTimeout):
379 02cab3e7 Michael Hanselmann
      # Ignore errors at this stage
380 02cab3e7 Michael Hanselmann
      pass
381 02cab3e7 Michael Hanselmann
382 02cab3e7 Michael Hanselmann
  # Close the connection from our side
383 02cab3e7 Michael Hanselmann
  try:
384 39cfc25b Michael Hanselmann
    # We don't care about the return value, see NOTES in SSL_shutdown(3).
385 02cab3e7 Michael Hanselmann
    SocketOperation(poller, sock, SOCKOP_SHUTDOWN, socket.SHUT_RDWR,
386 02cab3e7 Michael Hanselmann
                    write_timeout)
387 02cab3e7 Michael Hanselmann
  except HttpSocketTimeout:
388 02cab3e7 Michael Hanselmann
    raise HttpError("Timeout while shutting down connection")
389 02cab3e7 Michael Hanselmann
  except socket.error, err:
390 02cab3e7 Michael Hanselmann
    raise HttpError("Error while shutting down connection: %s" % err)
391 02cab3e7 Michael Hanselmann
392 02cab3e7 Michael Hanselmann
393 d7fa9982 Michael Hanselmann
def Handshake(poller, sock, write_timeout):
394 d7fa9982 Michael Hanselmann
  """Shakes peer's hands.
395 d7fa9982 Michael Hanselmann

396 d7fa9982 Michael Hanselmann
  @type poller: select.Poller
397 d7fa9982 Michael Hanselmann
  @param poller: Poller object as created by select.poll()
398 d7fa9982 Michael Hanselmann
  @type sock: socket
399 d7fa9982 Michael Hanselmann
  @param sock: Socket to be shut down
400 d7fa9982 Michael Hanselmann
  @type write_timeout: float
401 d7fa9982 Michael Hanselmann
  @param write_timeout: Write timeout for handshake
402 d7fa9982 Michael Hanselmann

403 d7fa9982 Michael Hanselmann
  """
404 d7fa9982 Michael Hanselmann
  try:
405 d7fa9982 Michael Hanselmann
    return SocketOperation(poller, sock, SOCKOP_HANDSHAKE, None, write_timeout)
406 d7fa9982 Michael Hanselmann
  except HttpSocketTimeout:
407 d7fa9982 Michael Hanselmann
    raise HttpError("Timeout during SSL handshake")
408 d7fa9982 Michael Hanselmann
  except socket.error, err:
409 d7fa9982 Michael Hanselmann
    raise HttpError("Error in SSL handshake: %s" % err)
410 d7fa9982 Michael Hanselmann
411 d7fa9982 Michael Hanselmann
412 f20cbea2 Michael Hanselmann
class HttpSslParams(object):
413 f20cbea2 Michael Hanselmann
  """Data class for SSL key and certificate.
414 f20cbea2 Michael Hanselmann

415 f20cbea2 Michael Hanselmann
  """
416 f20cbea2 Michael Hanselmann
  def __init__(self, ssl_key_path, ssl_cert_path):
417 f20cbea2 Michael Hanselmann
    """Initializes this class.
418 f20cbea2 Michael Hanselmann

419 f20cbea2 Michael Hanselmann
    @type ssl_key_path: string
420 f20cbea2 Michael Hanselmann
    @param ssl_key_path: Path to file containing SSL key in PEM format
421 f20cbea2 Michael Hanselmann
    @type ssl_cert_path: string
422 f20cbea2 Michael Hanselmann
    @param ssl_cert_path: Path to file containing SSL certificate in PEM format
423 f20cbea2 Michael Hanselmann

424 f20cbea2 Michael Hanselmann
    """
425 65c6b8e0 Michael Hanselmann
    self.ssl_key_pem = utils.ReadFile(ssl_key_path)
426 65c6b8e0 Michael Hanselmann
    self.ssl_cert_pem = utils.ReadFile(ssl_cert_path)
427 f20cbea2 Michael Hanselmann
428 65c6b8e0 Michael Hanselmann
  def GetKey(self):
429 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
430 65c6b8e0 Michael Hanselmann
                                          self.ssl_key_pem)
431 65c6b8e0 Michael Hanselmann
432 65c6b8e0 Michael Hanselmann
  def GetCertificate(self):
433 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
434 65c6b8e0 Michael Hanselmann
                                           self.ssl_cert_pem)
435 f20cbea2 Michael Hanselmann
436 f20cbea2 Michael Hanselmann
437 f4322a1e Michael Hanselmann
class HttpBase(object):
438 b14f759e Michael Hanselmann
  """Base class for HTTP server and client.
439 b14f759e Michael Hanselmann

440 b14f759e Michael Hanselmann
  """
441 b14f759e Michael Hanselmann
  def __init__(self):
442 22692e48 Michael Hanselmann
    self.using_ssl = None
443 f20cbea2 Michael Hanselmann
    self._ssl_params = None
444 65c6b8e0 Michael Hanselmann
    self._ssl_key = None
445 65c6b8e0 Michael Hanselmann
    self._ssl_cert = None
446 b14f759e Michael Hanselmann
447 f20cbea2 Michael Hanselmann
  def _CreateSocket(self, ssl_params, ssl_verify_peer):
448 b14f759e Michael Hanselmann
    """Creates a TCP socket and initializes SSL if needed.
449 b14f759e Michael Hanselmann

450 f20cbea2 Michael Hanselmann
    @type ssl_params: HttpSslParams
451 f20cbea2 Michael Hanselmann
    @param ssl_params: SSL key and certificate
452 b14f759e Michael Hanselmann
    @type ssl_verify_peer: bool
453 b14f759e Michael Hanselmann
    @param ssl_verify_peer: Whether to require client certificate and compare
454 b14f759e Michael Hanselmann
                            it with our certificate
455 b14f759e Michael Hanselmann

456 b14f759e Michael Hanselmann
    """
457 f20cbea2 Michael Hanselmann
    self._ssl_params = ssl_params
458 f20cbea2 Michael Hanselmann
459 b14f759e Michael Hanselmann
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
460 b14f759e Michael Hanselmann
461 b14f759e Michael Hanselmann
    # Should we enable SSL?
462 22692e48 Michael Hanselmann
    self.using_ssl = ssl_params is not None
463 b14f759e Michael Hanselmann
464 22692e48 Michael Hanselmann
    if not self.using_ssl:
465 b14f759e Michael Hanselmann
      return sock
466 b14f759e Michael Hanselmann
467 65c6b8e0 Michael Hanselmann
    self._ssl_key = ssl_params.GetKey()
468 65c6b8e0 Michael Hanselmann
    self._ssl_cert = ssl_params.GetCertificate()
469 65c6b8e0 Michael Hanselmann
470 b14f759e Michael Hanselmann
    ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
471 b14f759e Michael Hanselmann
    ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2)
472 b14f759e Michael Hanselmann
473 65c6b8e0 Michael Hanselmann
    ctx.use_privatekey(self._ssl_key)
474 65c6b8e0 Michael Hanselmann
    ctx.use_certificate(self._ssl_cert)
475 b14f759e Michael Hanselmann
    ctx.check_privatekey()
476 b14f759e Michael Hanselmann
477 b14f759e Michael Hanselmann
    if ssl_verify_peer:
478 b14f759e Michael Hanselmann
      ctx.set_verify(OpenSSL.SSL.VERIFY_PEER |
479 b14f759e Michael Hanselmann
                     OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
480 b14f759e Michael Hanselmann
                     self._SSLVerifyCallback)
481 b14f759e Michael Hanselmann
482 b14f759e Michael Hanselmann
    return OpenSSL.SSL.Connection(ctx, sock)
483 b14f759e Michael Hanselmann
484 b14f759e Michael Hanselmann
  def _SSLVerifyCallback(self, conn, cert, errnum, errdepth, ok):
485 b14f759e Michael Hanselmann
    """Verify the certificate provided by the peer
486 b14f759e Michael Hanselmann

487 b14f759e Michael Hanselmann
    We only compare fingerprints. The client must use the same certificate as
488 b14f759e Michael Hanselmann
    we do on our side.
489 b14f759e Michael Hanselmann

490 b14f759e Michael Hanselmann
    """
491 f20cbea2 Michael Hanselmann
    assert self._ssl_params, "SSL not initialized"
492 b14f759e Michael Hanselmann
493 65c6b8e0 Michael Hanselmann
    return (self._ssl_cert.digest("sha1") == cert.digest("sha1") and
494 65c6b8e0 Michael Hanselmann
            self._ssl_cert.digest("md5") == cert.digest("md5"))
495 b14f759e Michael Hanselmann
496 b14f759e Michael Hanselmann
497 02cab3e7 Michael Hanselmann
class HttpMessage(object):
498 02cab3e7 Michael Hanselmann
  """Data structure for HTTP message.
499 02cab3e7 Michael Hanselmann

500 02cab3e7 Michael Hanselmann
  """
501 02cab3e7 Michael Hanselmann
  def __init__(self):
502 02cab3e7 Michael Hanselmann
    self.start_line = None
503 02cab3e7 Michael Hanselmann
    self.headers = None
504 02cab3e7 Michael Hanselmann
    self.body = None
505 02cab3e7 Michael Hanselmann
    self.decoded_body = None
506 02cab3e7 Michael Hanselmann
507 02cab3e7 Michael Hanselmann
508 02cab3e7 Michael Hanselmann
class HttpClientToServerStartLine(object):
509 02cab3e7 Michael Hanselmann
  """Data structure for HTTP request start line.
510 02cab3e7 Michael Hanselmann

511 02cab3e7 Michael Hanselmann
  """
512 02cab3e7 Michael Hanselmann
  def __init__(self, method, path, version):
513 02cab3e7 Michael Hanselmann
    self.method = method
514 02cab3e7 Michael Hanselmann
    self.path = path
515 02cab3e7 Michael Hanselmann
    self.version = version
516 02cab3e7 Michael Hanselmann
517 02cab3e7 Michael Hanselmann
  def __str__(self):
518 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.method, self.path, self.version)
519 02cab3e7 Michael Hanselmann
520 02cab3e7 Michael Hanselmann
521 02cab3e7 Michael Hanselmann
class HttpServerToClientStartLine(object):
522 02cab3e7 Michael Hanselmann
  """Data structure for HTTP response start line.
523 02cab3e7 Michael Hanselmann

524 02cab3e7 Michael Hanselmann
  """
525 02cab3e7 Michael Hanselmann
  def __init__(self, version, code, reason):
526 02cab3e7 Michael Hanselmann
    self.version = version
527 02cab3e7 Michael Hanselmann
    self.code = code
528 02cab3e7 Michael Hanselmann
    self.reason = reason
529 02cab3e7 Michael Hanselmann
530 02cab3e7 Michael Hanselmann
  def __str__(self):
531 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.version, self.code, self.reason)
532 02cab3e7 Michael Hanselmann
533 02cab3e7 Michael Hanselmann
534 02cab3e7 Michael Hanselmann
class HttpMessageWriter(object):
535 02cab3e7 Michael Hanselmann
  """Writes an HTTP message to a socket.
536 02cab3e7 Michael Hanselmann

537 02cab3e7 Michael Hanselmann
  """
538 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, write_timeout):
539 358a8811 Michael Hanselmann
    """Initializes this class and writes an HTTP message to a socket.
540 358a8811 Michael Hanselmann

541 358a8811 Michael Hanselmann
    @type sock: socket
542 358a8811 Michael Hanselmann
    @param sock: Socket to be written to
543 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
544 358a8811 Michael Hanselmann
    @param msg: HTTP message to be written
545 358a8811 Michael Hanselmann
    @type write_timeout: float
546 358a8811 Michael Hanselmann
    @param write_timeout: Write timeout for socket
547 358a8811 Michael Hanselmann

548 358a8811 Michael Hanselmann
    """
549 02cab3e7 Michael Hanselmann
    self._msg = msg
550 02cab3e7 Michael Hanselmann
551 02cab3e7 Michael Hanselmann
    self._PrepareMessage()
552 02cab3e7 Michael Hanselmann
553 02cab3e7 Michael Hanselmann
    buf = self._FormatMessage()
554 02cab3e7 Michael Hanselmann
555 02cab3e7 Michael Hanselmann
    poller = select.poll()
556 b18dd019 Iustin Pop
557 b18dd019 Iustin Pop
    pos = 0
558 b18dd019 Iustin Pop
    end = len(buf)
559 b18dd019 Iustin Pop
    while pos < end:
560 b18dd019 Iustin Pop
      # Send only SOCK_BUF_SIZE bytes at a time
561 358a8811 Michael Hanselmann
      data = buf[pos:(pos + SOCK_BUF_SIZE)]
562 02cab3e7 Michael Hanselmann
563 02cab3e7 Michael Hanselmann
      sent = SocketOperation(poller, sock, SOCKOP_SEND, data,
564 02cab3e7 Michael Hanselmann
                             write_timeout)
565 02cab3e7 Michael Hanselmann
566 02cab3e7 Michael Hanselmann
      # Remove sent bytes
567 b18dd019 Iustin Pop
      pos += sent
568 02cab3e7 Michael Hanselmann
569 b18dd019 Iustin Pop
    assert pos == end, "Message wasn't sent completely"
570 02cab3e7 Michael Hanselmann
571 02cab3e7 Michael Hanselmann
  def _PrepareMessage(self):
572 02cab3e7 Michael Hanselmann
    """Prepares the HTTP message by setting mandatory headers.
573 02cab3e7 Michael Hanselmann

574 02cab3e7 Michael Hanselmann
    """
575 02cab3e7 Michael Hanselmann
    # RFC2616, section 4.3: "The presence of a message-body in a request is
576 02cab3e7 Michael Hanselmann
    # signaled by the inclusion of a Content-Length or Transfer-Encoding header
577 02cab3e7 Michael Hanselmann
    # field in the request's message-headers."
578 02cab3e7 Michael Hanselmann
    if self._msg.body:
579 02cab3e7 Michael Hanselmann
      self._msg.headers[HTTP_CONTENT_LENGTH] = len(self._msg.body)
580 02cab3e7 Michael Hanselmann
581 02cab3e7 Michael Hanselmann
  def _FormatMessage(self):
582 02cab3e7 Michael Hanselmann
    """Serializes the HTTP message into a string.
583 02cab3e7 Michael Hanselmann

584 02cab3e7 Michael Hanselmann
    """
585 02cab3e7 Michael Hanselmann
    buf = StringIO()
586 02cab3e7 Michael Hanselmann
587 02cab3e7 Michael Hanselmann
    # Add start line
588 02cab3e7 Michael Hanselmann
    buf.write(str(self._msg.start_line))
589 02cab3e7 Michael Hanselmann
    buf.write("\r\n")
590 02cab3e7 Michael Hanselmann
591 02cab3e7 Michael Hanselmann
    # Add headers
592 02cab3e7 Michael Hanselmann
    if self._msg.start_line.version != HTTP_0_9:
593 02cab3e7 Michael Hanselmann
      for name, value in self._msg.headers.iteritems():
594 02cab3e7 Michael Hanselmann
        buf.write("%s: %s\r\n" % (name, value))
595 02cab3e7 Michael Hanselmann
596 02cab3e7 Michael Hanselmann
    buf.write("\r\n")
597 02cab3e7 Michael Hanselmann
598 02cab3e7 Michael Hanselmann
    # Add message body if needed
599 02cab3e7 Michael Hanselmann
    if self.HasMessageBody():
600 02cab3e7 Michael Hanselmann
      buf.write(self._msg.body)
601 02cab3e7 Michael Hanselmann
602 02cab3e7 Michael Hanselmann
    elif self._msg.body:
603 02cab3e7 Michael Hanselmann
      logging.warning("Ignoring message body")
604 02cab3e7 Michael Hanselmann
605 02cab3e7 Michael Hanselmann
    return buf.getvalue()
606 02cab3e7 Michael Hanselmann
607 02cab3e7 Michael Hanselmann
  def HasMessageBody(self):
608 02cab3e7 Michael Hanselmann
    """Checks whether the HTTP message contains a body.
609 02cab3e7 Michael Hanselmann

610 02cab3e7 Michael Hanselmann
    Can be overriden by subclasses.
611 02cab3e7 Michael Hanselmann

612 02cab3e7 Michael Hanselmann
    """
613 02cab3e7 Michael Hanselmann
    return bool(self._msg.body)
614 02cab3e7 Michael Hanselmann
615 02cab3e7 Michael Hanselmann
616 02cab3e7 Michael Hanselmann
class HttpMessageReader(object):
617 02cab3e7 Michael Hanselmann
  """Reads HTTP message from socket.
618 02cab3e7 Michael Hanselmann

619 02cab3e7 Michael Hanselmann
  """
620 02cab3e7 Michael Hanselmann
  # Length limits
621 02cab3e7 Michael Hanselmann
  START_LINE_LENGTH_MAX = None
622 02cab3e7 Michael Hanselmann
  HEADER_LENGTH_MAX = None
623 02cab3e7 Michael Hanselmann
624 02cab3e7 Michael Hanselmann
  # Parser state machine
625 02cab3e7 Michael Hanselmann
  PS_START_LINE = "start-line"
626 02cab3e7 Michael Hanselmann
  PS_HEADERS = "headers"
627 02cab3e7 Michael Hanselmann
  PS_BODY = "entity-body"
628 02cab3e7 Michael Hanselmann
  PS_COMPLETE = "complete"
629 02cab3e7 Michael Hanselmann
630 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, read_timeout):
631 358a8811 Michael Hanselmann
    """Reads an HTTP message from a socket.
632 358a8811 Michael Hanselmann

633 358a8811 Michael Hanselmann
    @type sock: socket
634 358a8811 Michael Hanselmann
    @param sock: Socket to be read from
635 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
636 358a8811 Michael Hanselmann
    @param msg: Object for the read message
637 358a8811 Michael Hanselmann
    @type read_timeout: float
638 358a8811 Michael Hanselmann
    @param read_timeout: Read timeout for socket
639 358a8811 Michael Hanselmann

640 358a8811 Michael Hanselmann
    """
641 02cab3e7 Michael Hanselmann
    self.sock = sock
642 02cab3e7 Michael Hanselmann
    self.msg = msg
643 02cab3e7 Michael Hanselmann
644 02cab3e7 Michael Hanselmann
    self.poller = select.poll()
645 02cab3e7 Michael Hanselmann
    self.start_line_buffer = None
646 02cab3e7 Michael Hanselmann
    self.header_buffer = StringIO()
647 02cab3e7 Michael Hanselmann
    self.body_buffer = StringIO()
648 02cab3e7 Michael Hanselmann
    self.parser_status = self.PS_START_LINE
649 02cab3e7 Michael Hanselmann
    self.content_length = None
650 02cab3e7 Michael Hanselmann
    self.peer_will_close = None
651 02cab3e7 Michael Hanselmann
652 02cab3e7 Michael Hanselmann
    buf = ""
653 02cab3e7 Michael Hanselmann
    eof = False
654 02cab3e7 Michael Hanselmann
    while self.parser_status != self.PS_COMPLETE:
655 b18dd019 Iustin Pop
      data = SocketOperation(self.poller, sock, SOCKOP_RECV, SOCK_BUF_SIZE,
656 02cab3e7 Michael Hanselmann
                             read_timeout)
657 02cab3e7 Michael Hanselmann
658 02cab3e7 Michael Hanselmann
      if data:
659 02cab3e7 Michael Hanselmann
        buf += data
660 02cab3e7 Michael Hanselmann
      else:
661 02cab3e7 Michael Hanselmann
        eof = True
662 02cab3e7 Michael Hanselmann
663 02cab3e7 Michael Hanselmann
      # Do some parsing and error checking while more data arrives
664 02cab3e7 Michael Hanselmann
      buf = self._ContinueParsing(buf, eof)
665 02cab3e7 Michael Hanselmann
666 02cab3e7 Michael Hanselmann
      # Must be done only after the buffer has been evaluated
667 02cab3e7 Michael Hanselmann
      # TODO: Connection-length < len(data read) and connection closed
668 02cab3e7 Michael Hanselmann
      if (eof and
669 02cab3e7 Michael Hanselmann
          self.parser_status in (self.PS_START_LINE,
670 02cab3e7 Michael Hanselmann
                                 self.PS_HEADERS)):
671 02cab3e7 Michael Hanselmann
        raise HttpError("Connection closed prematurely")
672 02cab3e7 Michael Hanselmann
673 02cab3e7 Michael Hanselmann
    # Parse rest
674 02cab3e7 Michael Hanselmann
    buf = self._ContinueParsing(buf, True)
675 02cab3e7 Michael Hanselmann
676 02cab3e7 Michael Hanselmann
    assert self.parser_status == self.PS_COMPLETE
677 02cab3e7 Michael Hanselmann
    assert not buf, "Parser didn't read full response"
678 02cab3e7 Michael Hanselmann
679 02cab3e7 Michael Hanselmann
    msg.body = self.body_buffer.getvalue()
680 02cab3e7 Michael Hanselmann
681 02cab3e7 Michael Hanselmann
    # TODO: Content-type, error handling
682 02cab3e7 Michael Hanselmann
    if msg.body:
683 02cab3e7 Michael Hanselmann
      msg.decoded_body = HttpJsonConverter().Decode(msg.body)
684 02cab3e7 Michael Hanselmann
    else:
685 02cab3e7 Michael Hanselmann
      msg.decoded_body = None
686 02cab3e7 Michael Hanselmann
687 02cab3e7 Michael Hanselmann
    if msg.decoded_body:
688 02cab3e7 Michael Hanselmann
      logging.debug("Message body: %s", msg.decoded_body)
689 02cab3e7 Michael Hanselmann
690 02cab3e7 Michael Hanselmann
  def _ContinueParsing(self, buf, eof):
691 02cab3e7 Michael Hanselmann
    """Main function for HTTP message state machine.
692 02cab3e7 Michael Hanselmann

693 02cab3e7 Michael Hanselmann
    @type buf: string
694 02cab3e7 Michael Hanselmann
    @param buf: Receive buffer
695 02cab3e7 Michael Hanselmann
    @type eof: bool
696 02cab3e7 Michael Hanselmann
    @param eof: Whether we've reached EOF on the socket
697 02cab3e7 Michael Hanselmann
    @rtype: string
698 02cab3e7 Michael Hanselmann
    @return: Updated receive buffer
699 02cab3e7 Michael Hanselmann

700 02cab3e7 Michael Hanselmann
    """
701 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_START_LINE:
702 02cab3e7 Michael Hanselmann
      # Expect start line
703 02cab3e7 Michael Hanselmann
      while True:
704 02cab3e7 Michael Hanselmann
        idx = buf.find("\r\n")
705 02cab3e7 Michael Hanselmann
706 02cab3e7 Michael Hanselmann
        # RFC2616, section 4.1: "In the interest of robustness, servers SHOULD
707 02cab3e7 Michael Hanselmann
        # ignore any empty line(s) received where a Request-Line is expected.
708 02cab3e7 Michael Hanselmann
        # In other words, if the server is reading the protocol stream at the
709 02cab3e7 Michael Hanselmann
        # beginning of a message and receives a CRLF first, it should ignore
710 02cab3e7 Michael Hanselmann
        # the CRLF."
711 02cab3e7 Michael Hanselmann
        if idx == 0:
712 358a8811 Michael Hanselmann
          # TODO: Limit number of CRLFs/empty lines for safety?
713 02cab3e7 Michael Hanselmann
          buf = buf[:2]
714 02cab3e7 Michael Hanselmann
          continue
715 02cab3e7 Michael Hanselmann
716 02cab3e7 Michael Hanselmann
        if idx > 0:
717 02cab3e7 Michael Hanselmann
          self.start_line_buffer = buf[:idx]
718 02cab3e7 Michael Hanselmann
719 02cab3e7 Michael Hanselmann
          self._CheckStartLineLength(len(self.start_line_buffer))
720 02cab3e7 Michael Hanselmann
721 02cab3e7 Michael Hanselmann
          # Remove status line, including CRLF
722 02cab3e7 Michael Hanselmann
          buf = buf[idx + 2:]
723 02cab3e7 Michael Hanselmann
724 02cab3e7 Michael Hanselmann
          self.msg.start_line = self.ParseStartLine(self.start_line_buffer)
725 02cab3e7 Michael Hanselmann
726 02cab3e7 Michael Hanselmann
          self.parser_status = self.PS_HEADERS
727 02cab3e7 Michael Hanselmann
        else:
728 02cab3e7 Michael Hanselmann
          # Check whether incoming data is getting too large, otherwise we just
729 02cab3e7 Michael Hanselmann
          # fill our read buffer.
730 02cab3e7 Michael Hanselmann
          self._CheckStartLineLength(len(buf))
731 02cab3e7 Michael Hanselmann
732 02cab3e7 Michael Hanselmann
        break
733 02cab3e7 Michael Hanselmann
734 02cab3e7 Michael Hanselmann
    # TODO: Handle messages without headers
735 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_HEADERS:
736 02cab3e7 Michael Hanselmann
      # Wait for header end
737 02cab3e7 Michael Hanselmann
      idx = buf.find("\r\n\r\n")
738 02cab3e7 Michael Hanselmann
      if idx >= 0:
739 02cab3e7 Michael Hanselmann
        self.header_buffer.write(buf[:idx + 2])
740 02cab3e7 Michael Hanselmann
741 02cab3e7 Michael Hanselmann
        self._CheckHeaderLength(self.header_buffer.tell())
742 02cab3e7 Michael Hanselmann
743 02cab3e7 Michael Hanselmann
        # Remove headers, including CRLF
744 02cab3e7 Michael Hanselmann
        buf = buf[idx + 4:]
745 02cab3e7 Michael Hanselmann
746 02cab3e7 Michael Hanselmann
        self._ParseHeaders()
747 02cab3e7 Michael Hanselmann
748 02cab3e7 Michael Hanselmann
        self.parser_status = self.PS_BODY
749 02cab3e7 Michael Hanselmann
      else:
750 02cab3e7 Michael Hanselmann
        # Check whether incoming data is getting too large, otherwise we just
751 02cab3e7 Michael Hanselmann
        # fill our read buffer.
752 02cab3e7 Michael Hanselmann
        self._CheckHeaderLength(len(buf))
753 02cab3e7 Michael Hanselmann
754 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_BODY:
755 02cab3e7 Michael Hanselmann
      # TODO: Implement max size for body_buffer
756 02cab3e7 Michael Hanselmann
      self.body_buffer.write(buf)
757 02cab3e7 Michael Hanselmann
      buf = ""
758 02cab3e7 Michael Hanselmann
759 02cab3e7 Michael Hanselmann
      # Check whether we've read everything
760 02cab3e7 Michael Hanselmann
      #
761 02cab3e7 Michael Hanselmann
      # RFC2616, section 4.4: "When a message-body is included with a message,
762 02cab3e7 Michael Hanselmann
      # the transfer-length of that body is determined by one of the following
763 02cab3e7 Michael Hanselmann
      # [...] 5. By the server closing the connection. (Closing the connection
764 02cab3e7 Michael Hanselmann
      # cannot be used to indicate the end of a request body, since that would
765 02cab3e7 Michael Hanselmann
      # leave no possibility for the server to send back a response.)"
766 02cab3e7 Michael Hanselmann
      if (eof or
767 02cab3e7 Michael Hanselmann
          self.content_length is None or
768 02cab3e7 Michael Hanselmann
          (self.content_length is not None and
769 02cab3e7 Michael Hanselmann
           self.body_buffer.tell() >= self.content_length)):
770 02cab3e7 Michael Hanselmann
        self.parser_status = self.PS_COMPLETE
771 02cab3e7 Michael Hanselmann
772 02cab3e7 Michael Hanselmann
    return buf
773 02cab3e7 Michael Hanselmann
774 02cab3e7 Michael Hanselmann
  def _CheckStartLineLength(self, length):
775 02cab3e7 Michael Hanselmann
    """Limits the start line buffer size.
776 02cab3e7 Michael Hanselmann

777 02cab3e7 Michael Hanselmann
    @type length: int
778 02cab3e7 Michael Hanselmann
    @param length: Buffer size
779 02cab3e7 Michael Hanselmann

780 02cab3e7 Michael Hanselmann
    """
781 02cab3e7 Michael Hanselmann
    if (self.START_LINE_LENGTH_MAX is not None and
782 02cab3e7 Michael Hanselmann
        length > self.START_LINE_LENGTH_MAX):
783 02cab3e7 Michael Hanselmann
      raise HttpError("Start line longer than %d chars" %
784 02cab3e7 Michael Hanselmann
                       self.START_LINE_LENGTH_MAX)
785 02cab3e7 Michael Hanselmann
786 02cab3e7 Michael Hanselmann
  def _CheckHeaderLength(self, length):
787 02cab3e7 Michael Hanselmann
    """Limits the header buffer size.
788 02cab3e7 Michael Hanselmann

789 02cab3e7 Michael Hanselmann
    @type length: int
790 02cab3e7 Michael Hanselmann
    @param length: Buffer size
791 02cab3e7 Michael Hanselmann

792 02cab3e7 Michael Hanselmann
    """
793 02cab3e7 Michael Hanselmann
    if (self.HEADER_LENGTH_MAX is not None and
794 02cab3e7 Michael Hanselmann
        length > self.HEADER_LENGTH_MAX):
795 02cab3e7 Michael Hanselmann
      raise HttpError("Headers longer than %d chars" % self.HEADER_LENGTH_MAX)
796 02cab3e7 Michael Hanselmann
797 02cab3e7 Michael Hanselmann
  def ParseStartLine(self, start_line):
798 02cab3e7 Michael Hanselmann
    """Parses the start line of a message.
799 02cab3e7 Michael Hanselmann

800 02cab3e7 Michael Hanselmann
    Must be overriden by subclass.
801 02cab3e7 Michael Hanselmann

802 02cab3e7 Michael Hanselmann
    @type start_line: string
803 02cab3e7 Michael Hanselmann
    @param start_line: Start line string
804 02cab3e7 Michael Hanselmann

805 02cab3e7 Michael Hanselmann
    """
806 02cab3e7 Michael Hanselmann
    raise NotImplementedError()
807 02cab3e7 Michael Hanselmann
808 02cab3e7 Michael Hanselmann
  def _WillPeerCloseConnection(self):
809 02cab3e7 Michael Hanselmann
    """Evaluate whether peer will close the connection.
810 02cab3e7 Michael Hanselmann

811 02cab3e7 Michael Hanselmann
    @rtype: bool
812 02cab3e7 Michael Hanselmann
    @return: Whether peer will close the connection
813 02cab3e7 Michael Hanselmann

814 02cab3e7 Michael Hanselmann
    """
815 02cab3e7 Michael Hanselmann
    # RFC2616, section 14.10: "HTTP/1.1 defines the "close" connection option
816 02cab3e7 Michael Hanselmann
    # for the sender to signal that the connection will be closed after
817 02cab3e7 Michael Hanselmann
    # completion of the response. For example,
818 02cab3e7 Michael Hanselmann
    #
819 02cab3e7 Michael Hanselmann
    #        Connection: close
820 02cab3e7 Michael Hanselmann
    #
821 02cab3e7 Michael Hanselmann
    # in either the request or the response header fields indicates that the
822 02cab3e7 Michael Hanselmann
    # connection SHOULD NOT be considered `persistent' (section 8.1) after the
823 02cab3e7 Michael Hanselmann
    # current request/response is complete."
824 02cab3e7 Michael Hanselmann
825 02cab3e7 Michael Hanselmann
    hdr_connection = self.msg.headers.get(HTTP_CONNECTION, None)
826 02cab3e7 Michael Hanselmann
    if hdr_connection:
827 02cab3e7 Michael Hanselmann
      hdr_connection = hdr_connection.lower()
828 02cab3e7 Michael Hanselmann
829 02cab3e7 Michael Hanselmann
    # An HTTP/1.1 server is assumed to stay open unless explicitly closed.
830 02cab3e7 Michael Hanselmann
    if self.msg.start_line.version == HTTP_1_1:
831 02cab3e7 Michael Hanselmann
      return (hdr_connection and "close" in hdr_connection)
832 02cab3e7 Michael Hanselmann
833 02cab3e7 Michael Hanselmann
    # Some HTTP/1.0 implementations have support for persistent connections,
834 02cab3e7 Michael Hanselmann
    # using rules different than HTTP/1.1.
835 02cab3e7 Michael Hanselmann
836 02cab3e7 Michael Hanselmann
    # For older HTTP, Keep-Alive indicates persistent connection.
837 02cab3e7 Michael Hanselmann
    if self.msg.headers.get(HTTP_KEEP_ALIVE):
838 02cab3e7 Michael Hanselmann
      return False
839 02cab3e7 Michael Hanselmann
840 02cab3e7 Michael Hanselmann
    # At least Akamai returns a "Connection: Keep-Alive" header, which was
841 02cab3e7 Michael Hanselmann
    # supposed to be sent by the client.
842 02cab3e7 Michael Hanselmann
    if hdr_connection and "keep-alive" in hdr_connection:
843 02cab3e7 Michael Hanselmann
      return False
844 02cab3e7 Michael Hanselmann
845 02cab3e7 Michael Hanselmann
    return True
846 02cab3e7 Michael Hanselmann
847 02cab3e7 Michael Hanselmann
  def _ParseHeaders(self):
848 02cab3e7 Michael Hanselmann
    """Parses the headers.
849 02cab3e7 Michael Hanselmann

850 02cab3e7 Michael Hanselmann
    This function also adjusts internal variables based on header values.
851 02cab3e7 Michael Hanselmann

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

856 02cab3e7 Michael Hanselmann
    """
857 02cab3e7 Michael Hanselmann
    # Parse headers
858 02cab3e7 Michael Hanselmann
    self.header_buffer.seek(0, 0)
859 02cab3e7 Michael Hanselmann
    self.msg.headers = mimetools.Message(self.header_buffer, 0)
860 02cab3e7 Michael Hanselmann
861 02cab3e7 Michael Hanselmann
    self.peer_will_close = self._WillPeerCloseConnection()
862 02cab3e7 Michael Hanselmann
863 02cab3e7 Michael Hanselmann
    # Do we have a Content-Length header?
864 02cab3e7 Michael Hanselmann
    hdr_content_length = self.msg.headers.get(HTTP_CONTENT_LENGTH, None)
865 02cab3e7 Michael Hanselmann
    if hdr_content_length:
866 02cab3e7 Michael Hanselmann
      try:
867 02cab3e7 Michael Hanselmann
        self.content_length = int(hdr_content_length)
868 02cab3e7 Michael Hanselmann
      except ValueError:
869 02cab3e7 Michael Hanselmann
        self.content_length = None
870 02cab3e7 Michael Hanselmann
      if self.content_length is not None and self.content_length < 0:
871 02cab3e7 Michael Hanselmann
        self.content_length = None
872 02cab3e7 Michael Hanselmann
873 02cab3e7 Michael Hanselmann
    # if the connection remains open and a content-length was not provided,
874 02cab3e7 Michael Hanselmann
    # then assume that the connection WILL close.
875 02cab3e7 Michael Hanselmann
    if self.content_length is None:
876 02cab3e7 Michael Hanselmann
      self.peer_will_close = True