Statistics
| Branch: | Tag: | Revision:

root / lib / http / __init__.py @ 30e4e741

History | View | Annotate | Download (27.8 kB)

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

23 a43f68dc Michael Hanselmann
"""
24 a43f68dc Michael Hanselmann
25 42242313 Michael Hanselmann
import logging
26 42242313 Michael Hanselmann
import mimetools
27 a43f68dc Michael Hanselmann
import OpenSSL
28 42242313 Michael Hanselmann
import select
29 42242313 Michael Hanselmann
import socket
30 8a0b06d2 Michael Hanselmann
import errno
31 8a0b06d2 Michael Hanselmann
32 8a0b06d2 Michael Hanselmann
from cStringIO import StringIO
33 a43f68dc Michael Hanselmann
34 42242313 Michael Hanselmann
from ganeti import constants
35 a43f68dc Michael Hanselmann
from ganeti import serializer
36 f2a6fc9e Michael Hanselmann
from ganeti import utils
37 a43f68dc Michael Hanselmann
38 a43f68dc Michael Hanselmann
39 8a9f9060 Michael Hanselmann
HTTP_GANETI_VERSION = "Ganeti %s" % constants.RELEASE_VERSION
40 8a9f9060 Michael Hanselmann
41 42242313 Michael Hanselmann
HTTP_OK = 200
42 42242313 Michael Hanselmann
HTTP_NO_CONTENT = 204
43 42242313 Michael Hanselmann
HTTP_NOT_MODIFIED = 304
44 42242313 Michael Hanselmann
45 42242313 Michael Hanselmann
HTTP_0_9 = "HTTP/0.9"
46 42242313 Michael Hanselmann
HTTP_1_0 = "HTTP/1.0"
47 42242313 Michael Hanselmann
HTTP_1_1 = "HTTP/1.1"
48 42242313 Michael Hanselmann
49 42242313 Michael Hanselmann
HTTP_GET = "GET"
50 42242313 Michael Hanselmann
HTTP_HEAD = "HEAD"
51 8a9f9060 Michael Hanselmann
HTTP_POST = "POST"
52 8a9f9060 Michael Hanselmann
HTTP_PUT = "PUT"
53 99b5ef90 Michael Hanselmann
HTTP_DELETE = "DELETE"
54 8a9f9060 Michael Hanselmann
55 713faea6 Oleksiy Mishchenko
HTTP_ETAG = "ETag"
56 8a9f9060 Michael Hanselmann
HTTP_HOST = "Host"
57 8a9f9060 Michael Hanselmann
HTTP_SERVER = "Server"
58 8a9f9060 Michael Hanselmann
HTTP_DATE = "Date"
59 8a9f9060 Michael Hanselmann
HTTP_USER_AGENT = "User-Agent"
60 8a9f9060 Michael Hanselmann
HTTP_CONTENT_TYPE = "Content-Type"
61 8a9f9060 Michael Hanselmann
HTTP_CONTENT_LENGTH = "Content-Length"
62 8a9f9060 Michael Hanselmann
HTTP_CONNECTION = "Connection"
63 8a9f9060 Michael Hanselmann
HTTP_KEEP_ALIVE = "Keep-Alive"
64 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 25e7b43f Iustin Pop
  RFC2616, 10.4.1: The request could not be understood by the server
128 25e7b43f Iustin Pop
  due to malformed syntax. The client SHOULD NOT repeat the request
129 25e7b43f Iustin Pop
  without 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 25e7b43f Iustin Pop
  RFC2616, section 10.4.2: The request requires user
139 25e7b43f Iustin Pop
  authentication. The response MUST include a WWW-Authenticate header
140 25e7b43f Iustin Pop
  field (section 14.47) containing a challenge applicable to the
141 25e7b43f Iustin Pop
  requested resource.
142 b3660886 Michael Hanselmann

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

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

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

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

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

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

177 b3660886 Michael Hanselmann
  """
178 b3660886 Michael Hanselmann
  code = 405
179 b3660886 Michael Hanselmann
180 b3660886 Michael Hanselmann
181 b3660886 Michael Hanselmann
class HttpRequestTimeout(HttpException):
182 b3660886 Michael Hanselmann
  """408 Request Timeout
183 b3660886 Michael Hanselmann

184 25e7b43f Iustin Pop
  RFC2616, 10.4.9: The client did not produce a request within the
185 25e7b43f Iustin Pop
  time that the server was prepared to wait. The client MAY repeat the
186 25e7b43f Iustin Pop
  request without modifications at any later time.
187 b3660886 Michael Hanselmann

188 b3660886 Michael Hanselmann
  """
189 b3660886 Michael Hanselmann
  code = 408
190 b3660886 Michael Hanselmann
191 b3660886 Michael Hanselmann
192 b3660886 Michael Hanselmann
class HttpConflict(HttpException):
193 b3660886 Michael Hanselmann
  """409 Conflict
194 b3660886 Michael Hanselmann

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

200 b3660886 Michael Hanselmann
  """
201 b3660886 Michael Hanselmann
  code = 409
202 b3660886 Michael Hanselmann
203 b3660886 Michael Hanselmann
204 84f2756e Michael Hanselmann
class HttpGone(HttpException):
205 b3660886 Michael Hanselmann
  """410 Gone
206 b3660886 Michael Hanselmann

207 25e7b43f Iustin Pop
  RFC2616, 10.4.11: The requested resource is no longer available at
208 25e7b43f Iustin Pop
  the server and no forwarding address is known. This condition is
209 25e7b43f Iustin Pop
  expected to be considered permanent.
210 b3660886 Michael Hanselmann

211 b3660886 Michael Hanselmann
  """
212 a43f68dc Michael Hanselmann
  code = 410
213 a43f68dc Michael Hanselmann
214 a43f68dc Michael Hanselmann
215 84f2756e Michael Hanselmann
class HttpLengthRequired(HttpException):
216 b3660886 Michael Hanselmann
  """411 Length Required
217 b3660886 Michael Hanselmann

218 25e7b43f Iustin Pop
  RFC2616, 10.4.12: The server refuses to accept the request without a
219 25e7b43f Iustin Pop
  defined Content-Length. The client MAY repeat the request if it adds
220 25e7b43f Iustin Pop
  a valid Content-Length header field containing the length of the
221 25e7b43f Iustin Pop
  message-body in the request message.
222 b3660886 Michael Hanselmann

223 b3660886 Michael Hanselmann
  """
224 a43f68dc Michael Hanselmann
  code = 411
225 a43f68dc Michael Hanselmann
226 a43f68dc Michael Hanselmann
227 b3660886 Michael Hanselmann
class HttpPreconditionFailed(HttpException):
228 b3660886 Michael Hanselmann
  """412 Precondition Failed
229 b3660886 Michael Hanselmann

230 25e7b43f Iustin Pop
  RFC2616, 10.4.13: The precondition given in one or more of the
231 25e7b43f Iustin Pop
  request-header fields evaluated to false when it was tested on the
232 25e7b43f Iustin Pop
  server.
233 b3660886 Michael Hanselmann

234 b3660886 Michael Hanselmann
  """
