2011-09-27 14 views
13

मेरे कोड इस तरह दिखता है के साथ PUT अनुरोध में स्ट्रिंग भेजें:libcurl

curl = curl_easy_init(); 

if (curl) { 
    headers = curl_slist_append(headers, client_id_header); 
    headers = curl_slist_append(headers, "Content-Type: application/json"); 

    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 
    curl_easy_setopt(curl, CURLOPT_URL, "127.0.0.1/test.php"); 
    curl_easy_setopt(curl, CURLOPT_PUT, 1L); 

    res = curl_easy_perform(curl); 
    res = curl_easy_send(curl, json_struct, strlen(json_struct), &io_len); 

    curl_slist_free_all(headers); 
    curl_easy_cleanup(curl); 
} 

कौन सा काम नहीं करता है, इस कार्यक्रम बस हमेशा के लिए लटका हुआ है।

इन test.php में अनुरोध हेडर मैं कर रहे हैं:

array(6) { 
    ["Host"]=> 
    string(9) "127.0.0.1" 
    ["Accept"]=> 
    string(3) "*/*" 
    ["Transfer-Encoding"]=> 
    string(7) "chunked" 
    ["X-ClientId"]=> 
    string(36) "php_..." 
    ["Content-Type"]=> 
    string(16) "application/json" 
    ["Expect"]=> 
    string(12) "100-continue" 
} 

लेकिन शरीर खाली है, इसका मतलब है, कोई json डेटा अनुरोध के साथ भेजा जाता है।

क्या मैं libcurl साथ क्या करना चाहते वास्तव में तो और कुछ नहीं इन कमांड लाइन स्क्रिप्ट है:

curl -X PUT -H "Content-Type: application/json" -d '... some json ...' 127.0.0.1/test.php 

उत्तर

30

समझे यह :)

न का उपयोग

curl_easy_setopt(curl, CURLOPT_PUT, 1L); 

एक कस्टम अनुरोध करें और डेटा को POSTFIELDS के रूप में भेजें:

curl = curl_easy_init(); 

if (curl) { 
    headers = curl_slist_append(headers, client_id_header); 
    headers = curl_slist_append(headers, "Content-Type: application/json"); 

    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 
    curl_easy_setopt(curl, CURLOPT_URL, request_url); 
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); /* !!! */ 

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_struct); /* data goes here */ 

    res = curl_easy_perform(curl); 

    curl_slist_free_all(headers); 
    curl_easy_cleanup(curl); 
} 
+0

बिल्कुल सही! और यदि आप सर्वर से उत्तर को रोकना/दबाना चाहते हैं तो आपको डेटा प्राप्त करने के लिए 'CURLOPT_WRITEFUNCTION' सेट करना होगा या' CURLOPT_WRITEDATA' को एक अलग 'FILE * 'हैंडल पर सेट करना होगा। – karlphillip

+1

