feat(ST2.UtilPackages): bump up all packages

- Refresh PackageCache with latest versions of everything
This commit is contained in:
Iristyle
2013-09-16 22:35:46 -04:00
parent 7195197f0f
commit a000ce8acc
451 changed files with 14151 additions and 8317 deletions

View File

@@ -0,0 +1,65 @@
import sys
try:
# Python 2
import urllib2
import httplib
# Monkey patch AbstractBasicAuthHandler to prevent infinite recursion
def non_recursive_http_error_auth_reqed(self, authreq, host, req, headers):
authreq = headers.get(authreq, None)
if not hasattr(self, 'retried'):
self.retried = 0
if self.retried > 5:
raise urllib2.HTTPError(req.get_full_url(), 401, "basic auth failed",
headers, None)
else:
self.retried += 1
if authreq:
mo = urllib2.AbstractBasicAuthHandler.rx.search(authreq)
if mo:
scheme, quote, realm = mo.groups()
if scheme.lower() == 'basic':
return self.retry_http_basic_auth(host, req, realm)
urllib2.AbstractBasicAuthHandler.http_error_auth_reqed = non_recursive_http_error_auth_reqed
# Money patch urllib2.Request and httplib.HTTPConnection so that
# HTTPS proxies work in Python 2.6.1-2
if sys.version_info < (2, 6, 3):
urllib2.Request._tunnel_host = None
def py268_set_proxy(self, host, type):
if self.type == 'https' and not self._tunnel_host:
self._tunnel_host = self.host
else:
self.type = type
# The _Request prefix is to handle python private name mangling
self._Request__r_host = self._Request__original
self.host = host
urllib2.Request.set_proxy = py268_set_proxy
if sys.version_info < (2, 6, 5):
def py268_set_tunnel(self, host, port=None, headers=None):
""" Sets up the host and the port for the HTTP CONNECT Tunnelling.
The headers argument should be a mapping of extra HTTP headers
to send with the CONNECT request.
"""
self._tunnel_host = host
self._tunnel_port = port
if headers:
self._tunnel_headers = headers
else:
self._tunnel_headers.clear()
httplib.HTTPConnection._set_tunnel = py268_set_tunnel
except (ImportError):
# Python 3 does not need to be patched
pass

View File

@@ -0,0 +1,72 @@
import os
import re
import socket
try:
# Python 3
from http.client import HTTPConnection
from urllib.error import URLError
except (ImportError):
# Python 2
from httplib import HTTPConnection
from urllib2 import URLError
from ..console_write import console_write
from .debuggable_http_response import DebuggableHTTPResponse
class DebuggableHTTPConnection(HTTPConnection):
"""
A custom HTTPConnection that formats debugging info for Sublime Text
"""
response_class = DebuggableHTTPResponse
_debug_protocol = 'HTTP'
def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
**kwargs):
self.passwd = kwargs.get('passwd')
# Python 2.6.1 on OS X 10.6 does not include these
self._tunnel_host = None
self._tunnel_port = None
self._tunnel_headers = {}
if 'debug' in kwargs and kwargs['debug']:
self.debuglevel = 5
elif 'debuglevel' in kwargs:
self.debuglevel = kwargs['debuglevel']
HTTPConnection.__init__(self, host, port=port, timeout=timeout)
def connect(self):
if self.debuglevel == -1:
console_write(u'Urllib %s Debug General' % self._debug_protocol, True)
console_write(u" Connecting to %s on port %s" % (self.host, self.port))
HTTPConnection.connect(self)
def send(self, string):
# We have to use a positive debuglevel to get it passed to the
# HTTPResponse object, however we don't want to use it because by
# default debugging prints to the stdout and we can't capture it, so
# we temporarily set it to -1 for the standard httplib code
reset_debug = False
if self.debuglevel == 5:
reset_debug = 5
self.debuglevel = -1
HTTPConnection.send(self, string)
if reset_debug or self.debuglevel == -1:
if len(string.strip()) > 0:
console_write(u'Urllib %s Debug Write' % self._debug_protocol, True)
for line in string.strip().splitlines():
console_write(u' ' + line.decode('iso-8859-1'))
if reset_debug:
self.debuglevel = reset_debug
def request(self, method, url, body=None, headers={}):
original_headers = headers.copy()
# By default urllib2 and urllib.request override the Connection header,
# however, it is preferred to be able to re-use it
original_headers['Connection'] = 'Keep-Alive'
HTTPConnection.request(self, method, url, body, original_headers)