235 b3660886 Michael Hanselmann
  code = 412
236 b3660886 Michael Hanselmann
237 b3660886 Michael Hanselmann
238 79589f25 Michael Hanselmann
class HttpInternalServerError(HttpException):
239 b3660886 Michael Hanselmann
  """500 Internal Server Error
240 b3660886 Michael Hanselmann

241 25e7b43f Iustin Pop
  RFC2616, 10.5.1: The server encountered an unexpected condition
242 25e7b43f Iustin Pop
  which prevented it from fulfilling the request.
243 b3660886 Michael Hanselmann

244 b3660886 Michael Hanselmann
  """
245 a43f68dc Michael Hanselmann
  code = 500
246 a43f68dc Michael Hanselmann
247 a43f68dc Michael Hanselmann
248 84f2756e Michael Hanselmann
class HttpNotImplemented(HttpException):
249 b3660886 Michael Hanselmann
  """501 Not Implemented
250 b3660886 Michael Hanselmann

251 25e7b43f Iustin Pop
  RFC2616, 10.5.2: The server does not support the functionality
252 25e7b43f Iustin Pop
  required to fulfill the request.
253 b3660886 Michael Hanselmann

254 b3660886 Michael Hanselmann
  """
255 a43f68dc Michael Hanselmann
  code = 501
256 a43f68dc Michael Hanselmann
257 a43f68dc Michael Hanselmann
258 77e1d753 Iustin Pop
class HttpBadGateway(HttpException):
259 77e1d753 Iustin Pop
  """502 Bad Gateway
260 77e1d753 Iustin Pop

261 77e1d753 Iustin Pop
  RFC2616, 10.5.3: The server, while acting as a gateway or proxy,
262 77e1d753 Iustin Pop
  received an invalid response from the upstream server it accessed in
263 77e1d753 Iustin Pop
  attempting to fulfill the request.
264 77e1d753 Iustin Pop

265 77e1d753 Iustin Pop
  """
266 77e1d753 Iustin Pop
  code = 502
267 77e1d753 Iustin Pop
268 77e1d753 Iustin Pop
269 84f2756e Michael Hanselmann
class HttpServiceUnavailable(HttpException):
270 b3660886 Michael Hanselmann
  """503 Service Unavailable
271 b3660886 Michael Hanselmann

272 25e7b43f Iustin Pop
  RFC2616, 10.5.4: The server is currently unable to handle the
273 25e7b43f Iustin Pop
  request due to a temporary overloading or maintenance of the server.
274 b3660886 Michael Hanselmann

275 b3660886 Michael Hanselmann
  """
276 a43f68dc Michael Hanselmann
  code = 503
277 a43f68dc Michael Hanselmann
278 a43f68dc Michael Hanselmann
279 77e1d753 Iustin Pop
class HttpGatewayTimeout(HttpException):
280 77e1d753 Iustin Pop
  """504 Gateway Timeout
281 77e1d753 Iustin Pop

282 77e1d753 Iustin Pop
  RFC2616, 10.5.5: The server, while acting as a gateway or proxy, did
283 77e1d753 Iustin Pop
  not receive a timely response from the upstream server specified by
284 77e1d753 Iustin Pop
  the URI (e.g.  HTTP, FTP, LDAP) or some other auxiliary server
285 77e1d753 Iustin Pop
  (e.g. DNS) it needed to access in attempting to complete the
286 77e1d753 Iustin Pop
  request.
287 77e1d753 Iustin Pop

288 77e1d753 Iustin Pop
  """
289 77e1d753 Iustin Pop
  code = 504
290 77e1d753 Iustin Pop
291 77e1d753 Iustin Pop
292 84f2756e Michael Hanselmann
class HttpVersionNotSupported(HttpException):
293 b3660886 Michael Hanselmann
  """505 HTTP Version Not Supported
294 b3660886 Michael Hanselmann

295 25e7b43f Iustin Pop
  RFC2616, 10.5.6: The server does not support, or refuses to support,
296 25e7b43f Iustin Pop
  the HTTP protocol version that was used in the request message.
297 b3660886 Michael Hanselmann

298 b3660886 Michael Hanselmann
  """
299 42242313 Michael Hanselmann
  code = 505
300 42242313 Michael Hanselmann
301 42242313 Michael Hanselmann
302 7260cfbe Iustin Pop
class HttpJsonConverter: # pylint: disable-msg=W0232
303 a43f68dc Michael Hanselmann
  CONTENT_TYPE = "application/json"
304 a43f68dc Michael Hanselmann
305 7e950d31 Iustin Pop
  @staticmethod
306 7e950d31 Iustin Pop
  def Encode(data):
307 a43f68dc Michael Hanselmann
    return serializer.DumpJson(data)
308 a43f68dc Michael Hanselmann
309 7e950d31 Iustin Pop
  @staticmethod
310 7e950d31 Iustin Pop
  def Decode(data):
311 a43f68dc Michael Hanselmann
    return serializer.LoadJson(data)
312 a43f68dc Michael Hanselmann
313 a43f68dc Michael Hanselmann
314 aea0ed67 Michael Hanselmann
def WaitForSocketCondition(sock, event, timeout):
315 f22c1cea Michael Hanselmann
  """Waits for a condition to occur on the socket.
316 f22c1cea Michael Hanselmann

317 73a59d9e Michael Hanselmann
  @type sock: socket
318 358a8811 Michael Hanselmann
  @param sock: Wait for events on this socket
319 f22c1cea Michael Hanselmann
  @type event: int
320 f22c1cea Michael Hanselmann
  @param event: ORed condition (see select module)
321 f22c1cea Michael Hanselmann
  @type timeout: float or None
322 f22c1cea Michael Hanselmann
  @param timeout: Timeout in seconds
323 f22c1cea Michael Hanselmann
  @rtype: int or None
324 f22c1cea Michael Hanselmann
  @return: None for timeout, otherwise occured conditions
325 f22c1cea Michael Hanselmann

326 f22c1cea Michael Hanselmann
  """
327 f22c1cea Michael Hanselmann
  check = (event | select.POLLPRI |
328 f22c1cea Michael Hanselmann
           select.POLLNVAL | select.POLLHUP | select.POLLERR)
329 f22c1cea Michael Hanselmann
330 f22c1cea Michael Hanselmann
  if timeout is not None:
331 f22c1cea Michael Hanselmann
    # Poller object expects milliseconds
332 f22c1cea Michael Hanselmann
    timeout *= 1000
333 f22c1cea Michael Hanselmann
334 aea0ed67 Michael Hanselmann
  poller = select.poll()
335 f22c1cea Michael Hanselmann
  poller.register(sock, event)
336 f22c1cea Michael Hanselmann
  try:
337 f22c1cea Michael Hanselmann
    while True:
