Statistics
| Branch: | Tag: | Revision:

root / lib / http / __init__.py @ 0e632cbd

History | View | Annotate | Download (27.9 kB)

1 a43f68dc Michael Hanselmann
#
2 a43f68dc Michael Hanselmann
#
3 4ce6007f Michael Hanselmann
4 db4e138b Manuel Franceschini
# Copyright (C) 2007, 2008, 2010 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 f2a6fc9e Michael Hanselmann
from ganeti import utils
36 a43f68dc Michael Hanselmann
37 a43f68dc Michael Hanselmann
38 8a9f9060 Michael Hanselmann
HTTP_GANETI_VERSION = "Ganeti %s" % constants.RELEASE_VERSION
39 8a9f9060 Michael Hanselmann
40 42242313 Michael Hanselmann
HTTP_OK = 200
41 42242313 Michael Hanselmann
HTTP_NO_CONTENT = 204
42 42242313 Michael Hanselmann
HTTP_NOT_MODIFIED = 304
43 42242313 Michael Hanselmann
44 42242313 Michael Hanselmann
HTTP_0_9 = "HTTP/0.9"
45 42242313 Michael Hanselmann
HTTP_1_0 = "HTTP/1.0"
46 42242313 Michael Hanselmann
HTTP_1_1 = "HTTP/1.1"
47 42242313 Michael Hanselmann
48 42242313 Michael Hanselmann
HTTP_GET = "GET"
49 42242313 Michael Hanselmann
HTTP_HEAD = "HEAD"
50 8a9f9060 Michael Hanselmann
HTTP_POST = "POST"
51 8a9f9060 Michael Hanselmann
HTTP_PUT = "PUT"
52 99b5ef90 Michael Hanselmann
HTTP_DELETE = "DELETE"
53 8a9f9060 Michael Hanselmann
54 713faea6 Oleksiy Mishchenko
HTTP_ETAG = "ETag"
55 8a9f9060 Michael Hanselmann
HTTP_HOST = "Host"
56 8a9f9060 Michael Hanselmann
HTTP_SERVER = "Server"
57 8a9f9060 Michael Hanselmann
HTTP_DATE = "Date"
58 8a9f9060 Michael Hanselmann
HTTP_USER_AGENT = "User-Agent"
59 8a9f9060 Michael Hanselmann
HTTP_CONTENT_TYPE = "Content-Type"
60 8a9f9060 Michael Hanselmann
HTTP_CONTENT_LENGTH = "Content-Length"
61 8a9f9060 Michael Hanselmann
HTTP_CONNECTION = "Connection"
62 8a9f9060 Michael Hanselmann
HTTP_KEEP_ALIVE = "Keep-Alive"
63 b3660886 Michael Hanselmann
HTTP_WWW_AUTHENTICATE = "WWW-Authenticate"
64 b3660886 Michael Hanselmann
HTTP_AUTHORIZATION = "Authorization"
65 b3660886 Michael Hanselmann
HTTP_AUTHENTICATION_INFO = "Authentication-Info"
66 b3660886 Michael Hanselmann
HTTP_ALLOW = "Allow"
67 42242313 Michael Hanselmann
68 580558a3 Michael Hanselmann
HTTP_APP_OCTET_STREAM = "application/octet-stream"
69 16b037a9 Michael Hanselmann
HTTP_APP_JSON = "application/json"
70 580558a3 Michael Hanselmann
71 d7bace1b Michael Hanselmann
_SSL_UNEXPECTED_EOF = "Unexpected EOF"
72 d7bace1b Michael Hanselmann
73 73a59d9e Michael Hanselmann
# Socket operations
74 73a59d9e Michael Hanselmann
(SOCKOP_SEND,
75 73a59d9e Michael Hanselmann
 SOCKOP_RECV,
76 d7fa9982 Michael Hanselmann
 SOCKOP_SHUTDOWN,
77 d7fa9982 Michael Hanselmann
 SOCKOP_HANDSHAKE) = range(4)
