iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >详解Python中httptools模块的使用
  • 622
分享到

详解Python中httptools模块的使用

Python 官方文档:入门教程 => 点击学习

摘要

如果你用过 Fastapi 的话,那么你一定知道 uvicorn,它是一个基于 uvloop 和 Httptools 实现的高性能 ASGI 服务器。 其中 uvloop 采用 Cy

如果你用过 Fastapi 的话,那么你一定知道 uvicorn,它是一个基于 uvloop 和 Httptools 实现的高性能 ASGI 服务器

其中 uvloop 采用 Cython 编写,用于替换 asyncio 中的事件循环,可以让 asyncio 速度增加 2 到 4 倍。而 httptools 是基于 C 语言实现的 HTTP 解析器,用来解析 HTTP 请求的。

本次就来聊一聊 httptools 这个模块的详细用法,至于 uvloop、uvicorn 等相关内容,后续我会一点一点补充上去,并从源码的角度全给说明白(挖了个坑)。

httptools 是一个 HTTP 解析器,它首先提供了一个 parse_url 函数,用来解析 URL。

import httptools

# 第一个参数必须是 bytes 对象
url = httptools.parse_url(
    b"http://www.baidu.com"
)
# 返回一个 URL 对象
print(url.__class__)
"""
<class 'httptools.parser.parser.URL'>
"""

那么这个 URL 对象有哪些属性呢?

通过源码可知,总共有七个属性,我们来测试一下。

import httptools

# 第一个参数是 bytes 对象
url = b"http://satori:123456@www.baidu.com:80/s?wd=koishi#flag"
url_obj = httptools.parse_url(url)

print("协议:", url_obj.schema)
print("IP:", url_obj.host)
print("端口:", url_obj.port)
print("路径:", url_obj.path)
print("查询参数:", url_obj.query)
print("锚点:", url_obj.fragment)
print("用户信息:", url_obj.userinfo)
"""
协议: b'http'
IP: b'www.baidu.com'
端口: 80
路径: b'/s'
查询参数: b'wd=koishi'
锚点: b'flag'
用户信息: b'satori:123456'
"""

比较简单,如果参数不符合 URL 的标准格式,那么会抛出 HttpParserInvalidURLError 错误。

然后是 HTTP 请求报文和响应报文的解析,因为报文只是一坨字节流,需要将它解析成某个 Request 对象或 Response 对象,而 httptools 就是干这件事情的。

首先来看一下报文格式,请求报文如下:

接下来是响应报文:

所以无论是请求报文还是响应报文,都由 起始行 + 请求头/响应头 + 请求体/响应体 组成。而我们在拿到原始的报文之后,也可以很方便地进行解析,从图中可以看出最后一个 Header 字段和响应体之间有两个换行,而换行用 \r\n 表示。因此我们只要按照 "\r\n\r\n" 进行 split 即可,会得到一个数组,数组的第二个元素就是请求体/响应体,第一个元素就是起始行 + 请求头/响应头。

然后对数组的第一个元素按照 "\r\n" 再进行 split,又可以得到一个数组,该数组的第一个元素就是起始行,剩余的元素就是请求头/响应头。

所以我们在拿到报文之后,完全可以自己手动解析,但 httptools 是用 C 实现的,所以速度会快一些,但干的事情是一样的。下面来看看 httptools 如何解析请求报文:

from pprint import pprint
import httptools

# 请求报文
request_payload = b"""POST /index?a=1 HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 26
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Accept: text/html
Accept-Encoding: gzip, deflate, sdch
Cookie: _octo=GH1.1.1989111283.1493917476; logged_in=yes

{"name":"satori","age":17}"""

class Request:
    """
    将请求报文的解析结果封装成 Request 对象
    """
    def __init__(self):
        self.headers = {}
        self.body = b""
        self.path = None

    def on_url(self, path: bytes):
        self.path = path

    def on_header(self, name: bytes, value: bytes):
        self.headers[name] = value

    def on_body(self, body: bytes):
        self.body = body

# 实例化 Request 对象
request = Request()
# 将 request 作为参数传到 HttpRequestParser 中
parser = httptools.HttpRequestParser(request)
# 传入请求报文,进行解析
parser.feed_data(request_payload)

# 获取 HTTP 版本
print(parser.get_http_version())
"""
1.1
"""
# 是否是长链接(Connection 指定为 keep-alive)
print(parser.should_keep_alive())
"""
True
"""
# 获取请求方法
print(parser.get_method())
"""
b'POST'
"""
# 以上几个都是 HttpRequestParser 对象的方法

