API : Uploading attachment with curl

Added by Tom Raulet almost 9 years ago

Hi all,

I'm trying since last 4 days to upload an image using redmine API and curl.


My PHP code :

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_VERBOSE, 0);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/octet-stream',
    'X-Redmine-API-Key: '.$apiKey));
    curl_setopt($curl, CURLOPT_POST, 1);
    $data = array($filename =>'@'.$filename.';type=image/png');
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

    $response = curl_exec($curl);

    if (curl_errno($curl)) {
        $e = new \Exception(curl_error($curl), curl_errno($curl));
        throw $e;

    return $response;

I've also tried with

$data = array($filename =>'@'.$filename.')

without ;type=...

What is does ?

See bug_redmine.png attached to this post.

File is uploaded but not readable as image and corrupted ...

Supp info

If I

before sending it via API, the image is OK ...

and when I try using curl manually in terminal :

curl --data-binary "@feedback3340.png" -H "Content-Type: application/octet-stream" -X POST -H "X-Redmine-API-Key: APIKEYHERE" http://redmine.myhost.com/uploads.json

it works too

script about output :

  Redmine version                2.3.2.devel
  Ruby version                   2.0.0-p247 (2013-06-27) [armv6l-linux-eabihf]
  Rails version                  3.2.13
  Environment                    production
  Database adapter               Mysql2
  Subversion                     1.7.5
Redmine plugins:
  no plugin installed

=> I'm on raspberry Pi

web server used :

lighttpd/1.4.31 (ssl) - a light and fast webserver
Build-Date: Nov 17 2013 05:17:26

Thks for any help/trick



bug_redmine.png (31.1 KB)

Replies (1)

RE: API : Uploading attachment with curl - Added by Erik Dannenberg almost 9 years ago

The problem is CURLOPT_POSTFIELDS, as soon as you pass an array here php curl assumes a multipart/form-data transfer, which the redmine api does not understand. As a result the multipart headers end up in the uploaded image. Hence the corrupted image.

I'm afraid php curl is not an option for uploading files to redmine. You can create a custom post request though:

        $file = file_get_contents($filePath);
        $fp = fsockopen($urlOrIp, $port, $errno, $errstr, 30);
        if ($fp) {
            $out = "POST /uploads.json HTTP/1.1\r\n";
            $out .= "Host: $urlOrIp\r\n";
            $out .= "Content-Type: application/octet-stream\r\n";
            $out .= "X-Redmine-API-Key: $apiKey\r\n";
            $out .= 'Content-Length: ' . strlen($file) . "\r\n\r\n";
            fwrite($fp, $out);
            fwrite($fp, $file);
            $response = '';
            while (!feof($fp)) {
                $response .= fgets($fp, 128);
            $o = array();
            if (preg_match_all('/\{"upload":\{"token":"(.+)"\}\}/ms', $response, $o)) {
                return $o[1][0];
        return false;