78 73a59d9e Michael Hanselmann
79 b18dd019 Iustin Pop
# send/receive quantum
80 b18dd019 Iustin Pop
SOCK_BUF_SIZE = 32768
81 42242313 Michael Hanselmann
82 13b63666 Michael Hanselmann
83 02cab3e7 Michael Hanselmann
class HttpError(Exception):
84 02cab3e7 Michael Hanselmann
  """Internal exception for HTTP errors.
85 02cab3e7 Michael Hanselmann

86 02cab3e7 Michael Hanselmann
  This should only be used for internal error reporting.
87 02cab3e7 Michael Hanselmann

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

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

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

103 d7fa9982 Michael Hanselmann
  This should only be used for internal error reporting.
104 d7fa9982 Michael Hanselmann

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

111 73a59d9e Michael Hanselmann
  This should only be used for internal error reporting.
112 73a59d9e Michael Hanselmann

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

129 25e7b43f Iustin Pop
  RFC2616, 10.4.1: The request could not be understood by the server
130 25e7b43f Iustin Pop
  due to malformed syntax. The client SHOULD NOT repeat the request
131 25e7b43f Iustin Pop
  without modifications.
132 b3660886 Michael Hanselmann

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

140 25e7b43f Iustin Pop
  RFC2616, section 10.4.2: The request requires user
141 25e7b43f Iustin Pop
  authentication. The response MUST include a WWW-Authenticate header
142 25e7b43f Iustin Pop
  field (section 14.47) containing a challenge applicable to the
143 25e7b43f Iustin Pop
  requested resource.
144 b3660886 Michael Hanselmann

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

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

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

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

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

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

179 b3660886 Michael Hanselmann
  """
180 b3660886 Michael Hanselmann
  code = 405
181 b3660886 Michael Hanselmann
182 b3660886 Michael Hanselmann
183 580558a3 Michael Hanselmann
class HttpNotAcceptable(HttpException):
184 580558a3 Michael Hanselmann
  """406 Not Acceptable
185 580558a3 Michael Hanselmann

186 580558a3 Michael Hanselmann
  RFC2616, 10.4.7: The resource identified by the request is only capable of
187 580558a3 Michael Hanselmann
  generating response entities which have content characteristics not
188 580558a3 Michael Hanselmann
  acceptable according to the accept headers sent in the request.
189 580558a3 Michael Hanselmann

190 580558a3 Michael Hanselmann
  """
191 580558a3 Michael Hanselmann
  code = 406
192 580558a3 Michael Hanselmann
193 580558a3 Michael Hanselmann
194 b3660886 Michael Hanselmann
class HttpRequestTimeout(HttpException):
195 b3660886 Michael Hanselmann
  """408 Request Timeout
196 b3660886 Michael Hanselmann

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

201 b3660886 Michael Hanselmann
  """
202 b3660886 Michael Hanselmann
  code = 408
203 b3660886 Michael Hanselmann
204 b3660886 Michael Hanselmann
205 b3660886 Michael Hanselmann
class HttpConflict(HttpException):
206 b3660886 Michael Hanselmann
  """409 Conflict
207 b3660886 Michael Hanselmann

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

213 b3660886 Michael Hanselmann
  """
214 b3660886 Michael Hanselmann
  code = 409
215 b3660886 Michael Hanselmann
216 b3660886 Michael Hanselmann
217 84f2756e Michael Hanselmann
class HttpGone(HttpException):
218 b3660886 Michael Hanselmann
  """410 Gone
219 b3660886 Michael Hanselmann

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

224 b3660886 Michael Hanselmann
  """
225 a43f68dc Michael Hanselmann
  code = 410
226 a43f68dc Michael Hanselmann
227 a43f68dc Michael Hanselmann
228 84f2756e Michael Hanselmann
class HttpLengthRequired(HttpException):
229 b3660886 Michael Hanselmann
  """411 Length Required
230 b3660886 Michael Hanselmann

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

236 b3660886 Michael Hanselmann
  """
237 a43f68dc Michael Hanselmann
  code = 411
238 a43f68dc Michael Hanselmann
239 a43f68dc Michael Hanselmann
240 b3660886 Michael Hanselmann
class HttpPreconditionFailed(HttpException):
241 b3660886 Michael Hanselmann
  """412 Precondition Failed
242 b3660886 Michael Hanselmann

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

247 b3660886 Michael Hanselmann
  """
248 b3660886 Michael Hanselmann
  code = 412
249 b3660886 Michael Hanselmann
250 b3660886 Michael Hanselmann
251 580558a3 Michael Hanselmann
class HttpUnsupportedMediaType(HttpException):
252 580558a3 Michael Hanselmann
  """415 Unsupported Media Type
253 580558a3 Michael Hanselmann

254 580558a3 Michael Hanselmann
  RFC2616, 10.4.16: The server is refusing to service the request because the
255 580558a3 Michael Hanselmann
  entity of the request is in a format not supported by the requested resource
256 580558a3 Michael Hanselmann
  for the requested method.
257 580558a3 Michael Hanselmann

258 580558a3 Michael Hanselmann
  """
