Statistics
| Branch: | Tag: | Revision:

root / lib / http / __init__.py @ f8bd7df3

History | View | Annotate | Download (26.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 b3660886 Michael Hanselmann
HTTP_WWW_AUTHENTICATE = "WWW-Authenticate"
65 b3660886 Michael Hanselmann
HTTP_AUTHORIZATION = "Authorization"
66 b3660886 Michael Hanselmann
HTTP_AUTHENTICATION_INFO = "Authentication-Info"
67 b3660886 Michael Hanselmann
HTTP_ALLOW = "Allow"
68 42242313 Michael Hanselmann
69 d7bace1b Michael Hanselmann
_SSL_UNEXPECTED_EOF = "Unexpected EOF"
70 d7bace1b Michael Hanselmann
71 73a59d9e Michael Hanselmann
# Socket operations
72 73a59d9e Michael Hanselmann
(SOCKOP_SEND,
73 73a59d9e Michael Hanselmann
 SOCKOP_RECV,
74 d7fa9982 Michael Hanselmann
 SOCKOP_SHUTDOWN,
75 d7fa9982 Michael Hanselmann
 SOCKOP_HANDSHAKE) = range(4)
76 73a59d9e Michael Hanselmann
77 b18dd019 Iustin Pop
# send/receive quantum
78 b18dd019 Iustin Pop
SOCK_BUF_SIZE = 32768
79 42242313 Michael Hanselmann
80 13b63666 Michael Hanselmann
81 02cab3e7 Michael Hanselmann
class HttpError(Exception):
82 02cab3e7 Michael Hanselmann
  """Internal exception for HTTP errors.
83 02cab3e7 Michael Hanselmann

84 02cab3e7 Michael Hanselmann
  This should only be used for internal error reporting.
85 02cab3e7 Michael Hanselmann

86 02cab3e7 Michael Hanselmann
  """
87 02cab3e7 Michael Hanselmann
88 02cab3e7 Michael Hanselmann
89 39cfc25b Michael Hanselmann
class HttpConnectionClosed(Exception):
90 39cfc25b Michael Hanselmann
  """Internal exception for a closed connection.
91 39cfc25b Michael Hanselmann

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

95 39cfc25b Michael Hanselmann
  """
96 39cfc25b Michael Hanselmann
97 39cfc25b Michael Hanselmann
98 d7fa9982 Michael Hanselmann
class HttpSessionHandshakeUnexpectedEOF(HttpError):
99 d7fa9982 Michael Hanselmann
  """Internal exception for errors during SSL handshake.
100 d7fa9982 Michael Hanselmann

101 d7fa9982 Michael Hanselmann
  This should only be used for internal error reporting.
102 d7fa9982 Michael Hanselmann

103 d7fa9982 Michael Hanselmann
  """
104 d7fa9982 Michael Hanselmann
105 d7fa9982 Michael Hanselmann
106 c9d0fa8a Michael Hanselmann
class HttpSocketTimeout(Exception):
107 73a59d9e Michael Hanselmann
  """Internal exception for socket timeouts.
108 73a59d9e Michael Hanselmann

109 73a59d9e Michael Hanselmann
  This should only be used for internal error reporting.
110 73a59d9e Michael Hanselmann

111 73a59d9e Michael Hanselmann
  """
112 8a0b06d2 Michael Hanselmann
113 8a0b06d2 Michael Hanselmann
114 84f2756e Michael Hanselmann
class HttpException(Exception):
115 a43f68dc Michael Hanselmann
  code = None
116 a43f68dc Michael Hanselmann
  message = None
117 a43f68dc Michael Hanselmann
118 a8e01e9f Michael Hanselmann
  def __init__(self, message=None, headers=None):
119 42242313 Michael Hanselmann
    Exception.__init__(self)
120 a8e01e9f Michael Hanselmann
    self.message = message
121 a8e01e9f Michael Hanselmann
    self.headers = headers
122 a43f68dc Michael Hanselmann
123 a43f68dc Michael Hanselmann
124 84f2756e Michael Hanselmann
class HttpBadRequest(HttpException):
125 b3660886 Michael Hanselmann
  """400 Bad Request
126 b3660886 Michael Hanselmann

127 b3660886 Michael Hanselmann
  RFC2616, 10.4.1: The request could not be understood by the server due to
128 b3660886 Michael Hanselmann
  malformed syntax. The client SHOULD NOT repeat the request without
129 b3660886 Michael Hanselmann
  modifications.
130 b3660886 Michael Hanselmann

131 b3660886 Michael Hanselmann
  """
132 a43f68dc Michael Hanselmann
  code = 400
133 a43f68dc Michael Hanselmann
134 a43f68dc Michael Hanselmann
135 b3660886 Michael Hanselmann
class HttpUnauthorized(HttpException):
136 b3660886 Michael Hanselmann
  """401 Unauthorized
137 b3660886 Michael Hanselmann

138 b3660886 Michael Hanselmann
  RFC2616, section 10.4.2: The request requires user authentication. The
139 b3660886 Michael Hanselmann
  response MUST include a WWW-Authenticate header field (section 14.47)
140 b3660886 Michael Hanselmann
  containing a challenge applicable to the requested resource.
141 b3660886 Michael Hanselmann

142 b3660886 Michael Hanselmann
  """
143 b3660886 Michael Hanselmann
  code = 401
144 b3660886 Michael Hanselmann
145 b3660886 Michael Hanselmann
146 84f2756e Michael Hanselmann
class HttpForbidden(HttpException):
147 b3660886 Michael Hanselmann
  """403 Forbidden
148 b3660886 Michael Hanselmann

149 b3660886 Michael Hanselmann
  RFC2616, 10.4.4: The server understood the request, but is refusing to
150 b3660886 Michael Hanselmann
  fulfill it.  Authorization will not help and the request SHOULD NOT be
151 b3660886 Michael Hanselmann
  repeated.
152 b3660886 Michael Hanselmann

153 b3660886 Michael Hanselmann
  """
154 a43f68dc Michael Hanselmann
  code = 403
155 a43f68dc Michael Hanselmann
156 a43f68dc Michael Hanselmann
157 84f2756e Michael Hanselmann
class HttpNotFound(HttpException):
158 b3660886 Michael Hanselmann
  """404 Not Found
159 b3660886 Michael Hanselmann

160 b3660886 Michael Hanselmann
  RFC2616, 10.4.5: The server has not found anything matching the Request-URI.
161 b3660886 Michael Hanselmann
  No indication is given of whether the condition is temporary or permanent.
162 b3660886 Michael Hanselmann

163 b3660886 Michael Hanselmann
  """
164 a43f68dc Michael Hanselmann
  code = 404
165 a43f68dc Michael Hanselmann
166 a43f68dc Michael Hanselmann
167 b3660886 Michael Hanselmann
class HttpMethodNotAllowed(HttpException):
168 b3660886 Michael Hanselmann
  """405 Method Not Allowed
169 b3660886 Michael Hanselmann

170 b3660886 Michael Hanselmann
  RFC2616, 10.4.6: The method specified in the Request-Line is not allowed for
171 b3660886 Michael Hanselmann
  the resource identified by the Request-URI. The response MUST include an
172 b3660886 Michael Hanselmann
  Allow header containing a list of valid methods for the requested resource.
173 b3660886 Michael Hanselmann

174 b3660886 Michael Hanselmann
  """
175 b3660886 Michael Hanselmann
  code = 405
176 b3660886 Michael Hanselmann
177 b3660886 Michael Hanselmann
178 b3660886 Michael Hanselmann
class HttpRequestTimeout(HttpException):
179 b3660886 Michael Hanselmann
  """408 Request Timeout
180 b3660886 Michael Hanselmann

181 b3660886 Michael Hanselmann
  RFC2616, 10.4.9: The client did not produce a request within the time that
182 b3660886 Michael Hanselmann
  the server was prepared to wait. The client MAY repeat the request without
183 b3660886 Michael Hanselmann
  modifications at any later time.
184 b3660886 Michael Hanselmann

185 b3660886 Michael Hanselmann
  """
186 b3660886 Michael Hanselmann
  code = 408
187 b3660886 Michael Hanselmann
188 b3660886 Michael Hanselmann
189 b3660886 Michael Hanselmann
class HttpConflict(HttpException):
190 b3660886 Michael Hanselmann
  """409 Conflict
191 b3660886 Michael Hanselmann

192 b3660886 Michael Hanselmann
  RFC2616, 10.4.10: The request could not be completed due to a conflict with
193 b3660886 Michael Hanselmann
  the current state of the resource. This code is only allowed in situations
194 b3660886 Michael Hanselmann
  where it is expected that the user might be able to resolve the conflict and
195 b3660886 Michael Hanselmann
  resubmit the request.
196 b3660886 Michael Hanselmann

197 b3660886 Michael Hanselmann
  """
198 b3660886 Michael Hanselmann
  code = 409
199 b3660886 Michael Hanselmann
200 b3660886 Michael Hanselmann
201 84f2756e Michael Hanselmann
class HttpGone(HttpException):
202 b3660886 Michael Hanselmann
  """410 Gone
203 b3660886 Michael Hanselmann

204 b3660886 Michael Hanselmann
  RFC2616, 10.4.11: The requested resource is no longer available at the server
205 b3660886 Michael Hanselmann
  and no forwarding address is known. This condition is expected to be
206 b3660886 Michael Hanselmann
  considered permanent.
207 b3660886 Michael Hanselmann

208 b3660886 Michael Hanselmann
  """
209 a43f68dc Michael Hanselmann
  code = 410
210 a43f68dc Michael Hanselmann
211 a43f68dc Michael Hanselmann
212 84f2756e Michael Hanselmann
class HttpLengthRequired(HttpException):
213 b3660886 Michael Hanselmann
  """411 Length Required
214 b3660886 Michael Hanselmann

215 b3660886 Michael Hanselmann
  RFC2616, 10.4.12: The server refuses to accept the request without a defined
216 b3660886 Michael Hanselmann
  Content-Length. The client MAY repeat the request if it adds a valid
217 b3660886 Michael Hanselmann
  Content-Length header field containing the length of the message-body in the
218 b3660886 Michael Hanselmann
  request message.
219 b3660886 Michael Hanselmann

220 b3660886 Michael Hanselmann
  """
221 a43f68dc Michael Hanselmann
  code = 411
222 a43f68dc Michael Hanselmann
223 a43f68dc Michael Hanselmann
224 b3660886 Michael Hanselmann
class HttpPreconditionFailed(HttpException):
225 b3660886 Michael Hanselmann
  """412 Precondition Failed
226 b3660886 Michael Hanselmann

227 b3660886 Michael Hanselmann
  RFC2616, 10.4.13: The precondition given in one or more of the request-header
228 b3660886 Michael Hanselmann
  fields evaluated to false when it was tested on the server.
229 b3660886 Michael Hanselmann

230 b3660886 Michael Hanselmann
  """
231 b3660886 Michael Hanselmann
  code = 412
232 b3660886 Michael Hanselmann
233 b3660886 Michael Hanselmann
234 79589f25 Michael Hanselmann
class HttpInternalServerError(HttpException):
235 b3660886 Michael Hanselmann
  """500 Internal Server Error
236 b3660886 Michael Hanselmann

237 b3660886 Michael Hanselmann
  RFC2616, 10.5.1: The server encountered an unexpected condition which
238 b3660886 Michael Hanselmann
  prevented it from fulfilling the request.
239 b3660886 Michael Hanselmann

240 b3660886 Michael Hanselmann
  """
241 a43f68dc Michael Hanselmann
  code = 500
242 a43f68dc Michael Hanselmann
243 a43f68dc Michael Hanselmann
244 84f2756e Michael Hanselmann
class HttpNotImplemented(HttpException):
245 b3660886 Michael Hanselmann
  """501 Not Implemented
246 b3660886 Michael Hanselmann

247 b3660886 Michael Hanselmann
  RFC2616, 10.5.2: The server does not support the functionality required to
248 b3660886 Michael Hanselmann
  fulfill the request.
249 b3660886 Michael Hanselmann

250 b3660886 Michael Hanselmann
  """
251 a43f68dc Michael Hanselmann
  code = 501
252 a43f68dc Michael Hanselmann
253 a43f68dc Michael Hanselmann
254 84f2756e Michael Hanselmann
class HttpServiceUnavailable(HttpException):
255 b3660886 Michael Hanselmann
  """503 Service Unavailable
256 b3660886 Michael Hanselmann

257 b3660886 Michael Hanselmann
  RFC2616, 10.5.4: The server is currently unable to handle the request due to
258 b3660886 Michael Hanselmann
  a temporary overloading or maintenance of the server.
259 b3660886 Michael Hanselmann

260 b3660886 Michael Hanselmann
  """
261 a43f68dc Michael Hanselmann
  code = 503
262 a43f68dc Michael Hanselmann
263 a43f68dc Michael Hanselmann
264 84f2756e Michael Hanselmann
class HttpVersionNotSupported(HttpException):
265 b3660886 Michael Hanselmann
  """505 HTTP Version Not Supported
266 b3660886 Michael Hanselmann

267 b3660886 Michael Hanselmann
  RFC2616, 10.5.6: The server does not support, or refuses to support, the HTTP
268 b3660886 Michael Hanselmann
  protocol version that was used in the request message.
269 b3660886 Michael Hanselmann

270 b3660886 Michael Hanselmann
  """
271 42242313 Michael Hanselmann
  code = 505
272 42242313 Michael Hanselmann
273 42242313 Michael Hanselmann
274 84f2756e Michael Hanselmann
class HttpJsonConverter:
275 a43f68dc Michael Hanselmann
  CONTENT_TYPE = "application/json"
276 a43f68dc Michael Hanselmann
277 a43f68dc Michael Hanselmann
  def Encode(self, data):
278 a43f68dc Michael Hanselmann
    return serializer.DumpJson(data)
279 a43f68dc Michael Hanselmann
280 a43f68dc Michael Hanselmann
  def Decode(self, data):
281 a43f68dc Michael Hanselmann
    return serializer.LoadJson(data)
282 a43f68dc Michael Hanselmann
283 a43f68dc Michael Hanselmann
284 aea0ed67 Michael Hanselmann
def WaitForSocketCondition(sock, event, timeout):
285 f22c1cea Michael Hanselmann
  """Waits for a condition to occur on the socket.
286 f22c1cea Michael Hanselmann

287 73a59d9e Michael Hanselmann
  @type sock: socket
288 358a8811 Michael Hanselmann
  @param sock: Wait for events on this socket
289 f22c1cea Michael Hanselmann
  @type event: int
290 f22c1cea Michael Hanselmann
  @param event: ORed condition (see select module)
291 f22c1cea Michael Hanselmann
  @type timeout: float or None
292 f22c1cea Michael Hanselmann
  @param timeout: Timeout in seconds
293 f22c1cea Michael Hanselmann
  @rtype: int or None
294 f22c1cea Michael Hanselmann
  @return: None for timeout, otherwise occured conditions
295 f22c1cea Michael Hanselmann

296 f22c1cea Michael Hanselmann
  """
297 f22c1cea Michael Hanselmann
  check = (event | select.POLLPRI |
298 f22c1cea Michael Hanselmann
           select.POLLNVAL | select.POLLHUP | select.POLLERR)
299 f22c1cea Michael Hanselmann
300 f22c1cea Michael Hanselmann
  if timeout is not None:
301 f22c1cea Michael Hanselmann
    # Poller object expects milliseconds
302 f22c1cea Michael Hanselmann
    timeout *= 1000
303 f22c1cea Michael Hanselmann
304 aea0ed67 Michael Hanselmann
  poller = select.poll()
305 f22c1cea Michael Hanselmann
  poller.register(sock, event)
306 f22c1cea Michael Hanselmann
  try:
307 f22c1cea Michael Hanselmann
    while True:
308 f22c1cea Michael Hanselmann
      # TODO: If the main thread receives a signal and we have no timeout, we
309 f22c1cea Michael Hanselmann
      # could wait forever. This should check a global "quit" flag or
310 f22c1cea Michael Hanselmann
      # something every so often.
311 f22c1cea Michael Hanselmann
      io_events = poller.poll(timeout)
312 f22c1cea Michael Hanselmann
      if not io_events:
313 f22c1cea Michael Hanselmann
        # Timeout
314 f22c1cea Michael Hanselmann
        return None
315 f22c1cea Michael Hanselmann
      for (evfd, evcond) in io_events:
316 f22c1cea Michael Hanselmann
        if evcond & check:
317 f22c1cea Michael Hanselmann
          return evcond
318 f22c1cea Michael Hanselmann
  finally:
319 f22c1cea Michael Hanselmann
    poller.unregister(sock)
320 f22c1cea Michael Hanselmann
321 f22c1cea Michael Hanselmann
322 aea0ed67 Michael Hanselmann
def SocketOperation(sock, op, arg1, timeout):
323 73a59d9e Michael Hanselmann
  """Wrapper around socket functions.
324 73a59d9e Michael Hanselmann

325 73a59d9e Michael Hanselmann
  This function abstracts error handling for socket operations, especially
326 73a59d9e Michael Hanselmann
  for the complicated interaction with OpenSSL.
327 73a59d9e Michael Hanselmann

328 73a59d9e Michael Hanselmann
  @type sock: socket
329 358a8811 Michael Hanselmann
  @param sock: Socket for the operation
330 73a59d9e Michael Hanselmann
  @type op: int
331 73a59d9e Michael Hanselmann
  @param op: Operation to execute (SOCKOP_* constants)
332 73a59d9e Michael Hanselmann
  @type arg1: any
333 73a59d9e Michael Hanselmann
  @param arg1: Parameter for function (if needed)
334 73a59d9e Michael Hanselmann
  @type timeout: None or float
335 73a59d9e Michael Hanselmann
  @param timeout: Timeout in seconds or None
336 358a8811 Michael Hanselmann
  @return: Return value of socket function
337 73a59d9e Michael Hanselmann

338 73a59d9e Michael Hanselmann
  """
339 73a59d9e Michael Hanselmann
  # TODO: event_poll/event_check/override
340 d7fa9982 Michael Hanselmann
  if op in (SOCKOP_SEND, SOCKOP_HANDSHAKE):
341 73a59d9e Michael Hanselmann
    event_poll = select.POLLOUT
342 73a59d9e Michael Hanselmann
    event_check = select.POLLOUT
343 73a59d9e Michael Hanselmann
344 73a59d9e Michael Hanselmann
  elif op == SOCKOP_RECV:
345 73a59d9e Michael Hanselmann
    event_poll = select.POLLIN
346 73a59d9e Michael Hanselmann
    event_check = select.POLLIN | select.POLLPRI
347 73a59d9e Michael Hanselmann
348 73a59d9e Michael Hanselmann
  elif op == SOCKOP_SHUTDOWN:
349 73a59d9e Michael Hanselmann
    event_poll = None
350 73a59d9e Michael Hanselmann
    event_check = None
351 73a59d9e Michael Hanselmann
352 73a59d9e Michael Hanselmann
    # The timeout is only used when OpenSSL requests polling for a condition.
353 73a59d9e Michael Hanselmann
    # It is not advisable to have no timeout for shutdown.
354 73a59d9e Michael Hanselmann
    assert timeout
355 73a59d9e Michael Hanselmann
356 73a59d9e Michael Hanselmann
  else:
357 73a59d9e Michael Hanselmann
    raise AssertionError("Invalid socket operation")
358 73a59d9e Michael Hanselmann
359 d7fa9982 Michael Hanselmann
  # Handshake is only supported by SSL sockets
360 d7fa9982 Michael Hanselmann
  if (op == SOCKOP_HANDSHAKE and
361 d7fa9982 Michael Hanselmann
      not isinstance(sock, OpenSSL.SSL.ConnectionType)):
362 d7fa9982 Michael Hanselmann
    return
363 d7fa9982 Michael Hanselmann
364 73a59d9e Michael Hanselmann
  # No override by default
365 73a59d9e Michael Hanselmann
  event_override = 0
366 73a59d9e Michael Hanselmann
367 73a59d9e Michael Hanselmann
  while True:
368 73a59d9e Michael Hanselmann
    # Poll only for certain operations and when asked for by an override
369 d7fa9982 Michael Hanselmann
    if event_override or op in (SOCKOP_SEND, SOCKOP_RECV, SOCKOP_HANDSHAKE):
370 73a59d9e Michael Hanselmann
      if event_override:
371 73a59d9e Michael Hanselmann
        wait_for_event = event_override
372 73a59d9e Michael Hanselmann
      else:
373 73a59d9e Michael Hanselmann
        wait_for_event = event_poll
374 73a59d9e Michael Hanselmann
375 aea0ed67 Michael Hanselmann
      event = WaitForSocketCondition(sock, wait_for_event, timeout)
376 73a59d9e Michael Hanselmann
      if event is None:
377 c9d0fa8a Michael Hanselmann
        raise HttpSocketTimeout()
378 73a59d9e Michael Hanselmann
379 73a59d9e Michael Hanselmann
      if (op == SOCKOP_RECV and
380 73a59d9e Michael Hanselmann
          event & (select.POLLNVAL | select.POLLHUP | select.POLLERR)):
381 73a59d9e Michael Hanselmann
        return ""
382 73a59d9e Michael Hanselmann
383 73a59d9e Michael Hanselmann
      if not event & wait_for_event:
384 73a59d9e Michael Hanselmann
        continue
385 73a59d9e Michael Hanselmann
386 73a59d9e Michael Hanselmann
    # Reset override
387 73a59d9e Michael Hanselmann
    event_override = 0
388 73a59d9e Michael Hanselmann
389 73a59d9e Michael Hanselmann
    try:
390 73a59d9e Michael Hanselmann
      try:
391 73a59d9e Michael Hanselmann
        if op == SOCKOP_SEND:
392 73a59d9e Michael Hanselmann
          return sock.send(arg1)
393 73a59d9e Michael Hanselmann
394 73a59d9e Michael Hanselmann
        elif op == SOCKOP_RECV:
395 73a59d9e Michael Hanselmann
          return sock.recv(arg1)
396 73a59d9e Michael Hanselmann
397 73a59d9e Michael Hanselmann
        elif op == SOCKOP_SHUTDOWN:
398 73a59d9e Michael Hanselmann
          if isinstance(sock, OpenSSL.SSL.ConnectionType):
399 73a59d9e Michael Hanselmann
            # PyOpenSSL's shutdown() doesn't take arguments
400 73a59d9e Michael Hanselmann
            return sock.shutdown()
401 73a59d9e Michael Hanselmann
          else:
402 73a59d9e Michael Hanselmann
            return sock.shutdown(arg1)
403 73a59d9e Michael Hanselmann
404 d7fa9982 Michael Hanselmann
        elif op == SOCKOP_HANDSHAKE:
405 d7fa9982 Michael Hanselmann
          return sock.do_handshake()
406 d7fa9982 Michael Hanselmann
407 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantWriteError:
408 73a59d9e Michael Hanselmann
        # OpenSSL wants to write, poll for POLLOUT
409 73a59d9e Michael Hanselmann
        event_override = select.POLLOUT
410 73a59d9e Michael Hanselmann
        continue
411 73a59d9e Michael Hanselmann
412 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantReadError:
413 73a59d9e Michael Hanselmann
        # OpenSSL wants to read, poll for POLLIN
414 73a59d9e Michael Hanselmann
        event_override = select.POLLIN | select.POLLPRI
415 73a59d9e Michael Hanselmann
        continue
416 73a59d9e Michael Hanselmann
417 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.WantX509LookupError:
418 73a59d9e Michael Hanselmann
        continue
419 73a59d9e Michael Hanselmann
420 39cfc25b Michael Hanselmann
      except OpenSSL.SSL.ZeroReturnError, err:
421 39cfc25b Michael Hanselmann
        # SSL Connection has been closed. In SSL 3.0 and TLS 1.0, this only
422 39cfc25b Michael Hanselmann
        # occurs if a closure alert has occurred in the protocol, i.e. the
423 39cfc25b Michael Hanselmann
        # connection has been closed cleanly. Note that this does not
424 39cfc25b Michael Hanselmann
        # necessarily mean that the transport layer (e.g. a socket) has been
425 39cfc25b Michael Hanselmann
        # closed.
426 39cfc25b Michael Hanselmann
        if op == SOCKOP_SEND:
427 39cfc25b Michael Hanselmann
          # Can happen during a renegotiation
428 39cfc25b Michael Hanselmann
          raise HttpConnectionClosed(err.args)
429 39cfc25b Michael Hanselmann
        elif op == SOCKOP_RECV:
430 39cfc25b Michael Hanselmann
          return ""
431 39cfc25b Michael Hanselmann
432 39cfc25b Michael Hanselmann
        # SSL_shutdown shouldn't return SSL_ERROR_ZERO_RETURN
433 39cfc25b Michael Hanselmann
        raise socket.error(err.args)
434 39cfc25b Michael Hanselmann
435 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.SysCallError, err:
436 73a59d9e Michael Hanselmann
        if op == SOCKOP_SEND:
437 73a59d9e Michael Hanselmann
          # arg1 is the data when writing
438 73a59d9e Michael Hanselmann
          if err.args and err.args[0] == -1 and arg1 == "":
439 73a59d9e Michael Hanselmann
            # errors when writing empty strings are expected
440 73a59d9e Michael Hanselmann
            # and can be ignored
441 73a59d9e Michael Hanselmann
            return 0
442 73a59d9e Michael Hanselmann
443 d7fa9982 Michael Hanselmann
        if err.args == (-1, _SSL_UNEXPECTED_EOF):
444 d7fa9982 Michael Hanselmann
          if op == SOCKOP_RECV:
445 73a59d9e Michael Hanselmann
            return ""
446 d7fa9982 Michael Hanselmann
          elif op == SOCKOP_HANDSHAKE:
447 d7fa9982 Michael Hanselmann
            # Can happen if peer disconnects directly after the connection is
448 d7fa9982 Michael Hanselmann
            # opened.
449 d7fa9982 Michael Hanselmann
            raise HttpSessionHandshakeUnexpectedEOF(err.args)
450 73a59d9e Michael Hanselmann
451 73a59d9e Michael Hanselmann
        raise socket.error(err.args)
452 73a59d9e Michael Hanselmann
453 73a59d9e Michael Hanselmann
      except OpenSSL.SSL.Error, err:
454 73a59d9e Michael Hanselmann
        raise socket.error(err.args)
455 73a59d9e Michael Hanselmann
456 73a59d9e Michael Hanselmann
    except socket.error, err:
457 73a59d9e Michael Hanselmann
      if err.args and err.args[0] == errno.EAGAIN:
458 73a59d9e Michael Hanselmann
        # Ignore EAGAIN
459 73a59d9e Michael Hanselmann
        continue
460 73a59d9e Michael Hanselmann
461 73a59d9e Michael Hanselmann
      raise
462 73a59d9e Michael Hanselmann
463 73a59d9e Michael Hanselmann
464 aea0ed67 Michael Hanselmann
def ShutdownConnection(sock, close_timeout, write_timeout, msgreader, force):
465 02cab3e7 Michael Hanselmann
  """Closes the connection.
466 02cab3e7 Michael Hanselmann

467 358a8811 Michael Hanselmann
  @type sock: socket
468 358a8811 Michael Hanselmann
  @param sock: Socket to be shut down
469 358a8811 Michael Hanselmann
  @type close_timeout: float
470 358a8811 Michael Hanselmann
  @param close_timeout: How long to wait for the peer to close the connection
471 358a8811 Michael Hanselmann
  @type write_timeout: float
472 358a8811 Michael Hanselmann
  @param write_timeout: Write timeout for shutdown
473 358a8811 Michael Hanselmann
  @type msgreader: http.HttpMessageReader
474 358a8811 Michael Hanselmann
  @param msgreader: Request message reader, used to determine whether peer
475 358a8811 Michael Hanselmann
                    should close connection
476 358a8811 Michael Hanselmann
  @type force: bool
477 358a8811 Michael Hanselmann
  @param force: Whether to forcibly close the connection without waiting
478 358a8811 Michael Hanselmann
                for peer
479 358a8811 Michael Hanselmann

480 02cab3e7 Michael Hanselmann
  """
481 02cab3e7 Michael Hanselmann
  #print msgreader.peer_will_close, force
482 02cab3e7 Michael Hanselmann
  if msgreader and msgreader.peer_will_close and not force:
483 02cab3e7 Michael Hanselmann
    # Wait for peer to close
484 02cab3e7 Michael Hanselmann
    try:
485 02cab3e7 Michael Hanselmann
      # Check whether it's actually closed
486 aea0ed67 Michael Hanselmann
      if not SocketOperation(sock, SOCKOP_RECV, 1, close_timeout):
487 02cab3e7 Michael Hanselmann
        return
488 02cab3e7 Michael Hanselmann
    except (socket.error, HttpError, HttpSocketTimeout):
489 02cab3e7 Michael Hanselmann
      # Ignore errors at this stage
490 02cab3e7 Michael Hanselmann
      pass
491 02cab3e7 Michael Hanselmann
492 02cab3e7 Michael Hanselmann
  # Close the connection from our side
493 02cab3e7 Michael Hanselmann
  try:
494 39cfc25b Michael Hanselmann
    # We don't care about the return value, see NOTES in SSL_shutdown(3).
495 aea0ed67 Michael Hanselmann
    SocketOperation(sock, SOCKOP_SHUTDOWN, socket.SHUT_RDWR,
496 02cab3e7 Michael Hanselmann
                    write_timeout)
497 02cab3e7 Michael Hanselmann
  except HttpSocketTimeout:
498 02cab3e7 Michael Hanselmann
    raise HttpError("Timeout while shutting down connection")
499 02cab3e7 Michael Hanselmann
  except socket.error, err:
500 45eac583 Michael Hanselmann
    # Ignore ENOTCONN
501 45eac583 Michael Hanselmann
    if not (err.args and err.args[0] == errno.ENOTCONN):
502 45eac583 Michael Hanselmann
      raise HttpError("Error while shutting down connection: %s" % err)
503 02cab3e7 Michael Hanselmann
504 02cab3e7 Michael Hanselmann
505 aea0ed67 Michael Hanselmann
def Handshake(sock, write_timeout):
506 d7fa9982 Michael Hanselmann
  """Shakes peer's hands.
507 d7fa9982 Michael Hanselmann

508 d7fa9982 Michael Hanselmann
  @type sock: socket
509 d7fa9982 Michael Hanselmann
  @param sock: Socket to be shut down
510 d7fa9982 Michael Hanselmann
  @type write_timeout: float
511 d7fa9982 Michael Hanselmann
  @param write_timeout: Write timeout for handshake
512 d7fa9982 Michael Hanselmann

513 d7fa9982 Michael Hanselmann
  """
514 d7fa9982 Michael Hanselmann
  try:
515 aea0ed67 Michael Hanselmann
    return SocketOperation(sock, SOCKOP_HANDSHAKE, None, write_timeout)
516 d7fa9982 Michael Hanselmann
  except HttpSocketTimeout:
517 d7fa9982 Michael Hanselmann
    raise HttpError("Timeout during SSL handshake")
518 d7fa9982 Michael Hanselmann
  except socket.error, err:
519 d7fa9982 Michael Hanselmann
    raise HttpError("Error in SSL handshake: %s" % err)
520 d7fa9982 Michael Hanselmann
521 d7fa9982 Michael Hanselmann
522 f20cbea2 Michael Hanselmann
class HttpSslParams(object):
523 f20cbea2 Michael Hanselmann
  """Data class for SSL key and certificate.
524 f20cbea2 Michael Hanselmann

525 f20cbea2 Michael Hanselmann
  """
526 f20cbea2 Michael Hanselmann
  def __init__(self, ssl_key_path, ssl_cert_path):
527 f20cbea2 Michael Hanselmann
    """Initializes this class.
528 f20cbea2 Michael Hanselmann

529 f20cbea2 Michael Hanselmann
    @type ssl_key_path: string
530 f20cbea2 Michael Hanselmann
    @param ssl_key_path: Path to file containing SSL key in PEM format
531 f20cbea2 Michael Hanselmann
    @type ssl_cert_path: string
532 f20cbea2 Michael Hanselmann
    @param ssl_cert_path: Path to file containing SSL certificate in PEM format
533 f20cbea2 Michael Hanselmann

534 f20cbea2 Michael Hanselmann
    """
535 65c6b8e0 Michael Hanselmann
    self.ssl_key_pem = utils.ReadFile(ssl_key_path)
536 65c6b8e0 Michael Hanselmann
    self.ssl_cert_pem = utils.ReadFile(ssl_cert_path)
537 f20cbea2 Michael Hanselmann
538 65c6b8e0 Michael Hanselmann
  def GetKey(self):
539 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
540 65c6b8e0 Michael Hanselmann
                                          self.ssl_key_pem)
