mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-11 21:53:37 +00:00
cec4ed573d
Switched out sqlite3 libs in favour of SQLAlchemy v0.9, will gradually migrate dialects and scheme to be fully SQLAlchemy compliant for using there ORM with sessions instead of direct. Fixed getEpisode function to stop making unrequired scene number conversions on already converted data thats available now from cache.
218 lines
7.8 KiB
Python
218 lines
7.8 KiB
Python
"""Manage HTTP servers with CherryPy."""
|
|
|
|
import warnings
|
|
|
|
import cherrypy
|
|
from cherrypy.lib import attributes
|
|
from cherrypy._cpcompat import basestring, py3k
|
|
|
|
# We import * because we want to export check_port
|
|
# et al as attributes of this module.
|
|
from cherrypy.process.servers import *
|
|
|
|
|
|
class Server(ServerAdapter):
|
|
|
|
"""An adapter for an HTTP server.
|
|
|
|
You can set attributes (like socket_host and socket_port)
|
|
on *this* object (which is probably cherrypy.server), and call
|
|
quickstart. For example::
|
|
|
|
cherrypy.server.socket_port = 80
|
|
cherrypy.quickstart()
|
|
"""
|
|
|
|
socket_port = 8080
|
|
"""The TCP port on which to listen for connections."""
|
|
|
|
_socket_host = '127.0.0.1'
|
|
|
|
def _get_socket_host(self):
|
|
return self._socket_host
|
|
|
|
def _set_socket_host(self, value):
|
|
if value == '':
|
|
raise ValueError("The empty string ('') is not an allowed value. "
|
|
"Use '0.0.0.0' instead to listen on all active "
|
|
"interfaces (INADDR_ANY).")
|
|
self._socket_host = value
|
|
socket_host = property(
|
|
_get_socket_host,
|
|
_set_socket_host,
|
|
doc="""The hostname or IP address on which to listen for connections.
|
|
|
|
Host values may be any IPv4 or IPv6 address, or any valid hostname.
|
|
The string 'localhost' is a synonym for '127.0.0.1' (or '::1', if
|
|
your hosts file prefers IPv6). The string '0.0.0.0' is a special
|
|
IPv4 entry meaning "any active interface" (INADDR_ANY), and '::'
|
|
is the similar IN6ADDR_ANY for IPv6. The empty string or None are
|
|
not allowed.""")
|
|
|
|
socket_file = None
|
|
"""If given, the name of the UNIX socket to use instead of TCP/IP.
|
|
|
|
When this option is not None, the `socket_host` and `socket_port` options
|
|
are ignored."""
|
|
|
|
socket_queue_size = 5
|
|
"""The 'backlog' argument to socket.listen(); specifies the maximum number
|
|
of queued connections (default 5)."""
|
|
|
|
socket_timeout = 10
|
|
"""The timeout in seconds for accepted connections (default 10)."""
|
|
|
|
shutdown_timeout = 5
|
|
"""The time to wait for HTTP worker threads to clean up."""
|
|
|
|
protocol_version = 'HTTP/1.1'
|
|
"""The version string to write in the Status-Line of all HTTP responses,
|
|
for example, "HTTP/1.1" (the default). Depending on the HTTP server used,
|
|
this should also limit the supported features used in the response."""
|
|
|
|
thread_pool = 10
|
|
"""The number of worker threads to start up in the pool."""
|
|
|
|
thread_pool_max = -1
|
|
"""The maximum size of the worker-thread pool. Use -1 to indicate no limit.
|
|
"""
|
|
|
|
max_request_header_size = 500 * 1024
|
|
"""The maximum number of bytes allowable in the request headers.
|
|
If exceeded, the HTTP server should return "413 Request Entity Too Large".
|
|
"""
|
|
|
|
max_request_body_size = 100 * 1024 * 1024
|
|
"""The maximum number of bytes allowable in the request body. If exceeded,
|
|
the HTTP server should return "413 Request Entity Too Large"."""
|
|
|
|
instance = None
|
|
"""If not None, this should be an HTTP server instance (such as
|
|
CPWSGIServer) which cherrypy.server will control. Use this when you need
|
|
more control over object instantiation than is available in the various
|
|
configuration options."""
|
|
|
|
ssl_context = None
|
|
"""When using PyOpenSSL, an instance of SSL.Context."""
|
|
|
|
ssl_certificate = None
|
|
"""The filename of the SSL certificate to use."""
|
|
|
|
ssl_certificate_chain = None
|
|
"""When using PyOpenSSL, the certificate chain to pass to
|
|
Context.load_verify_locations."""
|
|
|
|
ssl_private_key = None
|
|
"""The filename of the private key to use with SSL."""
|
|
|
|
if py3k:
|
|
ssl_module = 'builtin'
|
|
"""The name of a registered SSL adaptation module to use with
|
|
the builtin WSGI server. Builtin options are: 'builtin' (to
|
|
use the SSL library built into recent versions of Python).
|
|
You may also register your own classes in the
|
|
wsgiserver.ssl_adapters dict."""
|
|
else:
|
|
ssl_module = 'pyopenssl'
|
|
"""The name of a registered SSL adaptation module to use with the
|
|
builtin WSGI server. Builtin options are 'builtin' (to use the SSL
|
|
library built into recent versions of Python) and 'pyopenssl' (to
|
|
use the PyOpenSSL project, which you must install separately). You
|
|
may also register your own classes in the wsgiserver.ssl_adapters
|
|
dict."""
|
|
|
|
statistics = False
|
|
"""Turns statistics-gathering on or off for aware HTTP servers."""
|
|
|
|
nodelay = True
|
|
"""If True (the default since 3.1), sets the TCP_NODELAY socket option."""
|
|
|
|
wsgi_version = (1, 0)
|
|
"""The WSGI version tuple to use with the builtin WSGI server.
|
|
The provided options are (1, 0) [which includes support for PEP 3333,
|
|
which declares it covers WSGI version 1.0.1 but still mandates the
|
|
wsgi.version (1, 0)] and ('u', 0), an experimental unicode version.
|
|
You may create and register your own experimental versions of the WSGI
|
|
protocol by adding custom classes to the wsgiserver.wsgi_gateways dict."""
|
|
|
|
def __init__(self):
|
|
self.bus = cherrypy.engine
|
|
self.httpserver = None
|
|
self.interrupt = None
|
|
self.running = False
|
|
|
|
def httpserver_from_self(self, httpserver=None):
|
|
"""Return a (httpserver, bind_addr) pair based on self attributes."""
|
|
if httpserver is None:
|
|
httpserver = self.instance
|
|
if httpserver is None:
|
|
from cherrypy import _cpwsgi_server
|
|
httpserver = _cpwsgi_server.CPWSGIServer(self)
|
|
if isinstance(httpserver, basestring):
|
|
# Is anyone using this? Can I add an arg?
|
|
httpserver = attributes(httpserver)(self)
|
|
return httpserver, self.bind_addr
|
|
|
|
def start(self):
|
|
"""Start the HTTP server."""
|
|
if not self.httpserver:
|
|
self.httpserver, self.bind_addr = self.httpserver_from_self()
|
|
ServerAdapter.start(self)
|
|
start.priority = 75
|
|
|
|
def _get_bind_addr(self):
|
|
if self.socket_file:
|
|
return self.socket_file
|
|
if self.socket_host is None and self.socket_port is None:
|
|
return None
|
|
return (self.socket_host, self.socket_port)
|
|
|
|
def _set_bind_addr(self, value):
|
|
if value is None:
|
|
self.socket_file = None
|
|
self.socket_host = None
|
|
self.socket_port = None
|
|
elif isinstance(value, basestring):
|
|
self.socket_file = value
|
|
self.socket_host = None
|
|
self.socket_port = None
|
|
else:
|
|
try:
|
|
self.socket_host, self.socket_port = value
|
|
self.socket_file = None
|
|
except ValueError:
|
|
raise ValueError("bind_addr must be a (host, port) tuple "
|
|
"(for TCP sockets) or a string (for Unix "
|
|
"domain sockets), not %r" % value)
|
|
bind_addr = property(
|
|
_get_bind_addr,
|
|
_set_bind_addr,
|
|
doc='A (host, port) tuple for TCP sockets or '
|
|
'a str for Unix domain sockets.')
|
|
|
|
def base(self):
|
|
"""Return the base (scheme://host[:port] or sock file) for this server.
|
|
"""
|
|
if self.socket_file:
|
|
return self.socket_file
|
|
|
|
host = self.socket_host
|
|
if host in ('0.0.0.0', '::'):
|
|
# 0.0.0.0 is INADDR_ANY and :: is IN6ADDR_ANY.
|
|
# Look up the host name, which should be the
|
|
# safest thing to spit out in a URL.
|
|
import socket
|
|
host = socket.gethostname()
|
|
|
|
port = self.socket_port
|
|
|
|
if self.ssl_certificate:
|
|
scheme = "https"
|
|
if port != 443:
|
|
host += ":%s" % port
|
|
else:
|
|
scheme = "http"
|
|
if port != 80:
|
|
host += ":%s" % port
|
|
|
|
return "%s://%s" % (scheme, host)
|