338 f22c1cea Michael Hanselmann
      # TODO: If the main thread receives a signal and we have no timeout, we
339 f22c1cea Michael Hanselmann
      # could wait forever. This should check a global "quit" flag or
340 f22c1cea Michael Hanselmann
      # something every so often.
341 f22c1cea Michael Hanselmann
      io_events = poller.poll(timeout)
342 f22c1cea Michael Hanselmann
      if not io_events:
343 f22c1cea Michael Hanselmann
        # Timeout
344 f22c1cea Michael Hanselmann
        return None
345 1122eb25 Iustin Pop
      for (_, evcond) in io_events:
346 f22c1cea Michael Hanselmann
        if evcond & check:
347 f22c1cea Michael Hanselmann
          return evcond
348 f22c1cea Michael Hanselmann
  finally:
349 f22c1cea Michael Hanselmann
    poller.unregister(sock)
350 f22c1cea Michael Hanselmann
351 f22c1cea Michael Hanselmann
352 aea0ed67 Michael Hanselmann
def SocketOperation(sock, op, arg1, timeout):
353 73a59d9e Michael Hanselmann
  """Wrapper around socket functions.
354 73a59d9e Michael Hanselmann

355 73a59d9e Michael Hanselmann
  This function abstracts error handling for socket operations, especially
356 73a59d9e Michael Hanselmann
  for the complicated interaction with OpenSSL.
357 73a59d9e Michael Hanselmann

358 73a59d9e Michael Hanselmann
  @type sock: socket
359 358a8811 Michael Hanselmann
  @param sock: Socket for the operation
360 73a59d9e Michael Hanselmann
  @type op: int
361 73a59d9e Michael Hanselmann
  @param op: Operation to execute (SOCKOP_* constants)
362 73a59d9e Michael Hanselmann
  @type arg1: any
363 73a59d9e Michael Hanselmann
  @param arg1: Parameter for function (if needed)
364 73a59d9e Michael Hanselmann
  @type timeout: None or float
365 73a59d9e Michael Hanselmann
  @param timeout: Timeout in seconds or None
366 358a8811 Michael Hanselmann
  @return: Return value of socket function
367 73a59d9e Michael Hanselmann

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

494 358a8811 Michael Hanselmann
  @type sock: socket
495 358a8811 Michael Hanselmann
  @param sock: Socket to be shut down
496 358a8811 Michael Hanselmann
  @type close_timeout: float
497 25e7b43f Iustin Pop
  @param close_timeout: How long to wait for the peer to close
498 25e7b43f Iustin Pop
      the connection
499 358a8811 Michael Hanselmann
  @type write_timeout: float
500 358a8811 Michael Hanselmann
  @param write_timeout: Write timeout for shutdown
501 358a8811 Michael Hanselmann
  @type msgreader: http.HttpMessageReader
502 25e7b43f Iustin Pop
  @param msgreader: Request message reader, used to determine whether
503 25e7b43f Iustin Pop
      peer should close connection
504 358a8811 Michael Hanselmann
  @type force: bool
505 25e7b43f Iustin Pop
  @param force: Whether to forcibly close the connection without
506 25e7b43f Iustin Pop
      waiting for peer
507 358a8811 Michael Hanselmann

508 02cab3e7 Michael Hanselmann
  """
509 02cab3e7 Michael Hanselmann
  #print msgreader.peer_will_close, force
510 02cab3e7 Michael Hanselmann
  if msgreader and msgreader.peer_will_close and not force:
511 02cab3e7 Michael Hanselmann
    # Wait for peer to close
512 02cab3e7 Michael Hanselmann
    try:
513 02cab3e7 Michael Hanselmann
      # Check whether it's actually closed
514 aea0ed67 Michael Hanselmann
      if not SocketOperation(sock, SOCKOP_RECV, 1, close_timeout):
515 02cab3e7 Michael Hanselmann
        return
516 02cab3e7 Michael Hanselmann
    except (socket.error, HttpError, HttpSocketTimeout):
517 02cab3e7 Michael Hanselmann
      # Ignore errors at this stage
518 02cab3e7 Michael Hanselmann
      pass
519 02cab3e7 Michael Hanselmann
520 02cab3e7 Michael Hanselmann
  # Close the connection from our side
521 02cab3e7 Michael Hanselmann
  try:
522 39cfc25b Michael Hanselmann
    # We don't care about the return value, see NOTES in SSL_shutdown(3).
523 aea0ed67 Michael Hanselmann
    SocketOperation(sock, SOCKOP_SHUTDOWN, socket.SHUT_RDWR,
524 02cab3e7 Michael Hanselmann
                    write_timeout)
525 02cab3e7 Michael Hanselmann
  except HttpSocketTimeout:
526 02cab3e7 Michael Hanselmann
    raise HttpError("Timeout while shutting down connection")
527 02cab3e7 Michael Hanselmann
  except socket.error, err:
528 45eac583 Michael Hanselmann
    # Ignore ENOTCONN
529 45eac583 Michael Hanselmann
    if not (err.args and err.args[0] == errno.ENOTCONN):
530 45eac583 Michael Hanselmann
      raise HttpError("Error while shutting down connection: %s" % err)
531 02cab3e7 Michael Hanselmann
532 02cab3e7 Michael Hanselmann
533 aea0ed67 Michael Hanselmann
def Handshake(sock, write_timeout):
534 d7fa9982 Michael Hanselmann
  """Shakes peer's hands.
535 d7fa9982 Michael Hanselmann

536 d7fa9982 Michael Hanselmann
  @type sock: socket
537 d7fa9982 Michael Hanselmann
  @param sock: Socket to be shut down
538 d7fa9982 Michael Hanselmann
  @type write_timeout: float
539 d7fa9982 Michael Hanselmann
  @param write_timeout: Write timeout for handshake
540 d7fa9982 Michael Hanselmann

541 d7fa9982 Michael Hanselmann
  """
542 d7fa9982 Michael Hanselmann
  try:
543 aea0ed67 Michael Hanselmann
    return SocketOperation(sock, SOCKOP_HANDSHAKE, None, write_timeout)
544 d7fa9982 Michael Hanselmann
  except HttpSocketTimeout:
545 d7fa9982 Michael Hanselmann
    raise HttpError("Timeout during SSL handshake")
546 d7fa9982 Michael Hanselmann
  except socket.error, err:
547 d7fa9982 Michael Hanselmann
    raise HttpError("Error in SSL handshake: %s" % err)
548 d7fa9982 Michael Hanselmann
549 d7fa9982 Michael Hanselmann
550 8d0a4f99 Michael Hanselmann
def InitSsl():
551 8d0a4f99 Michael Hanselmann
  """Initializes the SSL infrastructure.
552 8d0a4f99 Michael Hanselmann

553 8d0a4f99 Michael Hanselmann
  This function is idempotent.
554 8d0a4f99 Michael Hanselmann

555 8d0a4f99 Michael Hanselmann
  """