541 65c6b8e0 Michael Hanselmann
542 65c6b8e0 Michael Hanselmann
  def GetCertificate(self):
543 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
544 65c6b8e0 Michael Hanselmann
                                           self.ssl_cert_pem)
545 f20cbea2 Michael Hanselmann
546 f20cbea2 Michael Hanselmann
547 f4322a1e Michael Hanselmann
class HttpBase(object):
548 b14f759e Michael Hanselmann
  """Base class for HTTP server and client.
549 b14f759e Michael Hanselmann

550 b14f759e Michael Hanselmann
  """
551 b14f759e Michael Hanselmann
  def __init__(self):
552 22692e48 Michael Hanselmann
    self.using_ssl = None
553 f20cbea2 Michael Hanselmann
    self._ssl_params = None
554 65c6b8e0 Michael Hanselmann
    self._ssl_key = None
555 65c6b8e0 Michael Hanselmann
    self._ssl_cert = None
556 b14f759e Michael Hanselmann
557 f20cbea2 Michael Hanselmann
  def _CreateSocket(self, ssl_params, ssl_verify_peer):
558 b14f759e Michael Hanselmann
    """Creates a TCP socket and initializes SSL if needed.
559 b14f759e Michael Hanselmann

560 f20cbea2 Michael Hanselmann
    @type ssl_params: HttpSslParams
561 f20cbea2 Michael Hanselmann
    @param ssl_params: SSL key and certificate
562 b14f759e Michael Hanselmann
    @type ssl_verify_peer: bool
563 b14f759e Michael Hanselmann
    @param ssl_verify_peer: Whether to require client certificate and compare
564 b14f759e Michael Hanselmann
                            it with our certificate
565 b14f759e Michael Hanselmann

566 b14f759e Michael Hanselmann
    """
