Skip to content

Instantly share code, notes, and snippets.

@hanayashiki
Created July 19, 2019 03:55
Show Gist options
  • Save hanayashiki/9d1f8a3f65025c15107d87f471d09631 to your computer and use it in GitHub Desktop.
Save hanayashiki/9d1f8a3f65025c15107d87f471d09631 to your computer and use it in GitHub Desktop.
import socket
def extract_request_line(request):
first_line = request.split("\r\n")[0]
method, resource, ver = first_line.split(" ")
return method, resource, ver
def respond(method, resource):
if method == "GET" and resource == "/A":
return b"<h1>Resource A from my server!</h1>", 200
elif method == "GET" and resource == "/B":
return b"<h2>Resource B from my server!</h2>", 200
else:
return b"<h2>You asked for unknown resource, try A or B!</h2>", 404
response_template =\
b"HTTP/1.1 %d OK\r\n" +\
b"Date: Mon, 23 May 2005 22:38:34 GMT\r\n" +\
b"Content-Type: text/html; charset=UTF-8\r\n" +\
b"Content-Length: %d\r\n" +\
b"Accept-Ranges: bytes\r\n" +\
b"Connection: close\r\n" +\
b"\r\n" +\
b"%s"
def main():
sock = socket.socket() # socket.socket() 生成一个 socket 对象,它的方法是我们和传输层交互的接口。
sock.bind(("localhost", 80)) # 将 socket 对象和地址绑定,从而我们可以从 sock 接受向本地主机 80 端口发送的数据
sock.listen(5) # 建立等待 TCP 连接的队列
while True:
client, addr = sock.accept() # 调用 accept 方法,等待向本地主机 80 端口发送的数据。
# client 是另一个 socket 对象,它是用来完成服务器和该请求者通信的。
request = client.recv(4096) # 我们接收 client 发来的请求,4096 是一次接受的最大报文长度。
request = request.decode("utf-8") # 将二进制的报文解码为文本,由于 HTTP 报文必然是文本的,所以解码会成功
print("Got request from %r: " % (addr,))
print(request)
method, resource, ver = extract_request_line(request) # 解析请求的第一行,得到方法,资源名和版本
response_body, status_code = respond(method, resource) # 调用我们的反馈函数进行 body 和 status code 的生成
response = response_template % (status_code, len(response_body), response_body)
client.sendall(response) # 将回复发送给客户端,我们可以在浏览器上看到 Response 的效果
client.close()
sock.close()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment