Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/websdk/mercurial/httpclient/socketutil.py
diff options
context:
space:
mode:
Diffstat (limited to 'websdk/mercurial/httpclient/socketutil.py')
-rw-r--r--websdk/mercurial/httpclient/socketutil.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/websdk/mercurial/httpclient/socketutil.py b/websdk/mercurial/httpclient/socketutil.py
new file mode 100644
index 0000000..6f06a3c
--- /dev/null
+++ b/websdk/mercurial/httpclient/socketutil.py
@@ -0,0 +1,127 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""Abstraction to simplify socket use for Python < 2.6
+
+This will attempt to use the ssl module and the new
+socket.create_connection method, but fall back to the old
+methods if those are unavailable.
+"""
+import logging
+import socket
+
+logger = logging.getLogger(__name__)
+
+try:
+ import ssl
+ ssl.wrap_socket # make demandimporters load the module
+ have_ssl = True
+except ImportError:
+ import httplib
+ import urllib2
+ have_ssl = getattr(urllib2, 'HTTPSHandler', False)
+ ssl = False
+
+
+try:
+ create_connection = socket.create_connection
+except AttributeError:
+ def create_connection(address):
+ host, port = address
+ msg = "getaddrinfo returns an empty list"
+ sock = None
+ for res in socket.getaddrinfo(host, port, 0,
+ socket.SOCK_STREAM):
+ af, socktype, proto, _canonname, sa = res
+ try:
+ sock = socket.socket(af, socktype, proto)
+ logger.info("connect: (%s, %s)", host, port)
+ sock.connect(sa)
+ except socket.error, msg:
+ logger.info('connect fail: %s %s', host, port)
+ if sock:
+ sock.close()
+ sock = None
+ continue
+ break
+ if not sock:
+ raise socket.error, msg
+ return sock
+
+if ssl:
+ wrap_socket = ssl.wrap_socket
+ CERT_NONE = ssl.CERT_NONE
+ CERT_OPTIONAL = ssl.CERT_OPTIONAL
+ CERT_REQUIRED = ssl.CERT_REQUIRED
+else:
+ class FakeSocket(httplib.FakeSocket):
+ """Socket wrapper that supports SSL.
+ """
+ # backport the behavior from Python 2.6, which is to busy wait
+ # on the socket instead of anything nice. Sigh.
+ # See http://bugs.python.org/issue3890 for more info.
+ def recv(self, buflen=1024, flags=0):
+ """ssl-aware wrapper around socket.recv
+ """
+ if flags != 0:
+ raise ValueError(
+ "non-zero flags not allowed in calls to recv() on %s" %
+ self.__class__)
+ while True:
+ try:
+ return self._ssl.read(buflen)
+ except socket.sslerror, x:
+ if x.args[0] == socket.SSL_ERROR_WANT_READ:
+ continue
+ else:
+ raise x
+
+ _PROTOCOL_SSLv23 = 2
+
+ CERT_NONE = 0
+ CERT_OPTIONAL = 1
+ CERT_REQUIRED = 2
+
+ def wrap_socket(sock, keyfile=None, certfile=None,
+ server_side=False, cert_reqs=CERT_NONE,
+ ssl_version=_PROTOCOL_SSLv23, ca_certs=None,
+ do_handshake_on_connect=True,
+ suppress_ragged_eofs=True):
+ if cert_reqs != CERT_NONE and ca_certs:
+ raise CertificateValidationUnsupported(
+ 'SSL certificate validation requires the ssl module'
+ '(included in Python 2.6 and later.)')
+ sslob = socket.ssl(sock)
+ # borrow httplib's workaround for no ssl.wrap_socket
+ sock = FakeSocket(sock, sslob)
+ return sock
+
+
+class CertificateValidationUnsupported(Exception):
+ """Exception raised when cert validation is requested but unavailable."""
+# no-check-code