-
Notifications
You must be signed in to change notification settings - Fork 131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace http_request_full internals with treq #1058
Changes from 6 commits
62ff4f8
b527f69
d35e97f
12fbbda
82015b2
f3d826e
927669d
a22e08f
7bc6185
d822b65
89d0a42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ | |
from twisted.web.iweb import IBodyProducer | ||
from twisted.web.http import PotentialDataLoss | ||
from twisted.web.resource import Resource | ||
from treq._utils import default_pool, default_reactor | ||
from treq.client import HTTPClient | ||
|
||
from vumi.errors import VumiError | ||
|
||
|
@@ -119,6 +121,56 @@ def connectionLost(self, reason): | |
def http_request_full(url, data=None, headers={}, method='POST', | ||
timeout=None, data_limit=None, context_factory=None, | ||
agent_class=None, reactor=None): | ||
""" | ||
This is a drop in replacement for the original `http_request_full` method | ||
but it has its internals completely replaced by treq. Treq supports SNI | ||
and our implementation does not for some reason. Also, we do not want | ||
to continue maintaining this because we're favouring treq everywhere | ||
anyway. | ||
|
||
""" | ||
agent_class = agent_class or Agent | ||
if reactor is None: | ||
# The import replaces the local variable. | ||
from twisted.internet import reactor | ||
pool = default_pool(reactor, pool=None, persistent=False) | ||
context_factory = context_factory or WebClientContextFactory() | ||
agent = agent_class(reactor, pool=pool, contextFactory=context_factory) | ||
client = HTTPClient(agent) | ||
|
||
def handle_response(response): | ||
return SimplishReceiver(response, data_limit).deferred | ||
|
||
d = client.request(method, url, headers=headers, data=data) | ||
d.addCallback(handle_response) | ||
|
||
if timeout is not None: | ||
cancelling_on_timeout = [False] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reason that this is a list? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @smn perhaps you can answer this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the why escapes me, this was many years ago, I got it from the old implementation: https://github.com/praekelt/vumi/pull/1058/files/a22e08f7250ab6570fd96b8469d96090696b4560#diff-832ae36feb20f811191dde6be9132638R195 perhaps @jerith remembers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this not something to do with that
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a hack to get a mutable value that can be modified elsewhere:
This lets us pass There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this particular case, we use |
||
|
||
def raise_timeout(reason): | ||
if not cancelling_on_timeout[0] or reason.check(HttpTimeoutError): | ||
return reason | ||
return Failure(HttpTimeoutError("Timeout while connecting")) | ||
|
||
def cancel_on_timeout(): | ||
cancelling_on_timeout[0] = True | ||
d.cancel() | ||
|
||
def cancel_timeout(r, delayed_call): | ||
if delayed_call.active(): | ||
delayed_call.cancel() | ||
return r | ||
|
||
d.addErrback(raise_timeout) | ||
delayed_call = reactor.callLater(timeout, cancel_on_timeout) | ||
d.addCallback(cancel_timeout, delayed_call) | ||
|
||
return d | ||
|
||
|
||
def old_http_request_full(url, data=None, headers={}, method='POST', | ||
timeout=None, data_limit=None, context_factory=None, | ||
agent_class=None, reactor=None): | ||
if reactor is None: | ||
# The import replaces the local variable. | ||
from twisted.internet import reactor | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's a good idea to import from a private module.. These methods could change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And you don't seem to be using
default_reactor
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when calling
default_pool
we were sendingpool=None
andpersistence=False
. In that case the method will create a new HTTPSConnectionPool. so that is what I did instead.https://github.com/twisted/treq/blob/master/src/treq/_utils.py#L38-L42