summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-12-27 01:59:08 -0500
committerChris McDonough <chrism@plope.com>2011-12-27 01:59:08 -0500
commit822608bb3e8cdd92ae5180671fd6304adf635154 (patch)
tree05af69ee977d416277d51c526fed6e29564ccdc4
parente5c5c08361d5c5984e41ee73829f4d3f935864f4 (diff)
downloadwaitress-822608bb3e8cdd92ae5180671fd6304adf635154.tar.gz
renames, effective_host/effective_port, dont relog in task
-rw-r--r--TODO.txt8
-rw-r--r--waitress/__init__.py7
-rw-r--r--waitress/channel.py7
-rw-r--r--waitress/server.py14
-rw-r--r--waitress/task.py19
-rw-r--r--waitress/tests/test_channel.py6
-rw-r--r--waitress/tests/test_regression.py12
-rw-r--r--waitress/tests/test_server.py8
-rw-r--r--waitress/tests/test_task.py7
9 files changed, 46 insertions, 42 deletions
diff --git a/TODO.txt b/TODO.txt
index 2f45c89..451e3c7 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -6,7 +6,7 @@
- Coverage.
-- Waitress Version number in header.
+- Waitress version number in header.
- Put maintenance check on server rather than channel to avoid DOS.
@@ -14,8 +14,6 @@
- Test paste server runner on windows.
-- Logging.
-
-- Warn instead of relog in task.py.
-
- Get rid of dual-moded-ness.
+
+- "Verbose".
diff --git a/waitress/__init__.py b/waitress/__init__.py
index 7f82cf5..bde0764 100644
--- a/waitress/__init__.py
+++ b/waitress/__init__.py
@@ -1,10 +1,11 @@
-from waitress.server import WSGIHTTPServer
+from waitress.server import WSGIServer
-def serve(app, _server=WSGIHTTPServer, **kw):
+def serve(app, _server=WSGIServer, **kw):
# _server is a test shim
server = _server(app, **kw)
if server.adj.verbose: # pragma: no cover
- print('serving on http://%s:%s' % (server.ip, server.port))
+ print('serving on http://%s:%s' % (server.effective_host,
+ server.effective_port))
server.run()
def serve_paste(app, global_conf, **kw):
diff --git a/waitress/channel.py b/waitress/channel.py
index 50001ef..564afcc 100644
--- a/waitress/channel.py
+++ b/waitress/channel.py
@@ -21,10 +21,11 @@ import time
from waitress.compat import thread
from waitress.adjustments import Adjustments
from waitress.buffers import OverflowableBuffer
+from waitress.dispatcher import logging_dispatcher
from waitress.parser import HTTPRequestParser
-from waitress.task import HTTPTask
+from waitress.task import WSGITask
-class HTTPServerChannel(asyncore.dispatcher, object):
+class HTTPChannel(logging_dispatcher, object):
"""Channel that switches between asynchronous and synchronous mode.
Call set_sync() before using a channel in a thread other than
@@ -33,7 +34,7 @@ class HTTPServerChannel(asyncore.dispatcher, object):
Call set_async() to give the channel back to the thread handling
the main loop.
"""
- task_class = HTTPTask
+ task_class = WSGITask
parser_class = HTTPRequestParser
task_lock = thread.allocate_lock() # syncs access to task-related attrs
diff --git a/waitress/server.py b/waitress/server.py
index 3344054..203f476 100644
--- a/waitress/server.py
+++ b/waitress/server.py
@@ -16,21 +16,19 @@ import asyncore
import socket
from waitress.adjustments import Adjustments
-from waitress.channel import HTTPServerChannel
+from waitress.channel import HTTPChannel
+from waitress.dispatcher import logging_dispatcher
from waitress.task import ThreadedTaskDispatcher
from waitress import trigger
-class WSGIHTTPServer(asyncore.dispatcher, object):
+class WSGIServer(logging_dispatcher, object):
"""
if __name__ == '__main__':
- from waitress.task import ThreadedTaskDispatcher
- td = ThreadedTaskDispatcher()
- td.set_thread_count(4)
- server = WSGIHTTPServer(app, '', 8080, task_dispatcher=td)
+ server = WSGIServer(app)
server.run()
"""
- channel_class = HTTPServerChannel
+ channel_class = HTTPChannel
socketmod = socket # test shim
def __init__(self,
@@ -54,6 +52,7 @@ class WSGIHTTPServer(asyncore.dispatcher, object):
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((self.adj.host, self.adj.port))
+ self.effective_host, self.effective_port = self.getsockname()
self.server_name = self.get_server_name(self.adj.host)
if _start:
self.accept_connections()
@@ -131,3 +130,4 @@ class WSGIHTTPServer(asyncore.dispatcher, object):
def pull_trigger(self):
self.trigger.pull_trigger()
+
diff --git a/waitress/task.py b/waitress/task.py
index ceabfe3..8f3ee6c 100644
--- a/waitress/task.py
+++ b/waitress/task.py
@@ -17,10 +17,6 @@ import sys
import time
import traceback
-from waitress.utilities import (
- build_http_date,
- )
-
from waitress.compat import (
tobytes,
Queue,
@@ -29,6 +25,10 @@ from waitress.compat import (
reraise,
)
+from waitress.utilities import (
+ build_http_date,
+ )
+
rename_headers = {
'CONTENT_LENGTH' : 'CONTENT_LENGTH',
'CONTENT_TYPE' : 'CONTENT_TYPE',
@@ -136,8 +136,8 @@ class ThreadedTaskDispatcher(object):
return True
return False
-class HTTPTask(object):
- """An HTTP task accepts a request and writes to a channel.
+class WSGITask(object):
+ """A WSGI task accepts a request and writes to a channel.
See ITask, IHeaderOutput.
"""
@@ -151,6 +151,7 @@ class HTTPTask(object):
start_response_called = False
content_length = -1
content_bytes_written = 0
+ logged_write_excess = False
def __init__(self, channel, request_data):
self.channel = channel
@@ -288,11 +289,11 @@ class HTTPTask(object):
cl = self.content_length
if cl != -1:
towrite = data[:cl-self.content_bytes_written]
- if towrite != data:
- # XXX warn instead of relog
+ if towrite != data and not self.logged_write_excess:
self.channel.server.log_info(
'written content exceeded the number of bytes '
'specified by Content-Length header (%s)' % cl)
+ self.logged_write_excess = True
if towrite:
self.content_bytes_written += len(towrite)
channel.write(towrite)
@@ -395,7 +396,7 @@ class HTTPTask(object):
environ = {}
environ['REQUEST_METHOD'] = request_data.command.upper()
- environ['SERVER_PORT'] = str(server.adj.port)
+ environ['SERVER_PORT'] = str(server.effective_port)
environ['SERVER_NAME'] = server.server_name
environ['SERVER_SOFTWARE'] = server.adj.ident
environ['SERVER_PROTOCOL'] = "HTTP/%s" % self.version
diff --git a/waitress/tests/test_channel.py b/waitress/tests/test_channel.py
index e2540d5..4a6b5e2 100644
--- a/waitress/tests/test_channel.py
+++ b/waitress/tests/test_channel.py
@@ -1,10 +1,10 @@
import unittest
-class TestHTTPServerChannel(unittest.TestCase):
+class TestHTTPChannel(unittest.TestCase):
def _makeOne(self, sock, addr, adj=None, map=None):
- from waitress.channel import HTTPServerChannel
+ from waitress.channel import HTTPChannel
server = DummyServer()
- return HTTPServerChannel(server, sock, addr, adj=adj, map=map)
+ return HTTPChannel(server, sock, addr, adj=adj, map=map)
def _makeOneWithMap(self, adj=None):
sock = DummySock()
diff --git a/waitress/tests/test_regression.py b/waitress/tests/test_regression.py
index bde01b2..6e9cf0e 100644
--- a/waitress/tests/test_regression.py
+++ b/waitress/tests/test_regression.py
@@ -38,7 +38,7 @@ class FakeSocket: # pragma: no cover
def zombies_test():
- """Regression test for HTTPServerChannel.maintenance method
+ """Regression test for HTTPChannel.maintenance method
Bug: This method checks for channels that have been "inactive" for a
configured time. The bug was that last_activity is set at creation time
@@ -60,9 +60,9 @@ def zombies_test():
First we confirm the correct behavior, where a channel with no activity
for the timeout duration gets closed.
- >>> from waitress.channel import HTTPServerChannel
+ >>> from waitress.channel import HTTPChannel
>>> socket = FakeSocket(42)
- >>> channel = HTTPServerChannel(sb, socket, ('localhost', 42))
+ >>> channel = HTTPChannel(sb, socket, ('localhost', 42))
>>> channel.connected
True
@@ -73,7 +73,7 @@ def zombies_test():
... config.cleanup_interval) - 1
>>> socket2 = FakeSocket(7)
- >>> channel2 = HTTPServerChannel(sb, socket2, ('localhost', 7))
+ >>> channel2 = HTTPChannel(sb, socket2, ('localhost', 7))
>>> channel.connected
False
@@ -95,7 +95,7 @@ def zombies_test():
... config.cleanup_interval) - 1
>>> socket3 = FakeSocket(3)
- >>> channel3 = HTTPServerChannel(sb, socket3, ('localhost', 3))
+ >>> channel3 = HTTPChannel(sb, socket3, ('localhost', 3))
>>> channel2.connected
True
@@ -119,7 +119,7 @@ def zombies_test():
... config.cleanup_interval) - 1
>>> socket4 = FakeSocket(4)
- >>> channel4 = HTTPServerChannel(sb, socket4, ('localhost', 4))
+ >>> channel4 = HTTPChannel(sb, socket4, ('localhost', 4))
>>> channel3.connected
True
diff --git a/waitress/tests/test_server.py b/waitress/tests/test_server.py
index 125d80c..7d32214 100644
--- a/waitress/tests/test_server.py
+++ b/waitress/tests/test_server.py
@@ -2,12 +2,12 @@ import errno
import socket
import unittest
-class TestWSGIHTTPServer(unittest.TestCase):
+class TestWSGIServer(unittest.TestCase):
def _makeOne(self, application, host='127.0.0.1', port=62122,
_dispatcher=None, adj=None, map=None, _start=True,
_sock=None):
- from waitress.server import WSGIHTTPServer
- class TestServer(WSGIHTTPServer):
+ from waitress.server import WSGIServer
+ class TestServer(WSGIServer):
def bind(self, v):
pass
return TestServer(
@@ -155,6 +155,8 @@ class DummySock(object):
return 1
def listen(self, num):
self.listened = num
+ def getsockname(self):
+ return '127.0.0.1', 80
class DummyTaskDispatcher(object):
def __init__(self):
diff --git a/waitress/tests/test_task.py b/waitress/tests/test_task.py
index d7eb60e..a85ae1e 100644
--- a/waitress/tests/test_task.py
+++ b/waitress/tests/test_task.py
@@ -91,14 +91,14 @@ class TestThreadedTaskDispatcher(unittest.TestCase):
self.assertEqual(inst.shutdown(cancel_pending=False, timeout=.01),
False)
-class TestHTTPTask(unittest.TestCase):
+class TestWSGITask(unittest.TestCase):
def _makeOne(self, channel=None, request_data=None):
if channel is None:
channel = DummyChannel()
if request_data is None:
request_data = DummyParser()
- from waitress.task import HTTPTask
- return HTTPTask(channel, request_data)
+ from waitress.task import WSGITask
+ return WSGITask(channel, request_data)
def test_service(self):
inst = self._makeOne()
@@ -438,6 +438,7 @@ class DummyAdj(object):
class DummyServer(object):
server_name = 'localhost'
+ effective_port = 80
def __init__(self):
self.adj = DummyAdj()