mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Class to conveniently override some server options
Also, function to create a http_handler from a callable
This commit is contained in:
parent
45b290ad5b
commit
0f6e191bf8
@ -260,7 +260,7 @@ class HTTPPair(object):
|
|||||||
|
|
||||||
''' Represents a HTTP request/response pair '''
|
''' Represents a HTTP request/response pair '''
|
||||||
|
|
||||||
def __init__(self, conn, handle_request):
|
def __init__(self, handle_request, conn):
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
self.server_loop = conn.server_loop
|
self.server_loop = conn.server_loop
|
||||||
self.max_header_line_size = self.server_loop.opts.max_header_line_size * 1024
|
self.max_header_line_size = self.server_loop.opts.max_header_line_size * 1024
|
||||||
@ -522,3 +522,6 @@ class HTTPPair(object):
|
|||||||
|
|
||||||
def send_headers(self):
|
def send_headers(self):
|
||||||
self.sent_headers = True
|
self.sent_headers = True
|
||||||
|
|
||||||
|
def create_http_handler(handle_request):
|
||||||
|
return partial(HTTPPair, handle_request)
|
||||||
|
@ -14,7 +14,7 @@ from io import DEFAULT_BUFFER_SIZE, BytesIO
|
|||||||
|
|
||||||
from calibre.srv.errors import NonHTTPConnRequest, MaxSizeExceeded
|
from calibre.srv.errors import NonHTTPConnRequest, MaxSizeExceeded
|
||||||
from calibre.srv.http import http_communicate
|
from calibre.srv.http import http_communicate
|
||||||
from calibre.srv.opts import defaults
|
from calibre.srv.opts import Options
|
||||||
from calibre.utils.socket_inheritance import set_socket_inherit
|
from calibre.utils.socket_inheritance import set_socket_inherit
|
||||||
from calibre.utils.logging import ThreadSafeLog
|
from calibre.utils.logging import ThreadSafeLog
|
||||||
|
|
||||||
@ -337,7 +337,7 @@ class SocketFile(object): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class Connection(object):
|
class Connection(object): # {{{
|
||||||
|
|
||||||
' A thin wrapper around an active socket '
|
' A thin wrapper around an active socket '
|
||||||
|
|
||||||
@ -385,9 +385,9 @@ class Connection(object):
|
|||||||
|
|
||||||
def __exit__(self, *args):
|
def __exit__(self, *args):
|
||||||
self.close()
|
self.close()
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
class WorkerThread(Thread): # {{{
|
||||||
class WorkerThread(Thread):
|
|
||||||
|
|
||||||
daemon = True
|
daemon = True
|
||||||
|
|
||||||
@ -419,9 +419,9 @@ class WorkerThread(Thread):
|
|||||||
|
|
||||||
def __exit__(self, *args):
|
def __exit__(self, *args):
|
||||||
self.serving = False
|
self.serving = False
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
class ThreadPool(object): # {{{
|
||||||
class ThreadPool(object):
|
|
||||||
|
|
||||||
def __init__(self, server_loop, min_threads=10, max_threads=-1, accepted_queue_size=-1, accepted_queue_timeout=10):
|
def __init__(self, server_loop, min_threads=10, max_threads=-1, accepted_queue_size=-1, accepted_queue_timeout=10):
|
||||||
self.server_loop = server_loop
|
self.server_loop = server_loop
|
||||||
@ -514,7 +514,7 @@ class ThreadPool(object):
|
|||||||
@property
|
@property
|
||||||
def qsize(self):
|
def qsize(self):
|
||||||
return self._queue.qsize()
|
return self._queue.qsize()
|
||||||
|
# }}}
|
||||||
|
|
||||||
class ServerLoop(object):
|
class ServerLoop(object):
|
||||||
|
|
||||||
@ -528,7 +528,7 @@ class ServerLoop(object):
|
|||||||
# stdout is used
|
# stdout is used
|
||||||
log=None
|
log=None
|
||||||
):
|
):
|
||||||
self.opts = opts or defaults
|
self.opts = opts or Options()
|
||||||
if http_handler is None:
|
if http_handler is None:
|
||||||
def aborth(*args, **kwargs):
|
def aborth(*args, **kwargs):
|
||||||
raise NonHTTPConnRequest()
|
raise NonHTTPConnRequest()
|
||||||
@ -546,6 +546,7 @@ class ServerLoop(object):
|
|||||||
# AI_PASSIVE does not work with host of '' or None
|
# AI_PASSIVE does not work with host of '' or None
|
||||||
ba = ('0.0.0.0', ba[1])
|
ba = ('0.0.0.0', ba[1])
|
||||||
self.bind_address = ba
|
self.bind_address = ba
|
||||||
|
self.bound_address = None
|
||||||
self.ssl_context = None
|
self.ssl_context = None
|
||||||
if self.opts.ssl_certfile is not None and self.opts.ssl_keyfile is not None:
|
if self.opts.ssl_certfile is not None and self.opts.ssl_keyfile is not None:
|
||||||
self.ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
self.ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||||
@ -628,7 +629,7 @@ class ServerLoop(object):
|
|||||||
# Timeout so KeyboardInterrupt can be caught on Win32
|
# Timeout so KeyboardInterrupt can be caught on Win32
|
||||||
self.socket.settimeout(1)
|
self.socket.settimeout(1)
|
||||||
self.socket.listen(self.opts.request_queue_size)
|
self.socket.listen(self.opts.request_queue_size)
|
||||||
ba = self.bind_address
|
self.bound_address = ba = self.socket.getsockname()
|
||||||
if isinstance(ba, tuple):
|
if isinstance(ba, tuple):
|
||||||
ba = ':'.join(map(type(''), ba))
|
ba = ':'.join(map(type(''), ba))
|
||||||
self.log('calibre server listening on', ba)
|
self.log('calibre server listening on', ba)
|
||||||
|
@ -6,7 +6,8 @@ from __future__ import (unicode_literals, division, absolute_import,
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple, OrderedDict
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
Option = namedtuple('Option', 'name default longdoc shortdoc choices')
|
Option = namedtuple('Option', 'name default longdoc shortdoc choices')
|
||||||
|
|
||||||
@ -76,7 +77,13 @@ while i + 3 < len(raw_options):
|
|||||||
choices = default
|
choices = default
|
||||||
default = default.default
|
default = default.default
|
||||||
options.append(Option(name, default, doc, shortdoc, choices))
|
options.append(Option(name, default, doc, shortdoc, choices))
|
||||||
options = tuple(options)
|
options = OrderedDict([(o.name, o) for o in sorted(options, key=attrgetter('name'))])
|
||||||
del raw_options
|
del raw_options
|
||||||
|
|
||||||
defaults = namedtuple('Defaults', ' '.join(o.name for o in options))(*tuple(o.default for o in options))
|
class Options(object):
|
||||||
|
|
||||||
|
__slots__ = tuple(name for name in options)
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
for opt in options.itervalues():
|
||||||
|
setattr(self, opt.name, kwargs.get(opt.name, opt.default))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user