259 580558a3 Michael Hanselmann
  code = 415
260 580558a3 Michael Hanselmann
261 580558a3 Michael Hanselmann
262 79589f25 Michael Hanselmann
class HttpInternalServerError(HttpException):
263 b3660886 Michael Hanselmann
  """500 Internal Server Error
264 b3660886 Michael Hanselmann

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

268 b3660886 Michael Hanselmann
  """
269 a43f68dc Michael Hanselmann
  code = 500
270 a43f68dc Michael Hanselmann
271 a43f68dc Michael Hanselmann
272 84f2756e Michael Hanselmann
class HttpNotImplemented(HttpException):
273 b3660886 Michael Hanselmann
  """501 Not Implemented
274 b3660886 Michael Hanselmann

275 25e7b43f Iustin Pop
  RFC2616, 10.5.2: The server does not support the functionality
276 25e7b43f Iustin Pop
  required to fulfill the request.
277 b3660886 Michael Hanselmann

278 b3660886 Michael Hanselmann
  """
279 a43f68dc Michael Hanselmann
  code = 501
280 a43f68dc Michael Hanselmann
281 a43f68dc Michael Hanselmann
282 77e1d753 Iustin Pop
class HttpBadGateway(HttpException):
283 77e1d753 Iustin Pop
  """502 Bad Gateway
284 77e1d753 Iustin Pop

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

289 77e1d753 Iustin Pop
  """
290 77e1d753 Iustin Pop
  code = 502
291 77e1d753 Iustin Pop
292 77e1d753 Iustin Pop
293 84f2756e Michael Hanselmann
class HttpServiceUnavailable(HttpException):
294 b3660886 Michael Hanselmann
  """503 Service Unavailable
295 b3660886 Michael Hanselmann

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

299 b3660886 Michael Hanselmann
  """
300 a43f68dc Michael Hanselmann
  code = 503
301 a43f68dc Michael Hanselmann
302 a43f68dc Michael Hanselmann
303 77e1d753 Iustin Pop
class HttpGatewayTimeout(HttpException):
304 77e1d753 Iustin Pop
  """504 Gateway Timeout
305 77e1d753 Iustin Pop

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

312 77e1d753 Iustin Pop
  """
313 77e1d753 Iustin Pop
  code = 504
314 77e1d753 Iustin Pop
315 77e1d753 Iustin Pop
316 84f2756e Michael Hanselmann
class HttpVersionNotSupported(HttpException):
317 b3660886 Michael Hanselmann
  """505 HTTP Version Not Supported
318 b3660886 Michael Hanselmann

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

322 b3660886 Michael Hanselmann
  """
323 42242313 Michael Hanselmann
  code = 505
324 42242313 Michael Hanselmann
325 42242313 Michael Hanselmann
326 0e632cbd Michael Hanselmann
def ParseHeaders(buf):
327 0e632cbd Michael Hanselmann
  """Parses HTTP headers.
328 0e632cbd Michael Hanselmann

329 0e632cbd Michael Hanselmann
  @note: This is just a trivial wrapper around C{mimetools.Message}
330 0e632cbd Michael Hanselmann

331 0e632cbd Michael Hanselmann
  """
332 0e632cbd Michael Hanselmann
  return mimetools.Message(buf, 0)
