Search code examples
phpcurlphp-curl

PHP curl strange behavior PUT vs. POST


One of my projects contains an interface to a web based database, which I call using curl. A curl with -X PUT will create a new record, a curl with -X POST will update an existing record. If I perform this using Advanced REST Client, it works as it should. If I try this using a call of curl_exec out of my PHP script, the POST works but the PUT fails. 'Fails' means, I get a http 100 as response instead a 200 or 400.

$strXML = "<XML></XML>"; //valid XML here
$cURL = "https://www.webURL.here";
$cToken = "this_is_my_very_secret_token";
$ch = curl_init();

//POST

curl_setopt_array($ch, array(
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => "$strXML",
                CURLOPT_URL => $cURL,
                CURLOPT_HTTPHEADER => array("X-Auth-Token: $cToken","Content-Type:text/xml"),
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_VERBOSE => true
));
$strXMLEvents = curl_exec($ch);

The PUT call looks similar:

// PUT
curl_setopt_array($ch, array(
                    CURLOPT_PUT => true,
                    CURLOPT_POSTFIELDS => "$strXML",
                    CURLOPT_URL => $cURL,
                    CURLOPT_HTTPHEADER  => array("X-Auth-Token: $cToken","Content-Type:text/xml","Content-Length: ".strlen($strXML)),
                    CURLOPT_RETURNTRANSFER  => true,
                    CURLOPT_VERBOSE     => true
));
$strXMLEvents = curl_exec($ch);

Since I encounter this on my developing system (a win 10 PC), I thought, this could be the reason. But after I deployed the code onto the Linux webserver, the behavior stays the same...

Since the transfer works "manually" with ARC, I suspect a bug in my script - but I am not able to find it.


Solution

  • from the manual:

    CURLOPT_PUT

    TRUE to HTTP PUT a file. The file to PUT must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE.

    since we are not putting a file, instead of CURLOPT_PUT => true try CURLOPT_CUSTOMREQUEST => "PUT"

    // PUT
    curl_setopt_array($ch, array(
                        CURLOPT_CUSTOMREQUEST => "PUT",
                        CURLOPT_POSTFIELDS => "$strXML",
                        CURLOPT_URL => $cURL,
                        CURLOPT_HTTPHEADER  => array("X-Auth-Token: $cToken","Content-Type:text/xml" /* ,"Content-Length: ".strlen($strXML) */ ),
                        CURLOPT_RETURNTRANSFER  => true,
                        CURLOPT_VERBOSE     => true
    ));
    $strXMLEvents = curl_exec($ch);
    

    This way we just change the HTTP verb from POST to PUT