556 8d0a4f99 Michael Hanselmann
  if not OpenSSL.rand.status():
557 8d0a4f99 Michael Hanselmann
    raise EnvironmentError("OpenSSL could not collect enough entropy"
558 8d0a4f99 Michael Hanselmann
                           " for the PRNG")
559 8d0a4f99 Michael Hanselmann
560 8d0a4f99 Michael Hanselmann
  # TODO: Maybe add some additional seeding for OpenSSL's PRNG
561 8d0a4f99 Michael Hanselmann
562 8d0a4f99 Michael Hanselmann
563 f20cbea2 Michael Hanselmann
class HttpSslParams(object):
564 f20cbea2 Michael Hanselmann
  """Data class for SSL key and certificate.
565 f20cbea2 Michael Hanselmann

566 f20cbea2 Michael Hanselmann
  """
567 f20cbea2 Michael Hanselmann
  def __init__(self, ssl_key_path, ssl_cert_path):
568 f20cbea2 Michael Hanselmann
    """Initializes this class.
569 f20cbea2 Michael Hanselmann

570 f20cbea2 Michael Hanselmann
    @type ssl_key_path: string
571 f20cbea2 Michael Hanselmann
    @param ssl_key_path: Path to file containing SSL key in PEM format
572 f20cbea2 Michael Hanselmann
    @type ssl_cert_path: string
573 25e7b43f Iustin Pop
    @param ssl_cert_path: Path to file containing SSL certificate
574 25e7b43f Iustin Pop
        in PEM format
575 f20cbea2 Michael Hanselmann

576 f20cbea2 Michael Hanselmann
    """
577 65c6b8e0 Michael Hanselmann
    self.ssl_key_pem = utils.ReadFile(ssl_key_path)
578 65c6b8e0 Michael Hanselmann
    self.ssl_cert_pem = utils.ReadFile(ssl_cert_path)
579 f20cbea2 Michael Hanselmann
580 65c6b8e0 Michael Hanselmann
  def GetKey(self):
581 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
582 65c6b8e0 Michael Hanselmann
                                          self.ssl_key_pem)
583 65c6b8e0 Michael Hanselmann
584 65c6b8e0 Michael Hanselmann
  def GetCertificate(self):
585 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
586 65c6b8e0 Michael Hanselmann
                                           self.ssl_cert_pem)
587 f20cbea2 Michael Hanselmann
588 f20cbea2 Michael Hanselmann
589 f4322a1e Michael Hanselmann
class HttpBase(object):
590 b14f759e Michael Hanselmann
  """Base class for HTTP server and client.
591 b14f759e Michael Hanselmann

592 b14f759e Michael Hanselmann
  """
593 b14f759e Michael Hanselmann
  def __init__(self):
594 22692e48 Michael Hanselmann
    self.using_ssl = None
595 f20cbea2 Michael Hanselmann
    self._ssl_params = None
596 65c6b8e0 Michael Hanselmann
    self._ssl_key = None
597 65c6b8e0 Michael Hanselmann
    self._ssl_cert = None
598 b14f759e Michael Hanselmann
599 f20cbea2 Michael Hanselmann
  def _CreateSocket(self, ssl_params, ssl_verify_peer):
600 b14f759e Michael Hanselmann
    """Creates a TCP socket and initializes SSL if needed.
601 b14f759e Michael Hanselmann

602 f20cbea2 Michael Hanselmann
    @type ssl_params: HttpSslParams
603 f20cbea2 Michael Hanselmann
    @param ssl_params: SSL key and certificate
604 b14f759e Michael Hanselmann
    @type ssl_verify_peer: bool
605 25e7b43f Iustin Pop
    @param ssl_verify_peer: Whether to require client certificate
606 25e7b43f Iustin Pop
        and compare it with our certificate
607 b14f759e Michael Hanselmann

608 b14f759e Michael Hanselmann
    """
609 f20cbea2 Michael Hanselmann
    self._ssl_params = ssl_params
610 f20cbea2 Michael Hanselmann
611 b14f759e Michael Hanselmann
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
612 b14f759e Michael Hanselmann
613 b14f759e Michael Hanselmann
    # Should we enable SSL?
614 22692e48 Michael Hanselmann
    self.using_ssl = ssl_params is not None
615 b14f759e Michael Hanselmann
616 22692e48 Michael Hanselmann
    if not self.using_ssl:
617 b14f759e Michael Hanselmann
      return sock
618 b14f759e Michael Hanselmann
619 65c6b8e0 Michael Hanselmann
    self._ssl_key = ssl_params.GetKey()
620 65c6b8e0 Michael Hanselmann
    self._ssl_cert = ssl_params.GetCertificate()
621 65c6b8e0 Michael Hanselmann
622 b14f759e Michael Hanselmann
    ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
623 b14f759e Michael Hanselmann
    ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2)
624 b14f759e Michael Hanselmann
625 65c6b8e0 Michael Hanselmann
    ctx.use_privatekey(self._ssl_key)
626 65c6b8e0 Michael Hanselmann
    ctx.use_certificate(self._ssl_cert)
627 b14f759e Michael Hanselmann
    ctx.check_privatekey()
628 b14f759e Michael Hanselmann
629 b14f759e Michael Hanselmann
    if ssl_verify_peer:
630 b14f759e Michael Hanselmann
      ctx.set_verify(OpenSSL.SSL.VERIFY_PEER |
631 b14f759e Michael Hanselmann
                     OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
632 b14f759e Michael Hanselmann
                     self._SSLVerifyCallback)
633 b14f759e Michael Hanselmann
634 b14f759e Michael Hanselmann
    return OpenSSL.SSL.Connection(ctx, sock)
635 b14f759e Michael Hanselmann
636 b14f759e Michael Hanselmann
  def _SSLVerifyCallback(self, conn, cert, errnum, errdepth, ok):
637 b14f759e Michael Hanselmann
    """Verify the certificate provided by the peer
638 b14f759e Michael Hanselmann

639 b14f759e Michael Hanselmann
    We only compare fingerprints. The client must use the same certificate as
640 b14f759e Michael Hanselmann
    we do on our side.
641 b14f759e Michael Hanselmann

642 b14f759e Michael Hanselmann
    """
643 2d54e29c Iustin Pop
    # some parameters are unused, but this is the API
644 2d54e29c Iustin Pop
    # pylint: disable-msg=W0613
645 f20cbea2 Michael Hanselmann
    assert self._ssl_params, "SSL not initialized"
646 b14f759e Michael Hanselmann
647 65c6b8e0 Michael Hanselmann
    return (self._ssl_cert.digest("sha1") == cert.digest("sha1") and
648 65c6b8e0 Michael Hanselmann
            self._ssl_cert.digest("md5") == cert.digest("md5"))
649 b14f759e Michael Hanselmann
650 b14f759e Michael Hanselmann
651 02cab3e7 Michael Hanselmann
class HttpMessage(object):
652 02cab3e7 Michael Hanselmann
  """Data structure for HTTP message.
653 02cab3e7 Michael Hanselmann

654 02cab3e7 Michael Hanselmann
  """