333 0e632cbd Michael Hanselmann
334 0e632cbd Michael Hanselmann
335 aea0ed67 Michael Hanselmann
def SocketOperation(sock, op, arg1, timeout):
336 73a59d9e Michael Hanselmann
  """Wrapper around socket functions.
337 73a59d9e Michael Hanselmann

338 73a59d9e Michael Hanselmann
  This function abstracts error handling for socket operations, especially
339 73a59d9e Michael Hanselmann
  for the complicated interaction with OpenSSL.
340 73a59d9e Michael Hanselmann

341 73a59d9e Michael Hanselmann
  @type sock: socket
342 358a8811 Michael Hanselmann
  @param sock: Socket for the operation
343 73a59d9e Michael Hanselmann
  @type op: int
344 73a59d9e Michael Hanselmann
  @param op: Operation to execute (SOCKOP_* constants)
345 73a59d9e Michael Hanselmann
  @type arg1: any
346 73a59d9e Michael Hanselmann
  @param arg1: Parameter for function (if needed)
347 73a59d9e Michael Hanselmann
  @type timeout: None or float
348 73a59d9e Michael Hanselmann
  @param timeout: Timeout in seconds or None
349 358a8811 Michael Hanselmann
  @return: Return value of socket function
350 73a59d9e Michael Hanselmann

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

477 358a8811 Michael Hanselmann
  @type sock: socket
478 358a8811 Michael Hanselmann
  @param sock: Socket to be shut down
479 358a8811 Michael Hanselmann
  @type close_timeout: float
480 25e7b43f Iustin Pop
  @param close_timeout: How long to wait for the peer to close
481 25e7b43f Iustin Pop
      the connection
482 358a8811 Michael Hanselmann
  @type write_timeout: float
483 358a8811 Michael Hanselmann
  @param write_timeout: Write timeout for shutdown
484 358a8811 Michael Hanselmann
  @type msgreader: http.HttpMessageReader
485 25e7b43f Iustin Pop
  @param msgreader: Request message reader, used to determine whether
486 25e7b43f Iustin Pop
      peer should close connection
487 358a8811 Michael Hanselmann
  @type force: bool
488 25e7b43f Iustin Pop
  @param force: Whether to forcibly close the connection without
489 25e7b43f Iustin Pop
      waiting for peer
490 358a8811 Michael Hanselmann

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

519 d7fa9982 Michael Hanselmann
  @type sock: socket
520 d7fa9982 Michael Hanselmann
  @param sock: Socket to be shut down
521 d7fa9982 Michael Hanselmann
  @type write_timeout: float
522 d7fa9982 Michael Hanselmann
  @param write_timeout: Write timeout for handshake
523 d7fa9982 Michael Hanselmann

524 d7fa9982 Michael Hanselmann
  """
525 d7fa9982 Michael Hanselmann
  try:
526 aea0ed67 Michael Hanselmann
    return SocketOperation(sock, SOCKOP_HANDSHAKE, None, write_timeout)
527 d7fa9982 Michael Hanselmann
  except HttpSocketTimeout:
528 d7fa9982 Michael Hanselmann
    raise HttpError("Timeout during SSL handshake")
529 d7fa9982 Michael Hanselmann
  except socket.error, err:
530 d7fa9982 Michael Hanselmann
    raise HttpError("Error in SSL handshake: %s" % err)
531 d7fa9982 Michael Hanselmann
532 d7fa9982 Michael Hanselmann
533 8d0a4f99 Michael Hanselmann
def InitSsl():
534 8d0a4f99 Michael Hanselmann
  """Initializes the SSL infrastructure.
535 8d0a4f99 Michael Hanselmann

536 8d0a4f99 Michael Hanselmann
  This function is idempotent.
537 8d0a4f99 Michael Hanselmann

538 8d0a4f99 Michael Hanselmann
  """
539 8d0a4f99 Michael Hanselmann
  if not OpenSSL.rand.status():
540 8d0a4f99 Michael Hanselmann
    raise EnvironmentError("OpenSSL could not collect enough entropy"
541 8d0a4f99 Michael Hanselmann
                           " for the PRNG")
542 8d0a4f99 Michael Hanselmann
543 8d0a4f99 Michael Hanselmann
  # TODO: Maybe add some additional seeding for OpenSSL's PRNG
544 8d0a4f99 Michael Hanselmann
545 8d0a4f99 Michael Hanselmann
546 f20cbea2 Michael Hanselmann
class HttpSslParams(object):
547 f20cbea2 Michael Hanselmann
  """Data class for SSL key and certificate.
548 f20cbea2 Michael Hanselmann

549 f20cbea2 Michael Hanselmann
  """
550 f20cbea2 Michael Hanselmann
  def __init__(self, ssl_key_path, ssl_cert_path):
551 f20cbea2 Michael Hanselmann
    """Initializes this class.
552 f20cbea2 Michael Hanselmann

553 f20cbea2 Michael Hanselmann
    @type ssl_key_path: string
554 f20cbea2 Michael Hanselmann
    @param ssl_key_path: Path to file containing SSL key in PEM format
555 f20cbea2 Michael Hanselmann
    @type ssl_cert_path: string
556 25e7b43f Iustin Pop
    @param ssl_cert_path: Path to file containing SSL certificate
557 25e7b43f Iustin Pop
        in PEM format
558 f20cbea2 Michael Hanselmann

559 f20cbea2 Michael Hanselmann
    """
