2017-06-13 121 views
0

我试图设置一个代理服务器来发出发布请求。问题是当我提出我没有看到有效载荷的请求时。PHP卷曲发布请求 - 不发送有效负载

我注意到的一件事是,curl似乎在请求中为内容类型添加了一个额外的“边界”。

我错过了什么吗?

验证码:

$contentType = $_SERVER["HTTP_CONTENT_TYPE"]; 
$post = http_build_query($_POST); 
$ch = curl_init();  
$header = array("Content-Type:" . $contentType, 
     "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 
     "Accept-Encoding:gzip, deflate, br", 
     "Accept-Language:en-US,en;q=0.8", 
     "Connection:keep-alive", 
     "User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", 
     "Cache-Control:max-age=0", 
     "Upgrade-Insecure-Requests:1", 
     "Origin:<url here>"); 

echo "<b>POST</b><br>" . var_dump($_POST) . "<br><br>"; 

curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_POST, count($_POST)); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
curl_setopt($ch, CURLINFO_HEADER_OUT, true); 
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookiejar.txt"); 
curl_setopt($ch, CURLOPT_HTTPHEADER, $header); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
$result = curl_exec($ch); 

$headerSent = curl_getinfo($ch, CURLINFO_HEADER_OUT); 
echo "<b>Request Header</b><br>$headerSent<br><br>"; 

$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 
$header = substr($result, 0, $header_size); 
$body = substr($result, $header_size); 


echo "<b>Response Header</b><br>$header<br><br>"; 
echo "<b>Response Body</b><br>$body"; 

响应

$_POST = array(5) { ["formFields_Complaint_Type"]=> string(9) "1-GM2-226" 
["formFields_Descriptor_1"]=> string(10) "1-GM3-3085" 
["formFields_Descriptor_2"]=> string(9) "1-GM4-903" 
["formFields_Date/Time_of_Occurrence"]=> string(0) "" ["_target1"]=> string(1) " " } 

请求头:

POST <relative address> HTTP/1.1 Host: <url> 
Cookie: 
JSESSIONID=mDMJZQdLV4bhvJQ6vPyQvxqHVTynGS3byBnYsTpjDvY1xBnB93R8!-759339305!-1867032216 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 
Accept-Encoding:gzip, deflate, br 
Accept-Language:en-US,en;q=0.8 
Connection:keep-alive 
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 
Cache-Control:max-age=0 Upgrade-Insecure-Requests:1 
Origin: <url> 
Content-Length: 633 
Expect: 100-continue 
Content-Type:multipart/form-data; boundary=---- 
WebKitFormBoundarybdBepqnmjSF86t50; boundary=------------------------ 
f8e2ad22b9bb626c 
+1

调试curl时,总是启用'CURLOPT_VERBOSE' - 做到这一点,然后再试一次,并发布该输出。说,你正在做一些错误,我可能会评论当我得到时间 – hanshenrik

回答

0

最好的猜测:你的(最大,密码破译,但不是唯一)问题在于t arget服务器仅支持application/x-www-form-urlencoded编码的POST请求,但您的curl代码将application/x-www-form-urlencoded编码请求和multipart/form-data请求转换为multipart/form-data,而不管客户端使用什么。 (这是因为PHP透明转换他们两位名为$ _ POST平等的原生PHP数组)

这将使用multipart/form-data编码:

curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST); 

这将使用application/x-www-form-urlencoded编码:

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST)); 

您必须决定使用哪种编码,基于$_SERVER["HTTP_CONTENT_TYPE"];

  • 如果它们都不是这样(例如,如果它的application/json),则必须添加特殊代码来处理每个代码,并且只要$ _SERVER [“HTTP_CONTENT_TYPE”];是不是你已经做了一个特殊情况的类型(像原始$ _POST多部分和http_build_query($ _ POST)x-www-form-urlencoded)

  • 你也没有转发任意http头,你应该添加一些代码为

  • 如果你真的需要支持Upgrade-Insecure-Requests:1头,你需要实现特定的代码来处理,在代理方(去阅读关于这一主题的HTTP规范 - https://www.w3.org/TR/upgrade-insecure-requests/

  • 并且您对接受Accept-Encoding:gzip, deflate, br的目标说,但不提供任何代码来解码它们,因此它将l如果目标服务器决定使用它们中的任何一个(curl可以为你解码它们,使用CURLOPT_ENCODING,如果libcurl是使用gzip编译并且使用deflate和br支持的话,那么就像垃圾二进制数据一样。我从来没有见过与br支持的libcurl,我敢打赌你的curl没有它。可能有编译的gzip/deflate支持)