क्यों नहीं [CURLOPT_CUSTOMREQUEST' के बजाय 'CURLOPT_UPLOAD' का उपयोग करें, जैसे कि [प्रलेखन] (http://curl.haxx.se/libcurl/c/CURLOPT_PUT.html) कहता है? –

+0

मुझे 'curl_easy_setopt (curl, CURLOPT_CUSTOMREQUEST, NULL) करना था;' 'curl_easy_perform (कर्ल) के बाद;' अगले अनुरोधों को भी पुट अनुरोधों को रोकने के लिए। –

0

यह मेरे लिए काम नहीं करता है। मुझे इसे सही तरीके से करने के लिए अपलोड और PUT का उपयोग करना था। जवाब यह है कि मेरे लिए काम किया यहाँ है:

How do I send long PUT data in libcurl without using file pointers?

आप readfile के लिए कॉलबैक फ़ंक्शन की जरूरत है और उसके बाद का उपयोग करें कि सूचक कर्ल करने के लिए अपने डेटा की प्रतिलिपि कि कॉलबैक में प्रदान करता है।

अंततः मेरे लिए क्या काम किया गया यह सुनिश्चित करना था कि मैंने आपके पेलोड के आधार पर CURLOPT_INFILESIZE या CURLOPT_INFILESIZE_LARGE का उपयोग करके फ़ाइल आकार सेट किया है। अन्यथा आपको बैकस्ट्रीरी में पोस्ट की गई समस्या मिलती है।

Backstory: मैं एक JSON अनुरोध उम्मीद कर रहा था लेकिन या तो PUT कर्ल विकल्प या इस कस्टम अनुरोध दृष्टिकोण का उपयोग कर मैं एक ही अनुरोध कर दूसरी ओर सांत्वना

curl -H "Accept:application/json" -H "Authorization:authxxxx" -v -X PUT "http://server.xxxdomain.com/path0/path1/path2/state?data1=1&data2=1421468910543&data3=-3" 


* Adding handle: conn: 0x7fd752003a00 
* Adding handle: send: 0 
* Adding handle: recv: 0 
* Curl_addHandleToPipeline: length: 1 
* - Conn 0 (0x7fd752003a00) send_pipe: 1, recv_pipe: 0 
* About to connect() to server.xxxdomain.com port 80 (#0) 
* Trying ipaddress... 
* Connected to api-qos.boingodev.com (ipaddress) port 80 (#0) 
> PUT /path0/path1/path2/done?data1=1&data2=1421468910543&data3=-3 HTTP/1.1 
> User-Agent: curl/7.30.0 
> Host: server.xxxdomain.com 
> Accept:application/json 
> Authorization:authxxxx 
> 
< HTTP/1.1 411 Length Required 
* Server nginx/1.1.19 is not blacklisted 
< Server: nginx/1.1.19 
< Date: Sat, 17 Jan 2015 04:32:18 GMT 
< Content-Type: text/html 
< Content-Length: 181 
< Connection: close 
< 
<html> 
<head><title>411 Length Required</title></head> 
<body bgcolor="white"> 
<center><h1>411 Length Required</h1></center> 
<hr><center>nginx/1.1.19</center> 
</body> 
</html> 
* Closing connection 0 

के माध्यम से यह कर के रूप में एक ही परिणाम प्राप्त सांत्वना और एक डेटा क्षेत्र (-d डाल "" यूआरएल) जोड़ने पर मुझे हो जाता है जो मैं चाहता:

curl -H "Accept:application/json" -H "authxxxx" -v -X PUT -d "" "http://server.xxxdomain.com/path0/path1/path2/state?data1=1&data2=1421468910543&data3=-3" 
* Adding handle: conn: 0x7fe8aa803a00 
* Adding handle: send: 0 
* Adding handle: recv: 0 
* Curl_addHandleToPipeline: length: 1 
* - Conn 0 (0x7fe8aa803a00) send_pipe: 1, recv_pipe: 0 
* About to connect() to server.xxxdomain.com port 80 (#0) 
* Trying ipaddress... 
* Connected to server.xxxdomain.com (ipaddress) port 80 (#0) 
> PUT /path0/path1/path2/state?data1=1&data2=1421468910543&data3=-3" HTTP/1.1 
> User-Agent: curl/7.30.0 
> Host: server.xxxdomain.com 
> Accept:application/json 
> Authorization:authxxxx 
> Content-Length: 0 
> Content-Type: application/x-www-form-urlencoded 
> 
< HTTP/1.1 200 OK 
* Server nginx/1.1.19 is not blacklisted 
< Server: nginx/1.1.19 
< Date: Sat, 17 Jan 2015 17:16:59 GMT 
< Content-Type: application/json 
< Content-Length: 32 
< Connection: keep-alive 
< 
* Connection #0 to host server.xxxdomain.com left intact 
{"code":"0","message":"Success"} 

सारांश में जैसे मैं कर्ल विकल्पों PUT के बराबर कर देंगे यह पता लगाने की जरूरत है यह लग रहा है -डी ""। इसके अलावा आप दोनों प्रतिक्रियाओं के बीच अंतर देख सकते हैं, एक मामले में वापसी एचटीएमएल है और कनेक्शन बंद है। दूसरे मामले में सामग्री जेएसओएन है और कनेक्शन जिंदा रखा गया है।

मैं त्रुटि 411 पर क्या मिल गया है के आधार पर:

http://www.checkupdown.com/status/E411.html

समस्या यह है कि सामग्री की लंबाई है कि क्या आप CURLOPT_PUT या कस्टम विकल्प के साथ CURLOPT_UPLOAD का उपयोग की परवाह किए बिना निर्धारित करने की आवश्यकता है।

इसलिए, यदि आपके पास डेटा की एक धारा है तो आपको लगता है कि आपको अपने डेटा की लंबाई निर्धारित करने के लिए रीडाडाटा और रीडफ़ंक्शन विकल्प का उपयोग करना है।व्यवस्थापक को

नोट:

मन प्रतिनिधि 50 में रखें तो मैं कोई चारा नहीं क्रम में संवाद करने के लिए अलग पदों करना है टिप्पणियाँ पोस्ट करने के लिए आवश्यक है। तो इस पर विचार करें जब आप इन पदों को हटाने के बारे में सोच रहे हैं क्योंकि यह अतीत में किया गया है।

1

CURLOPT_PUT बहिष्कृत है, और थोड़ी देर के लिए किया गया है। आपको CURLOPT_UPLOAD का उपयोग करना चाहिए।

HTTP के साथ डेटा की अज्ञात मात्रा के लिए, आपको खंडित स्थानांतरण एन्कोडिंग का उपयोग करना चाहिए। CURLOPT_UPLOAD डॉक्स कहते हैं:

आप एक HTTP 1.1 सर्वर के लिए रखा उपयोग करते हैं, आप हस्तांतरण शुरू करने अगर आप chunked एन्कोडिंग का उपयोग करने से पहले आकार जानने के बिना डेटा अपलोड कर सकते हैं। आप CURLOPT_HTTPHEADER के साथ "स्थानांतरण-एन्कोडिंग: खंडित" जैसे शीर्षलेख जोड़कर इसे सक्षम करते हैं। HTTP 1.0 या बिना छिद्रित स्थानांतरण के, आपको आकार निर्दिष्ट करना होगा।

संबंधित मुद्दे