655 02cab3e7 Michael Hanselmann
  def __init__(self):
656 02cab3e7 Michael Hanselmann
    self.start_line = None
657 02cab3e7 Michael Hanselmann
    self.headers = None
658 02cab3e7 Michael Hanselmann
    self.body = None
659 02cab3e7 Michael Hanselmann
    self.decoded_body = None
660 02cab3e7 Michael Hanselmann
661 02cab3e7 Michael Hanselmann
662 02cab3e7 Michael Hanselmann
class HttpClientToServerStartLine(object):
663 02cab3e7 Michael Hanselmann
  """Data structure for HTTP request start line.
664 02cab3e7 Michael Hanselmann

665 02cab3e7 Michael Hanselmann
  """
666 02cab3e7 Michael Hanselmann
  def __init__(self, method, path, version):
667 02cab3e7 Michael Hanselmann
    self.method = method
668 02cab3e7 Michael Hanselmann
    self.path = path
669 02cab3e7 Michael Hanselmann
    self.version = version
670 02cab3e7 Michael Hanselmann
671 02cab3e7 Michael Hanselmann
  def __str__(self):
672 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.method, self.path, self.version)
673 02cab3e7 Michael Hanselmann
674 02cab3e7 Michael Hanselmann
675 02cab3e7 Michael Hanselmann
class HttpServerToClientStartLine(object):
676 02cab3e7 Michael Hanselmann
  """Data structure for HTTP response start line.
677 02cab3e7 Michael Hanselmann

678 02cab3e7 Michael Hanselmann
  """
679 02cab3e7 Michael Hanselmann
  def __init__(self, version, code, reason):
680 02cab3e7 Michael Hanselmann
    self.version = version
681 02cab3e7 Michael Hanselmann
    self.code = code
682 02cab3e7 Michael Hanselmann
    self.reason = reason
683 02cab3e7 Michael Hanselmann
684 02cab3e7 Michael Hanselmann
  def __str__(self):
685 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.version, self.code, self.reason)
686 02cab3e7 Michael Hanselmann
687 02cab3e7 Michael Hanselmann
688 02cab3e7 Michael Hanselmann
class HttpMessageWriter(object):
689 02cab3e7 Michael Hanselmann
  """Writes an HTTP message to a socket.
690 02cab3e7 Michael Hanselmann

691 02cab3e7 Michael Hanselmann
  """
692 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, write_timeout):
693 358a8811 Michael Hanselmann
    """Initializes this class and writes an HTTP message to a socket.
694 358a8811 Michael Hanselmann

695 358a8811 Michael Hanselmann
    @type sock: socket
696 358a8811 Michael Hanselmann
    @param sock: Socket to be written to
697 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
698 358a8811 Michael Hanselmann
    @param msg: HTTP message to be written
699 358a8811 Michael Hanselmann
    @type write_timeout: float
700 358a8811 Michael Hanselmann
    @param write_timeout: Write timeout for socket
701 358a8811 Michael Hanselmann

702 358a8811 Michael Hanselmann
    """
703 02cab3e7 Michael Hanselmann
    self._msg = msg
704 02cab3e7 Michael Hanselmann
705 02cab3e7 Michael Hanselmann
    self._PrepareMessage()
706 02cab3e7 Michael Hanselmann
707 02cab3e7 Michael Hanselmann
    buf = self._FormatMessage()
708 02cab3e7 Michael Hanselmann
709 b18dd019 Iustin Pop
    pos = 0
710 b18dd019 Iustin Pop
    end = len(buf)
711 b18dd019 Iustin Pop
    while pos < end:
712 b18dd019 Iustin Pop
      # Send only SOCK_BUF_SIZE bytes at a time
713 358a8811 Michael Hanselmann
      data = buf[pos:(pos + SOCK_BUF_SIZE)]
714 02cab3e7 Michael Hanselmann
715 aea0ed67 Michael Hanselmann
      sent = SocketOperation(sock, SOCKOP_SEND, data, write_timeout)
716 02cab3e7 Michael Hanselmann
717 02cab3e7 Michael Hanselmann
      # Remove sent bytes
718 b18dd019 Iustin Pop
      pos += sent
719 02cab3e7 Michael Hanselmann
720 b18dd019 Iustin Pop
    assert pos == end, "Message wasn't sent completely"
721 02cab3e7 Michael Hanselmann
722 02cab3e7 Michael Hanselmann
  def _PrepareMessage(self):
723 02cab3e7 Michael Hanselmann
    """Prepares the HTTP message by setting mandatory headers.
724 02cab3e7 Michael Hanselmann

725 02cab3e7 Michael Hanselmann
    """
726 02cab3e7 Michael Hanselmann
    # RFC2616, section 4.3: "The presence of a message-body in a request is
727 02cab3e7 Michael Hanselmann
    # signaled by the inclusion of a Content-Length or Transfer-Encoding header
728 02cab3e7 Michael Hanselmann
    # field in the request's message-headers."
729 02cab3e7 Michael Hanselmann
    if self._msg.body:
730 02cab3e7 Michael Hanselmann
      self._msg.headers[HTTP_CONTENT_LENGTH] = len(self._msg.body)
731 02cab3e7 Michael Hanselmann
732 02cab3e7 Michael Hanselmann
  def _FormatMessage(self):
733 02cab3e7 Michael Hanselmann
    """Serializes the HTTP message into a string.
734 02cab3e7 Michael Hanselmann

735 02cab3e7 Michael Hanselmann
    """
736 02cab3e7 Michael Hanselmann
    buf = StringIO()
737 02cab3e7 Michael Hanselmann
738 02cab3e7 Michael Hanselmann
    # Add start line
739 02cab3e7 Michael Hanselmann
    buf.write(str(self._msg.start_line))
740 02cab3e7 Michael Hanselmann
    buf.write("\r\n")
741 02cab3e7 Michael Hanselmann
742 02cab3e7 Michael Hanselmann
    # Add headers
743 02cab3e7 Michael Hanselmann
    if self._msg.start_line.version != HTTP_0_9:
744 02cab3e7 Michael Hanselmann
      for name, value in self._msg.headers.iteritems():
745 02cab3e7 Michael Hanselmann
        buf.write("%s: %s\r\n" % (name, value))
746 02cab3e7 Michael Hanselmann
747 02cab3e7 Michael Hanselmann
    buf.write("\r\n")
748 02cab3e7 Michael Hanselmann
749 02cab3e7 Michael Hanselmann
    # Add message body if needed
750 02cab3e7 Michael Hanselmann
    if self.HasMessageBody():
751 02cab3e7 Michael Hanselmann
      buf.write(self._msg.body)
752 02cab3e7 Michael Hanselmann
753 02cab3e7 Michael Hanselmann
    elif self._msg.body:
754 02cab3e7 Michael Hanselmann
      logging.warning("Ignoring message body")
