Basic HTTP handling.
1.1 --- a/server/server.py Sun Dec 11 02:27:29 2011 +0100
1.2 +++ b/server/server.py Sun Dec 11 04:30:28 2011 +0100
1.3 @@ -4,99 +4,107 @@
1.4 Author: Eugen Sawin <sawine@me73.com>
1.5 """
1.6
1.7 +import socketserver
1.8 +import logging
1.9 +import os.path
1.10 +from urllib.parse import urlparse
1.11 from argparse import ArgumentParser
1.12 from http.server import BaseHTTPRequestHandler, HTTPServer
1.13 -import socketserver
1.14 -from urllib.parse import urlparse
1.15 -import logging
1.16
1.17 ENCODING = "utf-8"
1.18
1.19 -
1.20 def parse_args():
1.21 parser = ArgumentParser(description="")
1.22 parser.add_argument("-p", type=int, default=8080, help="port")
1.23 parser.add_argument("-a", default="localhost", help="host address")
1.24 parser.add_argument("-l", default="log/server.log", help="log file")
1.25 + parser.add_argument("-d", default="../client", help="http docs path")
1.26 return parser.parse_args()
1.27
1.28
1.29 def main():
1.30 args = parse_args()
1.31 logging.basicConfig(filename=args.l, level=logging.DEBUG,
1.32 - format="[%(levelname)s @ %(asctime)s] %(message)s",
1.33 + format="[%(levelname)s@%(asctime)s] %(message)s",
1.34 datefmt="%d.%m.%Y %I:%M:%S")
1.35 - server = Server(args.a, args.p, GetHandler)
1.36 + server = Server(args.a, args.p, args.d, GetHandler)
1.37 server.run()
1.38
1.39
1.40 class GetHandler(BaseHTTPRequestHandler):
1.41
1.42 def do_GET(self):
1.43 - logging.debug("Received query: %s" % self.path)
1.44 - request = Request(self.path)
1.45 + request = Request(self.path, self.server.docs_path)
1.46 logging.info("Request: %s" % request)
1.47 - if self.path == "/":
1.48 - self.path = "/machine.html"
1.49 - parsed_path = urlparse(self.path)
1.50 - message = "\n".join(("client: %s:%i" % self.client_address,
1.51 - "path: %s" % parsed_path.path,
1.52 - "query: %s" % parsed_path.query,
1.53 - "params: %s" % parsed_path.params))
1.54 - self.send_response(200)
1.55 - resource = True
1.56 - if parsed_path.path.endswith(".html"):
1.57 - self.send_header("Content-type", "text/html")
1.58 - elif parsed_path.path.endswith(".css"):
1.59 - self.send_header("Content-type", "text/css")
1.60 - elif parsed_path.path.endswith(".js"):
1.61 - self.send_header("Content-type", "application/javascript")
1.62 - else:
1.63 - self.send_header("Content-type", "application/json")
1.64 - resource = False
1.65 + code, content_type, data = request()
1.66 + self.send_response(code)
1.67 + self.send_header("Content-type", content_type)
1.68 self.end_headers()
1.69 - if resource:
1.70 - self.wfile.write(bytes(open("../client" + parsed_path.path).read(), ENCODING))
1.71 - else:
1.72 - self.wfile.write(bytes("{'time': 73}", ENCODING))
1.73 + self.wfile.write(data)
1.74 +
1.75 + def log_message(self, format, *args):
1.76 + pass
1.77
1.78
1.79 class Server(HTTPServer):
1.80
1.81 - def __init__(self, host, port, handler):
1.82 + def __init__(self, host, port, docs_path, handler):
1.83 HTTPServer.__init__(self, (host, port), handler)
1.84 self.host = host
1.85 self.port = port
1.86 + self.docs_path = docs_path
1.87
1.88 def run(self):
1.89 logging.info("Server ready and listening at port %i." % self.port)
1.90 self.serve_forever()
1.91
1.92 +
1.93 class Request:
1.94
1.95 _request_types = {"help": []}
1.96 +
1.97 + @classmethod
1.98 + def _content_type(cls, doc):
1.99 + if doc.endswith(".html"):
1.100 + return "text/html"
1.101 + elif doc.endswith(".css"):
1.102 + return "text/css"
1.103 + elif doc.endswith(".js"):
1.104 + return "application/javascript"
1.105 + else:
1.106 + return "text/plain"
1.107
1.108 - def __init__(self, query):
1.109 + def __init__(self, query, docs_path):
1.110 self.args = {}
1.111 - pos = query.find("?")
1.112 - if pos == -1:
1.113 + self.docs_path = docs_path
1.114 + self.parsed = urlparse(query)
1.115 + if self.parsed.query == "":
1.116 self.__class__ = WebRequest
1.117 - self.args["doc"] = query
1.118 - else:
1.119 - com = query[:pos]
1.120 - arg_str = query[pos:]
1.121 - for t, args in _request_types:
1.122 - pass
1.123 + self.args["doc"] = self.parsed.path
1.124 + else:
1.125 + com = self.parsed.path.strip("/")
1.126 + self.args = dict([q.split("=") for q in self.parsed.query.split("&")])
1.127
1.128 def __str__(self):
1.129 return "%s(%s)" % (str(self.__class__).partition(".")[-1].rstrip("'>"),
1.130 ", ".join(["%s: %s" % (k, str(v))
1.131 for k, v in self.args.items()]))
1.132
1.133 +
1.134 class WebRequest(Request):
1.135
1.136 def __call__(self):
1.137 - pass
1.138 + if self.args["doc"] == "/":
1.139 + self.args["doc"] = "/machine.html"
1.140 + content_type = self._content_type(self.args["doc"])
1.141 + data = ""
1.142 + rel_path = self.docs_path + self.args["doc"]
1.143 + if os.path.exists(rel_path):
1.144 + data = open(rel_path).read()
1.145 + code = 200
1.146 + else:
1.147 + code = 404
1.148 + return (code, content_type, bytes(data, ENCODING))
1.149
1.150
1.151 if __name__ == "__main__":