requests.get 函数将哪些数据发送到 API?

Posted

技术标签:

【中文标题】requests.get 函数将哪些数据发送到 API?【英文标题】:Which data does the requests.get function send to an API? 【发布时间】:2019-06-11 10:05:52 【问题描述】:

我对 Python 中的请求函数有一个非常基本的问题。 我正在从公司网络向外部 API 发出请求。 我已经指定了代理(用户:pw@address:port)和验证(证书路径)。不幸的是,这会导致由防火墙引起的 SSL 错误。 现在我已向 IT 部门的同事询问设置 verify = False。在这种情况下,请求有效,我得到了我的结果。由于我不发送/接收敏感数据,因此我并不介意安全漏洞。 (纯理论) 我的担忧更多与我提供的代理数据有关。由于他们有我的个人 ID 和 PW,我想确保这些数据不会离开公司网络,而仅用于代理身份验证。

requests.get 函数是如何工作的,它向最终 API 发送什么信息?代理身份验证是否也发送到最终 API 还是仅用于公司网络代理?

【问题讨论】:

【参考方案1】:

tl;drproxies 数据不是发送到远程服务器的请求的一部分。


requests.get 函数是如何工作的...

requests 方便地包装较低级别的库。在内部,它使用urllib3,它使用http.client,它使用socket。这完全是关于通过网络套接字发送和接收字节。

最终,requests 创建了一个 PreparedRequest 对象。这个请求对象,resp。其属性中的数据通过 INET 套接字发送,该套接字由 urllib3.connection.HTTPConnection(派生自 http.client.HTTPConnection 的类)管理。此连接由urllib3.connectionpool.ConnectionPool 管理,由urllib3.poolmanager.Poolmanager 控制,urllib3.poolmanager.Poolmanagerrequests.adapters.HTTPAdapter 的一部分。这个HTTPAdapterrequests.sessions.Session 中被引用,由requests.api.get()requests.api.request() 创建和使用。

...它向最终 API 发送什么信息?

requests.get 调用中提供的参数用于创建您要发送的请求和/或用于发送此请求的连接。

最终在请求中的参数是:methodurlheadersfilesdatajsonparamsauthcookiesverifytimeoutproxies 等参数仅用于建立和管理连接,不会出现在请求中。

为了显示发送的内容,这里有一个小而愚蠢且完全不适合任何远程套接字端点的东西:

import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(('', 42424))
    s.listen(1)
    while True:
        conn, addr = s.accept()
        with conn:
            data = conn.recv(1024)
            print(data.decode())

还有我们的客户:

import requests

params = 'foo': 'bar'
requests.get("http://127.0.0.1:42424", params=params)

“服务器”打印:

GET /?foo=bar HTTP/1.1
Host: 127.0.0.1:42424
User-Agent: python-requests/2.18.4
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

在这两者之间放置一个非常简单的代理...

from socketserver import ThreadingTCPServer
import urllib.request
from http.server import SimpleHTTPRequestHandler

class Proxy(SimpleHTTPRequestHandler):
    def do_GET(self):
        self.copyfile(urllib.request.urlopen(self.path), self.wfile)

httpd = ThreadingTCPServer(('', 42425), Proxy)
httpd.serve_forever()

(这个配方被 effbot.org 的 Fredrik Lundh 公然窃取(并针对 Python 3 进行了调整))

...并在requests.get 调用中使用proxies ...

params = 'foo': 'bar'
proxies = 'http': '127.0.0.1:42425'
requests.get("http://127.0.0.1:42424", params=params, proxies=proxies)

...导致“服务器”收到以下内容:

GET /?foo=bar HTTP/1.1
Accept-Encoding: identity
Host: 127.0.0.1:42424
User-Agent: Python-urllib/3.6
Connection: close

因此,proxies 中提供的凭据保存在代理和您的客户端之间。

【讨论】:

非常感谢您的详细回答。这正是我想要的。对我来说最重要的是参数用于建立连接,不应通过 API 发送。

以上是关于requests.get 函数将哪些数据发送到 API?的主要内容,如果未能解决你的问题,请参考以下文章

python+requests——发送带参数的get请求

Python使用requests发送请求

大概看了一天python request源码。写下python requests库发送 get,post请求大概过程。

Python接口测试-使用requests模块发送GET请求

python3的requests.get有哪些请求参数

Python模块-requests