简体   繁体   English

模拟HTTP POST请求会产生意外结果

[英]Simulating HTTP POST request produces unexpected result

--- SOLVED --- - 解决了 -

It turned out the request body had literal r"\\n" (repr: "\\\\n" ) characters in it, and since I simply copy pasted the body as a Python string, Python thought I was giving it newline characters rather than escaped newline characters. 事实证明,请求正文中包含文字r"\\n" (repr: "\\\\n" )字符,由于我只是将正文复制为Python字符串,因此Python认为我是给它换行符而不是转义换行符。

The reason this causes a Bad Request is as follows: So the body was JSON, and in JSON you have to escape all your newline characters by definition. 导致Bad Request的原因如下:所以主体是JSON,在JSON中,您必须按定义转义所有换行符。 So when the server loads the JSON object from the raw text, an error is thrown causing Bad Request 因此,当服务器从原始文本加载JSON对象时,会引发错误,导致Bad Request

I realised this because the Content-Length header was different in both cases ( \\n is one char while \\\\\\n is two chars, although perhaps the Content-Length doesn't actually matter. 我意识到这是因为在两种情况下,Content-Length标头都不同( \\n是一个字符,而\\\\\\n是两个字符,尽管Content-Length实际上并不重要。

Also it is noteworthy that when a lower Content-Length is sent, Bad Request is also returned. 同样值得注意的是,当发送较低的Content-Length时,也会返回Bad Request I believe this is because the JSON body gets truncated, and the server doesn't accept the important char (eg closing brace or something) 我相信这是因为JSON正文被截断了,并且服务器不接受重要的字符(例如,大括号或其他东西)


--- Problem:--- ---问题:---

Summary: 摘要:

I am trying to use Python to simulate a POST request to bitbucket.org performed within my Firefox web browser. 我正在尝试使用Python模拟在Firefox Web浏览器中执行的对bitbucket.org的POST请求。 Here is what I did: 这是我所做的:

  1. Tracked the POST request using Firebug 使用Firebug跟踪了POST请求
  2. Copied the POST request headers 复制了POST请求标头
  3. Copied the POST request body (in application/json format) 复制了POST请求正文(应用程序/ json格式)


Code: 码:

Here is the code I use to POST my request, but it's a bit long and not very relevant. 这是我用来发布请求的代码,但是它有点长,而且不太相关。 My Content-Type is application/json, and my POST body is a JSON-encoded string. 我的Content-Type是application / json,我的POST正文是JSON编码的字符串。

    dataString = '{"branch":"master","files":[{"path":"readme.txt","content":"ntestxx\n \n"}],"message":"readme.txt edited online with Bitbucket","parents":["465305dc4da32f91da057b65297cda9b72c"],"repository":{"full_name":"minesite/ica-i18n"},"timestamp":"2014-03-20T23:49:29.759Z","transient":false}'
    headers = {'X-CSRFToken': '6TqWjCl698U99Iu6ZYGBAloCxZ', 'Content-Length': '2190', 'Accept-Language': 'en,en-us;q=0.7,zh;q=0.3', 'X-NewRelic-ID': 'VwMGVVZSGwIIUFBQDwU=, VwMGVVZSGwIIUFBQDwU=', 'Cookie': 'csrftoken=6TqWjCl698U99Iu6ZYGBAloCxZ; __utma=254090395.1171276563.1394767875.1394776803.1395358874.3; __utmc=254090395; __utmz=254090395.1394776803.2.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); bb_session=gpqergylgoa7icpwosqsbpxig0; __utmv=254090395.|1=isBBUser=true=1; recently-viewed-repos_1701252=3802872%2C108928; __utmb=254090395.21.9.1395359363952', 'Connection': 'keep-alive', 'Accept': 'application/json, text/javascript, */*; q=0.01', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0', 'Host': 'bitbucket.org', 'X-Requested-With': 'XMLHttpRequest', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'Referer': 'https://bitbucket.org/xxxxxx/xxxxxxx/src/465305dc4da32f91da057b6529a8e4/readme.txt?at=master', 'Content-Type': 'application/json; charset=UTF-8', 'Accept-Encoding': 'gzip, deflate'}
    edit = requests.post("https://bitbucket.org/!api/internal/repositories/xxxxxxx/xxxxxxxx/oecommits/", data=dataString, headers=headers)


Results vs. expected results: 结果与预期结果:

When I perform the POST request using my Firefox web browser (using Firebug's "resend request" function), I get a 409 CONFLICT response (Which is the desired response! I am simulating a request to an online editor, so that should be the correct response to a re-sent edit). 当我使用Firefox Web浏览器执行POST请求时(使用Firebug的“重新发送请求”功能),我收到409 CONFLICT响应(这是所需的响应!我正在模拟对在线编辑器的请求,因此应该正确回复重新发送的修改)。

However, when I try to simulate the request by copying the request header and the request body, I get a 400 BAD REQUEST response, and the response contains no other information, so I don't even know what my problem is. 但是,当我尝试通过复制请求标头和请求正文来模拟请求时,得到了400 BAD REQUEST响应,并且该响应不包含其他信息,因此我什至不知道我的问题是什么。

Regardless of how many times I send the POST in the web-browser (despite an incorrect timestamp), it achieves the intended outcome, but the server refuses to accept any requests I make using the python requests library. 无论我在网络浏览器中发送POST多少次(尽管时间戳不正确),都能达到预期的结果,但是服务器拒绝接受我使用python请求库发出的任何请求。


Response using browser request: 使用浏览器请求的响应:

Headers

HTTP/1.1 409 CONFLICT
Server: nginx/1.5.10
Date: Fri, 21 Mar 2014 00:20:55 GMT
Content-Type: text/plain
Content-Length: 45
Connection: keep-alive
x-served-by: app16
X-Render-Time: 0.558492183685
Content-Language: en
X-Static-Version: 48695e7c3140
Vary: Authorization, Accept-Language, Cookie
X-Version: e6778a5040f7
Etag: "92f0b780984e984140de0f8ed0a3992c"
X-Frame-Options: SAMEORIGIN
X-Request-Count: 483
X-NewRelic-App-Data: PxQEVFdXCAITVVlWBgMPUkYdFGQHBDcQUQxLA1tMXV1dSn8UXwJHCwtYGAMPF1pGUw8EFhlQRxYXH1dDC0gKDEQHSgxZVBpaUgtdDVQTQFgrWFsICAZ9V1kQIg1aXF4SLFBYVw4DEUxTEF0DTF0WHgNJCU8EVApUUgUHVFFQCgQCU1FXGwMGX1QdFAEBUVVbA1AJVQEBB1FSA11DHQdSDhdTag==

Body 身体

Specified change not on head of branch master


Response using python request: 使用python请求的响应:

Headers

content-length: 11
x-served-by: app10
x-render-time: 0.012787103653
content-language: en
content-type: text/plain
vary: Authorization, Accept-Language, Cookie
connection: keep-alive
server: nginx/1.5.10
x-version: e6778a5040f7
etag: "825644f747baab2c00e420dbbc39e4b3"
x-request-count: 321
x-newrelic-app-data: PxQEVFdXCAITVVlWBgMPUkYdFGQHBDcQUQxLA1tMXV1dSn8UXwJHCwtYGAMPF1pGUw8EFhlQRxYXH1dDC0gRB0MNTRBbXQ5gVhZWFEMCVkBIBhtRSFMJAARQUlsDBw9VXAIBC1tWVU4CUwtUFBpVAwFcWgdTVQIAXQBRWQQAGh9WBQ0RUmw=
date: Fri, 21 Mar 2014 00:51:01 GMT
x-frame-options: SAMEORIGIN
x-static-version: 48695e7c3140

Body 身体

Bad Request


Some of my ideas: 我的一些想法:

I am thinking that perhaps there is another component to a HTTP POST request that I need to simulate? 我在想,也许我需要模拟HTTP POST请求的另一个组件? Perhaps when Firefox sends a POST request, there is some header or wrapper added that makes the request valid? 也许当Firefox发送POST请求时,添加了一些使请求有效的标头或包装器?

Or is there something more to a POST request than just a method, headers, and body? 还是POST请求需要的不仅仅是方法,标头和正文?

Maybe it's something to do with the fact that it's HTTPS instead of HTTP? 也许是因为它是HTTPS而不是HTTP?


Update: 更新:

I have tried sending the "sent cookies" in with the request, to little success. 我尝试发送带有请求的“已发送的cookie”,但收效甚微。

Or is there something more to a POST request than just a method, headers, and body? 还是POST请求需要的不仅仅是方法,标头和正文?

No. The important part are the request headers. 否。重要的部分是请求标头。 They should be exactly the same in both cases. 在两种情况下,它们应该完全相同。

Because Firebug can just track the network requests inside Firefox, you'll need an external network analyzer like Wireshark to track the requests coming from your Python script. 由于Firebug只能跟踪Firefox内部的网络请求,因此您需要一个外部网络分析器(如Wireshark)来跟踪来自Python脚本的请求。 Of course you need to run it on the server where the script lies. 当然,您需要在脚本所在的服务器上运行它。

Another solution would be to run your request against a local web server and log the request information there. 另一种解决方案是对本地Web服务器运行您的请求,并将请求信息记录在该服务器上。

Then you'll be able to compare the request made in the browser with the one from your script. 然后,您可以将浏览器中的请求与脚本中的请求进行比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM