web-dev-qa-db-ja.com

cURL 'コンテンツの長さが必要です'エラー... 3日間の検索、運がありません

あなたが尋ねる前に:私はすでに答えを持っているすべての同様の質問をすでにチェックしました、そして提案された解決策のどれもうまくいきません。だから私は誰かが私のコードの間違いに気付くことができるかもしれないことを望んでいます。

GoogleにcURL投稿を送信すると、「POSTリクエストにはContent-lengthヘッダーが必要です」という411エラーが返されます。

//Info required to authenticate
$URL = "https://www.google.com/accounts/ClientLogin";
$POST = http_build_query(array(
 'Email' => '[email protected]',
 'Passwd' => 'XXXXXXXXXXXXXXX',
 'source' => 'primary',
 'service' => 'cl'
));

$ch = curl_init( $URL );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $POST);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$response = curl_exec($ch); //returns SID=<sid code>nLSID=<lsid code>nAuth=<auth code> or ERROR=<message>
if ( curl_errno($ch) )
 die( 'Error contacting server' );

//Successful auth results in http code 200
if ( curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200 )
 die( 'Failed to authenticate' );

//Extract auth code - Authorization: GoogleLogin auth=yourAuthToken
$auth_code = substr($response, strpos($response, 'Auth=')+5);

//We're done here
curl_close($ch);


$url = "https://www.googleapis.com/calendar/v3/calendars/".urlencode('[email protected]')."/events?sendNotifications=true&pp=1&key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx";  

$post_data = http_build_query(array(
    "end" => array("dateTime" => "2013-14-11T10:40:00.000-07:00"),  
    "start" => array("dateTime" => "2013-14-11T10:00:00.000-07:00"),  
    "summary" => "my_summary",
    "description" => "my_description"
));

$headers = array(
    'Authorization: GoogleLogin auth='.$auth_code.'',
    'Content-Type: application/json'
);

$ch2 = curl_init();  
curl_setopt($ch2, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch2, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch2, CURLOPT_POSTFIELDS, $post_data);  

$output = curl_exec($ch2);  

curl_close($ch2);

echo '<pre>'.print_r($output).'</pre>';

私が試したこと:

-'Content-length: '.strlen($ post_data)の追加

-'x-www-form-urlencoded 'のコンテンツタイプ

-post_dataに非常に単純なjson文字列を使用して、http_build_queryを使用しなかった

-POSTではなくPUTとして送信しようとしています

-そして、ここ数日の間に、今は思い出せないことがいくつかあります。

目的:PHPのみを使用して、ユーザーが認証手順を必要とせずに、MYカレンダーのみにイベントを追加します。これは、すべてをphp関数内で非同期に実行できる必要があります(AJAX経由で呼び出されます)。

注:Wordpressまたはその他のCMSを使用しない

-カイル

7
Kyle

CURLOPT_HTTPHEADERを設定する必要があると思います。パスデータをjson文字列として試すことができます。

$post_data = array(
    "end" => array("dateTime" => "2013-14-11T10:40:00.000-07:00"),  
    "start" => array("dateTime" => "2013-14-11T10:00:00.000-07:00"),  
    "summary" => "my_summary",
    "description" => "my_description"
);

$post_data = json_encode($post_data);
curl_setopt($ch2, CURLOPT_HTTPHEADER, array(  
   'Content-Type: application/json',  
   'Content-Length: ' . strlen($post_data),)  
 );  
8
Roopendra

あなたと同じコンテンツエラーを受け取りましたが、含めていた変数が原因で、ヘッダーに誤った改行があることがわかりました。

curl_setopt($ch, CURLINFO_HEADER_OUT, true);を使用してこれを追跡しました。これにより、curl_getinfo()はリクエストのヘッダーを出力に含めます。

変数でtrim()を使用すると修正されました。

3
nick

だから私はすぐに_curl_getinfo_呼び出しを使用して、何が送信されているかを確認しました(あなたの推奨ではありませんが、最初にこれを試す方が速かったです)...そして確かに...どこにもコンテンツの長さはありません。 Content-lengthヘッダーが私によって宣言されている場合と、私によって宣言されていない場合の両方で試しました。どちらのオプションでも、次のような結果になりました。

_content_type_ = text/html ...と言っていることも注目に値しますが、_application/json_として宣言しました。

使用されています:

_curl_setopt($ch2, CURLOPT_HTTPHEADER, array(
   'Authorization: GoogleLogin auth='.$auth_code,
   'Content-Type: application/json',  
   'Content-length:' . strlen($post_data))
 );
_

_curl_getinfo_の出力は次のとおりです。

_Array (
    [url] => https://www.googleapis.com/calendar/v3/calendars/XXXXXXXXXX%40developer.gserviceaccount.com/events?sendNotifications=true&pp=1&key=XXXXXXXX-XXXXXXXXXXXXXXXXXXXXXX
    [content_type] => text/html; charset=UTF-8
    [http_code] => 411
    [header_size] => 147
    [request_size] => 737
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.104391
    [namelookup_time] => 0.000687
    [connect_time] => 0.025284
    [pretransfer_time] => 0.079614
    [size_upload] => 159
    [size_download] => 934
    [speed_download] => 8947
    [speed_upload] => 1523
    [download_content_length] => 934
    [upload_content_length] => 159
    [starttransfer_time] => 0.104356
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [primary_ip] => 2607:f8b0:400e:c04::5f
    [primary_port] => 443
    [local_ip] => 2600:3c01::f03c:91ff:fe69:4a05
    [local_port] => 57581
    [redirect_url] =>  )
_
2
Kyle

更新された回答...

2回目のカールコールでは、1行に間違ったハンドルを使用したようです...

curl_setopt($ch, CURLOPT_POST, true);

あるはずです

curl_setopt($ch2, CURLOPT_POST, true);

元の回答...ヘッダーを渡していない。この形式でcontent-lengthをヘッダーとして渡してみましたか?

curl_setopt($ch,CURLOPT_HTTPHEADER,array('HeaderName: HeaderValue'));

現在、ヘッダーは1番です

curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-length:'.strlen($post_data)));
1
Lenny

私はしばらくの間、同様の問題に苦しんでいました。私の場合、ヘッダーに設定していた値の1つが改行文字で終わっていたためです。これは、投稿を受信するサーバーが二重改行を認識し、ヘッダーが終了したと時期尚早に判断することを意味しました(これにより、Content-Lengthヘッダーの読み取りが停止しました)。解決策は、改行文字をトリミングすることでした。

0
Daniel Howard