View File

@@ -0,0 +1,35 @@
import sys
try:
# Python 3
from urllib.request import HTTPHandler
except (ImportError):
# Python 2
from urllib2 import HTTPHandler
from .debuggable_http_connection import DebuggableHTTPConnection
from .persistent_handler import PersistentHandler
class DebuggableHTTPHandler(PersistentHandler, HTTPHandler):
"""
A custom HTTPHandler that formats debugging info for Sublime Text
"""
def __init__(self, debuglevel=0, debug=False, **kwargs):
# This is a special value that will not trigger the standard debug
# functionality, but custom code where we can format the output
if debug:
self._debuglevel = 5
else:
self._debuglevel = debuglevel
self.passwd = kwargs.get('passwd')
def http_open(self, req):
def http_class_wrapper(host, **kwargs):
kwargs['passwd'] = self.passwd
if 'debuglevel' not in kwargs:
kwargs['debuglevel'] = self._debuglevel
return DebuggableHTTPConnection(host, **kwargs)
return self.do_open(http_class_wrapper, req)

View File

@@ -0,0 +1,66 @@
try:
# Python 3
from http.client import HTTPResponse, IncompleteRead
except (ImportError):
# Python 2
from httplib import HTTPResponse, IncompleteRead
from ..console_write import console_write
class DebuggableHTTPResponse(HTTPResponse):
"""
A custom HTTPResponse that formats debugging info for Sublime Text
"""
_debug_protocol = 'HTTP'
def __init__(self, sock, debuglevel=0, method=None, **kwargs):
# We have to use a positive debuglevel to get it passed to here,
# however we don't want to use it because by default debugging prints
# to the stdout and we can't capture it, so we use a special -1 value
if debuglevel == 5:
debuglevel = -1
HTTPResponse.__init__(self, sock, debuglevel=debuglevel, method=method)
def begin(self):
return_value = HTTPResponse.begin(self)
if self.debuglevel == -1:
console_write(u'Urllib %s Debug Read' % self._debug_protocol, True)
# Python 2
if hasattr(self.msg, 'headers'):
headers = self.msg.headers
# Python 3
else:
headers = []
for header in self.msg:
headers.append("%s: %s" % (header, self.msg[header]))
versions = {
9: 'HTTP/0.9',
10: 'HTTP/1.0',
11: 'HTTP/1.1'
}
status_line = versions[self.version] + ' ' + str(self.status) + ' ' + self.reason
headers.insert(0, status_line)
for line in headers:
console_write(u" %s" % line.rstrip())
return return_value
def is_keep_alive(self):
# Python 2
if hasattr(self.msg, 'headers'):
connection = self.msg.getheader('connection')
# Python 3
else:
connection = self.msg['connection']
if connection and connection.lower() == 'keep-alive':
return True
return False
def read(self, *args):
try:
return HTTPResponse.read(self, *args)
except (IncompleteRead) as e:
return e.partial

View File

@@ -0,0 +1,9 @@
from .debuggable_http_response import DebuggableHTTPResponse
class DebuggableHTTPSResponse(DebuggableHTTPResponse):
"""
A version of DebuggableHTTPResponse that sets the debug protocol to HTTPS
"""
_debug_protocol = 'HTTPS'

View File

