Viewed   102 times

Note: solution at the end

If I attempt to do a HTTP POST of over 1024 characters, it fails. Why? Here is a minimal example:


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


function try_to_post($char_count) {
 $url = '';
 $post_data = str_repeat('x', $char_count);
 $c = curl_init();
                    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";

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


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 - 


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


Add the following option for cURL:


The reason seems to be that any POST over 1024 character causes the "Expect: 100-continue" HTTP header to be sent, and Lighttpd 1.4.* does not support it. I found a ticket for it:

They say it works in 1.5.



You can convince PHP's curl backend to stop doing the 100-continue-thing by setting an explicit request header:

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

This way you can post a request however long you would ever want and curl will not do the dual phase post.

I've blogged about this nearly two years ago.

Monday, October 3, 2022

Change the order around:

header("Location: ..."); // The new resource URL
header('HTTP/1.1 201 Created');
header('Content-type: application/json; charset=utf-8');
echo $response;


# curl -i "http://localhost/projects/scratch/302.php"
HTTP/1.1 201 Created
Date: Sun, 29 Jan 2012 23:09:02 GMT
Server: Apache/2.2.17 (Win32) mod_ssl/2.2.17 OpenSSL/0.9.8o PHP/5.3.4 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By: PHP/5.3.5
Location: ...
Content-Length: 0
Content-Type: application/json; charset=utf-8

Another way

Keep the original order, but force a 201. According to the PHP docs:

it also returns a REDIRECT (302) status code to the browser unless the 201 or a 3xx status code has already been set.

header('HTTP/1.1 201 Created', true, 201);
header("Location: ..."); // The new resource URL
header('Content-type: application/json; charset=utf-8');
echo $response;
Thursday, December 15, 2022

See also: How to post data in PHP using file_get_contents?

Basically you can use file_get_contents() and stream_context_create() for issuing a POST request. In your case:

$post = http_build_query(array(
    "username" => "user",
    "password" => "pw",
    "example" => "...",

$context = stream_context_create(array("http"=>array(
     "method" => "POST",
     "header" => "Content-Type: application/x-www-form-urlencodedrn" .
                 "Content-Length: ". strlen($post) . "rn",  
     "content" => $post,

$page = file_get_contents("", false, $context);
Sunday, September 18, 2022

Multiple -d looks fine. The docs said -d name=daniel -d skill=lousy will generate name=daniel&skill=lousy

So if you want send an array, you have to use the [] brackets.

-d name[]=peter -d name[]=paul -d name[]=mary

It looks like you can also use

-d "name[]=peter&name[]=paul&name=mary"
Thursday, October 27, 2022

Ah, simple mistake, I need to pass char * to curl_easy_setopt and not string. To fix this I've just used .c_str() like so:

CURL *curl = curl_easy_init();

string url = "";

char *data = "mode=test";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
CURLcode res = curl_easy_perform(curl);

bool success = (res == CURLE_OK);

Friday, August 12, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :