2017-06-13 115 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支持)