我正在使用cherrypy的wsgi服务器为我的django项目提供服务。服务器提供来自django项目的所有静态和媒体文件。代码如下
#create basic django WSGI app
app = WSGIHandler()
path = {'/': app}
#create app that handles static files from static root and put it in path
path[static_url] = StaticFileWsgiApplication(static_root)
#create app that handles /media and put it in path
path[media_url] = StaticFileWsgiApplication(media_root)
#dispatch the applications
dispatcher = wsgiserver.WSGIPathInfoDispatcher(path)
if __name__ == '__main__':
print 'Close window to exit'
#create wsgi cherrypy server
server = wsgiserver.CherryPyWSGIServer(
('0.0.0.0', 8000),
dispatcher,
server_name='cherrypy-django',
numthreads=20
)
try:
server.start()
except KeyboardInterrupt:
server.stop()
和静态文件应用
class StaticFileWsgiApplication(object):
#init function to get the directory of collectstatic (STATIC_ROOT)
def __init__(self, static_file_root):
self.static_file_root = os.path.normpath(static_file_root)
#Every wsgi app must be callable. It needs 2 arguments
#eviron: wsgi environ path
#start_response:Function creates the response
def __call__(self, environ, start_respone):
def done(status, headers, output):
#usefull for debugging
#returns the output(actual static file)
#also it produces the response using the start_response()
start_respone(status, headers.items())
return output
#get the path_info see PEP 333
path_info = environ['PATH_INFO']
#remove leading '/' from path (URI)
if path_info[0]=='/':
path_info = path_info[1:]
#actual file path in filesystem
file_path = os.path.normpath((os.path.join(self.static_file_root, path_info)))
#prevent escaping out of paths bellow media root (e.g via '..')
if not file_path.startswith(self.static_file_root):
status = '401 UNAUTHORIZED'
headers = {'Content_type':'text/plain'}
output = ['Permission denied. Illegal Path']
return done(status, headers, output)
#Only allow GET and HEAD requests not PUT, POST, DELETE
if not (environ['REQUEST_METHOD'] == 'GET' or environ['REQUEST_METHOD'] == 'HEAD'):
status = '405 METHOD NOT ALLOWED'
headers = {'Content_type':'text/plain'}
output = SimpleResponse(['405:Method not allowed'])
output.status_code = 405
return done(status, headers, output)
if not (os.path.exists(file_path)):
status = "404 NOT FOUND"
headers = {'Content_type':'text\plain'}
output = SimpleResponse(['Page not found %s' %file_path])
output.status_code = 404
return done(status, headers, output)
try:
fp = open(file_path, 'rb')
except IOError:
status = '401 UNAUTHORIZED'
headers = {'Content_type':'text/plain'}
output = SimpleResponse(['Permission denied %s' %file_path])
output.status_code = 401
return done(status, headers, output)
#This is a very simple implementation of conditional GET with
#the Last-Modified header. It makes media files a bit speedier
#because the files are only read off disk for the first request
#(assuming the browser/client supports conditional GET).
#mimetype needs to be ascii not uinicode, as django is all unicode, need to do conversion
mtime = http_date(os.stat(file_path)[stat.ST_MTIME]).encode('ascii','ignore')
if environ.get('HTTP_IF_MODIFIED_SINCE', None) == mtime:
headers = {'Last-Modified':mtime}
status = '304 NOT MODIFIED'
output = SimpleResponse()
output.status_code = 304
else:
status = '200 OK'
mime_type = mimetypes.guess_type(file_path)[0]
if mime_type:
headers = {'Content_type':mime_type}
output = BlockIteratorResponse(fp)
return done(status, headers,output)
我在调用中收到有关在使用之前未初始化标头的错误...可能是因为所有标头都在内部。错误是
UnboundLocalError:Local variable "headers" referenced before assignment
有趣的是,我只在Mozilla上收到此错误,但网络正常,一切都正常,并且在我登录我的网页后,它不再显示错误。
我应该在调用开始时初始化标头变量,如
headers = {}
为什么它只发生在firefox中?
答案 0 :(得分:0)
如果您想使用CherryPy提供静态内容,则应使用内置工具 - 请参阅Serving Static Content。我想你需要创建一个仅提供静态内容的CherryPy应用程序,然后将其与WSGIPathInfoDispatcher(...)
的Django应用程序结合使用。
但你应该考虑的是使用nginx + uWSGI - 请参阅Setting up Django and your web server with uWSGI and nginx。