Zaman cURL veri> PHP HTTP POST başarısız

4 Cevap php

Note: solution at the end

Ben 1024 karakterden uzun bir HTTP POST yapmak için çalışırsanız, başarısız olur. Neden? Burada en az bir örneği aşağıda verilmektedir:

recipient.php:

<?php
if (strlen(file_get_contents('php://input')) > 1000
    || strlen($HTTP_RAW_POST_DATA) > 1000) {
 echo "This was a triumph.";
}
?>

sender.php:

<?php
function try_to_post($char_count) {
 $url = 'http://gpx3quaa.joyent.us/test/recipient.php';
 $post_data = str_repeat('x', $char_count);
 $c = curl_init();
 curl_setopt_array($c,
                    array(  CURLOPT_URL => $url,
                            CURLOPT_HEADER => false,
                            CURLOPT_CONNECTTIMEOUT => 999,
                            CURLOPT_RETURNTRANSFER => true,
                            CURLOPT_POST => 1,
                            CURLOPT_POSTFIELDS => $post_data
                    )
 );
 $result = curl_exec($c);
 echo "{$result}\n";
 curl_close($c);
}

for ($i=1020;$i<1030;$i++) {
 echo "Trying {$i} - ";
 try_to_post($i);
}
?>

çıktı:

Trying 1020 - This was a triumph.
Trying 1021 - This was a triumph.
Trying 1022 - This was a triumph.
Trying 1023 - This was a triumph.
Trying 1024 - This was a triumph.
Trying 1025 - 
Trying 1026 - 
Trying 1027 - 
Trying 1028 - 
Trying 1029 -

yapılandırma:

PHP Version 5.2.6
libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3 libidn/1.8
lighttpd-1.4.19

Solution

CURL için aşağıdaki seçeneği ekleyin:

curl_setopt($ch,CURLOPT_HTTPHEADER,array("Expect:"));

HTTP başlık gönderilecek: "100-devam Expect", ve Lighttpd 1.4 * bunu desteklemiyor. Nedeni 1024 karakteri üzerinde herhangi POST neden olduğunu gibi görünüyor. Ben bunun için bir bilet bulundu: http://redmine.lighttpd.net/issues/show/1017

Onlar 1.5 çalışır söylüyorlar.

4 Cevap

Sen açık bir istek başlığı ayarlayarak 100-devam-şey yapıyor durdurmak için PHP'nin curl backend ikna edebilirsiniz:

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));

Eğer bir istek gönderebilir Bu şekilde ancak uzun hiç isteyeyim ve kıvırmak çift fazlı yazı yapmayacağım.

Ben ettik blogged about this yaklaşık iki yıl önce.

First thoughts...

curl_setopt için kılavuz sayfası CURLOPT_POSTFIELDS diyor

"The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with @ and use the full path. This can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value."

Bu değer, urlencoded sanki tedavi ve dolayısıyla hiçbir değere sahip bir büyük uzun bir isim gibi görünüyor ediliyor olabilir. Bir şey bir yerde bu ismi kesecek şekilde karar vermektir.

Belki böyle bir şey onu değiştirebilir

$post_data = "data=".str_repeat('x', $char_count);

Bu çok kolay oldu çıkıyor ve sorunu biraz daha derin oldu. Peki, nasıl hata ayıklama?

Find out exactly what CURL sends to the server

Başka bir hata ayıklama taktik aynı şeyi elde bir kıvrılma komut satırı formüle olmak ve onları yapar gibi HTTP isteği ayrıntılar çıkış olabilir.

Testing the server by hand

Siz örneğin, elle bir isteği gerçekleştirmek tarafından denklemden sunucu ortadan kaldırabilir sunucu üzerinde port 80 telnetting ve bir istek göndererek> 1024 karakter

POST /test/recipient.php HTTP/1.0
Host: gpx3quaa.joyent.us
Content-Length:1028

xxxxx(I put 1028 chars here, no point copying them all here!)

Ben bu tepki var

HTTP/1.0 200 OK
Connection: close
Content-type: text/html; charset=UTF-8
Content-Length: 19
Date: Tue, 20 Jan 2009 21:35:16 GMT
Server: lighttpd/1.4.19

This was a triumph.Connection closed by foreign host.

Yani en azından şimdi bazı CURL seçenek veya yapılandırma yerde ayarlama mümkün, bu istemci tarafında tüm biliyorum: (

Final Answer!

Sorun bu yüzden derin kazılmış ilgimi

Eğer CURLOPT_VERBOSE=>true kullanırsanız, o CURL büyük yazılarda ekstra bir başlık gönderir görürsünüz: Expect: 100-Continue. Sizin lighttpd'nin sunucu bu sevmez, öyle görünüyor.

Sen curl_setopt seçenekler dizisinin CURLOPT_HTTP_VERSION=>CURL_HTTP_VERSION_1_0 ile HTTP/1.0 kullanmak zorlayarak bunu yaparken CURL durdurabilirsiniz.

Ben SSL v3 kullanarak, bir IIS sunucusu ile benzer bir sorun vardı.

Ben CURLOPT_POSTFIELDS uzun 1024'ten oldu aşağıdaki cURL hatayı alıyorum tuttu:

52 - SSL read: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number, errno 0

CURLOPT_HTTPHEADER Ekleme: "Expect:" Benim için sorun çözüldü.

Bu iş parçacığı için çok teşekkür ederim!

Eğer Suhosin yama etkin olup olmadığını kontrol edin. Varsayılan olarak, bu indeksler belli bir sayıdan sonra POST verileri keser. Sen Suhosin yapılandırma tho bunu atlayabilir.