A little wsgi_test refactoring, added log_format argument to wsgi.server.
This commit is contained in:
@@ -15,6 +15,7 @@ DEFAULT_MAX_SIMULTANEOUS_REQUESTS = 1024
|
||||
DEFAULT_MAX_HTTP_VERSION = 'HTTP/1.1'
|
||||
MAX_REQUEST_LINE = 8192
|
||||
MINIMUM_CHUNK_SIZE = 4096
|
||||
DEFAULT_LOG_FORMAT='%(client_ip)s - - [%(date_time)s] "%(request_line)s" %(status_code)s %(body_length)s %(wall_seconds).6f'
|
||||
|
||||
__all__ = ['server', 'format_date_time']
|
||||
|
||||
@@ -303,13 +304,13 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
pass
|
||||
finish = time.time()
|
||||
|
||||
self.server.log_message('%s - - [%s] "%s" %s %s %.6f' % (
|
||||
self.get_client_ip(),
|
||||
self.log_date_time_string(),
|
||||
self.requestline,
|
||||
status_code[0],
|
||||
length[0],
|
||||
finish - start))
|
||||
self.server.log_message(self.server.log_format % dict(
|
||||
client_ip=self.get_client_ip(),
|
||||
date_time=self.log_date_time_string(),
|
||||
request_line=self.requestline,
|
||||
status_code=status_code[0],
|
||||
body_length=length[0],
|
||||
wall_seconds=finish - start))
|
||||
|
||||
def get_client_ip(self):
|
||||
client_ip = self.client_address[0]
|
||||
@@ -388,7 +389,8 @@ class Server(BaseHTTPServer.HTTPServer):
|
||||
max_http_version=None,
|
||||
protocol=HttpProtocol,
|
||||
minimum_chunk_size=None,
|
||||
log_x_forwarded_for=True):
|
||||
log_x_forwarded_for=True,
|
||||
log_format=DEFAULT_LOG_FORMAT):
|
||||
|
||||
self.outstanding_requests = 0
|
||||
self.socket = socket
|
||||
@@ -405,6 +407,7 @@ class Server(BaseHTTPServer.HTTPServer):
|
||||
if minimum_chunk_size is not None:
|
||||
protocol.minimum_chunk_size = minimum_chunk_size
|
||||
self.log_x_forwarded_for = log_x_forwarded_for
|
||||
self.log_format = log_format
|
||||
|
||||
def get_environ(self):
|
||||
socket = self.socket
|
||||
@@ -437,7 +440,8 @@ def server(sock, site,
|
||||
server_event=None,
|
||||
minimum_chunk_size=None,
|
||||
log_x_forwarded_for=True,
|
||||
custom_pool=None):
|
||||
custom_pool=None,
|
||||
log_format=DEFAULT_LOG_FORMAT):
|
||||
""" Start up a `WSGI <http://wsgi.org/wsgi/>`_ server handling requests from the supplied server
|
||||
socket. This function loops forever.
|
||||
|
||||
@@ -449,17 +453,18 @@ def server(sock, site,
|
||||
:param protocol: Protocol class. Deprecated.
|
||||
:param server_event: Used to collect the Server object. Deprecated.
|
||||
:param minimum_chunk_size: Minimum size in bytes for http chunks. This can be used to improve performance of applications which yield many small strings, though using it technically violates the WSGI spec.
|
||||
:param log_x_forwarded_for: If True (the default), logs the contents of the x-forwarded-for header in addition to the actual client ip address.
|
||||
:param log_x_forwarded_for: If True (the default), logs the contents of the x-forwarded-for header in addition to the actual client ip address in the 'client_ip' field of the log line.
|
||||
:param custom_pool: A custom Pool instance which is used to spawn client green threads. If this is supplied, max_size is ignored.
|
||||
:param log_formar: A python format string that is used as the template to generate log lines. The following values can be formatted into it: client_ip, date_time, request_line, status_code, body_length, wall_seconds. Look at DEFAULT_LOG_FORMAT for an example of how to use this.
|
||||
"""
|
||||
|
||||
serv = Server(sock, sock.getsockname(),
|
||||
site, log,
|
||||
environ=None,
|
||||
max_http_version=max_http_version,
|
||||
protocol=protocol,
|
||||
minimum_chunk_size=minimum_chunk_size,
|
||||
log_x_forwarded_for=log_x_forwarded_for)
|
||||
log_x_forwarded_for=log_x_forwarded_for,
|
||||
log_format=log_format)
|
||||
if server_event is not None:
|
||||
server_event.send(serv)
|
||||
if max_size is None:
|
||||
|
@@ -124,20 +124,36 @@ class TestHttpd(LimitedTestCase):
|
||||
super(TestHttpd, self).setUp()
|
||||
self.logfile = StringIO()
|
||||
self.site = Site()
|
||||
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)
|
||||
self.killer = None
|
||||
self.spawn_server()
|
||||
|
||||
def tearDown(self):
|
||||
super(TestHttpd, self).tearDown()
|
||||
api.kill(self.killer)
|
||||
api.sleep(0)
|
||||
|
||||
def spawn_server(self, **kwargs):
|
||||
"""Spawns a new wsgi server with the given arguments.
|
||||
Sets self.port to the port of the server, and self.killer is the greenlet
|
||||
running it.
|
||||
|
||||
Kills any previously-running server."""
|
||||
if self.killer:
|
||||
api.kill(self.killer)
|
||||
|
||||
new_kwargs = dict(max_size=128,
|
||||
log=self.logfile,
|
||||
site=self.site)
|
||||
new_kwargs.update(kwargs)
|
||||
|
||||
if 'sock' not in new_kwargs:
|
||||
new_kwargs['sock'] = api.tcp_listener(('localhost', 0))
|
||||
|
||||
self.port = new_kwargs['sock'].getsockname()[1]
|
||||
self.killer = api.spawn(
|
||||
wsgi.server,
|
||||
**new_kwargs)
|
||||
|
||||
def test_001_server(self):
|
||||
sock = api.connect_tcp(
|
||||
('localhost', self.port))
|
||||
@@ -317,10 +333,9 @@ class TestHttpd(LimitedTestCase):
|
||||
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
|
||||
|
||||
server_sock = api.ssl_listener(('localhost', 0), certificate_file, private_key_file)
|
||||
self.spawn_server(sock=server_sock, site=wsgi_app)
|
||||
|
||||
api.spawn(wsgi.server, server_sock, wsgi_app, log=StringIO())
|
||||
|
||||
sock = api.connect_tcp(('localhost', server_sock.getsockname()[1]))
|
||||
sock = api.connect_tcp(('localhost', self.port))
|
||||
sock = util.wrap_ssl(sock)
|
||||
sock.write('POST /foo HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nContent-length:3\r\n\r\nabc')
|
||||
result = sock.read(8192)
|
||||
@@ -334,7 +349,7 @@ class TestHttpd(LimitedTestCase):
|
||||
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
|
||||
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
|
||||
server_sock = api.ssl_listener(('localhost', 0), certificate_file, private_key_file)
|
||||
api.spawn(wsgi.server, server_sock, wsgi_app, log=StringIO())
|
||||
self.spawn_server(sock=server_sock, site=wsgi_app)
|
||||
|
||||
sock = api.connect_tcp(('localhost', server_sock.getsockname()[1]))
|
||||
sock = util.wrap_ssl(sock)
|
||||
@@ -505,16 +520,7 @@ class TestHttpd(LimitedTestCase):
|
||||
|
||||
# turning off the option should work too
|
||||
self.logfile = StringIO()
|
||||
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,
|
||||
log_x_forwarded_for=False)
|
||||
self.spawn_server(log_x_forwarded_for=False)
|
||||
|
||||
sock = api.connect_tcp(('localhost', self.port))
|
||||
sock.sendall('GET / HTTP/1.1\r\nHost: localhost\r\nX-Forwarded-For: 1.2.3.4, 5.6.7.8\r\n\r\n')
|
||||
@@ -551,16 +557,7 @@ class TestHttpd(LimitedTestCase):
|
||||
# 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)
|
||||
self.spawn_server(custom_pool=p)
|
||||
|
||||
# this stuff is copied from test_001_server, could be better factored
|
||||
sock = api.connect_tcp(
|
||||
@@ -623,6 +620,14 @@ class TestHttpd(LimitedTestCase):
|
||||
self.assertEquals(fd.read(7), 'testing')
|
||||
fd.close()
|
||||
|
||||
def test_025_log_format(self):
|
||||
self.spawn_server(log_format="HI %(request_line)s HI")
|
||||
sock = api.connect_tcp(('localhost', self.port))
|
||||
sock.sendall('GET /yo! HTTP/1.1\r\nHost: localhost\r\n\r\n')
|
||||
sock.recv(1024)
|
||||
sock.close()
|
||||
self.assert_('\nHI GET /yo! HTTP/1.1 HI\n' in self.logfile.getvalue(), self.logfile.getvalue())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
Reference in New Issue
Block a user