rapi.client, http.client: Format url correctly when using IPv6
[ganeti-local] / lib / http / __init__.py
index b291715..203e0d5 100644 (file)
@@ -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
@@ -32,7 +32,6 @@ import errno
 from cStringIO import StringIO
 
 from ganeti import constants
-from ganeti import serializer
 from ganeti import utils
 
 
@@ -67,6 +66,7 @@ HTTP_AUTHENTICATION_INFO = "Authentication-Info"
 HTTP_ALLOW = "Allow"
 
 HTTP_APP_OCTET_STREAM = "application/octet-stream"
+HTTP_APP_JSON = "application/json"
 
 _SSL_UNEXPECTED_EOF = "Unexpected EOF"
 
@@ -323,56 +323,6 @@ class HttpVersionNotSupported(HttpException):
   code = 505
 
 
-class HttpJsonConverter: # pylint: disable-msg=W0232
-  CONTENT_TYPE = "application/json"
-
-  @staticmethod
-  def Encode(data):
-    return serializer.DumpJson(data)
-
-  @staticmethod
-  def Decode(data):
-    return serializer.LoadJson(data)
-
-
-def WaitForSocketCondition(sock, event, timeout):
-  """Waits for a condition to occur on the socket.
-
-  @type sock: socket
-  @param sock: Wait for events on this socket
-  @type event: int
-  @param event: ORed condition (see select module)
-  @type timeout: float or None
-  @param timeout: Timeout in seconds
-  @rtype: int or None
-  @return: None for timeout, otherwise occured conditions
-
-  """
-  check = (event | select.POLLPRI |
-           select.POLLNVAL | select.POLLHUP | select.POLLERR)
-
-  if timeout is not None:
-    # Poller object expects milliseconds
-    timeout *= 1000
-
-  poller = select.poll()
-  poller.register(sock, event)
-  try:
-    while True:
-      # TODO: If the main thread receives a signal and we have no timeout, we
-      # could wait forever. This should check a global "quit" flag or
-      # something every so often.
-      io_events = poller.poll(timeout)
-      if not io_events:
-        # Timeout
-        return None
-      for (_, evcond) in io_events:
-        if evcond & check:
-          return evcond
-  finally:
-    poller.unregister(sock)
-
-
 def SocketOperation(sock, op, arg1, timeout):
   """Wrapper around socket functions.
 
@@ -423,13 +373,13 @@ def SocketOperation(sock, op, arg1, timeout):
       else:
         wait_for_event = event_poll
 
-      event = WaitForSocketCondition(sock, wait_for_event, timeout)
+      event = utils.WaitForFdCondition(sock, wait_for_event, timeout)
       if event is None:
         raise HttpSocketTimeout()
 
-      if (op == SOCKOP_RECV and
-          event & (select.POLLNVAL | select.POLLHUP | select.POLLERR)):
-        return ""
+      if event & (select.POLLNVAL | select.POLLHUP | select.POLLERR):
+        # Let the socket functions handle these
+        break
 
       if not event & wait_for_event:
         continue
@@ -620,7 +570,7 @@ class HttpBase(object):
     self._ssl_key = None
     self._ssl_cert = None
 
-  def _CreateSocket(self, ssl_params, ssl_verify_peer):
+  def _CreateSocket(self, ssl_params, ssl_verify_peer, family):
     """Creates a TCP socket and initializes SSL if needed.
 
     @type ssl_params: HttpSslParams
@@ -628,11 +578,14 @@ class HttpBase(object):
     @type ssl_verify_peer: bool
     @param ssl_verify_peer: Whether to require client certificate
         and compare it with our certificate
+    @type family: int
+    @param family: socket.AF_INET | socket.AF_INET6
 
     """
-    self._ssl_params = ssl_params
+    assert family in (socket.AF_INET, socket.AF_INET6)
 
-    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    self._ssl_params = ssl_params
+    sock = socket.socket(family, socket.SOCK_STREAM)
 
     # Should we enable SSL?
     self.using_ssl = ssl_params is not None
@@ -645,6 +598,7 @@ class HttpBase(object):
 
     ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
     ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2)
+    ctx.set_cipher_list(constants.OPENSSL_CIPHERS)
 
     ctx.use_privatekey(self._ssl_key)
     ctx.use_certificate(self._ssl_cert)
@@ -877,7 +831,7 @@ class HttpMessageReader(object):
         # the CRLF."
         if idx == 0:
           # TODO: Limit number of CRLFs/empty lines for safety?
-          buf = buf[:2]
+          buf = buf[2:]
           continue
 
         if idx > 0:
@@ -1034,7 +988,7 @@ class HttpMessageReader(object):
     if hdr_content_length:
       try:
         self.content_length = int(hdr_content_length)
-      except ValueError:
+      except (TypeError, ValueError):
         self.content_length = None
       if self.content_length is not None and self.content_length < 0:
         self.content_length = None