Server script to handle Exiv2 HTTP Write Access

The remote I/O feature will be available on the release 0.25. It allows Exiv2 to support http, ftp and ssh protocols (both read and write access). The write access for HTTP/HTTPS protocol requires the script on the server to handle the submitted data. This wiki helps you to create this script.

The submitted data

Exiv2 doesn't submit the whole file to the server to make efficient use of band-width. It only submits the part which is different from the original image file. The data is submitted via POST method and there are four parameters.

name type description
path string The path of the image file.
from integer The start position (byte index) in the image file is replaced by the submitted data.
to integer The end position (byte index) in the image file is replaced by the submitted data.
data base64-encoded data The data.

Example:

./exiv2 -M"set Exif.Photo.UserComment charset=Ascii Hello World" http://example.com/photo/test.jpg

After running the above command, let's assume that the part from the byte 100 to the byte 110 in the original image file is changed to "2f77 7777 2e69 6563 2e63 6800 0000 0000" (hexadecimal). The POST data should be.

path /photo/test.jpg
from 100
to 110
data MmY3NyA3Nzc3IDJlNjkgNjU2MyAyZTYzIDY4MDAgMDAwMCAwMDAw

The example sever-side script in PHP

$HTTP_DIR    = "/var/www";                   // the web root directory.
$path        = $_REQUEST['path'];            // the path of image file.
$from        = intval($_REQUEST['from']);    // the start position.
$to          = intval($_REQUEST['to']);      // the end position.
$binaryData  = base64_decode($_POST['data']);// the data.

if (empty($path) || !isset($from) || !isset($to)) {
    echo "Please POST: path, from, to, data";
    return;
}

$imagePath   = $HTTP_DIR.$path;              // the absolute path of image file.
$tempPath    = $HTTP_DIR.$path."_temp";      // the absolute path of temporary file.
$imageHandle = fopen($imagePath, "rb");
$tempHandle  = fopen($tempPath, "w+b");

#copy the head of image file (index 0 -> $from index) to the temp file.
if ($from != 0) {
    $contents = fread($imageHandle, $from);
    fwrite($tempHandle, $contents);
}

#insert the submitted data to the temp file.
if (!empty($binaryData)) {
    fwrite($tempHandle, $binaryData);
}

# move to index $to in the image file
fseek($imageHandle, $to, SEEK_SET );

# write the rest of image file to temp file
if (!feof($imageHandle)) {
    $contents = fread($imageHandle, filesize($imagePath) - $to);    
    fwrite($tempHandle, $contents);
}

#replace the image file with the temp file.
fclose($imageHandle);
fclose($tempHandle);
unlink($imagePath);
rename($tempPath, $imagePath);

EXIV2_HTTP_POST environmental variable.

The server-side script url can be specified with the environmental variable EXIV2_HTTP_POST, so Exiv2 knows the place to post the data. The default value is "/exiv2.php".

Example:

export EXIV2_HTTP_POST=http://example.com/script/exiv2.php

export EXIV2_HTTP_POST="/script/exiv2.php" // In this case, the protocol and host info are the same as the image url.

Redmine Appliance - Powered by TurnKey Linux