@@ -0,0 +1,25 @@
try:
# Python 3
from http.client import HTTPException
from urllib.error import URLError
except (ImportError):
# Python 2
from httplib import HTTPException
from urllib2 import URLError
class InvalidCertificateException(HTTPException, URLError):
"""
An exception for when an SSL certification is not valid for the URL
it was presented for.
"""
def __init__(self, host, cert, reason):
HTTPException.__init__(self)
self.host = host
self.cert = cert
self.reason = reason
def __str__(self):
return ('Host %s returned an invalid certificate (%s) %s\n' %
(self.host, self.reason, self.cert))

View File

@@ -0,0 +1,116 @@
import sys
import socket
try:
# Python 3
from urllib.error import URLError
except ImportError:
# Python 2
from urllib2 import URLError
from urllib import addinfourl
from ..console_write import console_write
class PersistentHandler:
connection = None
use_count = 0
def close(self):
if self.connection:
if self._debuglevel == 5:
s = '' if self.use_count == 1 else 's'
console_write(u"Urllib %s Debug General" % self.connection._debug_protocol, True)
console_write(u" Closing connection to %s on port %s after %s request%s" % (
self.connection.host, self.connection.port, self.use_count, s))
self.connection.close()
self.connection = None
self.use_count = 0
def do_open(self, http_class, req):
# Large portions from Python 3.3 Lib/urllib/request.py and
# Python 2.6 Lib/urllib2.py
if sys.version_info >= (3,):
host = req.host
else:
host = req.get_host()
if not host:
raise URLError('no host given')
if self.connection and self.connection.host != host:
self.close()
# Re-use the connection if possible
self.use_count += 1
if not self.connection:
h = http_class(host, timeout=req.timeout)
else:
h = self.connection
if self._debuglevel == 5:
console_write(u"Urllib %s Debug General" % h._debug_protocol, True)
console_write(u" Re-using connection to %s on port %s for request #%s" % (
h.host, h.port, self.use_count))
if sys.version_info >= (3,):
headers = dict(req.unredirected_hdrs)
headers.update(dict((k, v) for k, v in req.headers.items()
if k not in headers))
headers = dict((name.title(), val) for name, val in headers.items())
else:
h.set_debuglevel(self._debuglevel)
headers = dict(req.headers)
headers.update(req.unredirected_hdrs)
headers = dict(
(name.title(), val) for name, val in headers.items())
if req._tunnel_host and not self.connection:
tunnel_headers = {}
proxy_auth_hdr = "Proxy-Authorization"
if proxy_auth_hdr in headers:
tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
del headers[proxy_auth_hdr]
if sys.version_info >= (3,):
h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
else:
h._set_tunnel(req._tunnel_host, headers=tunnel_headers)
try:
if sys.version_info >= (3,):
h.request(req.get_method(), req.selector, req.data, headers)
else:
h.request(req.get_method(), req.get_selector(), req.data, headers)
except socket.error as err: # timeout error
h.close()
raise URLError(err)
else:
r = h.getresponse()
# Keep the connection around for re-use
if r.is_keep_alive():
self.connection = h
else:
if self._debuglevel == 5:
s = '' if self.use_count == 1 else 's'
console_write(u"Urllib %s Debug General" % h._debug_protocol, True)
console_write(u" Closing connection to %s on port %s after %s request%s" % (
h.host, h.port, self.use_count, s))
self.use_count = 0
self.connection = None
if sys.version_info >= (3,):
r.url = req.get_full_url()
r.msg = r.reason
return r
r.recv = r.read
fp = socket._fileobject(r, close=True)
resp = addinfourl(fp, r.msg, req.get_full_url())
resp.code = r.status
resp.msg = r.reason
return resp

View File