755 02cab3e7 Michael Hanselmann
756 02cab3e7 Michael Hanselmann
    return buf.getvalue()
757 02cab3e7 Michael Hanselmann
758 02cab3e7 Michael Hanselmann
  def HasMessageBody(self):
759 02cab3e7 Michael Hanselmann
    """Checks whether the HTTP message contains a body.
760 02cab3e7 Michael Hanselmann

761 5bbd3f7f Michael Hanselmann
    Can be overridden by subclasses.
762 02cab3e7 Michael Hanselmann

763 02cab3e7 Michael Hanselmann
    """
764 02cab3e7 Michael Hanselmann
    return bool(self._msg.body)
765 02cab3e7 Michael Hanselmann
766 02cab3e7 Michael Hanselmann
767 02cab3e7 Michael Hanselmann
class HttpMessageReader(object):
768 02cab3e7 Michael Hanselmann
  """Reads HTTP message from socket.
769 02cab3e7 Michael Hanselmann

770 02cab3e7 Michael Hanselmann
  """
771 02cab3e7 Michael Hanselmann
  # Length limits
772 02cab3e7 Michael Hanselmann
  START_LINE_LENGTH_MAX = None
773 02cab3e7 Michael Hanselmann
  HEADER_LENGTH_MAX = None
774 02cab3e7 Michael Hanselmann
775 02cab3e7 Michael Hanselmann
  # Parser state machine
776 02cab3e7 Michael Hanselmann
  PS_START_LINE = "start-line"
777 02cab3e7 Michael Hanselmann
  PS_HEADERS = "headers"
778 02cab3e7 Michael Hanselmann
  PS_BODY = "entity-body"
779 02cab3e7 Michael Hanselmann
  PS_COMPLETE = "complete"
780 02cab3e7 Michael Hanselmann
781 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, read_timeout):
782 358a8811 Michael Hanselmann
    """Reads an HTTP message from a socket.
783 358a8811 Michael Hanselmann

784 358a8811 Michael Hanselmann
    @type sock: socket
785 358a8811 Michael Hanselmann
    @param sock: Socket to be read from
786 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
787 358a8811 Michael Hanselmann
    @param msg: Object for the read message
788 358a8811 Michael Hanselmann
    @type read_timeout: float
789 358a8811 Michael Hanselmann
    @param read_timeout: Read timeout for socket
790 358a8811 Michael Hanselmann

791 358a8811 Michael Hanselmann
    """
792 02cab3e7 Michael Hanselmann
    self.sock = sock
793 02cab3e7 Michael Hanselmann
    self.msg = msg
794 02cab3e7 Michael Hanselmann
795 02cab3e7 Michael Hanselmann
    self.start_line_buffer = None
796 02cab3e7 Michael Hanselmann
    self.header_buffer = StringIO()
797 02cab3e7 Michael Hanselmann
    self.body_buffer = StringIO()
798 02cab3e7 Michael Hanselmann
    self.parser_status = self.PS_START_LINE
799 02cab3e7 Michael Hanselmann
    self.content_length = None
800 02cab3e7 Michael Hanselmann
    self.peer_will_close = None
801 02cab3e7 Michael Hanselmann
802 02cab3e7 Michael Hanselmann
    buf = ""
803 02cab3e7 Michael Hanselmann
    eof = False
804 02cab3e7 Michael Hanselmann
    while self.parser_status != self.PS_COMPLETE:
805 f088165d Michael Hanselmann
      # TODO: Don't read more than necessary (Content-Length), otherwise
806 f088165d Michael Hanselmann
      # data might be lost and/or an error could occur
807 aea0ed67 Michael Hanselmann
      data = SocketOperation(sock, SOCKOP_RECV, SOCK_BUF_SIZE, read_timeout)
808 02cab3e7 Michael Hanselmann
809 02cab3e7 Michael Hanselmann
      if data:
810 02cab3e7 Michael Hanselmann
        buf += data
811 02cab3e7 Michael Hanselmann
      else:
812 02cab3e7 Michael Hanselmann
        eof = True
813 02cab3e7 Michael Hanselmann
814 02cab3e7 Michael Hanselmann
      # Do some parsing and error checking while more data arrives
815 02cab3e7 Michael Hanselmann
      buf = self._ContinueParsing(buf, eof)
816 02cab3e7 Michael Hanselmann
817 02cab3e7 Michael Hanselmann
      # Must be done only after the buffer has been evaluated
818 02cab3e7 Michael Hanselmann
      # TODO: Connection-length < len(data read) and connection closed
819 02cab3e7 Michael Hanselmann
      if (eof and
820 02cab3e7 Michael Hanselmann
          self.parser_status in (self.PS_START_LINE,
821 02cab3e7 Michael Hanselmann
                                 self.PS_HEADERS)):
822 02cab3e7 Michael Hanselmann
        raise HttpError("Connection closed prematurely")
823 02cab3e7 Michael Hanselmann
824 02cab3e7 Michael Hanselmann
    # Parse rest
825 02cab3e7 Michael Hanselmann
    buf = self._ContinueParsing(buf, True)
826 02cab3e7 Michael Hanselmann
827 02cab3e7 Michael Hanselmann
    assert self.parser_status == self.PS_COMPLETE
828 02cab3e7 Michael Hanselmann
    assert not buf, "Parser didn't read full response"
829 02cab3e7 Michael Hanselmann
830 02cab3e7 Michael Hanselmann
    msg.body = self.body_buffer.getvalue()
831 02cab3e7 Michael Hanselmann
832 02cab3e7 Michael Hanselmann
    # TODO: Content-type, error handling
833 02cab3e7 Michael Hanselmann
    if msg.body:
834 02cab3e7 Michael Hanselmann
      msg.decoded_body = HttpJsonConverter().Decode(msg.body)
835 02cab3e7 Michael Hanselmann
    else:
836 02cab3e7 Michael Hanselmann
      msg.decoded_body = None
837 02cab3e7 Michael Hanselmann
838 02cab3e7 Michael Hanselmann
    if msg.decoded_body:
839 02cab3e7 Michael Hanselmann
      logging.debug("Message body: %s", msg.decoded_body)
840 02cab3e7 Michael Hanselmann
841 02cab3e7 Michael Hanselmann
  def _ContinueParsing(self, buf, eof):
842 02cab3e7 Michael Hanselmann
    """Main function for HTTP message state machine.
843 02cab3e7 Michael Hanselmann

844 02cab3e7 Michael Hanselmann
    @type buf: string
845 02cab3e7 Michael Hanselmann
    @param buf: Receive buffer
846 02cab3e7 Michael Hanselmann
    @type eof: bool
847 02cab3e7 Michael Hanselmann
    @param eof: Whether we've reached EOF on the socket
848 02cab3e7 Michael Hanselmann
    @rtype: string
849 02cab3e7 Michael Hanselmann
    @return: Updated receive buffer
850 02cab3e7 Michael Hanselmann

851 02cab3e7 Michael Hanselmann
    """
