当我尝试使用python请求库将文件发布到服务器时,出现HTTP代码400(错误请求)。
相应的curl
请求成功:
curl -X POST -i https://de.api.labs.sophos.com/analysis/file/static/v1 \
-H 'Authorization: auth_string' \
-H 'Content-Type: multipart/form-data' \
-F "file=@filename"
API文档:https://api.labs.sophos.com/doc/analysis/file/static.html
有人可以帮我解决我可能做错的事情吗?
到目前为止,我的代码:
import requests
url = "https://de.api.labs.sophos.com/analysis/file/static/v1"
headers = {'content-type': 'multipart/form-data', 'Authorization': authorization}
with open(filepath, 'rb') as f:
files = {'file': f} # Even tried {'file': f.read()}
r = requests.post(url, files=files, headers=headers)
if r.status_code in [200, 202]:
return r.json()
else:
return r
答案 0 :(得分:1)
尝试通过这种方式做到这一点:
import requests
url = "https://de.api.labs.sophos.com/analysis/file/static/v1"
headers = {'Authorization': authorization} # no Content-Type here
r = requests.post(url, headers=headers, files={"file": open(filepath, "rb")})
print(r.status_code, r.text)
当posting files与Content-Type
一起使用时,您不应该手动设置requests
标头。
原因有两个:
requests
将在发出实际的HTTP请求之前隐式将Content-Type
设置为multipart/form-data
(例如,对Content-Length
而言)Content-Type: multipart/form-data
时,还应指定一个boundary。如果未设置边界,则服务器将无法正确地从请求主体读取数据。因此,如果您使用Content-Type
,则边界是multipart/form-data
标头的必需部分。在您的示例中,您没有为请求设置边界。事实是requests
不会为您设置(如果您覆盖Content-Type
标头(您这样做)。然后服务器无法在请求正文中读取您的文件。因此,它将返回您400 Bad Request
。
发出请求后,可以通过键入print(r.request.headers["Content-Type"])
进行检查。它将输出以下内容:
multipart/form-data
,但必须看起来像这样:
multipart/form-data; boundary=6387a52fb4d1465310a2b63b2d1c6e70
另一方面,curl
隐式添加边界,因此您一切都很好,您会收到200 OK
。
您也可以检查它:
curl -H 'Content-Type: multipart/form-data' -F "file=@123.txt" -v http://httpbin.org/post
哪个输出:
* Connected to httpbin.org (34.230.136.58) port 80 (#0)
> POST /post HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.47.0
> Content-Type: multipart/form-data; boundary=------------------------d257f5f4377a3997
...