# AUTOGENERATED! DO NOT EDIT! File to edit: 02_http.ipynb (unless otherwise specified).

__all__ = ['ReuseThreadingServer', 'HandlerException', 'MinimalHTTPHandler']

# Cell
from http import client,HTTPStatus
from socketserver import ThreadingTCPServer,StreamRequestHandler
from fastcore.foundation import add_docs

# Cell
class ReuseThreadingServer(ThreadingTCPServer): allow_reuse_address = 1

# Cell
class HandlerException(Exception):
    "Class for exceptions from setup of `MinimalHTTPHandler`"
    def __init__(self, code, err=''):
        self.code = code
        super().__init__(str(err))

# Cell
class MinimalHTTPHandler(StreamRequestHandler):
    protocol_version,MessageClass = "HTTP/1.0",client.HTTPMessage
    def _setup(self):
        super().setup()
        self.raw_requestline = self.rfile.readline(65537)
        if len(self.raw_requestline) > 65536: raise HandlerException(HTTPStatus.REQUEST_URI_TOO_LONG)
        if not self.raw_requestline: raise HandlerException(HTTPStatus.BAD_REQUEST, "No request line")
        words = str(self.raw_requestline, 'iso-8859-1').rstrip('\r\n').split()
        if len(words) != 3: raise Exception(f'Invalid request: {words}')
        self.command,self.path,version = words
        if not version.startswith('HTTP/'): raise HandlerException( HTTPStatus.HTTP_VERSION_NOT_SUPPORTED, version )
        self.request_version = version.split('/', 1)[1]
        self.headers = client.parse_headers(self.rfile, _class=self.MessageClass)

    def setup(self):
        try: self._setup()
        except Exception as e: self.setup_ex(e)

    def setup_ex(self, e): raise e from None
    def send_header(self, keyword, value): self._headers_buffer.append(f"{keyword}: {value}\r\n")

    def end_headers(self):
        self._headers_buffer.append("\r\n")
        if self._headers_buffer: self.wfile.write("".join(self._headers_buffer).encode( 'latin-1', 'strict'))

    def send_response(self, code, message=''):
        if not message:
            try: message = HTTPStatus(code).phrase
            except ValueError: message = ''
        self._headers_buffer = [f"{self.protocol_version} {code} {message}\r\n"]
        self.send_header("Connection", "close")

# Cell
add_docs(MinimalHTTPHandler, "A greatly simplified version of `BaseHTTPHandler`. Overriding `handle` is required.",
         setup="Overriden from `BaseRequestHandler`",
         setup_ex="Override to handle exceptions in `setup`",
         send_response="Set the HTTP response code to `code`",
         send_header="Send a MIME header to the headers buffer",
         end_headers="Send the blank line ending the MIME headers",
         MessageClass="Class used for `http.client.parse_headers")