852 f088165d Michael Hanselmann
    # TODO: Use offset instead of slicing when possible
853 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_START_LINE:
854 02cab3e7 Michael Hanselmann
      # Expect start line
855 02cab3e7 Michael Hanselmann
      while True:
856 02cab3e7 Michael Hanselmann
        idx = buf.find("\r\n")
857 02cab3e7 Michael Hanselmann
858 02cab3e7 Michael Hanselmann
        # RFC2616, section 4.1: "In the interest of robustness, servers SHOULD
859 02cab3e7 Michael Hanselmann
        # ignore any empty line(s) received where a Request-Line is expected.
860 02cab3e7 Michael Hanselmann
        # In other words, if the server is reading the protocol stream at the
861 02cab3e7 Michael Hanselmann
        # beginning of a message and receives a CRLF first, it should ignore
862 02cab3e7 Michael Hanselmann
        # the CRLF."
863 02cab3e7 Michael Hanselmann
        if idx == 0:
864 358a8811 Michael Hanselmann
          # TODO: Limit number of CRLFs/empty lines for safety?
865 02cab3e7 Michael Hanselmann
          buf = buf[:2]
866 02cab3e7 Michael Hanselmann
          continue
867 02cab3e7 Michael Hanselmann
868 02cab3e7 Michael Hanselmann
        if idx > 0:
869 02cab3e7 Michael Hanselmann
          self.start_line_buffer = buf[:idx]
870 02cab3e7 Michael Hanselmann
871 02cab3e7 Michael Hanselmann
          self._CheckStartLineLength(len(self.start_line_buffer))
872 02cab3e7 Michael Hanselmann
873 02cab3e7 Michael Hanselmann
          # Remove status line, including CRLF
874 02cab3e7 Michael Hanselmann
          buf = buf[idx + 2:]
875 02cab3e7 Michael Hanselmann
876 02cab3e7 Michael Hanselmann
          self.msg.start_line = self.ParseStartLine(self.start_line_buffer)
877 02cab3e7 Michael Hanselmann
878 02cab3e7 Michael Hanselmann
          self.parser_status = self.PS_HEADERS
879 02cab3e7 Michael Hanselmann
        else:
880 02cab3e7 Michael Hanselmann
          # Check whether incoming data is getting too large, otherwise we just
881 02cab3e7 Michael Hanselmann
          # fill our read buffer.
882 02cab3e7 Michael Hanselmann
          self._CheckStartLineLength(len(buf))
883 02cab3e7 Michael Hanselmann
884 02cab3e7 Michael Hanselmann
        break
885 02cab3e7 Michael Hanselmann
886 02cab3e7 Michael Hanselmann
    # TODO: Handle messages without headers
887 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_HEADERS:
888 02cab3e7 Michael Hanselmann
      # Wait for header end
889 02cab3e7 Michael Hanselmann
      idx = buf.find("\r\n\r\n")
890 02cab3e7 Michael Hanselmann
      if idx >= 0:
891 02cab3e7 Michael Hanselmann
        self.header_buffer.write(buf[:idx + 2])
892 02cab3e7 Michael Hanselmann
893 02cab3e7 Michael Hanselmann
        self._CheckHeaderLength(self.header_buffer.tell())
894 02cab3e7 Michael Hanselmann
895 02cab3e7 Michael Hanselmann
        # Remove headers, including CRLF
896 02cab3e7 Michael Hanselmann
        buf = buf[idx + 4:]
897 02cab3e7 Michael Hanselmann
898 02cab3e7 Michael Hanselmann
        self._ParseHeaders()
899 02cab3e7 Michael Hanselmann
900 02cab3e7 Michael Hanselmann
        self.parser_status = self.PS_BODY
901 02cab3e7 Michael Hanselmann
      else:
902 02cab3e7 Michael Hanselmann
        # Check whether incoming data is getting too large, otherwise we just
903 02cab3e7 Michael Hanselmann
        # fill our read buffer.
904 02cab3e7 Michael Hanselmann
        self._CheckHeaderLength(len(buf))
905 02cab3e7 Michael Hanselmann
906 02cab3e7 Michael Hanselmann
    if self.parser_status == self.PS_BODY:
907 02cab3e7 Michael Hanselmann
      # TODO: Implement max size for body_buffer
908 02cab3e7 Michael Hanselmann
      self.body_buffer.write(buf)
909 02cab3e7 Michael Hanselmann
      buf = ""
910 02cab3e7 Michael Hanselmann
911 02cab3e7 Michael Hanselmann
      # Check whether we've read everything
912 02cab3e7 Michael Hanselmann
      #
913 02cab3e7 Michael Hanselmann
      # RFC2616, section 4.4: "When a message-body is included with a message,
914 02cab3e7 Michael Hanselmann
      # the transfer-length of that body is determined by one of the following
915 02cab3e7 Michael Hanselmann
      # [...] 5. By the server closing the connection. (Closing the connection
916 02cab3e7 Michael Hanselmann
      # cannot be used to indicate the end of a request body, since that would
917 02cab3e7 Michael Hanselmann
      # leave no possibility for the server to send back a response.)"
918 f088165d Michael Hanselmann
      #
919 f088165d Michael Hanselmann
      # TODO: Error when buffer length > Content-Length header
920 02cab3e7 Michael Hanselmann
      if (eof or
921 02cab3e7 Michael Hanselmann
          self.content_length is None or
922 02cab3e7 Michael Hanselmann
          (self.content_length is not None and
923 02cab3e7 Michael Hanselmann
           self.body_buffer.tell() >= self.content_length)):
924 02cab3e7 Michael Hanselmann
        self.parser_status = self.PS_COMPLETE
925 02cab3e7 Michael Hanselmann
926 02cab3e7 Michael Hanselmann
    return buf
927 02cab3e7 Michael Hanselmann
928 02cab3e7 Michael Hanselmann
  def _CheckStartLineLength(self, length):
929 02cab3e7 Michael Hanselmann
    """Limits the start line buffer size.
930 02cab3e7 Michael Hanselmann

931 02cab3e7 Michael Hanselmann
    @type length: int
932 02cab3e7 Michael Hanselmann
    @param length: Buffer size
933 02cab3e7 Michael Hanselmann

934 02cab3e7 Michael Hanselmann
    """
935 02cab3e7 Michael Hanselmann
    if (self.START_LINE_LENGTH_MAX is not None and
936 02cab3e7 Michael Hanselmann
        length > self.START_LINE_LENGTH_MAX):
937 02cab3e7 Michael Hanselmann
      raise HttpError("Start line longer than %d chars" %
938 02cab3e7 Michael Hanselmann
                       self.START_LINE_LENGTH_MAX)
939 02cab3e7 Michael Hanselmann
940 02cab3e7 Michael Hanselmann
  def _CheckHeaderLength(self, length):
