静态服务器显示固定页面,02-静态web服务器搭建之显示固定的内容

1 statichttpserver.py

采用[Python网络编程之TCP]章节中多路复用selector的做法,创建TcpServer。 这里需要注意的是每个请求发送给服务器都建立一条tcp连接,服务器处理完成该请求之后,即断开连接。

# -*- coding: utf-8 -*-

# @Author : 江河

# @Email : 2516638426@qq.com

# @Time : 2020/4/22 7:29

# @File : statichttpserver

# @Project: python高级项目

import selectors

import socket

from http_parsed import BaseRequest

class StaticHttpServer(object):

def __init__(self,host,port):

self.selector = selectors.DefaultSelector()

self.sock = socket.socket()

self.address = (host,port)

self.request_queue_size = 5

self.open_socket()

def accept(self,sock,mask):

sel = self.selector

conn,addr = sock.accept() # Should be ready

conn.setblocking(False)

sel.register(conn,selectors.EVENT_READ,self.read)

def write(self,sock,mask):

print('write')

sel = self.selector

# 组织相应的头信息(header)

response_headers = "HTTP/1.1 200 OK\r\n" # 200表示找到这个资源

response_headers += "\r\n" # 用一个空的行与body进行隔开

# 组织 内容(body)

response_body = "Hello World"

response = response = response_headers + response_body

sock.send(response.encode("utf-8"))

self.unregister(sock)

sock.close()

def read(self,conn,mask):

sel = self.selector

data = conn.recv(1000) # should be ready

if data:

conn.setblocking(False)

sel.unregister(conn)

# print('echoing',repr(data))

s = data.decode('utf-8')

self.req = BaseRequest(s)

# print(self.req.headers)

print(self.req.url)

print(self.req.method)

sel.register(conn,selectors.EVENT_WRITE,self.write)

else:

print('closing',conn)

sel.unregister(conn)

conn.close()

def server_close(self):

self.sock.close()

self.selector.close()

def server_bind(self):

"""

绑定

:return:

"""

sock = self.sock

sock.bind(self.address)

self.server_address = sock.getsockname()

def server_listen(self):

"""

监听

:return:

"""

self.sock.listen(self.request_queue_size)

def open_socket(self):

sock = self.sock

self.server_bind()

self.server_listen()

sock.setblocking(False)

def server_forever(self):

sock = self.sock

sel = self.selector

sel.register(sock,selectors.EVENT_READ,self.accept)

try:

while True:

events = sel.select()

for key,mask in events:

callback = key.data

callback(key.fileobj,mask)

finally:

print('close')

self.server_close()

if __name__ == '__main__':

host = '127.0.0.1'

port = 5001

print('running http://{}:{}'.format(host.port))

httpd = StaticHttpServer(host,port)

httpd.server_forever()

2 http_parsed.py

BaseRequest类主要用来对客户端发过来的http请求进行封装与解析。

# -*- coding: utf-8 -*-

# @Author : 江河

# @Email : 2516638426@qq.com

# @Time : 2020/4/22 7:42

# @File : http_parsed

# @Project: python高级项目

class BaseRequest(object):

"""

base request class

"""

def __init__(self,request):

self.request = request

# print(request)

self._parsed_request()

def _parsed_request(self):

"""

解析 request

:param request()

:return:

"""

self._parsed_header()

self._parsed_body()

def _parsed_header(self):

"""

GET /favicon.ico HTTP/1.1

Host: 127.0.0.1:5001

Connection: keep-alive

User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36

Accept: image/webp,image/apng,image/*,*/*;q=0.8

Referer: http://127.0.0.1:5001/

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9

"""

headers = self.request.split('\r\n\r\n',1)[0].split('\r\n')[1:]

query = {}

for h in headers:

k,v = h.split(':',1)

query[k] = v

self.headers = query

def _parsed_body(self):

"""

解析body

:param request:

:return:

"""

self.body = self.request.split('\r\n\r\n',1)[1]

@property

def method(self):

self._method = self.request.split()[0]

return self._method

@property

def url(self):

self._url = self.request.split()[1]

return self._url

@property

def protocol(self):

self._protocol = self.request.split()[2]

return self._protocol

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值