2024-03-29 00:05:50 +08:00

86 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import socket
import urllib.parse
# 设置服务器的根目录
WEB_ROOT = os.path.abspath("../www")
def serve_file(client_socket:socket.socket, path):
# 解析请求的URL路径移除开头的/并处理URL编码
requested_path = urllib.parse.unquote(path)
if requested_path == "/":
requested_path = "/index.html" # 默认页面
# 构建文件的绝对路径
file_path = os.path.join(WEB_ROOT, requested_path.lstrip('/'))
# 获取安全的绝对路径,以确保它不会跳出根目录
safe_path = os.path.abspath(file_path)
if not safe_path.startswith(WEB_ROOT):
# 如果请求的路径不是根目录的子路径则返回403 Forbidden
response = b"HTTP/1.1 403 Forbidden\r\n"
response += b"Content-Type: text/html\r\n"
response += b"\r\n"
response += b"<html><body><h1>403 Forbidden</h1></body></html>"
else:
try:
# 尝试打开并读取文件
with open(safe_path, "rb") as file:
content = file.read()
# 根据文件类型设置Content-Type这里简化处理仅对HTML进行了处理
content_type = "text/html" if safe_path.endswith(".html") else "application/octet-stream"
response = b"HTTP/1.1 200 OK\r\n"
response += f"Content-Type: {content_type}\r\n".encode()
response += b"Content-Length: " + str(len(content)).encode() + b"\r\n"
response += b"\r\n"
response += content
except FileNotFoundError:
# 文件未找到返回404响应
response = b"HTTP/1.1 404 Not Found\r\n"
response += b"Content-Type: text/html\r\n"
response += b"\r\n"
response += b"<html><body><h1>404 Not Found</h1></body></html>"
client_socket.send(response)
def start_server(host="0.0.0.0", port=80):
socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 允许地址重用
socket_server.bind((host, port))
socket_server.listen(5)
print(f"Server listening on {host}:{port}")
while True:
client_socket = None
try:
client_socket, address = socket_server.accept()
print(f"Connection from {address}")
# 接收客户端请求
request = client_socket.recv(1024).decode("utf-8")
if not request:
print("Empty request received.")
continue
# 解析HTTP请求的第一行获取请求路径
request_lines = request.split("\r\n")
if request_lines and len(request_lines[0].split(" ")) >= 3:
method, path, _ = request_lines[0].split(" ", 2)
# 根据路径返回相应的文件
serve_file(client_socket, path)
else:
print("Invalid request line:", request_lines[0])
# 关闭客户端连接
except ConnectionResetError:
print("Connection reset by peer.")
except Exception as e:
print(f"Unexpected error: {e}")
finally:
if client_socket:
client_socket.close()
if __name__ == "__main__":
start_server()