# 获取路径
print(request.path)
"""
b'/index?a=1'
"""

# 获取请求头
pprint(request.headers)
"""
{b'Accept': b'text/html',
 b'Accept-Encoding': b'gzip, deflate, sdch',
 b'Cache-Control': b'max-age=0',
 b'Connection': b'keep-alive',
 b'Content-Length': b'26',
 b'Cookie': b'_octo=GH1.1.1989111283.1493917476; logged_in=yes',
 b'Host': b'localhost:8080',
 b'Upgrade-Insecure-Requests': b'1'}
"""
# Cookie 也是请求头的一部分,但在解析的时候会单独拿出来
# 再解析成一个字典,然后通过 request.cookies 获取

# 获取请求体
print(request.body)
"""
b'{"name":"satori","age":17}'
"""

以上就是请求报文的解析,再来看看响应报文。

from pprint import pprint
import httptools

# 响应报文
response_payload = b"""HTTP/1.1 200 OK
Server: TornadoServer/6.1
Content-Type: text/html; charset=UTF-8
Date: Sun, 22 May 2022 17:54:11 GMT
Content-Length: 21

name: satori, age: 17"""

class Response:
    """
    将响应报文的解析结果封装成 Response 对象
    """
    def __init__(self):
        self.headers = {}
        self.body = b""
        self.status = b""

    def on_header(self, name: bytes, value: bytes):
        self.headers[name] = value

    def on_body(self, body: bytes):
        self.body = body

    def on_status(self, status: bytes):
        self.status = status

# 实例化 Response 对象
response = Response()
# 将 response 作为参数传到 HttpResponseParser 中
parser = httptools.HttpResponseParser(response)
# 传入响应报文,进行解析
parser.feed_data(response_payload)

# 获取 HTTP 版本
print(parser.get_http_version())
"""
1.1
"""
# 是否是长链接(不指定 Connection,默认为长连接)
print(parser.should_keep_alive())
"""
True
"""
# 获取状态码
print(parser.get_status_code())
"""
b'OK'
"""

# 获取状态码对应的描述
print(response.status)
"""
b'OK'
"""

# 获取响应头
pprint(response.headers)
"""
{b'Content-Length': b'21',
 b'Content-Type': b'text/html; charset=UTF-8',
 b'Date': b'Sun, 22 May 2022 17:54:11 GMT',
 b'Server': b'TornadoServer/6.1'}
"""

# 获取响应体
print(response.body)
"""
b'name: satori, age: 17'
"""

以上就是请求报文和响应报文的解析,但如果你不是手动发送 tcp 请求的话,那么该模块基本用不到。因为对于任何一个成熟的模块而言,都具备了报文解析功能。像 requests, httpx, aiohttp 等等,以及一些 WEB 框架,它们在拿到报文之后会自动解析成某个对象,我们直接通过指定的属性获取即可。

而 httptools 便是 uvicorn 的报文解析器,我们在使用 uvicorn 的时候,uvicorn 内部也会自动通过 httptools 将报文解析好,而不需要我们手动解析。

因此这里介绍的 httptools 了解一下即可,我们只需要知道它是基于 C 实现的,性能非常高就行。但我们不会手动使用它,而是在使用某个框架(uvicorn)的时候,由框架自动帮我们将报文解析好。

到此这篇关于详解python中httptools模块的使用的文章就介绍到这了,更多相关Python httptools模块内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详解Python中httptools模块的使用

