python中从头开始的HTTP服务器:响应数据类型问题

python中从头开始的HTTP服务器:响应数据类型问题,python,python-3.x,http,python-decorators,Python,Python 3.x,Http,Python Decorators,这是到目前为止我的代码。这是一项艰苦的工作,但现在我无法独自解决这个错误。有人能理解为什么缺少“内容”参数吗? 这是我测试过的curl命令 curl-X POST 127.0.0.1:1234/sort-H“内容类型:application/json”-d@payload.json 但是它抛出了一个打字错误。我必须在dict中转换json吗?我该怎么做?提前谢谢。 它可以与http_utils-module正常工作。我还为返回电影标题的函数导入了csv模块,为列表排序导入了json模块 &quo

这是到目前为止我的代码。这是一项艰苦的工作,但现在我无法独自解决这个错误。有人能理解为什么缺少“内容”参数吗? 这是我测试过的curl命令

curl-X POST 127.0.0.1:1234/sort-H“内容类型:application/json”-d@payload.json

但是它抛出了一个打字错误。我必须在dict中转换json吗?我该怎么做?提前谢谢。 它可以与http_utils-module正常工作。我还为返回电影标题的函数导入了csv模块,为列表排序导入了json模块

"""HTTP server module."""
import csv
import json

from datetime import datetime

from http_utils import TcpSocket

CRLF = "\r\n"
FILE_PATH = "film.csv"
REQUEST_TPL = "method: {}\nresource: {}\nversion: {}\nheaders: {}\nbody: {}\n"
RESPONSE_TPL = "status code: {}\nstatus msg: {}\nheaders: {}\nbody: {}\n"
STATUS_CODES = {
    200: "OK",
    404: "Not Found",
    405: "Not Allowed"
}
HTTP_RESPONSE_TPL = "{} {} {}\r\n{}\r\n\r\n{}\r\n"


def json_content(func):
    """Converts function return value to JSON."""
    def wrapper(*args, **kwargs):
        content = func(*args, **kwargs)
        if content is None:
            return (404, STATUS_CODES[404])
        return (200, json.dumps(content))
    return wrapper


class Request:
    """An HTTP Request."""

    def __init__(self, method, resource, http_version, headers, body):
        """Initializes request."""
        self.method = method
        self.resource = resource
        self.http_version = http_version
        self.headers = headers
        self.body = body

    def __repr__(self):
        """Returns request attributes formatted as a string."""
        return REQUEST_TPL.format(
            self.method,
            self.resource,
            self.http_version,
            self.headers,
            self.body
        )


class Response:
    """An HTTP Response."""

    def __init__(self, http_version, status_code, status_message, headers, body):
        """Initializes request."""
        self.http_version = http_version
        self.status_code = status_code
        self.status_message = STATUS_CODES[status_code]
        self.headers = headers
        self.body = body

    def __repr__(self):
        """Return response attributes formatted as a string."""
        return RESPONSE_TPL.format(
            self.status_code,
            self.status_message,
            self.headers,
            self.body
        )


class HTTPServer:
    """A simple HTTP server."""


    def __init__(self, host, port):
        """Initializes server."""
        self.host = host
        self.port = port
        self.socket = None
        self.collections = {
            "headers": {
                "GET": self.get_request_headers
            },
            "movies": {
                "GET": self.search_movie_title
            },
            "sort": {
                "POST": self.sort_numbers
            }
        }

    def __call__(self):
        """Starts server and execute logic."""
        with TcpSocket(self.host, self.port) as self.socket:
            while True:
                raw_request = self.recieve_request()
                request = self.process_request(raw_request)
                response = self.handle_request(request)
                data = self.send_response(response)

    def recieve_request(self):
        """Recieves raw data by client."""
        return self.socket.recieve_data()

    def process_request(self, raw_request):
        """Processes raw request to Request object."""
        request_segments = raw_request.decode().split(CRLF)
        (method, resource, http_version) = request_segments[0].split(" ")
        headers = self._get_headers(request_segments[1:-2])
        body = self._get_body(request_segments[-1])
        return Request(method, resource, http_version, headers, body)

    def handle_request(self, request):
        """Handles request and creates response instance."""
        status_code = 200
        requested_collection = request.resource.split("/")[1]
        http_method = request.method
        try:
            collection = self.collections[requested_collection]
        except KeyError:
            status_code = 404
        else:
            try:
                method = collection[http_method]
            except KeyError:
                status_code = 405
            else:
                (status_code, content) = method(request)
        if status_code != 200:
            content = STATUS_CODES[status_code]
        status_message = STATUS_CODES[status_code]
        headers = self._generate_response_headers(content)
        http_version = request.http_version
        return Response(http_version, status_code, status_message, headers, content)

    def send_response(self, response):
        """Deserializes response object and sends HTTP response to client."""
        headers = "\r\n".join(
            f"{key}: {value}" for (key, value) in response.headers.items()
        )
        response_data = HTTP_RESPONSE_TPL.format(
            response.http_version,
            response.status_code,
            response.status_message,
            headers,
            response.body
        ).encode("utf-8")
        self.socket.send_data(response_data)
        return response_data

    @staticmethod
    def _get_headers(raw_headers):
        """Puts headers inside a dict."""
        headers = {}
        for header in raw_headers:
            (key, value) = header.split(": ")
            headers[key] = value
        return headers

    @staticmethod
    def _get_body(raw_body):
        """Put JSON body inside a dict."""
        return json.loads(raw_body) if raw_body else None

    def _generate_response_headers(self, content):
        """Generates response headers."""
        return {
            "Content-Type": "application/json",
            "Host": f"{self.host}:{self.port}",
            "Date": datetime.now().ctime(),
            "Content-Length": len(content)
        }

    @staticmethod
    @json_content
    def sort_numbers(request):
        """Sorts list of numbers."""
        if not request.body:
            return []
        numbers = request.body["input"]
        return sorted(numbers)

    @staticmethod
    @json_content
    def get_request_headers(request):
        """gets headers of request."""
        return request.headers

    @staticmethod
    @json_content
    def search_movie_title(request):
        """Searches movie title."""
        movie_title = request.resource.split("/")[-1]
        with open(FILE_PATH, encoding="latin-1", newline="") as csv_file:
            reader = csv.DictReader(csv_file, delimiter=";")
            for row in reader:
                if row["Title"] == movie_title:
                    return row
        return None


if __name__ == "__main__":
    server = HTTPServer("127.0.0.1", 7777)
    server()

它在哪里抛出类型错误?请添加回溯。另外,除非是为了练习,否则没有理由从头开始编写HTTP服务器……为了完整性,您可能还想展示一个
payload.json
的简短示例。对不起,我忘记了回溯:
Output:traceback(最近一次调用最后一次):文件“HTTP_server.py”,第213行,在服务器()文件“HTTP_server.py”的第58行,在handle\u request headers=self.\u generate\u response\u headers(content)TypeError:\u generate\u response\u headers()缺少一个必需的位置参数:'content'
payload.json'只是一个json文件,其中包含如下列表:[5、7、9、11、13]