diff --git a/src/calibre/srv/errors.py b/src/calibre/srv/errors.py index 72388edcaa..bfd951d7fe 100644 --- a/src/calibre/srv/errors.py +++ b/src/calibre/srv/errors.py @@ -7,12 +7,6 @@ __license__ = 'GPL v3' __copyright__ = '2015, Kovid Goyal ' -class NonHTTPConnRequest(Exception): - - def __init__(self, data=None): - Exception.__init__(self, '') - self.data = data - class MaxSizeExceeded(Exception): def __init__(self, prefix, size, limit): diff --git a/src/calibre/srv/http.py b/src/calibre/srv/http.py index b7f5f5eaee..704d32f232 100644 --- a/src/calibre/srv/http.py +++ b/src/calibre/srv/http.py @@ -16,7 +16,7 @@ from operator import itemgetter from calibre import as_unicode from calibre.constants import __version__ from calibre.srv.errors import ( - MaxSizeExceeded, NonHTTPConnRequest, HTTP404, IfNoneMatch, BadChunkedInput, RangeNotSatisfiable) + MaxSizeExceeded, HTTP404, IfNoneMatch, BadChunkedInput, RangeNotSatisfiable) from calibre.srv.respond import finalize_output, generate_static_output from calibre.srv.utils import MultiDict, http_date, socket_errors_to_ignore @@ -143,7 +143,7 @@ def read_headers(readline): # {{{ return hdict # }}} -def http_communicate(conn): +def http_communicate(handle_request, conn): ' Represents interaction with a http client over a single, persistent connection ' request_seen = False def repr_for_pair(pair): @@ -163,7 +163,7 @@ def http_communicate(conn): # the HTTPPair constructor, the error doesn't # get written to the previous request. pair = None - pair = conn.server_loop.http_handler(conn) + pair = HTTPPair(handle_request, conn) # This order of operations should guarantee correct pipelining. pair.parse_request() @@ -186,8 +186,6 @@ def http_communicate(conn): # Don't bother writing the 408 if the response # has already started being written. simple_response(pair, httplib.REQUEST_TIMEOUT) - except NonHTTPConnRequest: - raise except socket.error: # This socket is broken. Log the error and close connection conn.server_loop.log.exception( @@ -601,4 +599,4 @@ class HTTPPair(object): def create_http_handler(handle_request): - return partial(HTTPPair, handle_request) + return partial(http_communicate, handle_request) diff --git a/src/calibre/srv/loop.py b/src/calibre/srv/loop.py index ed3ccae224..bb3b6e9188 100644 --- a/src/calibre/srv/loop.py +++ b/src/calibre/srv/loop.py @@ -13,8 +13,7 @@ from threading import Thread, current_thread, Lock from io import DEFAULT_BUFFER_SIZE, BytesIO from calibre.constants import iswindows -from calibre.srv.errors import NonHTTPConnRequest, MaxSizeExceeded -from calibre.srv.http import http_communicate +from calibre.srv.errors import MaxSizeExceeded from calibre.srv.opts import Options from calibre.srv.utils import socket_errors_to_ignore, socket_error_eintr, socket_errors_nonblocking, Corked from calibre.utils.socket_inheritance import set_socket_inherit @@ -384,9 +383,6 @@ class Connection(object): # {{{ self.socket_file = SocketFile(socket) self.closed = False - def nonhttp_communicate(self, data): - self.server_loop.nonhttp_handler(self, data) - def close(self): """Close the socket underlying this connection.""" if self.closed: @@ -425,10 +421,7 @@ class WorkerThread(Thread): # {{{ if conn is None: return # Clean exit with conn, self: - try: - http_communicate(conn) - except NonHTTPConnRequest as e: - conn.nonhttp_communicate(e.data) + self.server_loop.req_resp_handler(conn) except (KeyboardInterrupt, SystemExit): self.server_loop.stop() except socket.error: @@ -547,23 +540,15 @@ class ServerLoop(object): def __init__( self, + req_resp_handler, bind_address=('localhost', 8080), - http_handler=None, - nonhttp_handler=None, opts=None, # A calibre logging object. If None a default log that logs to # stdout is used log=None ): self.opts = opts or Options() - if http_handler is None: - def aborth(*args, **kwargs): - raise NonHTTPConnRequest() - http_handler = aborth - self.http_handler = http_handler - self.nonhttp_handler = nonhttp_handler - if http_handler is None and nonhttp_handler is None: - raise ValueError('You must specify at least one protocol handler') + self.req_resp_handler = req_resp_handler self.log = log or ThreadSafeLog(level=ThreadSafeLog.DEBUG) self.gso_cache, self.gso_lock = {}, Lock() ba = bind_address @@ -811,7 +796,7 @@ class ServerLoop(object): s.close() return sock -def echo_handler(conn, data): +def echo_handler(conn): keep_going = True while keep_going: try: @@ -826,7 +811,7 @@ def echo_handler(conn, data): conn.socket_file.flush() if __name__ == '__main__': - s = ServerLoop(nonhttp_handler=echo_handler) + s = ServerLoop(echo_handler) with HandleInterrupt(s.tick_once): try: s.serve_forever() diff --git a/src/calibre/srv/tests/base.py b/src/calibre/srv/tests/base.py index 42d162848f..f02d39d077 100644 --- a/src/calibre/srv/tests/base.py +++ b/src/calibre/srv/tests/base.py @@ -39,8 +39,9 @@ class TestServer(Thread): from calibre.srv.http import create_http_handler kwargs['shutdown_timeout'] = kwargs.get('shutdown_timeout', 0.1) self.loop = ServerLoop( + create_http_handler(handler), opts=Options(**kwargs), - bind_address=('localhost', 0), http_handler=create_http_handler(handler), + bind_address=('localhost', 0), log=TestLog(level=ThreadSafeLog.WARN), ) self.log = self.loop.log @@ -68,4 +69,4 @@ class TestServer(Thread): def change_handler(self, handler): from calibre.srv.http import create_http_handler - self.loop.http_handler = create_http_handler(handler) + self.loop.req_resp_handler = create_http_handler(handler)