567 f20cbea2 Michael Hanselmann
    self._ssl_params = ssl_params
568 f20cbea2 Michael Hanselmann
569 b14f759e Michael Hanselmann
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
570 b14f759e Michael Hanselmann
571 b14f759e Michael Hanselmann
    # Should we enable SSL?
572 22692e48 Michael Hanselmann
    self.using_ssl = ssl_params is not None
573 b14f759e Michael Hanselmann
574 22692e48 Michael Hanselmann
    if not self.using_ssl:
575 b14f759e Michael Hanselmann
      return sock
576 b14f759e Michael Hanselmann
577 65c6b8e0 Michael Hanselmann
    self._ssl_key = ssl_params.GetKey()
578 65c6b8e0 Michael Hanselmann
    self._ssl_cert = ssl_params.GetCertificate()
579 65c6b8e0 Michael Hanselmann
580 b14f759e Michael Hanselmann
    ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
581 b14f759e Michael Hanselmann
    ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2)
582 b14f759e Michael Hanselmann
583 65c6b8e0 Michael Hanselmann
    ctx.use_privatekey(self._ssl_key)
584 65c6b8e0 Michael Hanselmann
    ctx.use_certificate(self._ssl_cert)
585 b14f759e Michael Hanselmann
    ctx.check_privatekey()
