X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/a8950eb7a262abed064eefd885f98fe4ca2ca339..b459a848d:/lib/http/server.py diff --git a/lib/http/server.py b/lib/http/server.py index 3a05a43..cb76185 100644 --- a/lib/http/server.py +++ b/lib/http/server.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2007, 2008 Google Inc. +# Copyright (C) 2007, 2008, 2010 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -33,12 +33,13 @@ import asyncore from ganeti import http from ganeti import utils +from ganeti import netutils -WEEKDAYNAME = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] +WEEKDAYNAME = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] MONTHNAME = [None, - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] # Default error message DEFAULT_ERROR_CONTENT_TYPE = "text/html" @@ -88,6 +89,14 @@ class _HttpServerRequest(object): # authentication) self.private = None + def __repr__(self): + status = ["%s.%s" % (self.__class__.__module__, self.__class__.__name__), + self.request_method, self.request_path, + "headers=%r" % str(self.request_headers), + "body=%r" % (self.request_body, )] + + return "<%s at %#x>" % (" ".join(status), id(self)) + class _HttpServerToClientMessageWriter(http.HttpMessageWriter): """Writes an HTTP response to client. @@ -169,7 +178,7 @@ class _HttpClientToServerMessageReader(http.HttpMessageReader): if len(words) == 3: [method, path, version] = words - if version[:5] != 'HTTP/': + if version[:5] != "HTTP/": raise http.HttpBadRequest("Bad request version (%r)" % version) try: @@ -269,6 +278,14 @@ class HttpServerRequestExecutor(object): try: try: request_msg_reader = self._ReadRequest() + + # RFC2616, 14.23: All Internet-based HTTP/1.1 servers MUST respond + # with a 400 (Bad Request) status code to any HTTP/1.1 request + # message which lacks a Host header field. + if (self.request_msg.start_line.version == http.HTTP_1_1 and + http.HTTP_HOST not in self.request_msg.headers): + raise http.HttpBadRequest(message="Missing Host header") + self._HandleRequest() # Only wait for client to close if we didn't have any exception. @@ -311,7 +328,9 @@ class HttpServerRequestExecutor(object): handler_context = _HttpServerRequest(self.request_msg.start_line.method, self.request_msg.start_line.path, self.request_msg.headers, - self.request_msg.decoded_body) + self.request_msg.body) + + logging.debug("Handling request %r", handler_context) try: try: @@ -329,12 +348,12 @@ class HttpServerRequestExecutor(object): logging.exception("Unknown exception") raise http.HttpInternalServerError(message="Unknown error") - # TODO: Content-type - encoder = http.HttpJsonConverter() + if not isinstance(result, basestring): + raise http.HttpError("Handler function didn't return string type") + self.response_msg.start_line.code = http.HTTP_OK - self.response_msg.body = encoder.Encode(result) self.response_msg.headers = handler_context.resp_headers - self.response_msg.headers[http.HTTP_CONTENT_TYPE] = encoder.CONTENT_TYPE + self.response_msg.body = result finally: # No reason to keep this any longer, even for exceptions handler_context.private = None @@ -419,6 +438,7 @@ class HttpServerRequestExecutor(object): """ return self.error_message_format % values + class HttpServer(http.HttpBase, asyncore.dispatcher): """Generic HTTP server class @@ -459,8 +479,8 @@ class HttpServer(http.HttpBase, asyncore.dispatcher): self.mainloop = mainloop self.local_address = local_address self.port = port - - self.socket = self._CreateSocket(ssl_params, ssl_verify_peer) + family = netutils.IPAddress.GetAddressFamily(local_address) + self.socket = self._CreateSocket(ssl_params, ssl_verify_peer, family) # Allow port to be reused self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -517,7 +537,7 @@ class HttpServer(http.HttpBase, asyncore.dispatcher): """Called for each incoming connection """ - # pylint: disable-msg=W0212 + # pylint: disable=W0212 (connection, client_addr) = self.socket.accept() self._CollectChildren(False) @@ -540,7 +560,7 @@ class HttpServer(http.HttpBase, asyncore.dispatcher): utils.ResetTempfileModule() self.request_executor(self, connection, client_addr) - except Exception: # pylint: disable-msg=W0703 + except Exception: # pylint: disable=W0703 logging.exception("Error while handling request from %s:%s", client_addr[0], client_addr[1]) os._exit(1)