Sending a file via HTTP PUT in PHP

17,744

Solution 1

Aha! After a little "rubber ducking" with the grumpy dwarf stuffed doll on my desk here, I figured out the solution:

        $data = file_get_contents($tmpFile);
         $params = array(
             'http' => array(
                 'method' => 'PUT',
                 'header' => "Authorization: Basic " . base64_encode($this->ci->config->item('ws_login') . ':' . $this->ci->config->item('ws_passwd')) . "\r\nContent-type: text/xml\r\n",
                 'content' => file_get_contents($tmpFile)
             )
         );
         $ctx = stream_context_create($params);
         $response = @file_get_contents($url, false, $ctx);

         return ($response == '');

Solution 2

CURL works for me. Here is snippet from my code,

                $handle = curl_init ($server_url);

                if ($handle)
                {
                    // specify custom header
                    $customHeader = array(
                        "Content-type: $file_type"
                    );
                    $curlOptArr = array(
                        CURLOPT_PUT => TRUE,
                        CURLOPT_HEADER => TRUE,
                        CURLOPT_HTTPHEADER => $customHeader,
                        CURLOPT_INFILESIZE => $file_size,
                        CURLOPT_INFILE => $file,
                        CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
                        CURLOPT_USERPWD => $user . ':' . $password,
                        CURLOPT_RETURNTRANSFER => TRUE
                    );
                    curl_setopt_array($handle, $curlOptArr);
                    $ret = curl_exec($handle);
                    $errRet = curl_error($handle);
                    curl_close($handle);

EDIT: Just updated my code. I don't use authentication myself so this is not tested.

Solution 3

This works for me...

function put($_server,$_file,$_data)
{
  $fp = @fsockopen ($_server, 80, $errno, $errstr, 30);
  if ($fp)
  {
    $p = "PUT $_file HTTP/1.0\r\n";
    $p.= "User-Agent: Mozilla/3.0 (Windows NT 5.0; U) Opera 7.21  [da]\r\n";
    $p.= "Host: $_server\r\n";
    $p.= "Accept: text/html, application/xml;q=0.9, application/xhtml+xml;q=0.9, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n";
    $p.= "Accept-Language: da;q=1.0,en;q=0.9\r\n";
    $p.= "Accept-Charset: windows-1252, utf-8, utf-16, iso-8859-1;q=0.6, *;q=0.1\r\n";
    $p.= "Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n";
    $p.= "Referer: http://www.nasa.gov/secret/flightplans.asp\r\n";
    $p.= "Content-type: application/x-www-form-urlencoded\r\n";
    $p.= "Content-length: ".strlen($_data)."\r\n";
    $p.= "\r\n";
    $p.= $_data;

    //echo($p);
    fputs ($fp, $p);
  }
  else die("dagnabbit : $errstr");

  while ($l=fgets($fp))
    echo($l);
  fclose($fp);
}

Many of the header lines are probably not necessary... but it works when I talk to my couchdb so I haven't gotten around to weeding them out.

Share:
17,744

Related videos on Youtube

GrumpyCanuck
Author by

GrumpyCanuck

Long time web application programmer, now working for a social commerce company.

Updated on June 04, 2022

Comments

  • GrumpyCanuck
    GrumpyCanuck almost 2 years

    I've been struggling for several hours trying to figure out how to get this work. I'm trying to send a file via HTTP-PUT to an eXist db. There is user authentication for the server, so I was trying to do something like this:

    I have the URL where the doc is to be PUTted to I have the username and password for the eXist DB I have the content that needs to be sent via the PUT

    I tried getting to work with cURL but it would fail silently I tried to use PHP streams, but kept getting "error 201/created" but no file was actually created.

    Any help with this would be GREATLY appreciated.

    Here's some sample code I tried using PHP streams

            $data = file_get_contents($tmpFile);                                                                                                    
             $header = array(
                 "Authorization: Basic " . base64_encode($this->ci->config->item('ws_login') . ':' . $this->ci->config->item('ws_passwd')),
                 "Content-Type: text/xml"
             );  
             $params = array(
                 'http' => array(
                     'method' => 'PUT',
                     'header' => $header,
                     'content' => $data));
             $ctx = stream_context_create($params);
    
             $response = file_get_contents($url, false, $ctx);
    
  • meder omuraliev
    meder omuraliev over 14 years
    Can you explain? Was it the addition of the content key, or the return statement?
  • GrumpyCanuck
    GrumpyCanuck over 14 years
    It was one thing: changing the way I was building the header. I still have to suppress the out of file_get_contents as it returns a warning, but I can live with that for now until I find a better way to trap it.
  • GrumpyCanuck
    GrumpyCanuck over 14 years
    That's from my own blog, and I found that it wasn't working correctly. ;)
  • allnightgrocery
    allnightgrocery over 14 years
    I'm not sure if that's hilarious, or sad, or both :O
  • GrumpyCanuck
    GrumpyCanuck over 14 years
    I wasn't able to get the HTTP authentication stuff to work with cURL. Can you update that cURL example to use it?