586 b14f759e Michael Hanselmann
587 b14f759e Michael Hanselmann
    if ssl_verify_peer:
588 b14f759e Michael Hanselmann
      ctx.set_verify(OpenSSL.SSL.VERIFY_PEER |
589 b14f759e Michael Hanselmann
                     OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
590 b14f759e Michael Hanselmann
                     self._SSLVerifyCallback)
591 b14f759e Michael Hanselmann
592 b14f759e Michael Hanselmann
    return OpenSSL.SSL.Connection(ctx, sock)
593 b14f759e Michael Hanselmann
594 b14f759e Michael Hanselmann
  def _SSLVerifyCallback(self, conn, cert, errnum, errdepth, ok):
595 b14f759e Michael Hanselmann
    """Verify the certificate provided by the peer
596 b14f759e Michael Hanselmann

597 b14f759e Michael Hanselmann
    We only compare fingerprints. The client must use the same certificate as
598 b14f759e Michael Hanselmann
    we do on our side.
599 b14f759e Michael Hanselmann

600 b14f759e Michael Hanselmann
    """
601 f20cbea2 Michael Hanselmann
    assert self._ssl_params, "SSL not initialized"
602 b14f759e Michael Hanselmann
603 65c6b8e0 Michael Hanselmann
    return (self._ssl_cert.digest("sha1") == cert.digest("sha1") and
604 65c6b8e0 Michael Hanselmann
            self._ssl_cert.digest("md5") == cert.digest("md5"))
