壳把请求翻译成什么

👁️ 2 人浏览 💬 0 人评论 ❤️ 添加收藏

(每道题开头都有同一段:上面那个应用的全部源码——render 把标题和正文塞进页面骨架 PAGElist_html / form_html 生成列表和表单,STATIC 是静态文件表,handle 是入口。判题机不联网,题里直接调 handle。)

真机上的壳(标准库 http.server):

from http.server import BaseHTTPRequestHandler, HTTPServer


class H(BaseHTTPRequestHandler):
    def _serve(self, method):
        n = int(self.headers.get("Content-Length") or 0)
        body = self.rfile.read(n).decode("utf-8") if n else ""
        status, headers, text = handle(method, self.path, body, NOTES)
        data = text.encode("utf-8")
        self.send_response(status)
        for k, v in headers.items():
            self.send_header(k, v + ("; charset=utf-8" if k == "Content-Type" and v.startswith("text/") else ""))
        self.send_header("Content-Length", str(len(data)))
        self.end_headers()
        if method != "HEAD":
            self.wfile.write(data)

    def do_GET(self):
        self._serve("GET")

    def do_POST(self):
        self._serve("POST")

    def do_HEAD(self):
        self._serve("HEAD")

NOTES = []
HTTPServer(("127.0.0.1", 8000), H).serve_forever()

没有网络也能看壳的逻辑:模拟一次「读请求 → 调 handle → 拼响应」,看拼出来的头:

import html
import json
from urllib.parse import urlparse, parse_qs

PAGE = "<!doctype html><html><head><meta charset=\"utf-8\"><title>{title}</title><link rel=\"stylesheet\" href=\"/static/style.css\"></head><body><h1>{title}</h1>{body}</body></html>"


def render(title, body):
    return PAGE.replace("{title}", html.escape(title)).replace("{body}", body)


def list_html(notes):
    if not notes:
        return "<p>还没有留言</p>"
    return "<ul>" + "".join("<li>" + html.escape(n) + "</li>" for n in notes) + "</ul>"


def form_html():
    return "<form method=\"post\" action=\"/add\"><input name=\"text\"><button>发表</button></form>"


STATIC = {"/static/style.css": ("text/css", "h1 { color: #2563eb; }\n")}


def handle(method, url, body="", notes=None):
    notes = [] if notes is None else notes
    u = urlparse(url)
    path = u.path
    if path in STATIC:
        if method != "GET":
            return 405, {"Content-Type": "text/html"}, "<p>只能 GET</p>"
        ctype, content = STATIC[path]
        return 200, {"Content-Type": ctype}, content
    if path.startswith("/static/"):
        return 404, {"Content-Type": "text/html"}, "<p>没有这个文件</p>"
    if path == "/":
        return 200, {"Content-Type": "text/html"}, render("留言板", list_html(notes) + form_html())
    if path == "/about":
        return 200, {"Content-Type": "text/html"}, render("关于", "<p>一个用标准库写的留言板。</p>")
    if path.startswith("/notes/"):
        tail = path[len("/notes/"):]
        if not tail.isdigit() or not 1 <= int(tail) <= len(notes):
            return 404, {"Content-Type": "text/html"}, render("没有这条", "<p>没有这条留言</p>")
        return 200, {"Content-Type": "text/html"}, render("第 " + tail + " 条", "<p>" + html.escape(notes[int(tail) - 1]) + "</p>")
    if path == "/api/notes":
        return 200, {"Content-Type": "application/json"}, json.dumps({"count": len(notes), "notes": notes}, ensure_ascii=False)
    if path == "/add":
        if method != "POST":
            return 405, {"Content-Type": "text/html"}, "<p>请用表单提交</p>"
        text = parse_qs(body).get("text", [""])[0].strip()
        if not text:
            return 400, {"Content-Type": "text/html"}, "<p>留言不能为空</p>"
        notes.append(text)
        return 303, {"Content-Type": "text/html", "Location": "/"}, ""
    return 404, {"Content-Type": "text/html"}, render("找不到", "<p>没有这个页面</p>")

SAMPLE = ["第一条留言", "今天天气不错", "<b>不许</b>"]

def build_response(method, path, body, notes):
    status, headers, text = handle(method, path, body, notes)
    data = text.encode("utf-8")
    lines = ["HTTP/1.0 " + str(status)]
    for k, v in headers.items():
        lines.append(k + ": " + v + ("; charset=utf-8" if k == "Content-Type" and v.startswith("text/") else ""))
    lines.append("Content-Length: " + str(len(data)))
    return lines

print(("|".join(build_response("GET", "/api/notes", "", list(SAMPLE))) + "//" + build_response("GET", "/", "", list(SAMPLE))[1]).replace(" ", "_"))
提交你的答案
请登录后提交答案。
去登录
代码编辑器
Ctrl + Enter 运行
本次输入:
输出:

                        
👩‍🏫
AI
💬 题目评论

全部评论