diff --git a/client/command.py b/client/command.py index 7eae322..573b9b6 100644 --- a/client/command.py +++ b/client/command.py @@ -41,14 +41,6 @@ class AbstractCommand(ABC): def command(self): pass - @staticmethod - def build_message(command, host, path): - message = f"{command} {path} HTTP/1.1\r\n" - message += f"Host: {host}\r\n" - message += "Accept: */*\r\nAccept-Encoding: identity\r\n" - - return message.encode(FORMAT) - def execute(self, sub_request=False): (host, path) = self.parse_uri() @@ -120,10 +112,6 @@ class AbstractCommand(ABC): class AbstractWithBodyCommand(AbstractCommand, ABC): - @staticmethod - def build_message(command, host, path): - message = AbstractCommand.build_message() - def _build_message(self, message: str) -> bytes: body = input(f"Enter {self.command} data: ").encode(FORMAT) print() diff --git a/server/RequestHandler.py b/server/RequestHandler.py index 8070a99..f02f9a6 100644 --- a/server/RequestHandler.py +++ b/server/RequestHandler.py @@ -93,7 +93,7 @@ class RequestHandler: else: path = self.root + target mime = mimetypes.guess_type(path)[0] - if mime.startswith("test"): + if mime.startswith("text"): file = open(path, "rb", FORMAT) else: file = open(path, "rb") @@ -104,7 +104,7 @@ class RequestHandler: message += date + "\r\n" if mime: message += f"Content-Type: {mime}" - if mime.startswith("test"): + if mime.startswith("text"): message += "; charset=UTF-8" message += "\r\n" message += f"Content-Length: {len(buffer)}\r\n" diff --git a/server/command.py b/server/command.py new file mode 100644 index 0000000..548c542 --- /dev/null +++ b/server/command.py @@ -0,0 +1,98 @@ +import logging +from abc import ABC, abstractmethod +from typing import Dict, Tuple +from urllib.parse import urlparse + +from client.httpclient import FORMAT, HTTPClient +from httplib import parser +from httplib.exceptions import InvalidResponse, InvalidStatusLine, UnsupportedEncoding +from httplib.message import Message +from httplib.retriever import PreambleRetriever + + +def create(method: str, message: Message): + + if method == "GET": + return GetCommand(url, port) + elif method == "HEAD": + return HeadCommand(url, port) + elif method == "POST": + return PostCommand(url, port) + elif method == "PUT": + return PutCommand(url, port) + else: + raise ValueError() + + +class AbstractCommand(ABC): + path: str + headers: Dict[str, str] + + def __init(self): + pass + + @property + @abstractmethod + def command(self): + pass + + +class AbstractWithBodyCommand(AbstractCommand, ABC): + + def _build_message(self, message: str) -> bytes: + body = input(f"Enter {self.command} data: ").encode(FORMAT) + print() + + message += "Content-Type: text/plain\r\n" + message += f"Content-Length: {len(body)}\r\n" + message += "\r\n" + message = message.encode(FORMAT) + message += body + message += b"\r\n" + + return message + + +class HeadCommand(AbstractCommand): + @property + def command(self): + return "HEAD" + + +class GetCommand(AbstractCommand): + + def __init__(self, uri: str, port, dir=None): + super().__init__(uri, port) + self.dir = dir + self.filename = None + + @property + def command(self): + return "GET" + + def _get_preamble(self, retriever): + lines = retriever.retrieve() + (version, status, msg) = parser.parse_status_line(next(lines)) + headers = parser.parse_headers(lines) + + logging.debug("---response begin---\r\n%s--- response end---", "".join(retriever.buffer)) + + return Message(version, status, msg, headers) + + def _await_response(self, client, retriever): + msg = self._get_preamble(retriever) + + from client import response_handler + self.filename = response_handler.handle(client, msg, self, self.dir) + + +class PostCommand(AbstractWithBodyCommand): + @property + def command(self): + return "POST" + + +class PutCommand(AbstractWithBodyCommand): + @property + def command(self): + return "PUT"