本文链接: https://www.lsjlt.com/news/198341.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解Python中httptools模块的使用
    如果你用过 FastAPI 的话,那么你一定知道 uvicorn,它是一个基于 uvloop 和 httptools 实现的高性能 ASGI 服务器。 其中 uvloop 采用 Cy...
    99+
    2023-03-03
    Python httptools模块使用 Python httptools模块 Python httptools
  • Python中httptools模块如何使用
    这篇文章主要介绍“Python中httptools模块如何使用”,在日常操作中,相信很多人在Python中httptools模块如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python中httpto...
    99+
    2023-07-05
  • python中os模块和sys模块的使用详解
    目录一、os模块二、os模块中的os.walk()函数三、sys模块一、os模块 os.getcwd() 获取当前的工作目录 os.chdir(‘绝对路径/相对于当前工作...
    99+
    2023-03-21
    python os模块 python sys模块
  • Python中shutil模块的使用详解
    简介:shutil 模块提供了一系列对文件和文件集合的高阶操作。特别是提供了一些支持文件拷贝和删除的函数,该模块主要强大之处在于其对文件的复制与删除操作更是比较支持好。 主要方法: ...
    99+
    2022-11-13
  • Python中Numpy模块使用详解
    目录NumPyndarray对象​ ​Numpy数据类型​​Numpy数组属性NumPy NumPy(Numerical Python) 是 Python 的一个扩展程序库...
    99+
    2022-11-11
  • python urllib.request模块的使用详解
    目录urllib子模块 request模块 function request.urlopen() class request.Request python的urllib模块提供了一系...
    99+
    2022-11-11
  • 详解python时间模块中的datetime模块
    Python提供了多个内置模块用于操作日期时间,像calendar,time,datetime。time模块我在之前的文章已经有所介绍,它提供的接口与C标准库time.h基本一致。相比于time模块,dat...
    99+
    2022-06-04
    模块 详解 时间
  • 详解Python编程中time模块的使用
    一、简介 time模块提供各种操作时间的函数 说明:一般有两种表示时间的方式: 第一种是时间戳的方式(相对于1970.1.1 00:00:00以秒计算的偏移量),时间戳是惟一的 第二种以数组的形式表示即(s...
    99+
    2022-06-04
    详解 模块 Python
  • Python中itertools模块的使用教程详解
    目录itertools模块的介绍无限迭代器(Infinite Iterators)组合迭代器(Combinatoric Iterators)有限迭代器(Iterators Termi...
    99+
    2022-11-11
  • 详解Python中Addict模块的使用方法
    目录介绍1.安装2.用法3.要牢记的事情4.属性,如键、item等5.默认值6.转化为普通字典7.计数8.更新9.Addict 是怎么来的介绍 Addit 是一个Python模块,除...
    99+
    2022-11-11
  • 详解Python中的Array模块
    Python中的array模块是一个预定义的数组,因此其在内存中占用的空间比标准列表小得多,同时也可以执行快速的元素级别操作,例如添加、删除、索引和切片等操作。此外,数组中的所有元素...
    99+
    2023-05-15
    Python Array模块 Python Array
  • 详解Python中的PyInputPlus模块
    目录安装PyInputPlus关键字参数min、max、greaterThan和lessThan关键字参数blank关键字参数limit、timeout和default关键字参数al...
    99+
    2022-11-11
  • Python之OptionParser模块使用详解
    目录介绍基本用法参数选项OptionParser()parser.add_option()生成帮助错误提示代码示例总结介绍 OptionParser是一个更方便、更灵活、更强大的用于...
    99+
    2022-11-13
  • 详解Python中heapq模块的用法
    heapq 模块提供了堆算法。heapq是一种子节点和父节点排序的树形数据结构。这个模块提供heap[k] <= heap[2*k+1] and heap[k] <= heap[2*k+2]。为...
    99+
    2022-06-04
    详解 模块 Python
  • Python中模块string.py详解
    一、用法 字符串常量: import string print(string.ascii_lowercase) print(string.ascii_uppercase) print(string....
    99+
    2022-06-04
    详解 模块 Python
  • python中os模块详解
    os模块提供了对目录或者文件的新建/删除/查看文件属性,还提供了对文件以及目录的路径操作。比如说:绝对路径,父目录…… os.sep可以取代操作系统特定的路径分隔符。windows下为 “\”,Linux下...
    99+
    2022-06-04
    详解 模块 python
  • Python中BeautifulSoup模块详解
    目录前言安装库导入库解析文档示例提取数据示例CSS选择器实例小项目总结前言     BeautifulSoup是主要以解析web网页的Python模块,...
    99+
    2022-11-13
  • python常用模块详解
    目录一、模块概述二、模块内容三、模块导入的原理四、模块导入的方法五、random模块 六、time模块(1)python表示时间的三种格式(2)常用方法:(3)时间元组、时...
    99+
    2022-11-12
  • python的logging模块详解
    日志级别>>>import logging >>>logging.NOTSET 0 >>>logging.DEBUG 10 >>>logging.INFO 20 >...
    99+
    2023-01-31
    详解 模块 python
  • Python的io模块详解
    Python的io模块提供了多个流式处理接口,具体的处理函数实现位于_pyio.py模块中。 在_io.py模块中,提供了唯一的模块方法open(name, mode=None, buffering=None),但是没有read()方法。...
    99+
    2023-01-31
    详解 模块 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作