Compare commits
1 Commits
amigaos
...
always-ssl
Author | SHA1 | Date |
---|---|---|
Matt Martz | 41c310f732 |
76
speedtest.py
76
speedtest.py
|
@ -412,6 +412,7 @@ class SpeedtestHTTPConnection(HTTPConnection):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
source_address = kwargs.pop('source_address', None)
|
source_address = kwargs.pop('source_address', None)
|
||||||
timeout = kwargs.pop('timeout', 10)
|
timeout = kwargs.pop('timeout', 10)
|
||||||
|
kwargs.pop('verify', None)
|
||||||
|
|
||||||
HTTPConnection.__init__(self, *args, **kwargs)
|
HTTPConnection.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -443,12 +444,22 @@ if HTTPSConnection:
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
source_address = kwargs.pop('source_address', None)
|
source_address = kwargs.pop('source_address', None)
|
||||||
timeout = kwargs.pop('timeout', 10)
|
timeout = kwargs.pop('timeout', 10)
|
||||||
|
verify = kwargs.pop('verify', True)
|
||||||
|
|
||||||
HTTPSConnection.__init__(self, *args, **kwargs)
|
HTTPSConnection.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.source_address = source_address
|
self.source_address = source_address
|
||||||
|
|
||||||
|
self.verify = verify
|
||||||
|
if not verify and hasattr(ssl, 'SSLContext'):
|
||||||
|
self._context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||||
|
if ssl.OP_NO_SSLv2:
|
||||||
|
self._context.options |= ssl.OP_NO_SSLv2
|
||||||
|
self._context.options |= ssl.OP_NO_SSLv3
|
||||||
|
self._context.verify_mode = ssl.CERT_NONE
|
||||||
|
self._context.check_hostname = False
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
"Connect to a host on a given (SSL) port."
|
"Connect to a host on a given (SSL) port."
|
||||||
|
|
||||||
|
@ -457,7 +468,7 @@ if HTTPSConnection:
|
||||||
if ssl:
|
if ssl:
|
||||||
try:
|
try:
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if hasattr(ssl, 'SSLContext'):
|
if hasattr(ssl, 'SSLContext') and self.verify:
|
||||||
kwargs['server_hostname'] = self.host
|
kwargs['server_hostname'] = self.host
|
||||||
self.sock = self._context.wrap_socket(self.sock, **kwargs)
|
self.sock = self._context.wrap_socket(self.sock, **kwargs)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -482,7 +493,8 @@ if HTTPSConnection:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _build_connection(connection, source_address, timeout, context=None):
|
def _build_connection(connection, source_address, timeout, verify=None,
|
||||||
|
context=None):
|
||||||
"""Cross Python 2.4 - Python 3 callable to build an ``HTTPConnection`` or
|
"""Cross Python 2.4 - Python 3 callable to build an ``HTTPConnection`` or
|
||||||
``HTTPSConnection`` with the args we need
|
``HTTPSConnection`` with the args we need
|
||||||
|
|
||||||
|
@ -492,7 +504,8 @@ def _build_connection(connection, source_address, timeout, context=None):
|
||||||
def inner(host, **kwargs):
|
def inner(host, **kwargs):
|
||||||
kwargs.update({
|
kwargs.update({
|
||||||
'source_address': source_address,
|
'source_address': source_address,
|
||||||
'timeout': timeout
|
'timeout': timeout,
|
||||||
|
'verify': verify,
|
||||||
})
|
})
|
||||||
if context:
|
if context:
|
||||||
kwargs['context'] = context
|
kwargs['context'] = context
|
||||||
|
@ -514,7 +527,7 @@ class SpeedtestHTTPHandler(AbstractHTTPHandler):
|
||||||
_build_connection(
|
_build_connection(
|
||||||
SpeedtestHTTPConnection,
|
SpeedtestHTTPConnection,
|
||||||
self.source_address,
|
self.source_address,
|
||||||
self.timeout
|
self.timeout,
|
||||||
),
|
),
|
||||||
req
|
req
|
||||||
)
|
)
|
||||||
|
@ -527,11 +540,12 @@ class SpeedtestHTTPSHandler(AbstractHTTPHandler):
|
||||||
args we need for ``source_address`` and ``timeout``
|
args we need for ``source_address`` and ``timeout``
|
||||||
"""
|
"""
|
||||||
def __init__(self, debuglevel=0, context=None, source_address=None,
|
def __init__(self, debuglevel=0, context=None, source_address=None,
|
||||||
timeout=10):
|
timeout=10, verify=True):
|
||||||
AbstractHTTPHandler.__init__(self, debuglevel)
|
AbstractHTTPHandler.__init__(self, debuglevel)
|
||||||
self._context = context
|
self._context = context
|
||||||
self.source_address = source_address
|
self.source_address = source_address
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
self.verify = verify
|
||||||
|
|
||||||
def https_open(self, req):
|
def https_open(self, req):
|
||||||
return self.do_open(
|
return self.do_open(
|
||||||
|
@ -539,6 +553,7 @@ class SpeedtestHTTPSHandler(AbstractHTTPHandler):
|
||||||
SpeedtestHTTPSConnection,
|
SpeedtestHTTPSConnection,
|
||||||
self.source_address,
|
self.source_address,
|
||||||
self.timeout,
|
self.timeout,
|
||||||
|
self.verify,
|
||||||
context=self._context,
|
context=self._context,
|
||||||
),
|
),
|
||||||
req
|
req
|
||||||
|
@ -547,7 +562,7 @@ class SpeedtestHTTPSHandler(AbstractHTTPHandler):
|
||||||
https_request = AbstractHTTPHandler.do_request_
|
https_request = AbstractHTTPHandler.do_request_
|
||||||
|
|
||||||
|
|
||||||
def build_opener(source_address=None, timeout=10):
|
def build_opener(source_address=None, timeout=10, verify=True):
|
||||||
"""Function similar to ``urllib2.build_opener`` that will build
|
"""Function similar to ``urllib2.build_opener`` that will build
|
||||||
an ``OpenerDirector`` with the explicit handlers we want,
|
an ``OpenerDirector`` with the explicit handlers we want,
|
||||||
``source_address`` for binding, ``timeout`` and our custom
|
``source_address`` for binding, ``timeout`` and our custom
|
||||||
|
@ -568,7 +583,7 @@ def build_opener(source_address=None, timeout=10):
|
||||||
SpeedtestHTTPHandler(source_address=source_address_tuple,
|
SpeedtestHTTPHandler(source_address=source_address_tuple,
|
||||||
timeout=timeout),
|
timeout=timeout),
|
||||||
SpeedtestHTTPSHandler(source_address=source_address_tuple,
|
SpeedtestHTTPSHandler(source_address=source_address_tuple,
|
||||||
timeout=timeout),
|
timeout=timeout, verify=verify),
|
||||||
HTTPDefaultErrorHandler(),
|
HTTPDefaultErrorHandler(),
|
||||||
HTTPRedirectHandler(),
|
HTTPRedirectHandler(),
|
||||||
HTTPErrorProcessor()
|
HTTPErrorProcessor()
|
||||||
|
@ -655,7 +670,7 @@ def build_user_agent():
|
||||||
return user_agent
|
return user_agent
|
||||||
|
|
||||||
|
|
||||||
def build_request(url, data=None, headers=None, bump='0', secure=False):
|
def build_request(url, data=None, headers=None, bump='0'):
|
||||||
"""Build a urllib2 request object
|
"""Build a urllib2 request object
|
||||||
|
|
||||||
This function automatically adds a User-Agent header to all requests
|
This function automatically adds a User-Agent header to all requests
|
||||||
|
@ -666,8 +681,7 @@ def build_request(url, data=None, headers=None, bump='0', secure=False):
|
||||||
headers = {}
|
headers = {}
|
||||||
|
|
||||||
if url[0] == ':':
|
if url[0] == ':':
|
||||||
scheme = ('http', 'https')[bool(secure)]
|
schemed_url = '%s%s' % ('https', url)
|
||||||
schemed_url = '%s%s' % (scheme, url)
|
|
||||||
else:
|
else:
|
||||||
schemed_url = url
|
schemed_url = url
|
||||||
|
|
||||||
|
@ -909,7 +923,7 @@ class SpeedtestResults(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, download=0, upload=0, ping=0, server=None, client=None,
|
def __init__(self, download=0, upload=0, ping=0, server=None, client=None,
|
||||||
opener=None, secure=False):
|
opener=None, verify=True):
|
||||||
self.download = download
|
self.download = download
|
||||||
self.upload = upload
|
self.upload = upload
|
||||||
self.ping = ping
|
self.ping = ping
|
||||||
|
@ -927,9 +941,7 @@ class SpeedtestResults(object):
|
||||||
if opener:
|
if opener:
|
||||||
self._opener = opener
|
self._opener = opener
|
||||||
else:
|
else:
|
||||||
self._opener = build_opener()
|
self._opener = build_opener(verify=verify)
|
||||||
|
|
||||||
self._secure = secure
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.dict())
|
return repr(self.dict())
|
||||||
|
@ -972,7 +984,7 @@ class SpeedtestResults(object):
|
||||||
headers = {'Referer': 'http://c.speedtest.net/flash/speedtest.swf'}
|
headers = {'Referer': 'http://c.speedtest.net/flash/speedtest.swf'}
|
||||||
request = build_request('://www.speedtest.net/api/api.php',
|
request = build_request('://www.speedtest.net/api/api.php',
|
||||||
data='&'.join(api_data).encode(),
|
data='&'.join(api_data).encode(),
|
||||||
headers=headers, secure=self._secure)
|
headers=headers)
|
||||||
f, e = catch_request(request, opener=self._opener)
|
f, e = catch_request(request, opener=self._opener)
|
||||||
if e:
|
if e:
|
||||||
raise ShareResultsConnectFailure(e)
|
raise ShareResultsConnectFailure(e)
|
||||||
|
@ -991,7 +1003,7 @@ class SpeedtestResults(object):
|
||||||
raise ShareResultsSubmitFailure('Could not submit results to '
|
raise ShareResultsSubmitFailure('Could not submit results to '
|
||||||
'speedtest.net')
|
'speedtest.net')
|
||||||
|
|
||||||
self._share = 'http://www.speedtest.net/result/%s.png' % resultid[0]
|
self._share = 'https://www.speedtest.net/result/%s.png' % resultid[0]
|
||||||
|
|
||||||
return self._share
|
return self._share
|
||||||
|
|
||||||
|
@ -1050,14 +1062,13 @@ class Speedtest(object):
|
||||||
"""Class for performing standard speedtest.net testing operations"""
|
"""Class for performing standard speedtest.net testing operations"""
|
||||||
|
|
||||||
def __init__(self, config=None, source_address=None, timeout=10,
|
def __init__(self, config=None, source_address=None, timeout=10,
|
||||||
secure=False, shutdown_event=None):
|
shutdown_event=None, verify=True):
|
||||||
self.config = {}
|
self.config = {}
|
||||||
|
|
||||||
self._source_address = source_address
|
self._source_address = source_address
|
||||||
self._timeout = timeout
|
self._timeout = timeout
|
||||||
self._opener = build_opener(source_address, timeout)
|
self._opener = build_opener(source_address, timeout, verify=verify)
|
||||||
|
self._verify = verify
|
||||||
self._secure = secure
|
|
||||||
|
|
||||||
if shutdown_event:
|
if shutdown_event:
|
||||||
self._shutdown_event = shutdown_event
|
self._shutdown_event = shutdown_event
|
||||||
|
@ -1075,7 +1086,7 @@ class Speedtest(object):
|
||||||
self.results = SpeedtestResults(
|
self.results = SpeedtestResults(
|
||||||
client=self.config['client'],
|
client=self.config['client'],
|
||||||
opener=self._opener,
|
opener=self._opener,
|
||||||
secure=secure,
|
verify=self._verify,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -1093,7 +1104,7 @@ class Speedtest(object):
|
||||||
if gzip:
|
if gzip:
|
||||||
headers['Accept-Encoding'] = 'gzip'
|
headers['Accept-Encoding'] = 'gzip'
|
||||||
request = build_request('://www.speedtest.net/speedtest-config.php',
|
request = build_request('://www.speedtest.net/speedtest-config.php',
|
||||||
headers=headers, secure=self._secure)
|
headers=headers)
|
||||||
uh, e = catch_request(request, opener=self._opener)
|
uh, e = catch_request(request, opener=self._opener)
|
||||||
if e:
|
if e:
|
||||||
raise ConfigRetrievalError(e)
|
raise ConfigRetrievalError(e)
|
||||||
|
@ -1223,9 +1234,7 @@ class Speedtest(object):
|
||||||
|
|
||||||
urls = [
|
urls = [
|
||||||
'://www.speedtest.net/speedtest-servers-static.php',
|
'://www.speedtest.net/speedtest-servers-static.php',
|
||||||
'http://c.speedtest.net/speedtest-servers-static.php',
|
|
||||||
'://www.speedtest.net/speedtest-servers.php',
|
'://www.speedtest.net/speedtest-servers.php',
|
||||||
'http://c.speedtest.net/speedtest-servers.php',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
|
@ -1239,7 +1248,6 @@ class Speedtest(object):
|
||||||
'%s?threads=%s' % (url,
|
'%s?threads=%s' % (url,
|
||||||
self.config['threads']['download']),
|
self.config['threads']['download']),
|
||||||
headers=headers,
|
headers=headers,
|
||||||
secure=self._secure
|
|
||||||
)
|
)
|
||||||
uh, e = catch_request(request, opener=self._opener)
|
uh, e = catch_request(request, opener=self._opener)
|
||||||
if e:
|
if e:
|
||||||
|
@ -1432,7 +1440,8 @@ class Speedtest(object):
|
||||||
if urlparts[0] == 'https':
|
if urlparts[0] == 'https':
|
||||||
h = SpeedtestHTTPSConnection(
|
h = SpeedtestHTTPSConnection(
|
||||||
urlparts[1],
|
urlparts[1],
|
||||||
source_address=source_address_tuple
|
source_address=source_address_tuple,
|
||||||
|
verify=self._verify,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
h = SpeedtestHTTPConnection(
|
h = SpeedtestHTTPConnection(
|
||||||
|
@ -1493,7 +1502,7 @@ class Speedtest(object):
|
||||||
requests = []
|
requests = []
|
||||||
for i, url in enumerate(urls):
|
for i, url in enumerate(urls):
|
||||||
requests.append(
|
requests.append(
|
||||||
build_request(url, bump=i, secure=self._secure)
|
build_request(url, bump=i)
|
||||||
)
|
)
|
||||||
|
|
||||||
def producer(q, requests, request_count):
|
def producer(q, requests, request_count):
|
||||||
|
@ -1576,7 +1585,7 @@ class Speedtest(object):
|
||||||
headers = {'Content-length': size}
|
headers = {'Content-length': size}
|
||||||
requests.append(
|
requests.append(
|
||||||
(
|
(
|
||||||
build_request(self.best['url'], data, secure=self._secure,
|
build_request(self.best['url'], data,
|
||||||
headers=headers),
|
headers=headers),
|
||||||
size
|
size
|
||||||
)
|
)
|
||||||
|
@ -1719,9 +1728,11 @@ def parse_args():
|
||||||
parser.add_argument('--source', help='Source IP address to bind to')
|
parser.add_argument('--source', help='Source IP address to bind to')
|
||||||
parser.add_argument('--timeout', default=10, type=PARSER_TYPE_FLOAT,
|
parser.add_argument('--timeout', default=10, type=PARSER_TYPE_FLOAT,
|
||||||
help='HTTP timeout in seconds. Default 10')
|
help='HTTP timeout in seconds. Default 10')
|
||||||
parser.add_argument('--secure', action='store_true',
|
parser.add_argument('--no-verify', default=True, dest='verify',
|
||||||
help='Use HTTPS instead of HTTP when communicating '
|
action='store_false',
|
||||||
'with speedtest.net operated servers')
|
help='Do not verify SSL certs, only affects Python '
|
||||||
|
'versions supporting SSL verification, such as '
|
||||||
|
'>=2.7.9 or where backported.')
|
||||||
parser.add_argument('--no-pre-allocate', dest='pre_allocate',
|
parser.add_argument('--no-pre-allocate', dest='pre_allocate',
|
||||||
action='store_const', default=True, const=False,
|
action='store_const', default=True, const=False,
|
||||||
help='Do not pre allocate upload data. Pre allocation '
|
help='Do not pre allocate upload data. Pre allocation '
|
||||||
|
@ -1751,7 +1762,6 @@ def validate_optional_args(args):
|
||||||
"""
|
"""
|
||||||
optional_args = {
|
optional_args = {
|
||||||
'json': ('json/simplejson python module', json),
|
'json': ('json/simplejson python module', json),
|
||||||
'secure': ('SSL support', HTTPSConnection),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for arg, info in optional_args.items():
|
for arg, info in optional_args.items():
|
||||||
|
@ -1834,7 +1844,7 @@ def shell():
|
||||||
speedtest = Speedtest(
|
speedtest = Speedtest(
|
||||||
source_address=args.source,
|
source_address=args.source,
|
||||||
timeout=args.timeout,
|
timeout=args.timeout,
|
||||||
secure=args.secure
|
verify=args.verify,
|
||||||
)
|
)
|
||||||
except (ConfigRetrievalError,) + HTTP_ERRORS:
|
except (ConfigRetrievalError,) + HTTP_ERRORS:
|
||||||
printer('Cannot retrieve speedtest configuration', error=True)
|
printer('Cannot retrieve speedtest configuration', error=True)
|
||||||
|
|
Loading…
Reference in New Issue