-
Notifications
You must be signed in to change notification settings - Fork 40
/
httpd.py
97 lines (75 loc) · 2.81 KB
/
httpd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# -*- encoding: utf-8 -*-
#
# Copyright 2012 posativ <info@posativ.org>. All rights reserved.
# License: BSD Style, 2 clauses. see acrylamid/__init__.py
"""
Internal Webserver
~~~~~~~~~~~~~~~~~~
Launch a dumb webserver as thread."""
import os
import time
import urllib
import posixpath
from threading import Thread
from SocketServer import TCPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
class ReuseAddressServer(TCPServer):
"""avoids socket.error: [Errno 48] Address already in use"""
allow_reuse_address = True
def serve_forever(self):
"""Handle one request at a time until doomsday."""
while not self.kill_received:
if not self.wait:
self.handle_request()
else:
time.sleep(0.1)
class AcrylServe(SimpleHTTPRequestHandler):
"""This is a modified version of python's -m SimpleHTTPServer to
serve on a specific sub directory of :func:`os.getcwd`."""
www_root = '.'
def translate_path(self, path):
"""Translate a /-separated PATH to the local filename syntax.
Components that mean special things to the local file system
(e.g. drive or directory names) are ignored. (XXX They should
probably be diagnosed.)
"""
# abandon query parameters
path = path.split('?', 1)[0]
path = path.split('#', 1)[0]
path = posixpath.normpath(urllib.unquote(path))
words = path.split('/')
words = filter(None, words)
path = os.path.join(os.getcwd(), self.www_root)
for word in words:
drive, word = os.path.splitdrive(word)
head, word = os.path.split(word)
if word in (os.curdir, os.pardir):
continue
path = os.path.join(path, word)
return path
def end_headers(self):
self.wfile.write('Cache-Control: max-age=0, must-revalidate\r\n')
SimpleHTTPRequestHandler.end_headers(self)
class Webserver(Thread):
"""A single-threaded webserver to serve while generation.
:param port: port to listen on
:param root: serve this directory under /"""
def __init__(self, port=8000, root='.'):
Thread.__init__(self)
Handler = AcrylServe
Handler.www_root = root
Handler.log_error = lambda x, *y: None
Handler.log_message = lambda x, *y: None
self.httpd = ReuseAddressServer(("", port), Handler)
self.httpd.wait = False
self.httpd.kill_received = False
def setwait(self, value):
self.httpd.wait = value
wait = property(lambda self: self.httpd.wait, setwait)
def run(self):
self.httpd.serve_forever()
self.join(1)
def shutdown(self):
""""Sets kill_recieved and closes the server socket."""
self.httpd.kill_received = True
self.httpd.socket.close()