941 02cab3e7 Michael Hanselmann
    """Limits the header buffer size.
942 02cab3e7 Michael Hanselmann

943 02cab3e7 Michael Hanselmann
    @type length: int
944 02cab3e7 Michael Hanselmann
    @param length: Buffer size
945 02cab3e7 Michael Hanselmann

946 02cab3e7 Michael Hanselmann
    """
947 02cab3e7 Michael Hanselmann
    if (self.HEADER_LENGTH_MAX is not None and
948 02cab3e7 Michael Hanselmann
        length > self.HEADER_LENGTH_MAX):
949 02cab3e7 Michael Hanselmann
      raise HttpError("Headers longer than %d chars" % self.HEADER_LENGTH_MAX)
950 02cab3e7 Michael Hanselmann
951 02cab3e7 Michael Hanselmann
  def ParseStartLine(self, start_line):
952 02cab3e7 Michael Hanselmann
    """Parses the start line of a message.
953 02cab3e7 Michael Hanselmann

954 5bbd3f7f Michael Hanselmann
    Must be overridden by subclass.
955 02cab3e7 Michael Hanselmann

956 02cab3e7 Michael Hanselmann
    @type start_line: string
957 02cab3e7 Michael Hanselmann
    @param start_line: Start line string
958 02cab3e7 Michael Hanselmann

959 02cab3e7 Michael Hanselmann
    """
960 02cab3e7 Michael Hanselmann
    raise NotImplementedError()
961 02cab3e7 Michael Hanselmann
962 02cab3e7 Michael Hanselmann
  def _WillPeerCloseConnection(self):
963 02cab3e7 Michael Hanselmann
    """Evaluate whether peer will close the connection.
964 02cab3e7 Michael Hanselmann

965 02cab3e7 Michael Hanselmann
    @rtype: bool
966 02cab3e7 Michael Hanselmann
    @return: Whether peer will close the connection
967 02cab3e7 Michael Hanselmann

968 02cab3e7 Michael Hanselmann
    """
969 02cab3e7 Michael Hanselmann
    # RFC2616, section 14.10: "HTTP/1.1 defines the "close" connection option
970 02cab3e7 Michael Hanselmann
    # for the sender to signal that the connection will be closed after
971 02cab3e7 Michael Hanselmann
    # completion of the response. For example,
972 02cab3e7 Michael Hanselmann
    #
973 02cab3e7 Michael Hanselmann
    #        Connection: close
974 02cab3e7 Michael Hanselmann
    #
975 02cab3e7 Michael Hanselmann
    # in either the request or the response header fields indicates that the
976 02cab3e7 Michael Hanselmann
    # connection SHOULD NOT be considered `persistent' (section 8.1) after the
977 02cab3e7 Michael Hanselmann
    # current request/response is complete."
978 02cab3e7 Michael Hanselmann
979 02cab3e7 Michael Hanselmann
    hdr_connection = self.msg.headers.get(HTTP_CONNECTION, None)
980 02cab3e7 Michael Hanselmann
    if hdr_connection:
981 02cab3e7 Michael Hanselmann
      hdr_connection = hdr_connection.lower()
982 02cab3e7 Michael Hanselmann
983 02cab3e7 Michael Hanselmann
    # An HTTP/1.1 server is assumed to stay open unless explicitly closed.
984 02cab3e7 Michael Hanselmann
    if self.msg.start_line.version == HTTP_1_1:
985 02cab3e7 Michael Hanselmann
      return (hdr_connection and "close" in hdr_connection)
986 02cab3e7 Michael Hanselmann
987 02cab3e7 Michael Hanselmann
    # Some HTTP/1.0 implementations have support for persistent connections,
988 02cab3e7 Michael Hanselmann
    # using rules different than HTTP/1.1.
989 02cab3e7 Michael Hanselmann
990 02cab3e7 Michael Hanselmann
    # For older HTTP, Keep-Alive indicates persistent connection.
991 02cab3e7 Michael Hanselmann
    if self.msg.headers.get(HTTP_KEEP_ALIVE):
992 02cab3e7 Michael Hanselmann
      return False
993 02cab3e7 Michael Hanselmann
994 02cab3e7 Michael Hanselmann
    # At least Akamai returns a "Connection: Keep-Alive" header, which was
995 02cab3e7 Michael Hanselmann
    # supposed to be sent by the client.
996 02cab3e7 Michael Hanselmann
    if hdr_connection and "keep-alive" in hdr_connection:
997 02cab3e7 Michael Hanselmann
      return False
998 02cab3e7 Michael Hanselmann
999 02cab3e7 Michael Hanselmann
    return True
1000 02cab3e7 Michael Hanselmann
1001 02cab3e7 Michael Hanselmann
  def _ParseHeaders(self):
1002 02cab3e7 Michael Hanselmann
    """Parses the headers.
1003 02cab3e7 Michael Hanselmann

1004 02cab3e7 Michael Hanselmann
    This function also adjusts internal variables based on header values.
1005 02cab3e7 Michael Hanselmann

1006 25e7b43f Iustin Pop
    RFC2616, section 4.3: The presence of a message-body in a request is
1007 02cab3e7 Michael Hanselmann
    signaled by the inclusion of a Content-Length or Transfer-Encoding header
1008 25e7b43f Iustin Pop
    field in the request's message-headers.
1009 02cab3e7 Michael Hanselmann

1010 02cab3e7 Michael Hanselmann
    """
1011 02cab3e7 Michael Hanselmann
    # Parse headers
1012 02cab3e7 Michael Hanselmann
    self.header_buffer.seek(0, 0)
1013 02cab3e7 Michael Hanselmann
    self.msg.headers = mimetools.Message(self.header_buffer, 0)
1014 02cab3e7 Michael Hanselmann
1015 02cab3e7 Michael Hanselmann
    self.peer_will_close = self._WillPeerCloseConnection()
1016 02cab3e7 Michael Hanselmann
1017 02cab3e7 Michael Hanselmann
    # Do we have a Content-Length header?
1018 02cab3e7 Michael Hanselmann
    hdr_content_length = self.msg.headers.get(HTTP_CONTENT_LENGTH, None)
1019 02cab3e7 Michael Hanselmann
    if hdr_content_length:
1020 02cab3e7 Michael Hanselmann
      try:
1021 02cab3e7 Michael Hanselmann
        self.content_length = int(hdr_content_length)
1022 02cab3e7 Michael Hanselmann
      except ValueError:
1023 02cab3e7 Michael Hanselmann
        self.content_length = None
1024 02cab3e7 Michael Hanselmann
      if self.content_length is not None and self.content_length < 0:
1025 02cab3e7 Michael Hanselmann
        self.content_length = None
1026 02cab3e7 Michael Hanselmann
1027 02cab3e7 Michael Hanselmann
    # if the connection remains open and a content-length was not provided,
1028 02cab3e7 Michael Hanselmann
    # then assume that the connection WILL close.
1029 02cab3e7 Michael Hanselmann
    if self.content_length is None:
1030 02cab3e7 Michael Hanselmann
      self.peer_will_close = True