0

I'm using Curl to upload photos to an actual site. I can see from Fiddler that the headers look like this:

Host: test.example.com
Proxy-Connection: keep-alive
Data-Type: json
Accept-Encoding: gzip, deflate
Content-Length: 62601
Content-Type: application/json
Accept-Language: en-us
Accept: application/json
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36

I'm using the exact headers as above. I'm getting the value for content-length using filesize

   $file = 'test.jpg';
   $file_size = filesize($file);

    $headers = array(
                "Host: test.example.com",
                "Proxy-Connection: keep-alive",
                "Data-Type: json",
                "Accept-Encoding: gzip, deflate",
                "Content-length: $file_size",
                "Content-Type: application/json",       
                "Accept-Language: en-us",
                "Connection: keep-alive",
                "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36",
            );

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
$result = curl_exec($ch);

I don't actually need the headers, the script generally works without it, but it fails too frequently and in an effort to troubleshoot I put the headers in.

All the headers work fine except for content-length. When I put that in I get a response from the server that indicates the command is not well formed (I cannot show the actual response here). I do not understand a lot about content-length but I believe this tells the server the size of the file and it helps it determine that the upload is complete. I think if I had this properly working it would increase the stability of my script.

I would appreciate any help.

Adam Sinclair
  • 1,654
  • 12
  • 15
user2029890
  • 2,493
  • 6
  • 34
  • 65
  • Can it be, that the content-length is now twice in? – loveNoHate Sep 16 '14 at 11:02
  • It may really help if we can see the content of $data or $data_string ? – Isaac Sep 16 '14 at 11:05
  • Sorry, typo with POSTFIELDS being there twice. I can't show the contents of $data but it contains additional info about a thumbnail. Does that help? Maybe I'm sending the wrong content value? – user2029890 Sep 16 '14 at 11:08
  • 1
    Curl sets the content-length itself, why not let it decide what's best ? – NaeiKinDus Sep 16 '14 at 11:10
  • Didn't know that. I assumed the lack of it is why I'm having stability issues. – user2029890 Sep 16 '14 at 11:13
  • 1
    Content-Length is used so that the server can determine whether to reject the message or not. That means you can protect from people trying to send you terabytes of data just by inspecting headers. If no Content-Length is specified, you can close the connection all together. Now, the tricky part when setting the content-length yourself is that you might not include the size of delimiters between headers and actual content. Hence why what @NaeiKinDus said - let curl figure it out. – N.B. Sep 16 '14 at 11:14
  • Thanks for the response. Assuming I want to try it, what would be the proper way to determine size? We have the photo and the contents of $data which has thumbnail info and some additional text. – user2029890 Sep 16 '14 at 11:17
  • @user2029890 Can we just see wich value did you you put for the photo in $data ? – Isaac Sep 16 '14 at 11:19
  • I wish I could and I appreciate you trying to help. Is it sufficient to say that the data that gets sent has the base64 contents of a thumbnail and the image plus some basic text about the image? – user2029890 Sep 16 '14 at 11:26

1 Answers1

0

If you're looking to send a file with curl, put the complete filePath preceded by @ and curl will handle the rest.

$headers = array(
        "Proxy-Connection: keep-alive",
        "Data-Type: json",
        "Accept-Encoding: gzip, deflate",
        "Content-Type: application/json",       
        "Accept-Language: en-us",
        "Connection: keep-alive",
    );
$data = array(
    'fieldForFile' => '@'.  $filePath //Don't forget @ and the complete file path to the file
    'anyOtherFields' => $value,


);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
// Use CURLOPT_USERAGENT for setting the user agent
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $POST_DATA);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
$response = curl_exec($ch);

// Error handling
if($errno = curl_errno($ch)) {
    $error_message = curl_strerror($errno);
    echo "cURL error ({$errno}):\n {$error_message}";
} else {
    echo "Success";
}

curl_close ($ch);
Isaac
  • 983
  • 1
  • 7
  • 13
  • Thank you for that. What about if its not completely a file. In my case, I'm reading the base64 contents of the jpg, combining it with other data and saving all that into a variable which then gets posted. – user2029890 Sep 16 '14 at 14:03
  • @user2029890 So you just have one postfields for all the data is that it ? – Isaac Sep 16 '14 at 14:07