0

I have been trying for a long to get a file upload to work from my lisp application using an HTTPPost. I am running the services module on Drupal 7 with the a RESTFul server (with the file resource enabled). I am able to connect to the server and login then use the cookie that is returned to send another http-post to ?q=rest/file which includes the file. This post has a content type of multipart/form-data and always returns 200 OK but the file upload never occurs.

I tried doing a similar post from php CURL and it uploaded without a hitch. When I set CURLOPT_VERBOSE and examined the header of the successful POST, I noticed that the content-type was application/x-www-form-urlencoded. Finally I decided to try and change the content-type in my curl example to a multipart/form-data looking like this: multipart/form-data; boundary=----------PrqXvhHr3Bb68fVcGv7ohf0K6OOSsi0R4M4JpYPlA4rovP56s7 and now the file is no longer properly uploaded (but still returns success).

I am now thinking maybe I am having all this trouble because the RESTful server does not work with multipart/form-data requests. Does anyone know? Has anyone tried this? All the documentation I have read suggests that file transfers should always be done with multipart/form-data.

Here is the code I am using to do the file upload through php/curl in case anyone might find it useful in understanding this problem:

<?php
// node data

$filename = '/Users/mike/hello.png';//'C:\Users\Mike\Desktop\hello.png';
$title = 'A node created with services 3.x and REST server';
$body = '<p>Body lorem ipsum</p>';
$tags = 'TEST_TAG, TEST_TAG2';
$type = 'test'; // node type
$vid = 2; // vid of vocabulary marked as "Tags"

$services_url = 'http://localhost:8888/?q=rest';

/*
 * Server REST - user.login
 */

// REST Server URL for auth
$request_url = $services_url . '/user/login';

// User data
$user_data = array(
  'username' => 'login',
  'password' => 'password',
);

$user_data = http_build_query($user_data);

$fp = @fopen("/Users/Mike/curl-error.log", "w");//'/Users/Mike/curl-error.log';

// cURL
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json')); // Accept JSON response
curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST
curl_setopt($curl, CURLOPT_POSTFIELDS, $user_data); // Set POST data
curl_setopt($curl, CURLOPT_HEADER, FALSE);  // Ask to not return Header
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FAILONERROR, TRUE);

$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// Check if login was successful
if ($http_code == 200) {
  // Convert json response as array
  $logged_user = json_decode($response);
}
else {
  // Get error msg
  $http_message = curl_error($curl);
  die('Auth error ' . $http_message);
}

// Define cookie session
$cookie_session = $logged_user->session_name . '=' . $logged_user->sessid;

/*
 * Server REST - file.create
 */

if(!file_exists($filename)) {
  die('File not exists');
}

if(!is_readable($filename)) {
  die('File not readable');
}

// file
$file = array(
  'filesize' => filesize($filename),
  'filename' => basename($filename),
  'file' => '@' . $filename, //'file' => base64_encode(file_get_contents($filename)),
  'uid' => $logged_user->user->uid,
);

$file = http_build_query($file);

// REST Server URL for file upload
$request_url = $services_url . '/file';

// cURL
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($curl,   CURLOPT_STDERR, $fp);
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST
curl_setopt($curl, CURLOPT_POSTFIELDS, $file); // Set POST data
curl_setopt($curl, CURLOPT_HEADER, FALSE);  // Ask to not return Header
curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); // use the previously saved session
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FAILONERROR, TRUE);
curl_setopt_array($curl, array(CURLINFO_HEADER_OUT => true) );
$response = curl_exec($curl);
//$postdata = file_get_contents("php://input");
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$headerSent = curl_getinfo($curl, CURLINFO_HEADER_OUT );
// Check if login was successful
if ($http_code == 200) {
  // Convert json response as array
  $file_data = json_decode($response);
}
else {
  // Get error msg
  $http_message = curl_error($curl);
  die('Sending file error<br>' . $http_message . "\n<br>");
}

// file id (nessesary for node)
$fid = $file_data->fid;

/*
 * Server REST - node.create
 */

// REST Server URL
$request_url = $services_url . '/node';


// Node data
$node_data = array(
  'title' => $title,
  'type' => $type,
  'body' => $body,
  'taxonomy[tags][' . $vid . ']' => $tags,
  'field_main_image[]' => array('fid' => $fid, 'list' => 1, 'data' => NULL),
);
$node_data = http_build_query($node_data);


// cURL
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json')); // Accept JSON response

curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST
curl_setopt($curl, CURLOPT_POSTFIELDS, $node_data); // Set POST data
curl_setopt($curl, CURLOPT_HEADER, FALSE);  // Ask to not return Header
curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); // use the previously saved session
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FAILONERROR, TRUE);

$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// Check if login was successful
if ($http_code == 200) {
  // Convert json response as array
  $node = json_decode($response);
}
else {
  // Get error msg
  $http_message = curl_error($curl);
  die('Getting data error<br>' . $http_message . "\n<br>");
}

print_r($node);
1

Didn't try this unfortunately. However, maybe this help - try to base64 encode file and send it as typical field, and then decode it?

Regards, Slava.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.