560 65c6b8e0 Michael Hanselmann
    self.ssl_key_pem = utils.ReadFile(ssl_key_path)
561 65c6b8e0 Michael Hanselmann
    self.ssl_cert_pem = utils.ReadFile(ssl_cert_path)
562 2d93a6a7 Apollon Oikonomopoulos
    self.ssl_cert_path = ssl_cert_path
563 f20cbea2 Michael Hanselmann
564 65c6b8e0 Michael Hanselmann
  def GetKey(self):
565 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
566 65c6b8e0 Michael Hanselmann
                                          self.ssl_key_pem)
567 65c6b8e0 Michael Hanselmann
568 65c6b8e0 Michael Hanselmann
  def GetCertificate(self):
569 65c6b8e0 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
570 65c6b8e0 Michael Hanselmann
                                           self.ssl_cert_pem)
571 f20cbea2 Michael Hanselmann
572 f20cbea2 Michael Hanselmann
573 f4322a1e Michael Hanselmann
class HttpBase(object):
574 b14f759e Michael Hanselmann
  """Base class for HTTP server and client.
575 b14f759e Michael Hanselmann

576 b14f759e Michael Hanselmann
  """
577 b14f759e Michael Hanselmann
  def __init__(self):
578 22692e48 Michael Hanselmann
    self.using_ssl = None
579 f20cbea2 Michael Hanselmann
    self._ssl_params = None
580 65c6b8e0 Michael Hanselmann
    self._ssl_key = None
581 65c6b8e0 Michael Hanselmann
    self._ssl_cert = None
582 b14f759e Michael Hanselmann
583 db4e138b Manuel Franceschini
  def _CreateSocket(self, ssl_params, ssl_verify_peer, family):
584 b14f759e Michael Hanselmann
    """Creates a TCP socket and initializes SSL if needed.
585 b14f759e Michael Hanselmann

586 f20cbea2 Michael Hanselmann
    @type ssl_params: HttpSslParams
587 f20cbea2 Michael Hanselmann
    @param ssl_params: SSL key and certificate
588 b14f759e Michael Hanselmann
    @type ssl_verify_peer: bool
589 25e7b43f Iustin Pop
    @param ssl_verify_peer: Whether to require client certificate
590 25e7b43f Iustin Pop
        and compare it with our certificate
591 db4e138b Manuel Franceschini
    @type family: int
592 db4e138b Manuel Franceschini
    @param family: socket.AF_INET | socket.AF_INET6
593 b14f759e Michael Hanselmann

594 b14f759e Michael Hanselmann
    """
595 db4e138b Manuel Franceschini
    assert family in (socket.AF_INET, socket.AF_INET6)
596 f20cbea2 Michael Hanselmann
597 db4e138b Manuel Franceschini
    self._ssl_params = ssl_params
598 db4e138b Manuel Franceschini
    sock = socket.socket(family, socket.SOCK_STREAM)
599 b14f759e Michael Hanselmann
600 b14f759e Michael Hanselmann
    # Should we enable SSL?
601 22692e48 Michael Hanselmann
    self.using_ssl = ssl_params is not None
602 b14f759e Michael Hanselmann
603 22692e48 Michael Hanselmann
    if not self.using_ssl:
604 b14f759e Michael Hanselmann
      return sock
605 b14f759e Michael Hanselmann
606 65c6b8e0 Michael Hanselmann
    self._ssl_key = ssl_params.GetKey()
607 65c6b8e0 Michael Hanselmann
    self._ssl_cert = ssl_params.GetCertificate()
608 65c6b8e0 Michael Hanselmann
609 b14f759e Michael Hanselmann
    ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
610 b14f759e Michael Hanselmann
    ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2)
611 91c69613 Michael Hanselmann
612 91c69613 Michael Hanselmann
    ciphers = self.GetSslCiphers()
613 91c69613 Michael Hanselmann
    logging.debug("Setting SSL cipher string %s", ciphers)
614 91c69613 Michael Hanselmann
    ctx.set_cipher_list(ciphers)
615 b14f759e Michael Hanselmann
616 65c6b8e0 Michael Hanselmann
    ctx.use_privatekey(self._ssl_key)
