diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2021-03-03 23:09:11 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2021-03-03 23:09:11 +0300 |
commit | 69580ef09cfb0f41fa50d3252f4a83cfb7f153b5 (patch) | |
tree | 87f2c4c07719f30698a0f34c61020c395181c7d3 /cgi-bin/get.py | |
parent | prune obsolete entry from .gitignore (diff) | |
download | linux-status-69580ef09cfb0f41fa50d3252f4a83cfb7f153b5.tar.gz linux-status-69580ef09cfb0f41fa50d3252f4a83cfb7f153b5.zip |
add server.py
It runs a web server and imports the request handling classes from
get.py directly, hence eliminating the performance culprit (which was
the `import` processing for each request).
Diffstat (limited to '')
-rwxr-xr-x | cgi-bin/get.py | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/cgi-bin/get.py b/cgi-bin/get.py index 3831812..1453dc2 100755 --- a/cgi-bin/get.py +++ b/cgi-bin/get.py @@ -10,6 +10,7 @@ import cgi from collections import namedtuple from concurrent.futures import ThreadPoolExecutor from enum import Enum +import http.server import json import os import pwd @@ -38,16 +39,43 @@ class Response: def __init__(self, data): self.data = data - def print(self): - print("Content-Type: text/html; charset=utf-8") - print() - if self.data is not None: - print(self.dump_json(self.data)) + def headers(self): + yield 'Content-Type', 'text/html; charset=utf-8' @staticmethod def dump_json(data): return json.dumps(data, ensure_ascii=False) + def body(self): + return self.dump_json(self.data) + + def write_as_cgi_script(self): + self.write_headers_as_cgi_script() + self.write_body_as_cgi_script() + + def write_headers_as_cgi_script(self): + for name, val in self.headers(): + print(f'{name}: {val}') + print() + + def write_body_as_cgi_script(self): + if self.data is not None: + print(self.body()) + + def write_as_request_handler(self, handler): + handler.send_response(http.server.HTTPStatus.OK) + self.write_headers_as_request_handler(handler) + self.write_body_as_request_handler(handler) + + def write_headers_as_request_handler(self, handler): + for name, val in self.headers(): + handler.send_header(name, val) + handler.end_headers() + + def write_body_as_request_handler(self, handler): + if self.data is not None: + handler.wfile.write(self.body().encode(errors='replace')) + def run_do(*args, **kwargs): output = subprocess.run(args, stdin=DEVNULL, stdout=PIPE, stderr=STDOUT, universal_newlines=True, **kwargs) @@ -318,6 +346,12 @@ class Request(Enum): def __str__(self): return self.value + @staticmethod + def from_http_path(path): + if not path or path[0] != '/': + raise ValueError('HTTP path must start with a forward slash /') + return Request(path[1:]) + def process(self): if self is Request.STATUS: return StatusTask().complete() @@ -331,7 +365,7 @@ class Request(Enum): def process_cgi_request(): params = cgi.FieldStorage() what = params['what'].value - Request(what).process().print() + Request(what).process().write_as_cgi_script() def main(): |