diff -ur release/fedora/client/proxyclient.py p/fedora/client/proxyclient.py --- release/fedora/client/proxyclient.py 2013-04-01 11:28:08.461340997 -0700 +++ p/fedora/client/proxyclient.py 2013-04-04 10:13:56.173838097 -0700 @@ -27,7 +27,8 @@ import urllib import httplib import logging -import requests +# For handling an exception that's coming from requests: +import ssl import time import warnings @@ -46,6 +47,9 @@ from bunch import bunchify from kitchen.text.converters import to_bytes +import requests +# For handling an exception that's coming from requests: +import urllib3 from fedora import __version__, b_ from fedora.client import AppError, AuthError, ServerError @@ -112,7 +116,7 @@ .. attribute:: timeout A float describing the timeout of the connection. The timeout only affects the connection process itself, not the downloading of the - response body. Defaults to 30 seconds. + response body. Defaults to 120 seconds. .. versionchanged:: 0.3.33 Added the timeout attribute @@ -120,8 +124,8 @@ log = log def __init__(self, base_url, useragent=None, session_name='tg-visit', - session_as_cookie=True, debug=False, insecure=False, retries=0, - timeout=30.0): + session_as_cookie=True, debug=False, insecure=False, retries=None, + timeout=None): '''Create a client configured for a particular service. :arg base_url: Base of every URL used to contact the server @@ -144,7 +148,7 @@ number makes it try forever. Defaults to zero, no retries. :kwarg timeout: A float describing the timeout of the connection. The timeout only affects the connection process itself, not the downloading - of the response body. Defaults to 30 seconds. + of the response body. Defaults to 120 seconds. .. versionchanged:: 0.3.33 Added the timeout kwarg @@ -178,8 +182,17 @@ ' constructor with session_as_cookie=False'), DeprecationWarning, stacklevel=2) self.insecure = insecure - self.retries = retries or 0 - self.timeout = timeout or 30.0 + + # Have to do retries and timeout default values this way as BaseClient + # sends None for these values if not overridden by the user. + if retries is None: + retries = 0 + else: + self.retries = retries + if timeout is None: + self.timeout = 120.0 + else: + self.timeout = timeout self.log.debug(b_('proxyclient.__init__:exited')) def __get_debug(self): @@ -381,18 +394,41 @@ verify=not self.insecure, timeout=timeout, ) - except requests.Timeout: + except (requests.Timeout, requests.exceptions.SSLError) as e: + if isinstance(e, requests.exceptions.SSLError): + # And now we know how not to code a library exception + # hierarchy... We're expecting that requests is raising + # the following stupidity: + # requests.exceptions.SSLError( + # urllib3.exceptions.SSLError( + # ssl.SSLError('The read operation timed out'))) + # If we weren't interested in reraising the exception with + # full tracdeback we could use a try: except instead of + # this gross conditional. But we need to code defensively + # because we don't want to raise an unrelated exception + # here and if requests/urllib3 can do this sort of + # nonsense, they may change the nonsense in the future + if not (e.args and isinstance(e.args[0], + urllib3.exceptions.SSLError) + and e.args[0].args + and isinstance(e.args[0].args[0], ssl.SSLError) + and e.args[0].args[0].args + and 'timed out' in e.args[0].args[0].args[0]): + # We're only interested in timeouts here + raise self.log.debug(b_('Request timed out')) if retries < 0 or num_tries < retries: num_tries += 1 self.log.debug(b_('Attempt #%(try)s failed') % {'try': num_tries}) time.sleep(0.5) continue + # Fail and raise an error + # Raising our own exception protects the user from the + # implementation detail of requests vs pycurl vs urllib + raise ServerError(url, -1, 'Request timed out after %s seconds' % timeout) # When the python-requests module gets a response, it attempts to - # guess the encoding using "charade", a fork of "chardet" which it - # bundles (and which we are in the process of unbundling: - # https://bugzilla.redhat.com/show_bug.cgi?id=910236). + # guess the encoding using chardet (or a fork) # That process can take an extraordinarily long time for long # response.text strings.. upwards of 30 minutes for FAS queries to # /accounts/user/list JSON api! Therefore, we cut that codepath Only in release/fedora: __init__.pyc Only in release/fedora: release.pyc diff -ur release/flask_fas_openid.py p/flask_fas_openid.py --- release/flask_fas_openid.py 2013-04-01 11:28:08.516340400 -0700 +++ p/flask_fas_openid.py 2013-04-04 10:03:00.926567045 -0700 @@ -126,8 +126,8 @@ :raises: Might raise an redirect to the OpenID endpoint """ if return_url is None: - if 'next' in args.values: - return_url = args.values['next'] + if 'next' in flask.request.args.values: + return_url = flask.request.args.values['next'] else: return_url = flask.request.url oidconsumer = consumer.Consumer(flask.session, None)