617 65c6b8e0 Michael Hanselmann
    ctx.use_certificate(self._ssl_cert)
618 b14f759e Michael Hanselmann
    ctx.check_privatekey()
619 b14f759e Michael Hanselmann
620 b14f759e Michael Hanselmann
    if ssl_verify_peer:
621 b14f759e Michael Hanselmann
      ctx.set_verify(OpenSSL.SSL.VERIFY_PEER |
622 b14f759e Michael Hanselmann
                     OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
623 b14f759e Michael Hanselmann
                     self._SSLVerifyCallback)
624 b14f759e Michael Hanselmann
625 2d93a6a7 Apollon Oikonomopoulos
      # Also add our certificate as a trusted CA to be sent to the client.
626 2d93a6a7 Apollon Oikonomopoulos
      # This is required at least for GnuTLS clients to work.
627 2d93a6a7 Apollon Oikonomopoulos
      try:
628 2d93a6a7 Apollon Oikonomopoulos
        # This will fail for PyOpenssl versions before 0.10
629 2d93a6a7 Apollon Oikonomopoulos
        ctx.add_client_ca(self._ssl_cert)
630 2d93a6a7 Apollon Oikonomopoulos
      except AttributeError:
631 2d93a6a7 Apollon Oikonomopoulos
        # Fall back to letting OpenSSL read the certificate file directly.
632 2d93a6a7 Apollon Oikonomopoulos
        ctx.load_client_ca(ssl_params.ssl_cert_path)
633 2d93a6a7 Apollon Oikonomopoulos
634 b14f759e Michael Hanselmann
    return OpenSSL.SSL.Connection(ctx, sock)
635 b14f759e Michael Hanselmann
636 b459a848 Andrea Spadaccini
  def GetSslCiphers(self): # pylint: disable=R0201
637 91c69613 Michael Hanselmann
    """Returns the ciphers string for SSL.
638 91c69613 Michael Hanselmann

639 91c69613 Michael Hanselmann
    """
640 91c69613 Michael Hanselmann
    return constants.OPENSSL_CIPHERS
641 91c69613 Michael Hanselmann
642 b14f759e Michael Hanselmann
  def _SSLVerifyCallback(self, conn, cert, errnum, errdepth, ok):
643 b14f759e Michael Hanselmann
    """Verify the certificate provided by the peer
644 b14f759e Michael Hanselmann

645 b14f759e Michael Hanselmann
    We only compare fingerprints. The client must use the same certificate as
646 b14f759e Michael Hanselmann
    we do on our side.
647 b14f759e Michael Hanselmann

648 b14f759e Michael Hanselmann
    """
649 2d54e29c Iustin Pop
    # some parameters are unused, but this is the API
650 b459a848 Andrea Spadaccini
    # pylint: disable=W0613
651 f20cbea2 Michael Hanselmann
    assert self._ssl_params, "SSL not initialized"
652 b14f759e Michael Hanselmann
653 65c6b8e0 Michael Hanselmann
    return (self._ssl_cert.digest("sha1") == cert.digest("sha1") and
654 65c6b8e0 Michael Hanselmann
            self._ssl_cert.digest("md5") == cert.digest("md5"))
655 b14f759e Michael Hanselmann
656 b14f759e Michael Hanselmann
657 02cab3e7 Michael Hanselmann
class HttpMessage(object):
658 02cab3e7 Michael Hanselmann
  """Data structure for HTTP message.
659 02cab3e7 Michael Hanselmann

660 02cab3e7 Michael Hanselmann
  """
661 02cab3e7 Michael Hanselmann
  def __init__(self):
662 02cab3e7 Michael Hanselmann
    self.start_line = None
663 02cab3e7 Michael Hanselmann
    self.headers = None
664 02cab3e7 Michael Hanselmann
    self.body = None
665 02cab3e7 Michael Hanselmann
666 02cab3e7 Michael Hanselmann
667 02cab3e7 Michael Hanselmann
class HttpClientToServerStartLine(object):
668 02cab3e7 Michael Hanselmann
  """Data structure for HTTP request start line.
669 02cab3e7 Michael Hanselmann

670 02cab3e7 Michael Hanselmann
  """
671 02cab3e7 Michael Hanselmann
  def __init__(self, method, path, version):
672 02cab3e7 Michael Hanselmann
    self.method = method
673 02cab3e7 Michael Hanselmann
    self.path = path