605 b14f759e Michael Hanselmann
606 b14f759e Michael Hanselmann
607 02cab3e7 Michael Hanselmann
class HttpMessage(object):
608 02cab3e7 Michael Hanselmann
  """Data structure for HTTP message.
609 02cab3e7 Michael Hanselmann

610 02cab3e7 Michael Hanselmann
  """
611 02cab3e7 Michael Hanselmann
  def __init__(self):
612 02cab3e7 Michael Hanselmann
    self.start_line = None
613 02cab3e7 Michael Hanselmann
    self.headers = None
614 02cab3e7 Michael Hanselmann
    self.body = None
615 02cab3e7 Michael Hanselmann
    self.decoded_body = None
616 02cab3e7 Michael Hanselmann
617 02cab3e7 Michael Hanselmann
618 02cab3e7 Michael Hanselmann
class HttpClientToServerStartLine(object):
619 02cab3e7 Michael Hanselmann
  """Data structure for HTTP request start line.
620 02cab3e7 Michael Hanselmann

621 02cab3e7 Michael Hanselmann
  """
622 02cab3e7 Michael Hanselmann
  def __init__(self, method, path, version):
623 02cab3e7 Michael Hanselmann
    self.method = method
624 02cab3e7 Michael Hanselmann
    self.path = path
625 02cab3e7 Michael Hanselmann
    self.version = version
626 02cab3e7 Michael Hanselmann
627 02cab3e7 Michael Hanselmann
  def __str__(self):
628 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.method, self.path, self.version)
629 02cab3e7 Michael Hanselmann
630 02cab3e7 Michael Hanselmann
631 02cab3e7 Michael Hanselmann
class HttpServerToClientStartLine(object):
632 02cab3e7 Michael Hanselmann
  """Data structure for HTTP response start line.
633 02cab3e7 Michael Hanselmann

634 02cab3e7 Michael Hanselmann
  """
635 02cab3e7 Michael Hanselmann
  def __init__(self, version, code, reason):
636 02cab3e7 Michael Hanselmann
    self.version = version
637 02cab3e7 Michael Hanselmann
    self.code = code
638 02cab3e7 Michael Hanselmann
    self.reason = reason
639 02cab3e7 Michael Hanselmann
640 02cab3e7 Michael Hanselmann
  def __str__(self):
641 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.version, self.code, self.reason)
642 02cab3e7 Michael Hanselmann
643 02cab3e7 Michael Hanselmann
644 02cab3e7 Michael Hanselmann
class HttpMessageWriter(object):
645 02cab3e7 Michael Hanselmann
  """Writes an HTTP message to a socket.
646 02cab3e7 Michael Hanselmann

647 02cab3e7 Michael Hanselmann
  """