@@ -0,0 +1,345 @@
import re
import socket
import base64
import hashlib
import os
import sys
try:
# Python 3
from http.client import HTTPS_PORT
from urllib.request import parse_keqv_list, parse_http_list
except (ImportError):
# Python 2
from httplib import HTTPS_PORT
from urllib2 import parse_keqv_list, parse_http_list
from ..console_write import console_write
from .debuggable_https_response import DebuggableHTTPSResponse
from .debuggable_http_connection import DebuggableHTTPConnection
from .invalid_certificate_exception import InvalidCertificateException
# The following code is wrapped in a try because the Linux versions of Sublime
# Text do not include the ssl module due to the fact that different distros
# have different versions
try:
import ssl
class ValidatingHTTPSConnection(DebuggableHTTPConnection):
"""
A custom HTTPConnection class that validates SSL certificates, and
allows proxy authentication for HTTPS connections.
"""
default_port = HTTPS_PORT
response_class = DebuggableHTTPSResponse
_debug_protocol = 'HTTPS'
def __init__(self, host, port=None, key_file=None, cert_file=None,
ca_certs=None, **kwargs):
passed_args = {}
if 'timeout' in kwargs:
passed_args['timeout'] = kwargs['timeout']
if 'debug' in kwargs:
passed_args['debug'] = kwargs['debug']
DebuggableHTTPConnection.__init__(self, host, port, **passed_args)
self.passwd = kwargs.get('passwd')
self.key_file = key_file
self.cert_file = cert_file
self.ca_certs = ca_certs
if 'user_agent' in kwargs:
self.user_agent = kwargs['user_agent']
if self.ca_certs:
self.cert_reqs = ssl.CERT_REQUIRED
else:
self.cert_reqs = ssl.CERT_NONE
def get_valid_hosts_for_cert(self, cert):
"""
Returns a list of valid hostnames for an SSL certificate
:param cert: A dict from SSLSocket.getpeercert()
:return: An array of hostnames
"""
if 'subjectAltName' in cert:
return [x[1] for x in cert['subjectAltName']
if x[0].lower() == 'dns']
else:
return [x[0][1] for x in cert['subject']
if x[0][0].lower() == 'commonname']
def validate_cert_host(self, cert, hostname):
"""
Checks if the cert is valid for the hostname
:param cert: A dict from SSLSocket.getpeercert()
:param hostname: A string hostname to check
:return: A boolean if the cert is valid for the hostname
"""
hosts = self.get_valid_hosts_for_cert(cert)
for host in hosts:
host_re = host.replace('.', '\.').replace('*', '[^.]*')
if re.search('^%s$' % (host_re,), hostname, re.I):
return True
return False
def _tunnel(self):
"""
This custom _tunnel method allows us to read and print the debug
log for the whole response before throwing an error, and adds
support for proxy authentication
"""
self._proxy_host = self.host
self._proxy_port = self.port
self._set_hostport(self._tunnel_host, self._tunnel_port)
self._tunnel_headers['Host'] = u"%s:%s" % (self.host, self.port)
self._tunnel_headers['User-Agent'] = self.user_agent
self._tunnel_headers['Proxy-Connection'] = 'Keep-Alive'
request = "CONNECT %s:%d HTTP/1.1\r\n" % (self.host, self.port)
for header, value in self._tunnel_headers.items():
request += "%s: %s\r\n" % (header, value)
request += "\r\n"
if sys.version_info >= (3,):
request = bytes(request, 'iso-8859-1')
self.send(request)
response = self.response_class(self.sock, method=self._method)
(version, code, message) = response._read_status()
status_line = u"%s %s %s" % (version, code, message.rstrip())
headers = [status_line]
if self.debuglevel in [-1, 5]:
console_write(u'Urllib %s Debug Read' % self._debug_protocol, True)
console_write(u" %s" % status_line)
content_length = 0
close_connection = False
while True:
line = response.fp.readline()
if sys.version_info >= (3,):
line = str(line, encoding='iso-8859-1')
if line == '\r\n':
break
headers.append(line.rstrip())
parts = line.rstrip().split(': ', 1)
name = parts[0].lower()
value = parts[1].lower().strip()
if name == 'content-length':
content_length = int(value)
if name in ['connection', 'proxy-connection'] and value == 'close':
close_connection = True
if self.debuglevel in [-1, 5]:
console_write(u" %s" % line.rstrip())
# Handle proxy auth for SSL connections since regular urllib punts on this
if code == 407 and self.passwd and 'Proxy-Authorization' not in self._tunnel_headers:
if content_length:
response._safe_read(content_length)
supported_auth_methods = {}
for line in headers:
parts = line.split(': ', 1)
if parts[0].lower() != 'proxy-authenticate':
continue
details = parts[1].split(' ', 1)
supported_auth_methods[details[0].lower()] = details[1] if len(details) > 1 else ''
username, password = self.passwd.find_user_password(None, "%s:%s" % (
self._proxy_host, self._proxy_port))
if 'digest' in supported_auth_methods:
response_value = self.build_digest_response(
supported_auth_methods['digest'], username, password)
if response_value:
self._tunnel_headers['Proxy-Authorization'] = u"Digest %s" % response_value
elif 'basic' in supported_auth_methods:
response_value = u"%s:%s" % (username, password)
response_value = base64.b64encode(response_value).strip()
self._tunnel_headers['Proxy-Authorization'] = u"Basic %s" % response_value
if 'Proxy-Authorization' in self._tunnel_headers:
self.host = self._proxy_host
self.port = self._proxy_port
# If the proxy wanted the connection closed, we need to make a new connection
if close_connection:
self.sock.close()
self.sock = socket.create_connection((self.host, self.port), self.timeout)
return self._tunnel()
if code != 200:
self.close()
raise socket.error("Tunnel connection failed: %d %s" % (code,
message.strip()))
def build_digest_response(self, fields, username, password):
"""
Takes a Proxy-Authenticate: Digest header and creates a response
header
:param fields:
The string portion of the Proxy-Authenticate header after
"Digest "
:param username:
The username to use for the response
:param password:
The password to use for the response
:return:
None if invalid Proxy-Authenticate header, otherwise the
string of fields for the Proxy-Authorization: Digest header
"""
fields = parse_keqv_list(parse_http_list(fields))
realm = fields.get('realm')
nonce = fields.get('nonce')
qop = fields.get('qop')
algorithm = fields.get('algorithm')
if algorithm:
algorithm = algorithm.lower()
opaque = fields.get('opaque')
if algorithm in ['md5', None]:
def md5hash(string):
return hashlib.md5(string).hexdigest()
hash = md5hash
elif algorithm == 'sha':
def sha1hash(string):
return hashlib.sha1(string).hexdigest()
hash = sha1hash
else:
return None
host_port = u"%s:%s" % (self.host, self.port)
a1 = "%s:%s:%s" % (username, realm, password)
a2 = "CONNECT:%s" % host_port
ha1 = hash(a1)
ha2 = hash(a2)
if qop == None:
response = hash(u"%s:%s:%s" % (ha1, nonce, ha2))
elif qop == 'auth':
nc = '00000001'
cnonce = hash(os.urandom(8))[:8]
response = hash(u"%s:%s:%s:%s:%s:%s" % (ha1, nonce, nc, cnonce, qop, ha2))
else:
return None
response_fields = {
'username': username,
'realm': realm,
'nonce': nonce,
'response': response,
'uri': host_port
}
if algorithm:
response_fields['algorithm'] = algorithm
if qop == 'auth':
response_fields['nc'] = nc
response_fields['cnonce'] = cnonce
response_fields['qop'] = qop
if opaque:
response_fields['opaque'] = opaque
return ', '.join([u"%s=\"%s\"" % (field, response_fields[field]) for field in response_fields])
def connect(self):
"""
Adds debugging and SSL certification validation
"""
if self.debuglevel == -1:
console_write(u"Urllib HTTPS Debug General", True)
console_write(u" Connecting to %s on port %s" % (self.host, self.port))
self.sock = socket.create_connection((self.host, self.port), self.timeout)
if self._tunnel_host:
self._tunnel()
if self.debuglevel == -1:
console_write(u"Urllib HTTPS Debug General", True)
console_write(u" Connecting to %s on port %s" % (self.host, self.port))
console_write(u" CA certs file at %s" % (self.ca_certs.decode(sys.getfilesystemencoding())))
self.sock = ssl.wrap_socket(self.sock, keyfile=self.key_file,
certfile=self.cert_file, cert_reqs=self.cert_reqs,
ca_certs=self.ca_certs)
if self.debuglevel == -1:
console_write(u" Successfully upgraded connection to %s:%s with SSL" % (
self.host, self.port))
# This debugs and validates the SSL certificate
if self.cert_reqs & ssl.CERT_REQUIRED:
cert = self.sock.getpeercert()
if self.debuglevel == -1:
subjectMap = {
'organizationName': 'O',
'commonName': 'CN',
'organizationalUnitName': 'OU',
'countryName': 'C',
'serialNumber': 'serialNumber',
'commonName': 'CN',
'localityName': 'L',
'stateOrProvinceName': 'S'
}
subject_list = list(cert['subject'])
subject_list.reverse()
subject_parts = []
for pair in subject_list:
if pair[0][0] in subjectMap:
field_name = subjectMap[pair[0][0]]
else:
field_name = pair[0][0]
subject_parts.append(field_name + '=' + pair[0][1])
console_write(u" Server SSL certificate:")
console_write(u" subject: " + ','.join(subject_parts))
if 'subjectAltName' in cert:
console_write(u" common name: " + cert['subjectAltName'][0][1])
if 'notAfter' in cert:
console_write(u" expire date: " + cert['notAfter'])
hostname = self.host.split(':', 0)[0]
if not self.validate_cert_host(cert, hostname):
if self.debuglevel == -1:
console_write(u" Certificate INVALID")
raise InvalidCertificateException(hostname, cert,
'hostname mismatch')
if self.debuglevel == -1:
console_write(u" Certificate validated for %s" % hostname)
except (ImportError):
pass

View File

@@ -0,0 +1,59 @@
try:
# Python 3
from urllib.error import URLError
import urllib.request as urllib_compat
except (ImportError):
# Python 2
from urllib2 import URLError
import urllib2 as urllib_compat
# The following code is wrapped in a try because the Linux versions of Sublime
# Text do not include the ssl module due to the fact that different distros
# have different versions
try:
import ssl
from .validating_https_connection import ValidatingHTTPSConnection
from .invalid_certificate_exception import InvalidCertificateException
from .persistent_handler import PersistentHandler
if hasattr(urllib_compat, 'HTTPSHandler'):
class ValidatingHTTPSHandler(PersistentHandler, urllib_compat.HTTPSHandler):
"""
A urllib handler that validates SSL certificates for HTTPS requests
"""
def __init__(self, **kwargs):
# This is a special value that will not trigger the standard debug
# functionality, but custom code where we can format the output
self._debuglevel = 0
if 'debug' in kwargs and kwargs['debug']:
self._debuglevel = 5
elif 'debuglevel' in kwargs:
self._debuglevel = kwargs['debuglevel']
self._connection_args = kwargs
def https_open(self, req):
def http_class_wrapper(host, **kwargs):
full_kwargs = dict(self._connection_args)
full_kwargs.update(kwargs)
return ValidatingHTTPSConnection(host, **full_kwargs)
try:
return self.do_open(http_class_wrapper, req)
except URLError as e:
if type(e.reason) == ssl.SSLError and e.reason.args[0] == 1:
raise InvalidCertificateException(req.host, '',
e.reason.args[1])
raise
https_request = urllib_compat.AbstractHTTPHandler.do_request_
else:
raise ImportError()
except (ImportError) as e:
class ValidatingHTTPSHandler():
def __init__(self, **kwargs):
raise e