many pep8 improvements
This commit is contained in:
+121
-92
@@ -16,21 +16,23 @@ import traceback
|
||||
VERSION = '1.2.5'
|
||||
SERVER_NAME = socket.gethostname()
|
||||
SERVER_SOFTWARE = 'Rocket %s' % VERSION
|
||||
HTTP_SERVER_SOFTWARE = '%s Python/%s' % (SERVER_SOFTWARE, sys.version.split(' ')[0])
|
||||
HTTP_SERVER_SOFTWARE = '%s Python/%s' % (
|
||||
SERVER_SOFTWARE, sys.version.split(' ')[0])
|
||||
BUF_SIZE = 16384
|
||||
SOCKET_TIMEOUT = 10 # in secs
|
||||
THREAD_STOP_CHECK_INTERVAL = 1 # in secs, How often should threads check for a server stop message?
|
||||
IS_JYTHON = platform.system() == 'Java' # Handle special cases for Jython
|
||||
SOCKET_TIMEOUT = 10 # in secs
|
||||
THREAD_STOP_CHECK_INTERVAL = 1 # in secs, How often should threads check for a server stop message?
|
||||
IS_JYTHON = platform.system() == 'Java' # Handle special cases for Jython
|
||||
IGNORE_ERRORS_ON_CLOSE = set([errno.ECONNABORTED, errno.ECONNRESET])
|
||||
DEFAULT_LISTEN_QUEUE_SIZE = 5
|
||||
DEFAULT_MIN_THREADS = 10
|
||||
DEFAULT_MAX_THREADS = 0
|
||||
DEFAULTS = dict(LISTEN_QUEUE_SIZE = DEFAULT_LISTEN_QUEUE_SIZE,
|
||||
MIN_THREADS = DEFAULT_MIN_THREADS,
|
||||
MAX_THREADS = DEFAULT_MAX_THREADS)
|
||||
DEFAULTS = dict(LISTEN_QUEUE_SIZE=DEFAULT_LISTEN_QUEUE_SIZE,
|
||||
MIN_THREADS=DEFAULT_MIN_THREADS,
|
||||
MAX_THREADS=DEFAULT_MAX_THREADS)
|
||||
|
||||
PY3K = sys.version_info[0] > 2
|
||||
|
||||
|
||||
class NullHandler(logging.Handler):
|
||||
"A Logging handler to prevent library errors."
|
||||
def emit(self, record):
|
||||
@@ -94,6 +96,7 @@ except ImportError:
|
||||
# TODO - This part is still very experimental.
|
||||
#from .filelike import FileLikeSocket
|
||||
|
||||
|
||||
class Connection(object):
|
||||
__slots__ = [
|
||||
'setblocking',
|
||||
@@ -170,6 +173,7 @@ except ImportError:
|
||||
# Import Package Modules
|
||||
# package imports removed in monolithic build
|
||||
|
||||
|
||||
class FileLikeSocket(object):
|
||||
def __init__(self, conn, buf_size=BUF_SIZE):
|
||||
self.conn = conn
|
||||
@@ -317,13 +321,12 @@ class WSGIFuture(Future):
|
||||
else:
|
||||
return super(WSGIFuture, self).set_running_or_notify_cancel()
|
||||
|
||||
|
||||
def remember(self, name, lifespan=None):
|
||||
self._lifespan = lifespan or self._lifespan
|
||||
|
||||
if name in self._mem_dict:
|
||||
raise NameError('Cannot remember future by name "%s". ' % name + \
|
||||
'A future already exists with that name.' )
|
||||
raise NameError('Cannot remember future by name "%s". ' % name +
|
||||
'A future already exists with that name.')
|
||||
self._name = name
|
||||
self._mem_dict[name] = self
|
||||
|
||||
@@ -334,6 +337,7 @@ class WSGIFuture(Future):
|
||||
del self._mem_dict[self._name]
|
||||
self._name = None
|
||||
|
||||
|
||||
class _WorkItem(object):
|
||||
def __init__(self, future, fn, args, kwargs):
|
||||
self.future = future
|
||||
@@ -353,6 +357,7 @@ class _WorkItem(object):
|
||||
else:
|
||||
self.future.set_result(result)
|
||||
|
||||
|
||||
class WSGIExecutor(ThreadPoolExecutor):
|
||||
multithread = True
|
||||
multiprocess = False
|
||||
@@ -366,7 +371,8 @@ class WSGIExecutor(ThreadPoolExecutor):
|
||||
if self._shutdown_lock.acquire():
|
||||
if self._shutdown:
|
||||
self._shutdown_lock.release()
|
||||
raise RuntimeError('Cannot schedule new futures after shutdown')
|
||||
raise RuntimeError(
|
||||
'Cannot schedule new futures after shutdown')
|
||||
|
||||
f = WSGIFuture(self.futures)
|
||||
w = _WorkItem(f, fn, args, kwargs)
|
||||
@@ -378,6 +384,7 @@ class WSGIExecutor(ThreadPoolExecutor):
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class FuturesMiddleware(object):
|
||||
"Futures middleware that adds a Futures Executor to the environment"
|
||||
def __init__(self, app, threads=5):
|
||||
@@ -405,11 +412,13 @@ try:
|
||||
has_ssl = True
|
||||
except ImportError:
|
||||
has_ssl = False
|
||||
|
||||
class SSLError(socket.error):
|
||||
pass
|
||||
# Import Package Modules
|
||||
# package imports removed in monolithic build
|
||||
|
||||
|
||||
class Listener(Thread):
|
||||
"""The Listener class is a class responsible for accepting connections
|
||||
and queuing them to be processed by a worker thread."""
|
||||
@@ -446,18 +455,18 @@ class Listener(Thread):
|
||||
elif not os.path.exists(interface[2]):
|
||||
data = (interface[2], interface[0], interface[1])
|
||||
self.err_log.error("Cannot find key file "
|
||||
"'%s'. Cannot bind to %s:%s" % data)
|
||||
"'%s'. Cannot bind to %s:%s" % data)
|
||||
return
|
||||
elif not os.path.exists(interface[3]):
|
||||
data = (interface[3], interface[0], interface[1])
|
||||
self.err_log.error("Cannot find certificate file "
|
||||
"'%s'. Cannot bind to %s:%s" % data)
|
||||
"'%s'. Cannot bind to %s:%s" % data)
|
||||
return
|
||||
|
||||
if self.clientcert_req and not os.path.exists(interface[4]):
|
||||
data = (interface[4], interface[0], interface[1])
|
||||
self.err_log.error("Cannot find root ca certificate file "
|
||||
"'%s'. Cannot bind to %s:%s" % data)
|
||||
"'%s'. Cannot bind to %s:%s" % data)
|
||||
return
|
||||
|
||||
# Set socket options
|
||||
@@ -499,18 +508,18 @@ class Listener(Thread):
|
||||
ca_certs = self.interface[4]
|
||||
cert_reqs = ssl.CERT_OPTIONAL
|
||||
sock = ssl.wrap_socket(sock,
|
||||
keyfile = self.interface[2],
|
||||
certfile = self.interface[3],
|
||||
server_side = True,
|
||||
cert_reqs = cert_reqs,
|
||||
ca_certs = ca_certs,
|
||||
ssl_version = ssl.PROTOCOL_SSLv23)
|
||||
keyfile=self.interface[2],
|
||||
certfile=self.interface[3],
|
||||
server_side=True,
|
||||
cert_reqs=cert_reqs,
|
||||
ca_certs=ca_certs,
|
||||
ssl_version=ssl.PROTOCOL_SSLv23)
|
||||
else:
|
||||
sock = ssl.wrap_socket(sock,
|
||||
keyfile = self.interface[2],
|
||||
certfile = self.interface[3],
|
||||
server_side = True,
|
||||
ssl_version = ssl.PROTOCOL_SSLv23)
|
||||
keyfile=self.interface[2],
|
||||
certfile=self.interface[3],
|
||||
server_side=True,
|
||||
ssl_version=ssl.PROTOCOL_SSLv23)
|
||||
|
||||
except SSLError:
|
||||
# Generally this happens when an HTTP request is received on a
|
||||
@@ -598,19 +607,17 @@ except ImportError:
|
||||
# package imports removed in monolithic build
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Setup Logging
|
||||
log = logging.getLogger('Rocket')
|
||||
log.addHandler(NullHandler())
|
||||
|
||||
|
||||
class Rocket(object):
|
||||
"""The Rocket class is responsible for handling threads and accepting and
|
||||
dispatching connections."""
|
||||
|
||||
def __init__(self,
|
||||
interfaces = ('127.0.0.1', 8000),
|
||||
interfaces=('127.0.0.1', 8000),
|
||||
method = 'wsgi',
|
||||
app_info = None,
|
||||
min_threads = None,
|
||||
@@ -650,15 +657,16 @@ class Rocket(object):
|
||||
self.active_queue = Queue()
|
||||
|
||||
self._threadpool = ThreadPool(get_method(method),
|
||||
app_info = app_info,
|
||||
active_queue = self.active_queue,
|
||||
monitor_queue = self.monitor_queue,
|
||||
min_threads = min_threads,
|
||||
max_threads = max_threads)
|
||||
app_info=app_info,
|
||||
active_queue=self.active_queue,
|
||||
monitor_queue=self.monitor_queue,
|
||||
min_threads=min_threads,
|
||||
max_threads=max_threads)
|
||||
|
||||
# Build our socket listeners
|
||||
self.listeners = [Listener(i, queue_size, self.active_queue) for i in self.interfaces]
|
||||
for ndx in range(len(self.listeners)-1, 0, -1):
|
||||
self.listeners = [Listener(
|
||||
i, queue_size, self.active_queue) for i in self.interfaces]
|
||||
for ndx in range(len(self.listeners) - 1, 0, -1):
|
||||
if not self.listeners[ndx].ready:
|
||||
del self.listeners[ndx]
|
||||
|
||||
@@ -705,7 +713,8 @@ class Rocket(object):
|
||||
str_extract = lambda l: (l.addr, l.port, l.secure and '*' or '')
|
||||
|
||||
msg = 'Listening on sockets: '
|
||||
msg += ', '.join(['%s:%i%s' % str_extract(l) for l in self.listeners])
|
||||
msg += ', '.join(
|
||||
['%s:%i%s' % str_extract(l) for l in self.listeners])
|
||||
log.info(msg)
|
||||
|
||||
for l in self.listeners:
|
||||
@@ -730,7 +739,7 @@ class Rocket(object):
|
||||
|
||||
return self.stop()
|
||||
|
||||
def stop(self, stoplogging = False):
|
||||
def stop(self, stoplogging=False):
|
||||
log.info('Stopping %s' % SERVER_SOFTWARE)
|
||||
|
||||
self.startstop_lock.acquire()
|
||||
@@ -773,23 +782,24 @@ class Rocket(object):
|
||||
self.stop()
|
||||
self.start()
|
||||
|
||||
|
||||
def CherryPyWSGIServer(bind_addr,
|
||||
wsgi_app,
|
||||
numthreads = 10,
|
||||
server_name = None,
|
||||
max = -1,
|
||||
request_queue_size = 5,
|
||||
timeout = 10,
|
||||
shutdown_timeout = 5):
|
||||
numthreads=10,
|
||||
server_name=None,
|
||||
max=-1,
|
||||
request_queue_size=5,
|
||||
timeout=10,
|
||||
shutdown_timeout=5):
|
||||
""" A Cherrypy wsgiserver-compatible wrapper. """
|
||||
max_threads = max
|
||||
if max_threads < 0:
|
||||
max_threads = 0
|
||||
return Rocket(bind_addr, 'wsgi', {'wsgi_app': wsgi_app},
|
||||
min_threads = numthreads,
|
||||
max_threads = max_threads,
|
||||
queue_size = request_queue_size,
|
||||
timeout = timeout)
|
||||
min_threads=numthreads,
|
||||
max_threads=max_threads,
|
||||
queue_size=request_queue_size,
|
||||
timeout=timeout)
|
||||
|
||||
# Monolithic build...end of module: rocket\main.py
|
||||
# Monolithic build...start of module: rocket\monitor.py
|
||||
@@ -803,6 +813,7 @@ from threading import Thread
|
||||
# Import Package Modules
|
||||
# package imports removed in monolithic build
|
||||
|
||||
|
||||
class Monitor(Thread):
|
||||
# Monitor worker class.
|
||||
|
||||
@@ -926,8 +937,10 @@ class Monitor(Thread):
|
||||
for c in stale:
|
||||
if __debug__:
|
||||
# "EXPR and A or B" kept for Py2.4 compatibility
|
||||
data = (c.client_addr, c.server_port, c.ssl and '*' or '')
|
||||
self.log.debug('Flushing stale connection: %s:%i%s' % data)
|
||||
data = (
|
||||
c.client_addr, c.server_port, c.ssl and '*' or '')
|
||||
self.log.debug(
|
||||
'Flushing stale connection: %s:%i%s' % data)
|
||||
|
||||
self.connections.remove(c)
|
||||
list_changed = True
|
||||
@@ -940,7 +953,6 @@ class Monitor(Thread):
|
||||
# Dynamically resize the threadpool to adapt to our changing needs.
|
||||
self._threadpool.dynamic_resize()
|
||||
|
||||
|
||||
def stop(self):
|
||||
self.active = False
|
||||
|
||||
@@ -984,6 +996,7 @@ import logging
|
||||
log = logging.getLogger('Rocket.Errors.ThreadPool')
|
||||
log.addHandler(NullHandler())
|
||||
|
||||
|
||||
class ThreadPool:
|
||||
"""The ThreadPool class is a container class for all the worker threads. It
|
||||
manages the number of actively running threads."""
|
||||
@@ -1011,7 +1024,7 @@ class ThreadPool:
|
||||
self.alive = False
|
||||
|
||||
# TODO - Optimize this based on some real-world usage data
|
||||
self.grow_threshold = int(max_threads/10) + 2
|
||||
self.grow_threshold = int(max_threads / 10) + 2
|
||||
|
||||
if not isinstance(app_info, dict):
|
||||
app_info = dict()
|
||||
@@ -1193,7 +1206,9 @@ Content-Type: %s
|
||||
%s
|
||||
'''
|
||||
if IS_JYTHON:
|
||||
HTTP_METHODS = set(['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'])
|
||||
HTTP_METHODS = set(['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT',
|
||||
'DELETE', 'TRACE', 'CONNECT'])
|
||||
|
||||
|
||||
class Worker(Thread):
|
||||
"""The Worker class is a base class responsible for receiving connections
|
||||
@@ -1223,7 +1238,7 @@ class Worker(Thread):
|
||||
self.req_log.addHandler(NullHandler())
|
||||
|
||||
# Error Log
|
||||
self.err_log = logging.getLogger('Rocket.Errors.'+self.getName())
|
||||
self.err_log = logging.getLogger('Rocket.Errors.' + self.getName())
|
||||
self.err_log.addHandler(NullHandler())
|
||||
|
||||
def _handleError(self, typ, val, tb):
|
||||
@@ -1301,11 +1316,11 @@ class Worker(Thread):
|
||||
self.err_log.debug('Serving a request')
|
||||
try:
|
||||
self.run_app(conn)
|
||||
log_info = dict(client_ip = conn.client_addr,
|
||||
time = datetime.now().strftime('%c'),
|
||||
status = self.status.split(' ')[0],
|
||||
size = self.size,
|
||||
request_line = self.request_line)
|
||||
log_info = dict(client_ip=conn.client_addr,
|
||||
time=datetime.now().strftime('%c'),
|
||||
status=self.status.split(' ')[0],
|
||||
size=self.size,
|
||||
request_line=self.request_line)
|
||||
self.req_log.info(LOG_LINE % log_info)
|
||||
except:
|
||||
exc = sys.exc_info()
|
||||
@@ -1314,11 +1329,12 @@ class Worker(Thread):
|
||||
break
|
||||
else:
|
||||
if self.request_line:
|
||||
log_info = dict(client_ip = conn.client_addr,
|
||||
time = datetime.now().strftime('%c'),
|
||||
status = self.status.split(' ')[0],
|
||||
size = self.size,
|
||||
request_line = self.request_line + ' - not stopping')
|
||||
log_info = dict(client_ip=conn.client_addr,
|
||||
time=datetime.now(
|
||||
).strftime('%c'),
|
||||
status=self.status.split(' ')[0],
|
||||
size=self.size,
|
||||
request_line=self.request_line + ' - not stopping')
|
||||
self.req_log.info(LOG_LINE % log_info)
|
||||
|
||||
if self.closeConnection:
|
||||
@@ -1382,13 +1398,15 @@ class Worker(Thread):
|
||||
except socket.timeout:
|
||||
raise SocketTimeout("Socket timed out before request.")
|
||||
except TypeError:
|
||||
raise SocketClosed("ssl bug caused closer of socket, upgrade to python 2.7")
|
||||
raise SocketClosed(
|
||||
"ssl bug caused closer of socket, upgrade to python 2.7")
|
||||
|
||||
d = d.strip()
|
||||
|
||||
if not d:
|
||||
if __debug__:
|
||||
self.err_log.debug('Client did not send a recognizable request.')
|
||||
self.err_log.debug(
|
||||
'Client did not send a recognizable request.')
|
||||
raise SocketClosed('Client closed socket.')
|
||||
|
||||
self.request_line = d
|
||||
@@ -1408,11 +1426,12 @@ class Worker(Thread):
|
||||
raise BadRequest
|
||||
|
||||
req = match.groupdict()
|
||||
for k,v in req.iteritems():
|
||||
for k, v in req.iteritems():
|
||||
if not v:
|
||||
req[k] = ""
|
||||
if k == 'path':
|
||||
req['path'] = r'%2F'.join([unquote(x) for x in re_SLASH.split(v)])
|
||||
req['path'] = r'%2F'.join(
|
||||
[unquote(x) for x in re_SLASH.split(v)])
|
||||
|
||||
return req
|
||||
|
||||
@@ -1421,15 +1440,15 @@ class Worker(Thread):
|
||||
try:
|
||||
method, uri, proto = d.split(' ')
|
||||
if not proto.startswith('HTTP') or \
|
||||
proto[-3:] not in ('1.0', '1.1') or \
|
||||
method not in HTTP_METHODS:
|
||||
proto[-3:] not in ('1.0', '1.1') or \
|
||||
method not in HTTP_METHODS:
|
||||
self.send_response('400 Bad Request')
|
||||
raise BadRequest
|
||||
except ValueError:
|
||||
self.send_response('400 Bad Request')
|
||||
raise BadRequest
|
||||
|
||||
req = dict(method=method, protocol = proto)
|
||||
req = dict(method=method, protocol=proto)
|
||||
scheme = ''
|
||||
host = ''
|
||||
if uri == '*' or uri.startswith('/'):
|
||||
@@ -1454,7 +1473,6 @@ class Worker(Thread):
|
||||
host=host)
|
||||
return req
|
||||
|
||||
|
||||
def read_headers(self, sock_file, environ):
|
||||
try:
|
||||
lname = None
|
||||
@@ -1464,9 +1482,10 @@ class Worker(Thread):
|
||||
try:
|
||||
l = str(l, 'ISO-8859-1')
|
||||
except UnicodeDecodeError:
|
||||
self.err_log.warning('Invalid request header: '+repr(l))
|
||||
self.err_log.warning(
|
||||
'Invalid request header: ' + repr(l))
|
||||
|
||||
if l.strip().replace('\0','') == '':
|
||||
if l.strip().replace('\0', '') == '':
|
||||
break
|
||||
elif l[0] in ' \t' and lname:
|
||||
# Some headers take more than one line
|
||||
@@ -1476,25 +1495,30 @@ class Worker(Thread):
|
||||
l = l.split(':', 1)
|
||||
# HTTP header names are us-ascii encoded
|
||||
|
||||
lname = str('HTTP_'+l[0].strip().upper().replace('-', '_'))
|
||||
lname = str(
|
||||
'HTTP_' + l[0].strip().upper().replace('-', '_'))
|
||||
lval = str(l[-1].strip())
|
||||
environ[lname] = lval
|
||||
|
||||
except socket.timeout:
|
||||
raise SocketTimeout("Socket timed out before request.")
|
||||
|
||||
|
||||
class SocketTimeout(Exception):
|
||||
"Exception for when a socket times out between requests."
|
||||
pass
|
||||
|
||||
|
||||
class BadRequest(Exception):
|
||||
"Exception for when a client sends an incomprehensible request."
|
||||
pass
|
||||
|
||||
|
||||
class SocketClosed(Exception):
|
||||
"Exception for when a socket is closed by the client."
|
||||
pass
|
||||
|
||||
|
||||
class ChunkedReader(object):
|
||||
def __init__(self, sock_file):
|
||||
self.stream = sock_file
|
||||
@@ -1542,6 +1566,7 @@ class ChunkedReader(object):
|
||||
def readlines(self):
|
||||
yield self.readline()
|
||||
|
||||
|
||||
def get_method(method):
|
||||
methods = dict(wsgi=WSGIWorker)
|
||||
return methods[method.lower()]
|
||||
@@ -1559,7 +1584,6 @@ from wsgiref.util import FileWrapper
|
||||
# package imports removed in monolithic build
|
||||
|
||||
|
||||
|
||||
if PY3K:
|
||||
from email.utils import formatdate
|
||||
else:
|
||||
@@ -1578,6 +1602,7 @@ BASE_ENV = {'SERVER_NAME': SERVER_NAME,
|
||||
'wsgi.file_wrapper': FileWrapper
|
||||
}
|
||||
|
||||
|
||||
class WSGIWorker(Worker):
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Builds some instance variables that will last the life of the
|
||||
@@ -1588,9 +1613,10 @@ class WSGIWorker(Worker):
|
||||
multithreaded = self.app_info.get('max_threads') != 1
|
||||
else:
|
||||
multithreaded = False
|
||||
self.base_environ = dict({'SERVER_SOFTWARE': self.app_info['server_software'],
|
||||
'wsgi.multithread': multithreaded,
|
||||
})
|
||||
self.base_environ = dict(
|
||||
{'SERVER_SOFTWARE': self.app_info['server_software'],
|
||||
'wsgi.multithread': multithreaded,
|
||||
})
|
||||
self.base_environ.update(BASE_ENV)
|
||||
|
||||
# Grab our application
|
||||
@@ -1614,7 +1640,7 @@ class WSGIWorker(Worker):
|
||||
environ = self.base_environ.copy()
|
||||
|
||||
# Grab the headers
|
||||
self.read_headers(sock_file,environ)
|
||||
self.read_headers(sock_file, environ)
|
||||
|
||||
# Add CGI Variables
|
||||
environ['SERVER_PORT'] = str(conn.server_port)
|
||||
@@ -1644,7 +1670,7 @@ class WSGIWorker(Worker):
|
||||
peercert = conn.socket.getpeercert(binary_form=True)
|
||||
environ['SSL_CLIENT_RAW_CERT'] = \
|
||||
peercert and ssl.DER_cert_to_PEM_cert(peercert)
|
||||
except Exception,e:
|
||||
except Exception, e:
|
||||
print e
|
||||
|
||||
if environ.get('HTTP_TRANSFER_ENCODING', '') == 'chunked':
|
||||
@@ -1822,7 +1848,7 @@ class WSGIWorker(Worker):
|
||||
if __debug__:
|
||||
self.err_log.debug('Finally closing output and sock_file')
|
||||
|
||||
if hasattr(output,'close'):
|
||||
if hasattr(output, 'close'):
|
||||
output.close()
|
||||
|
||||
sock_file.close()
|
||||
@@ -1833,19 +1859,21 @@ class WSGIWorker(Worker):
|
||||
# the following code is not part of Rocket but was added in web2py for testing purposes
|
||||
#
|
||||
|
||||
|
||||
def demo_app(environ, start_response):
|
||||
global static_folder
|
||||
import os
|
||||
types = {'htm': 'text/html','html': 'text/html','gif': 'image/gif',
|
||||
'jpg': 'image/jpeg','png': 'image/png','pdf': 'applications/pdf'}
|
||||
types = {'htm': 'text/html', 'html': 'text/html', 'gif': 'image/gif',
|
||||
'jpg': 'image/jpeg', 'png': 'image/png', 'pdf': 'applications/pdf'}
|
||||
if static_folder:
|
||||
if not static_folder.startswith('/'):
|
||||
static_folder = os.path.join(os.getcwd(),static_folder)
|
||||
path = os.path.join(static_folder, environ['PATH_INFO'][1:] or 'index.html')
|
||||
type = types.get(path.split('.')[-1],'text')
|
||||
static_folder = os.path.join(os.getcwd(), static_folder)
|
||||
path = os.path.join(
|
||||
static_folder, environ['PATH_INFO'][1:] or 'index.html')
|
||||
type = types.get(path.split('.')[-1], 'text')
|
||||
if os.path.exists(path):
|
||||
try:
|
||||
data = open(path,'rb').read()
|
||||
data = open(path, 'rb').read()
|
||||
start_response('200 OK', [('Content-Type', type)])
|
||||
except IOError:
|
||||
start_response('404 NOT FOUND', [])
|
||||
@@ -1858,21 +1886,22 @@ def demo_app(environ, start_response):
|
||||
data = '<html><body><h1>Hello from Rocket Web Server</h1></body></html>'
|
||||
return [data]
|
||||
|
||||
|
||||
def demo():
|
||||
from optparse import OptionParser
|
||||
parser = OptionParser()
|
||||
parser.add_option("-i", "--ip", dest="ip",default="127.0.0.1",
|
||||
parser.add_option("-i", "--ip", dest="ip", default="127.0.0.1",
|
||||
help="ip address of the network interface")
|
||||
parser.add_option("-p", "--port", dest="port",default="8000",
|
||||
parser.add_option("-p", "--port", dest="port", default="8000",
|
||||
help="post where to run web server")
|
||||
parser.add_option("-s", "--static", dest="static",default=None,
|
||||
parser.add_option("-s", "--static", dest="static", default=None,
|
||||
help="folder containing static files")
|
||||
(options, args) = parser.parse_args()
|
||||
global static_folder
|
||||
static_folder = options.static
|
||||
print 'Rocket running on %s:%s' % (options.ip, options.port)
|
||||
r=Rocket((options.ip,int(options.port)),'wsgi', {'wsgi_app':demo_app})
|
||||
r = Rocket((options.ip, int(options.port)), 'wsgi', {'wsgi_app': demo_app})
|
||||
r.start()
|
||||
|
||||
if __name__=='__main__':
|
||||
if __name__ == '__main__':
|
||||
demo()
|
||||
|
||||
Reference in New Issue
Block a user