648 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, write_timeout):
649 358a8811 Michael Hanselmann
    """Initializes this class and writes an HTTP message to a socket.
650 358a8811 Michael Hanselmann

651 358a8811 Michael Hanselmann
    @type sock: socket
652 358a8811 Michael Hanselmann
    @param sock: Socket to be written to
653 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
654 358a8811 Michael Hanselmann
    @param msg: HTTP message to be written
655 358a8811 Michael Hanselmann
    @type write_timeout: float
656 358a8811 Michael Hanselmann
    @param write_timeout: Write timeout for socket
657 358a8811 Michael Hanselmann

658 358a8811 Michael Hanselmann
    """
659 02cab3e7 Michael Hanselmann
    self._msg = msg
660 02cab3e7 Michael Hanselmann
661 02cab3e7 Michael Hanselmann
    self._PrepareMessage()
662 02cab3e7 Michael Hanselmann
663 02cab3e7 Michael Hanselmann
    buf = self._FormatMessage()
664 02cab3e7 Michael Hanselmann
665 b18dd019 Iustin Pop
    pos = 0
666 b18dd019 Iustin Pop
    end = len(buf)
667 b18dd019 Iustin Pop
    while pos < end:
668 b18dd019 Iustin Pop
      # Send only SOCK_BUF_SIZE bytes at a time
669 358a8811 Michael Hanselmann
      data = buf[pos:(pos + SOCK_BUF_SIZE)]
670 02cab3e7 Michael Hanselmann
671 aea0ed67 Michael Hanselmann
      sent = SocketOperation(sock, SOCKOP_SEND, data, write_timeout)
672 02cab3e7 Michael Hanselmann
673 02cab3e7 Michael Hanselmann
      # Remove sent bytes
674 b18dd019 Iustin Pop
      pos += sent
675 02cab3e7 Michael Hanselmann
676 b18dd019 Iustin Pop
    assert pos == end, "Message wasn't sent completely"
677 02cab3e7 Michael Hanselmann
678 02cab3e7 Michael Hanselmann
  def _PrepareMessage(self):
679 02cab3e7 Michael Hanselmann
    """Prepares the HTTP message by setting mandatory headers.
680 02cab3e7 Michael Hanselmann

681 02cab3e7 Michael Hanselmann
    """
682 02cab3e7 Michael Hanselmann
    # RFC2616, section 4.3: "The presence of a message-body in a request is
683 02cab3e7 Michael Hanselmann
    # signaled by the inclusion of a Content-Length or Transfer-Encoding header
684 02cab3e7 Michael Hanselmann
    # field in the request's message-headers."
685 02cab3e7 Michael Hanselmann
    if self._msg.body:
686 02cab3e7 Michael Hanselmann
      self._msg.headers[HTTP_CONTENT_LENGTH] = len(self._msg.body)
687 02cab3e7 Michael Hanselmann
688 02cab3e7 Michael Hanselmann
  def _FormatMessage(self):
689 02cab3e7 Michael Hanselmann
    """Serializes the HTTP message into a string.
690 02cab3e7 Michael Hanselmann

691 02cab3e7 Michael Hanselmann
    """
692 02cab3e7 Michael Hanselmann
    buf = StringIO()
693 02cab3e7 Michael Hanselmann
694 02cab3e7 Michael Hanselmann
    # Add start line
695 02cab3e7 Michael Hanselmann
    buf.write(str(self._msg.start_line))
696 02cab3e7 Michael Hanselmann
    buf.write("\r\n")
697 02cab3e7 Michael Hanselmann
698 02cab3e7 Michael Hanselmann
    # Add headers
699 02cab3e7 Michael Hanselmann
    if self._msg.start_line.version != HTTP_0_9:
700 02cab3e7 Michael Hanselmann
      for name, value in self._msg.headers.iteritems():
701 02cab3e7 Michael Hanselmann
        buf.write("%s: %s\r\n" % (name, value))
702 02cab3e7 Michael Hanselmann
703 02cab3e7 Michael Hanselmann
    buf.write("\r\n")
704 02cab3e7 Michael Hanselmann
705 02cab3e7 Michael Hanselmann
    # Add message body if needed
706 02cab3e7 Michael Hanselmann
    if self.HasMessageBody():
707 02cab3e7 Michael Hanselmann
      buf.write(self._msg.body)
708 02cab3e7 Michael Hanselmann
709 02cab3e7 Michael Hanselmann
    elif self._msg.body:
710 02cab3e7 Michael Hanselmann
      logging.warning("Ignoring message body")
711 02cab3e7 Michael Hanselmann
712 02cab3e7 Michael Hanselmann
    return buf.getvalue()
713 02cab3e7 Michael Hanselmann
714 02cab3e7 Michael Hanselmann
  def HasMessageBody(self):
715 02cab3e7 Michael Hanselmann
    """Checks whether the HTTP message contains a body.
716 02cab3e7 Michael Hanselmann

717 02cab3e7 Michael Hanselmann
    Can be overriden by subclasses.
718 02cab3e7 Michael Hanselmann

719 02cab3e7 Michael Hanselmann
    """
720 02cab3e7 Michael Hanselmann
    return bool(self._msg.body)
721 02cab3e7 Michael Hanselmann
722 02cab3e7 Michael Hanselmann
723 02cab3e7 Michael Hanselmann
class HttpMessageReader(object):
724 02cab3e7 Michael Hanselmann
  """Reads HTTP message from socket.
725 02cab3e7 Michael Hanselmann

726 02cab3e7 Michael Hanselmann
  """
727 02cab3e7 Michael Hanselmann
  # Length limits
728 02cab3e7 Michael Hanselmann
  START_LINE_LENGTH_MAX = None
729 02cab3e7 Michael Hanselmann
  HEADER_LENGTH_MAX = None
730 02cab3e7 Michael Hanselmann
731 02cab3e7 Michael Hanselmann
  # Parser state machine
732 02cab3e7 Michael Hanselmann
  PS_START_LINE = "start-line"
733 02cab3e7 Michael Hanselmann
  PS_HEADERS = "headers"
734 02cab3e7 Michael Hanselmann
  PS_BODY = "entity-body"
735 02cab3e7 Michael Hanselmann
  PS_COMPLETE = "complete"
736 02cab3e7 Michael Hanselmann
737 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, read_timeout):
738 358a8811 Michael Hanselmann
    """Reads an HTTP message from a socket.
739 358a8811 Michael Hanselmann

740 358a8811 Michael Hanselmann
    @type sock: socket
741 358a8811 Michael Hanselmann
    @param sock: Socket to be read from
742 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
743 358a8811 Michael Hanselmann
    @param msg: Object for the read message
744 358a8811 Michael Hanselmann
    @type read_timeout: float
745 358a8811 Michael Hanselmann
    @param read_timeout: Read timeout for socket
746 358a8811 Michael Hanselmann

747 358a8811 Michael Hanselmann
    """
748 02cab3e7 Michael Hanselmann
    self.sock = sock
749 02cab3e7 Michael Hanselmann
    self.msg = msg
750 02cab3e7 Michael Hanselmann
751 02cab3e7 Michael Hanselmann
    self.start_line_buffer = None
752 02cab3e7 Michael Hanselmann
    self.header_buffer = StringIO()
753 02cab3e7 Michael Hanselmann
    self.body_buffer = StringIO()
754 02cab3e7 Michael Hanselmann
    self.parser_status = self.PS_START_LINE
755 02cab3e7 Michael Hanselmann
    self.content_length = None
756 02cab3e7 Michael Hanselmann
    self.peer_will_close = None
757 02cab3e7 Michael Hanselmann
758 02cab3e7 Michael Hanselmann
    buf = ""
759 02cab3e7 Michael Hanselmann
    eof = False
760 02cab3e7 Michael Hanselmann
    while self.parser_status != self.PS_COMPLETE:
761 f088165d Michael Hanselmann
      # TODO: Don't read more than necessary (Content-Length), otherwise
762 f088165d Michael Hanselmann
      # data might be lost and/or an error could occur
763 aea0ed67 Michael Hanselmann
      data = SocketOperation(sock, SOCKOP_RECV, SOCK_BUF_SIZE, read_timeout)
764 02cab3e7 Michael Hanselmann
765 02cab3e7 Michael Hanselmann
      if data:
766 02cab3e7 Michael Hanselmann
        buf += data
767 02cab3e7 Michael Hanselmann
      else:
