使用python实现判断HTTP请求报文是否结束的判断。
2018-03-07 00:49
579 查看
1. 目的
使用python实现判断HTTP请求报文是否结束的判断。2. 项目意义
理解socket通信中的接收recv字节数大小掌握HTTP协议报文格式
完善web服务器的请求信息解析
实现返回页面显示请求信息
3. 项目技术要点
基于python3.6语言编写此项目通过mini_web.py来实现web服务器解析请求信息功能
request_end方法实现请求报文解析和结束判断
deal_with_request实现返回页面显示请求信息
请求信息同步打印显示在终端窗口
默认测试地址localhost:8888
4. HTTP协议
完整的HTTP请求包括:一个请求行、若干HTTP头域和可选的实体内容三部分请求行请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议版本,格式如下:
Method Request-URI HTTP-Version CRLF
其中的Method表示请求方法,Request-URI是同一资源标识符,HTTP-Version表示请求的HTTP协议版本,CRLF表示回车换行。
其中的Method表示请求方法,Request-URI是同一资源标识符,HTTP-Version表示请求的HTTP协议版本,CRLF表示回车换行。
请求方法有8种,方法名全为大写:
(1)GET 请求获取Request-URI指定的资源
(2)HEAD 请求获取Request-URI制定资源的响应消息报头
(3)POST 用于向服务器提交数据,正常情况下带有“消息体”
(4)PUT 请求服务器存储一个资源,并用Request-URI作为其标识
(5)DELETE 请求服务器删除Request-URI所标识的资源
(6)TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
(7)CONNECT 保留将来使用
(8)OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求。
HTTP头域分为四种:通用头域、请求头域、响应头域和实体头域。每个头域由一个域名、冒号和域值三部分组成,域名大小写无关,域值前可以添加任何数量的空格符。
通用头域
通用头域是指请求和响应都支持的HTTP头域,最常见的有Cache-Control、Connection和Transfer-Encoding,具体含义如下:
(1) Cache-Control:指定请求和相应遵循的缓存机制,最常见的值是no-cache,指示请求和响应消息不能缓存;
(2) Connection:用于指定处理完本次请求/响应后,客户端和服务器是否还要继续保持连接。
(3) Transfer-Encoding:用于指定实体内容的传输编码方式。
请求头域
请求头域是只有在请求头中带有的,用于向服务器传递关于请求或者关于客户端的附件信息。常见的有:Accept、Accept-Encoding、Accept-Language、Accept-Charset、Host、Referer、User-Agent和Cookie,具体含义如下:
(1) Accept: 用于指定客户端程序能够处理的MIME类型,多个时用逗号隔开;
(2) Accept-Encoding:指定客户端程序支持的压缩方式;
(3) Accept-Language: 指定客户端期望返回哪个国家语言的文档;
(4) Accept-Charset:指定客户端程序可以使用的字符集;
(5) Host:指定资源所在的主机名和端口号;
(6) Referer:指定请求uri的源资源地址,也就是用户从哪个uri过来,允许服务器生成回退链表;
(7) User-Agent:浏览器客户端信息,如使用哪种浏览器等;
(8) Cookie:服务器在浏览器端留下的信息,这是最重要的请求头字段之一。
实体头域
HTTP请求和响应中都可以包含实体头域,实体头域包含实体内容的一些信息。常见的实体头域有:Content-Encoding、Content-Length、Content-Type和Expires,具体含义如下:
(1) Content-Encoding:指明实体内容采用的压缩方式;
(2) Content-Length:指明实体内容的长度,单位为字节;
(3) Content-Type:指定实体内容的MIME类型;
(4) Expires:指明实体内容在什么时间之后过期,不再缓存。
因此,由Content-Length头域标明后续的实体内容的字节长度,浏览器或者服务器根据解析出来的Content-Length去读取后续的实体内容。以此来判断是否传输完数据
5. 技术细节
服务器类基本功能实现:初始化功能init创建服务器端套接字、绑定端口、监听设置等一系列操作socket永久启动功能run_forvever接收客户端请求后通过协程来建立调用浏览器请求处理措施
_request_end判断并解析请求数据
浏览器请求处理deal_with_request接收解析信息,并将相关内容返回给浏览器以显示
_request_end方法的处理逻辑
http请求报文接收完毕判断逻辑
完整源码链接:
https://github.com/ScrappyZhang/http_request_close_judgement def _request_end(self, client_socket):
# 判断并解析请求数据
recv_data = ''
request_header = '' # 请求头字符串
request_headers = {} # 请求头解析后的字典
content_entity = '' # 实体
content_length = 0 # 实体长度
request_line = '' # 请求行
while True:
# 完整读取请求数据
recv_data_s = client_socket.recv(256)
print('接收长度为', len(recv_data_s))
if recv_data_s == b'':
request_line = '0'
return request_line, request_headers, content_entity
try:
recv_data_s = recv_data_s.decode()
except Exception as e:
recv_data_s = recv_data_s.decode('gbk')
if "\r\n\r\n" not in recv_data:
recv_data += recv_data_s
if "\r\n\r\n" not in recv_data:
pass
else:
if request_header == '':
# 第一次接收到, 空行 说明请求头结束
space_line_index = recv_data.index("\r\n\r\n")
request_header = recv_data[0: space_line_index]
content_entity = recv_data[space_line_index + 4:]
for index, request in enumerate(request_header.split('\r\n')):
if index == 0:
request_line = request
else:
key = request.split(':')[0]
value = request.lstrip(key).lstrip(':')
key = key.strip(' ').lower()
value = value.strip(' ')
request_headers[key] = value
if "content-length" in request_headers.keys():
# 查看content_length是否在请求头,若在,需要获取其值
content_length = int(request_headers['content-length'])
if content_length == len(content_entity.encode()):
print("接收请求数据完毕")
return request_line, request_headers, content_entity
else:
# 不存在则说明只有请求头,没有实体
return request_line, request_headers, content_entity
else:
# 实体数据
content_entity += recv_data_s
if content_length == len(content_entity.encode()):
print("接收请求数据完毕")
return request_line, request_headers, content_entity
相关文章推荐
- 判断Keep-Alive模式的HTTP请求的结束的实现代码
- 判断Keep-Alive模式的HTTP请求的结束的实现代码
- 使用Python实现一个栈判断括号是否平衡
- 【Android】使用ConnectivityManager与NetworkInfo实现判断当前网络环境是否可用
- python+httplib实现HTTP POST提交数据,使用Basic Authentication(基本验证)做登陆验证
- Android 下使用 JSON 实现 HTTP 请求
- Android判断网络状态是否断开+Android完全关闭应用程序+ 本文讲述了Android中不同Activity之间的数据传递 — Bundle对象的实现(-)+Android中Bundle的使用示例
- Android 下使用 JSON 实现 HTTP 请求,外加几个示例!
- HTTP代理实现请求报文的拦截与篡改--目录
- Python 判断日期大小( 判断开始时间是否早于结束时间)
- HTTP代理实现请求报文的拦截与篡改
- 使用(Filter)过虑器实现对Session是否过时的判断
- java使用socket实现http简单get请求
- Android 下使用 JSON 实现 HTTP 请求
- SOA服务的基本实现方法—使用HTTP协议传输XML请求(POX-over-HTTP)
- 负载均衡之---应用请求路由模块的使用(ARR)(四)[使用ARR实现HTTP负载均衡]
- 用Python实现求最大公约数和判断是否是素数
- Android 下使用 JSON 实现 HTTP 请求,外加几个示例!
- python判断端口是否打开的实现代码