From 56d566e55a2310007eef0d0c20aa814ead73d1a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Mon, 18 Aug 2014 19:16:13 +0000 Subject: [PATCH] add a tls_prefix parameter to utils.request This assumes that a backend only ever connects to a single domain, because we set the fingerprint on the whole session --- vdirsyncer/utils/__init__.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/vdirsyncer/utils/__init__.py b/vdirsyncer/utils/__init__.py index 937c439..402709a 100644 --- a/vdirsyncer/utils/__init__.py +++ b/vdirsyncer/utils/__init__.py @@ -12,6 +12,7 @@ import os import click import requests +from requests.packages.urllib3.poolmanager import PoolManager from .. import exceptions, log from .compat import iteritems, urlparse @@ -178,8 +179,23 @@ def _password_from_keyring(username, resource): key = new_key +class _FingerprintAdapter(requests.adapters.HTTPAdapter): + def __init__(self, fingerprint=None, **kwargs): + self.fingerprint = str(fingerprint) + super(_FingerprintAdapter, self).__init__(**kwargs) + + def send(self, *args, **kwargs): + return super(_FingerprintAdapter, self).send(*args, **kwargs) + + def init_poolmanager(self, connections, maxsize, block=False): + self.poolmanager = PoolManager(num_pools=connections, + maxsize=maxsize, + block=block, + assert_fingerprint=self.fingerprint) + + def request(method, url, data=None, headers=None, auth=None, verify=None, - session=None, latin1_fallback=True): + session=None, latin1_fallback=True, tls_fingerprint=None): ''' Wrapper method for requests, to ease logging and mocking. Parameters should be the same as for ``requests.request``, except: @@ -194,9 +210,16 @@ def request(method, url, data=None, headers=None, auth=None, verify=None, ''' if session is None: - func = requests.request - else: - func = session.request + session = requests.Session() + + if tls_fingerprint is not None: + https_prefix = 'https://' + + if not isinstance(session.adapters[https_prefix], _FingerprintAdapter): + fingerprint_adapter = _FingerprintAdapter(tls_fingerprint) + session.mount(https_prefix, fingerprint_adapter) + + func = session.request logger.debug(u'{} {}'.format(method, url)) logger.debug(headers)