views:

821

answers:

4

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);
+1  A: 

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 == '');
GrumpyCanuck
Can you explain? Was it the addition of the `content` key, or the return statement?
meder
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
A: 

If your eXist-db has the SOAP interface enabled, there's an open-source library called PheXist that would make interacting with the database easier.

jonthornton
A: 
function _publish($service, $doc) {
 $params = array(
  'http' => array(
   'method' => 'PUT'));
 $context = stream_context_create($params);
 $fp = fopen($service, 'rb', false, $context);
 $response = fwrite($fp,file_get_contents($doc));
 if ($response === false) {
  return false;
 }
 // Pull out the status code from the header
 $metaData = stream_get_meta_data($fp);
 preg_match_all("/HTTP\/1\.[1|0]\s(\d{3})/", $metaData['wrapper_data'][0], $matches);
 $code = end($matches[1]);
 if ($code == 200) {
  return true;
 } else {
  return false;
 }
}

from http://www.littlehart.net/atthekeyboard/2008/01/11/how-to-http-put-a-file-somewhere-using-php/

agentile
That's from my own blog, and I found that it wasn't working correctly. ;)
GrumpyCanuck
I'm not sure if that's hilarious, or sad, or both :O
lo_fye
A: 

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.

ZZ Coder
I wasn't able to get the HTTP authentication stuff to work with cURL. Can you update that cURL example to use it?
GrumpyCanuck