Created
October 20, 2011 03:22
-
-
Save chadselph/1300341 to your computer and use it in GitHub Desktop.
requests gevent demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
requests uses a singleton AuthManager, which when used with gevent's monkey patching | |
(or presumably, the threading module) can be set by one thread, and read by another. | |
The AuthManager maps urls to credentials which assumes for any url you will always | |
request it with the same credentials. This turned out to be false for us, and thus, | |
the bug. Here's code to reliably reproduce it. | |
""" | |
import base64 | |
import gevent.monkey | |
from gevent.pywsgi import WSGIServer | |
gevent.monkey.patch_all() | |
import requests | |
port = 8899 | |
def cycle_auths(n): | |
# cycle between user1 and user2 | |
auths = [('user1', 'pass1', 'forced_basic'), ('user2', 'pass2', 'forced_basic')] | |
for i in xrange(n): | |
yield auths[i % len(auths)] | |
def app(env, start_response): | |
if not env.get('HTTP_AUTHORIZATION'): | |
# force requests to send the auth! | |
start_response("401 Unauthorized", []) | |
return "" | |
start_response("200 OK", []) | |
b64auth = env['HTTP_AUTHORIZATION'][6:] | |
user, password = base64.b64decode(b64auth).split(':') | |
print user, password, "should be", env['wsgi.input'].read() | |
return "" | |
g = gevent.Greenlet(WSGIServer(('', port), app).serve_forever).start() | |
gevent.sleep(2) # wait for the server to start | |
def mk_request(auth): | |
r = requests.post('http://localhost:{port}'.format(port=port), | |
data=auth[0], auth=auth) | |
threads = [gevent.spawn(mk_request, auth) for auth in cycle_auths(20)] | |
gevent.joinall(threads) | |
gevent.sleep(2) | |
# show that in a non-race situation, the auth will be correct | |
thread = [gevent.spawn(mk_request, ('user3', 'pass3'))] | |
gevent.joinall(thread) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment