Automated merge with http://bitbucket.org/which_linden/eventlet/
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -23,6 +23,7 @@ Linden Lab Contributors
|
||||
|
||||
Thanks To
|
||||
---------
|
||||
* gholt, wsgi patches for accepting a custom pool, and returning 400 if content-length is invalid
|
||||
* Luke Tucker, bug report regarding wsgi + webob
|
||||
* Chuck Thier, reporting a bug in processes.py
|
||||
* Brantley Harris, reporting bug #4
|
||||
|
@@ -33,6 +33,8 @@ def inject(module_name, new_globals, *additional_modules):
|
||||
for name, mod in additional_modules:
|
||||
if saved[name] is not None:
|
||||
sys.modules[name] = saved[name]
|
||||
else:
|
||||
del sys.modules[name]
|
||||
|
||||
return module
|
||||
|
||||
|
@@ -167,6 +167,17 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
if not self.parse_request():
|
||||
return
|
||||
|
||||
content_length = self.headers.getheader('content-length')
|
||||
if content_length:
|
||||
try:
|
||||
int(content_length)
|
||||
except ValueError:
|
||||
self.wfile.write(
|
||||
"HTTP/1.0 400 Bad Request\r\n"
|
||||
"Connection: close\r\nContent-length: 0\r\n\r\n")
|
||||
self.close_connection = 1
|
||||
return
|
||||
|
||||
self.environ = self.get_environ()
|
||||
self.application = self.server.app
|
||||
try:
|
||||
@@ -423,7 +434,8 @@ def server(sock, site,
|
||||
protocol=HttpProtocol,
|
||||
server_event=None,
|
||||
minimum_chunk_size=None,
|
||||
log_x_forwarded_for=True):
|
||||
log_x_forwarded_for=True,
|
||||
custom_pool=None):
|
||||
""" Start up a `WSGI <http://wsgi.org/wsgi/>`_ server handling requests from the supplied server
|
||||
socket. This function loops forever.
|
||||
|
||||
@@ -449,7 +461,10 @@ def server(sock, site,
|
||||
server_event.send(serv)
|
||||
if max_size is None:
|
||||
max_size = DEFAULT_MAX_SIMULTANEOUS_REQUESTS
|
||||
pool = Pool(max_size=max_size)
|
||||
if custom_pool is not None:
|
||||
pool = custom_pool
|
||||
else:
|
||||
pool = Pool(max_size=max_size)
|
||||
try:
|
||||
host, port = sock.getsockname()
|
||||
port = ':%s' % (port, )
|
||||
|
72
tests/patcher_test.py
Normal file
72
tests/patcher_test.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import os
|
||||
import tempfile
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from tests import LimitedTestCase
|
||||
|
||||
base_module_contents = """
|
||||
import socket
|
||||
import urllib
|
||||
print "base", socket, urllib
|
||||
"""
|
||||
|
||||
patching_module_contents = """
|
||||
from eventlet.green import socket
|
||||
from eventlet.green import urllib
|
||||
from eventlet import patcher
|
||||
print 'patcher', socket, urllib
|
||||
patcher.inject('%s', globals(), ('socket', socket), ('urllib', urllib))
|
||||
del patcher
|
||||
"""
|
||||
|
||||
import_module_contents = """
|
||||
import %(mod)s
|
||||
import httplib
|
||||
print "importing", %(mod)s, httplib, %(mod)s.socket, %(mod)s.urllib
|
||||
"""
|
||||
|
||||
class Patcher(LimitedTestCase):
|
||||
TEST_TIMEOUT=3 # starting processes is time-consuming
|
||||
def setUp(self):
|
||||
self._saved_syspath = sys.path
|
||||
self.tempfiles = []
|
||||
|
||||
def tearDown(self):
|
||||
sys.path = self._saved_syspath
|
||||
for tf in self.tempfiles:
|
||||
os.remove(tf)
|
||||
|
||||
def write_to_tempfile(self, contents):
|
||||
fn, filename = tempfile.mkstemp('_patcher_test.py')
|
||||
fd = os.fdopen(fn, 'w')
|
||||
fd.write(contents)
|
||||
fd.close()
|
||||
self.tempfiles.append(filename)
|
||||
return os.path.dirname(filename), os.path.basename(filename)
|
||||
|
||||
def test_patch_a_module(self):
|
||||
base = self.write_to_tempfile(base_module_contents)
|
||||
base_modname = os.path.splitext(base[1])[0]
|
||||
patching = self.write_to_tempfile(patching_module_contents % base_modname)
|
||||
patching_modname = os.path.splitext(patching[1])[0]
|
||||
importing = self.write_to_tempfile(
|
||||
import_module_contents % dict(mod=patching_modname))
|
||||
|
||||
python_path = os.pathsep.join(sys.path)
|
||||
python_path += os.pathsep.join((base[0], patching[0], importing[0]))
|
||||
new_env = os.environ.copy()
|
||||
new_env['PYTHONPATH'] = python_path
|
||||
p = subprocess.Popen([sys.executable,
|
||||
os.path.join(importing[0], importing[1])],
|
||||
stdout=subprocess.PIPE, env=new_env)
|
||||
output = p.communicate()
|
||||
lines = output[0].split("\n")
|
||||
self.assert_(lines[0].startswith('patcher'))
|
||||
self.assert_(lines[1].startswith('base'))
|
||||
self.assert_(lines[2].startswith('importing'))
|
||||
self.assert_('eventlet.green.socket' in lines[1])
|
||||
self.assert_('eventlet.green.urllib' in lines[1])
|
||||
self.assert_('eventlet.green.socket' in lines[2])
|
||||
self.assert_('eventlet.green.urllib' in lines[2])
|
||||
self.assert_('eventlet.green.httplib' not in lines[2])
|
@@ -490,7 +490,45 @@ class TestHttpd(LimitedTestCase):
|
||||
'Connection: close\r\n'
|
||||
'\r\n\r\n')
|
||||
self.assert_('200 OK' in fd.read())
|
||||
|
||||
|
||||
def test_022_custom_pool(self):
|
||||
# just test that it accepts the parameter for now
|
||||
# TODO: test that it uses the pool and that you can waitall() to
|
||||
# ensure that all clients finished
|
||||
from eventlet import pool
|
||||
p = pool.Pool(max_size=5)
|
||||
api.kill(self.killer)
|
||||
listener = api.tcp_listener(('localhost', 0))
|
||||
self.port = listener.getsockname()[1]
|
||||
self.killer = api.spawn(
|
||||
wsgi.server,
|
||||
listener,
|
||||
self.site,
|
||||
max_size=128,
|
||||
log=self.logfile,
|
||||
custom_pool=p)
|
||||
|
||||
# this stuff is copied from test_001_server, could be better factored
|
||||
sock = api.connect_tcp(
|
||||
('localhost', self.port))
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.0\r\nHost: localhost\r\n\r\n')
|
||||
result = fd.read()
|
||||
fd.close()
|
||||
self.assert_(result.startswith('HTTP'), result)
|
||||
self.assert_(result.endswith('hello world'))
|
||||
|
||||
def test_023_bad_content_length(self):
|
||||
sock = api.connect_tcp(
|
||||
('localhost', self.port))
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.0\r\nHost: localhost\r\nContent-length: argh\r\n\r\n')
|
||||
result = fd.read()
|
||||
fd.close()
|
||||
self.assert_(result.startswith('HTTP'), result)
|
||||
self.assert_('400 Bad Request' in result)
|
||||
self.assert_('500' not in result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
Reference in New Issue
Block a user