768 02cab3e7 Michael Hanselmann
        eof = True
769 02cab3e7 Michael Hanselmann
770 02cab3e7 Michael Hanselmann
      # Do some parsing and error checking while more data arrives
771 02cab3e7 Michael Hanselmann
      buf = self._ContinueParsing(buf, eof)
772 02cab3e7 Michael Hanselmann
773 02cab3e7 Michael Hanselmann
      # Must be done only after the buffer has been evaluated
774 02cab3e7 Michael Hanselmann
      # TODO: Connection-length < len(data read) and connection closed
775 02cab3e7 Michael Hanselmann
      if (eof and
776 02cab3e7 Michael Hanselmann
          self.parser_status in (self.PS_START_LINE,
777 02cab3e7 Michael Hanselmann
                                 self.PS_HEADERS)):
778 02cab3e7 Michael Hanselmann
        raise HttpError("Connection closed prematurely")
779 02cab3e7 Michael Hanselmann
780 02cab3e7 Michael Hanselmann
    # Parse rest
781 02cab3e7 Michael Hanselmann
    buf = self._ContinueParsing(buf, True)
782 02cab3e7 Michael Hanselmann
783 02cab3e7 Michael Hanselmann
    assert self.parser_status == self.PS_COMPLETE
784 02cab3e7 Michael Hanselmann
    assert not buf, "Parser didn't read full response"
785 02cab3e7 Michael Hanselmann
786 02cab3e7 Michael Hanselmann
    msg.body = self.body_buffer.getvalue()
787 02cab3e7 Michael Hanselmann
788 02cab3e7 Michael Hanselmann
    # TODO: Content-type, error handling
789 02cab3e7 Michael Hanselmann
    if msg.body:
790 02cab3e7 Michael Hanselmann
      msg.decoded_body = HttpJsonConverter().Decode(msg.body)
791 02cab3e7 Michael Hanselmann
    else:
792 02cab3e7 Michael Hanselmann
      msg.decoded_body = None
793 02cab3e7 Michael Hanselmann
794 02cab3e7 Michael Hanselmann
    if msg.decoded_body:
795 02cab3e7 Michael Hanselmann
      logging.debug("Message body: %s", msg.decoded_body)
796 02cab3e7 Michael Hanselmann
797 02cab3e7 Michael Hanselmann
  def _ContinueParsing(self, buf, eof):
798 02cab3e7 Michael Hanselmann
    """Main function for HTTP message state machine.
799 02cab3e7 Michael Hanselmann

800 02cab3e7 Michael Hanselmann
    @type buf: string
801 02cab3e7 Michael Hanselmann
    @param buf: Receive buffer
802 02cab3e7 Michael Hanselmann
    @type eof: bool
803 02cab3e7 Michael Hanselmann
    @param eof: Whether we've reached EOF on the socket
804 02cab3e7 Michael Hanselmann
    @rtype: string
805 02cab3e7 Michael Hanselmann
    @return: Updated receive buffer
806 02cab3e7 Michael Hanselmann

807 02cab3e7 Michael Hanselmann
    """
808 f088165d Michael Hanselmann
    # TODO: Use offset instead of slicing when possible
809 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_START_LINE:
810 02cab3e7 Michael Hanselmann
      # Expect start line
811 02cab3e7 Michael Hanselmann
      while True:
812 02cab3e7 Michael Hanselmann
        idx = buf.find("\r\n")
813 02cab3e7 Michael Hanselmann
814 02cab3e7 Michael Hanselmann
        # RFC2616, section 4.1: "In the interest of robustness, servers SHOULD
815 02cab3e7 Michael Hanselmann
        # ignore any empty line(s) received where a Request-Line is expected.
816 02cab3e7 Michael Hanselmann
        # In other words, if the server is reading the protocol stream at the
817 02cab3e7 Michael Hanselmann
        # beginning of a message and receives a CRLF first, it should ignore
818 02cab3e7 Michael Hanselmann
        # the CRLF."
819 02cab3e7 Michael Hanselmann
        if idx == 0:
820 358a8811 Michael Hanselmann
          # TODO: Limit number of CRLFs/empty lines for safety?
821 02cab3e7 Michael Hanselmann
          buf = buf[:2]
822 02cab3e7 Michael Hanselmann
          continue
823 02cab3e7 Michael Hanselmann
824 02cab3e7 Michael Hanselmann
        if idx > 0:
825 02cab3e7 Michael Hanselmann
          self.start_line_buffer = buf[:idx]
826 02cab3e7 Michael Hanselmann
827 02cab3e7 Michael Hanselmann
          self._CheckStartLineLength(len(self.start_line_buffer))
828 02cab3e7 Michael Hanselmann
829 02cab3e7 Michael Hanselmann
          # Remove status line, including CRLF
830 02cab3e7 Michael Hanselmann
          buf = buf[idx + 2:]
831 02cab3e7 Michael Hanselmann
832 02cab3e7 Michael Hanselmann
          self.msg.start_line = self.ParseStartLine(self.start_line_buffer)
833 02cab3e7 Michael Hanselmann
834 02cab3e7 Michael Hanselmann
          self.parser_status = self.PS_HEADERS
835 02cab3e7 Michael Hanselmann
        else:
836 02cab3e7 Michael Hanselmann
          # Check whether incoming data is getting too large, otherwise we just
837 02cab3e7 Michael Hanselmann
          # fill our read buffer.
838 02cab3e7 Michael Hanselmann
          self._CheckStartLineLength(len(buf))
839 02cab3e7 Michael Hanselmann
840 02cab3e7 Michael Hanselmann
        break
841 02cab3e7 Michael Hanselmann
842 02cab3e7 Michael Hanselmann
    # TODO: Handle messages without headers
843 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_HEADERS:
844 02cab3e7 Michael Hanselmann
      # Wait for header end
845 02cab3e7 Michael Hanselmann
      idx = buf.find("\r\n\r\n")
846 02cab3e7 Michael Hanselmann
      if idx >= 0:
847 02cab3e7 Michael Hanselmann
        self.header_buffer.write(buf[:idx + 2])
848 02cab3e7 Michael Hanselmann
849 02cab3e7 Michael Hanselmann
        self._CheckHeaderLength(self.header_buffer.tell())
850 02cab3e7 Michael Hanselmann
851 02cab3e7 Michael Hanselmann
        # Remove headers, including CRLF
852 02cab3e7 Michael Hanselmann
        buf = buf[idx + 4:]
853 02cab3e7 Michael Hanselmann
854 02cab3e7 Michael Hanselmann
        self._ParseHeaders()
855 02cab3e7 Michael Hanselmann
856 02cab3e7 Michael Hanselmann
        self.parser_status = self.PS_BODY
857 02cab3e7 Michael Hanselmann
      else:
858 02cab3e7 Michael Hanselmann
        # Check whether incoming data is getting too large, otherwise we just
859 02cab3e7 Michael Hanselmann
        # fill our read buffer.
860 02cab3e7 Michael Hanselmann
        self._CheckHeaderLength(len(buf))
861 02cab3e7 Michael Hanselmann
862 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_BODY:
863 02cab3e7 Michael Hanselmann
      # TODO: Implement max size for body_buffer
864 02cab3e7 Michael Hanselmann
      self.body_buffer.write(buf)
865 02cab3e7 Michael Hanselmann
      buf = ""
866 02cab3e7 Michael Hanselmann
867 02cab3e7 Michael Hanselmann
      # Check whether we've read everything
868 02cab3e7 Michael Hanselmann
      #
869 02cab3e7 Michael Hanselmann
      # RFC2616, section 4.4: "When a message-body is included with a message,
870 02cab3e7 Michael Hanselmann
      # the transfer-length of that body is determined by one of the following
871 02cab3e7 Michael Hanselmann
      # [...] 5. By the server closing the connection. (Closing the connection
872 02cab3e7 Michael Hanselmann
      # cannot be used to indicate the end of a request body, since that would
873 02cab3e7 Michael Hanselmann
      # leave no possibility for the server to send back a response.)"
874 f088165d Michael Hanselmann
      #
875 f088165d Michael Hanselmann
      # TODO: Error when buffer length > Content-Length header
876 02cab3e7 Michael Hanselmann
      if (eof or
877 02cab3e7 Michael Hanselmann
          self.content_length is None or
878 02cab3e7 Michael Hanselmann
          (self.content_length is not None and
879 02cab3e7 Michael Hanselmann
           self.body_buffer.tell() >= self.content_length)):
880 02cab3e7 Michael Hanselmann
        self.parser_status = self.PS_COMPLETE
881 02cab3e7 Michael Hanselmann
882 02cab3e7 Michael Hanselmann
    return buf
883 02cab3e7 Michael Hanselmann
884 02cab3e7 Michael Hanselmann
  def _CheckStartLineLength(self, length):
885 02cab3e7 Michael Hanselmann
    """Limits the start line buffer size.
886 02cab3e7 Michael Hanselmann

887 02cab3e7 Michael Hanselmann
    @type length: int
888 02cab3e7 Michael Hanselmann
    @param length: Buffer size
889 02cab3e7 Michael Hanselmann

890 02cab3e7 Michael Hanselmann
    """
891 02cab3e7 Michael Hanselmann
    if (self.START_LINE_LENGTH_MAX is not None and
892 02cab3e7 Michael Hanselmann
        length > self.START_LINE_LENGTH_MAX):
893 02cab3e7 Michael Hanselmann
      raise HttpError("Start line longer than %d chars" %
894 02cab3e7 Michael Hanselmann
                       self.START_LINE_LENGTH_MAX)
895 02cab3e7 Michael Hanselmann
896 02cab3e7 Michael Hanselmann
  def _CheckHeaderLength(self, length):
897 02cab3e7 Michael Hanselmann
    """Limits the header buffer size.
898 02cab3e7 Michael Hanselmann

899 02cab3e7 Michael Hanselmann
    @type length: int
900 02cab3e7 Michael Hanselmann
    @param length: Buffer size
901 02cab3e7 Michael Hanselmann

902 02cab3e7 Michael Hanselmann
    """
903 02cab3e7 Michael Hanselmann
    if (self.HEADER_LENGTH_MAX is not None and
904 02cab3e7 Michael Hanselmann
        length > self.HEADER_LENGTH_MAX):
905 02cab3e7 Michael Hanselmann
      raise HttpError("Headers longer than %d chars" % self.HEADER_LENGTH_MAX)
906 02cab3e7 Michael Hanselmann
907 02cab3e7 Michael Hanselmann
  def ParseStartLine(self, start_line):
908 02cab3e7 Michael Hanselmann
    """Parses the start line of a message.
909 02cab3e7 Michael Hanselmann

910 02cab3e7 Michael Hanselmann
    Must be overriden by subclass.
911 02cab3e7 Michael Hanselmann

912 02cab3e7 Michael Hanselmann
    @type start_line: string
913 02cab3e7 Michael Hanselmann
    @param start_line: Start line string
914 02cab3e7 Michael Hanselmann

915 02cab3e7 Michael Hanselmann
    """
916 02cab3e7 Michael Hanselmann
    raise NotImplementedError()
917 02cab3e7 Michael Hanselmann
918 02cab3e7 Michael Hanselmann
  def _WillPeerCloseConnection(self):
919 02cab3e7 Michael Hanselmann
    """Evaluate whether peer will close the connection.
920 02cab3e7 Michael Hanselmann

921 02cab3e7 Michael Hanselmann
    @rtype: bool
922 02cab3e7 Michael Hanselmann
    @return: Whether peer will close the connection
923 02cab3e7 Michael Hanselmann

924 02cab3e7 Michael Hanselmann
    """
925 02cab3e7 Michael Hanselmann
    # RFC2616, section 14.10: "HTTP/1.1 defines the "close" connection option
926 02cab3e7 Michael Hanselmann
    # for the sender to signal that the connection will be closed after
927 02cab3e7 Michael Hanselmann
    # completion of the response. For example,
928 02cab3e7 Michael Hanselmann
    #
929 02cab3e7 Michael Hanselmann
    #        Connection: close
930 02cab3e7 Michael Hanselmann
    #
931 02cab3e7 Michael Hanselmann
    # in either the request or the response header fields indicates that the
932 02cab3e7 Michael Hanselmann
    # connection SHOULD NOT be considered `persistent' (section 8.1) after the
933 02cab3e7 Michael Hanselmann
    # current request/response is complete."
934 02cab3e7 Michael Hanselmann
935 02cab3e7 Michael Hanselmann
    hdr_connection = self.msg.headers.get(HTTP_CONNECTION, None)
936 02cab3e7 Michael Hanselmann
    if hdr_connection:
937 02cab3e7 Michael Hanselmann
      hdr_connection = hdr_connection.lower()
938 02cab3e7 Michael Hanselmann
939 02cab3e7 Michael Hanselmann
    # An HTTP/1.1 server is assumed to stay open unless explicitly closed.
940 02cab3e7 Michael Hanselmann
    if self.msg.start_line.version == HTTP_1_1:
941 02cab3e7 Michael Hanselmann
      return (hdr_connection and "close" in hdr_connection)
942 02cab3e7 Michael Hanselmann
943 02cab3e7 Michael Hanselmann
    # Some HTTP/1.0 implementations have support for persistent connections,
944 02cab3e7 Michael Hanselmann
    # using rules different than HTTP/1.1.
945 02cab3e7 Michael Hanselmann
946 02cab3e7 Michael Hanselmann
    # For older HTTP, Keep-Alive indicates persistent connection.
947 02cab3e7 Michael Hanselmann
    if self.msg.headers.get(HTTP_KEEP_ALIVE):
948 02cab3e7 Michael Hanselmann
      return False
949 02cab3e7 Michael Hanselmann
950 02cab3e7 Michael Hanselmann
    # At least Akamai returns a "Connection: Keep-Alive" header, which was
951 02cab3e7 Michael Hanselmann
    # supposed to be sent by the client.
952 02cab3e7 Michael Hanselmann
    if hdr_connection and "keep-alive" in hdr_connection:
953 02cab3e7 Michael Hanselmann
      return False
954 02cab3e7 Michael Hanselmann
955 02cab3e7 Michael Hanselmann
    return True
956 02cab3e7 Michael Hanselmann
957 02cab3e7 Michael Hanselmann
  def _ParseHeaders(self):
958 02cab3e7 Michael Hanselmann
    """Parses the headers.
959 02cab3e7 Michael Hanselmann

960 02cab3e7 Michael Hanselmann
    This function also adjusts internal variables based on header values.
961 02cab3e7 Michael Hanselmann

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

966 02cab3e7 Michael Hanselmann
    """
967 02cab3e7 Michael Hanselmann
    # Parse headers
968 02cab3e7 Michael Hanselmann
    self.header_buffer.seek(0, 0)
969 02cab3e7 Michael Hanselmann
    self.msg.headers = mimetools.Message(self.header_buffer, 0)
970 02cab3e7 Michael Hanselmann
971 02cab3e7 Michael Hanselmann
    self.peer_will_close = self._WillPeerCloseConnection()
972 02cab3e7 Michael Hanselmann
973 02cab3e7 Michael Hanselmann
    # Do we have a Content-Length header?
974 02cab3e7 Michael Hanselmann
    hdr_content_length = self.msg.headers.get(HTTP_CONTENT_LENGTH, None)
975 02cab3e7 Michael Hanselmann
    if hdr_content_length:
976 02cab3e7 Michael Hanselmann
      try:
977 02cab3e7 Michael Hanselmann
        self.content_length = int(hdr_content_length)
978 02cab3e7 Michael Hanselmann
      except ValueError:
979 02cab3e7 Michael Hanselmann
        self.content_length = None
980 02cab3e7 Michael Hanselmann
      if self.content_length is not None and self.content_length < 0:
981 02cab3e7 Michael Hanselmann
        self.content_length = None
982 02cab3e7 Michael Hanselmann
983 02cab3e7 Michael Hanselmann
    # if the connection remains open and a content-length was not provided,
984 02cab3e7 Michael Hanselmann
    # then assume that the connection WILL close.
985 02cab3e7 Michael Hanselmann
    if self.content_length is None:
986 02cab3e7 Michael Hanselmann
      self.peer_will_close = True