674 02cab3e7 Michael Hanselmann
    self.version = version
675 02cab3e7 Michael Hanselmann
676 02cab3e7 Michael Hanselmann
  def __str__(self):
677 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.method, self.path, self.version)
678 02cab3e7 Michael Hanselmann
679 02cab3e7 Michael Hanselmann
680 02cab3e7 Michael Hanselmann
class HttpServerToClientStartLine(object):
681 02cab3e7 Michael Hanselmann
  """Data structure for HTTP response start line.
682 02cab3e7 Michael Hanselmann

683 02cab3e7 Michael Hanselmann
  """
684 02cab3e7 Michael Hanselmann
  def __init__(self, version, code, reason):
685 02cab3e7 Michael Hanselmann
    self.version = version
686 02cab3e7 Michael Hanselmann
    self.code = code
687 02cab3e7 Michael Hanselmann
    self.reason = reason
688 02cab3e7 Michael Hanselmann
689 02cab3e7 Michael Hanselmann
  def __str__(self):
690 02cab3e7 Michael Hanselmann
    return "%s %s %s" % (self.version, self.code, self.reason)
691 02cab3e7 Michael Hanselmann
692 02cab3e7 Michael Hanselmann
693 02cab3e7 Michael Hanselmann
class HttpMessageWriter(object):
694 02cab3e7 Michael Hanselmann
  """Writes an HTTP message to a socket.
695 02cab3e7 Michael Hanselmann

696 02cab3e7 Michael Hanselmann
  """
697 02cab3e7 Michael Hanselmann
  def __init__(self, sock, msg, write_timeout):
698 358a8811 Michael Hanselmann
    """Initializes this class and writes an HTTP message to a socket.
699 358a8811 Michael Hanselmann

700 358a8811 Michael Hanselmann
    @type sock: socket
701 358a8811 Michael Hanselmann
    @param sock: Socket to be written to
702 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
703 358a8811 Michael Hanselmann
    @param msg: HTTP message to be written
704 358a8811 Michael Hanselmann
    @type write_timeout: float
705 358a8811 Michael Hanselmann
    @param write_timeout: Write timeout for socket
706 358a8811 Michael Hanselmann

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

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

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

766 5bbd3f7f Michael Hanselmann
    Can be overridden by subclasses.
767 02cab3e7 Michael Hanselmann

768 02cab3e7 Michael Hanselmann
    """
769 02cab3e7 Michael Hanselmann
    return bool(self._msg.body)
770 02cab3e7 Michael Hanselmann
771 02cab3e7 Michael Hanselmann
772 02cab3e7 Michael Hanselmann
class HttpMessageReader(object):
773 02cab3e7 Michael Hanselmann
  """Reads HTTP message from socket.
774 02cab3e7 Michael Hanselmann

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

789 358a8811 Michael Hanselmann
    @type sock: socket
790 358a8811 Michael Hanselmann
    @param sock: Socket to be read from
791 358a8811 Michael Hanselmann
    @type msg: http.HttpMessage
792 358a8811 Michael Hanselmann
    @param msg: Object for the read message
793 358a8811 Michael Hanselmann
    @type read_timeout: float
794 358a8811 Michael Hanselmann
    @param read_timeout: Read timeout for socket
795 358a8811 Michael Hanselmann

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

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

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

928 02cab3e7 Michael Hanselmann
    @type length: int
929 02cab3e7 Michael Hanselmann
    @param length: Buffer size
930 02cab3e7 Michael Hanselmann

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

940 02cab3e7 Michael Hanselmann
    @type length: int
941 02cab3e7 Michael Hanselmann
    @param length: Buffer size
942 02cab3e7 Michael Hanselmann

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

951 5bbd3f7f Michael Hanselmann
    Must be overridden by subclass.
952 02cab3e7 Michael Hanselmann

953 02cab3e7 Michael Hanselmann
    @type start_line: string
954 02cab3e7 Michael Hanselmann
    @param start_line: Start line string
955 02cab3e7 Michael Hanselmann

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

962 02cab3e7 Michael Hanselmann
    @rtype: bool
963 02cab3e7 Michael Hanselmann
    @return: Whether peer will close the connection
964 02cab3e7 Michael Hanselmann

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

1001 02cab3e7 Michael Hanselmann
    This function also adjusts internal variables based on header values.
1002 02cab3e7 Michael Hanselmann

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

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