Thursday, April 20, 2017

Gotcha of the Day: Using Tasker's HTTP POST Action and PHP to upload a file

I plan to enhance 3shrink to support generating 3 letter codes in response to an upload. Before making this change, however, I wanted to understand how Tasker's HTTP POST Action works with respect to files. That way, I could be sure that any change I made to the core of 3shrink would play nicely with Tasker.

Tasker's HTTP POST Action is surprisingly finicky to use. The trickiest part: when you select a file to upload, Tasker injects a relative path to the file in the UI. Say, DCIM/Camera/20170330_005914.jpg. However, without the leading /, Tasker just assumes that this is an arbitrary string. And if you just add a leading slash to the path, you'll end up with a Tasker error about the file not being found. What's required is to have a valid absolute path in place.

After much playing, I learned that a valid absolute path begins with /sdcard, not /storage/emulated as some the file dialog box initially indicated. (At least that's how it works on my LG G6)

The other piece of the puzzle: you'll want to set the appropriate Content-Type for your file (using application/octet-stream is a fine catch-all).

Here are the correct settings:

On the PHP side of things, you can access this data by reading in the stream associated with php://input. Here's some sample code that slurps in the file from the web and writes it locally as capture.data. Notice that I'm doing a bit of checking here to insure that the Content-Type is set as I expect it.

<?
/*
 * A chunk of PHP code to catch an incoming file that's been posted
 * by Tasker's HTTP Post action
 */

if(isset($_SERVER['CONTENT_TYPE']) && $_SERVER['CONTENT_TYPE'] == 'application/octet-stream') {
  $out_fd = fopen(__DIR__ . "/capture.data", "w");
  $in_fd  = fopen("php://input", "r");
  while($data = fgets($in_fd)) {
    fputs($out_fd, $data);
  }
  echo "saved: " . filesize(__DIR__ . "/capture.data") . "\n";
} else {
  die("malformed request");
}
?>

If all goes as planned, Tasker should happily push the file, and your PHP script should happily pull it in. Enjoy!

Note: for uploading a queue of files, it's far smarter to use the FolderSync and the its Tasker Plugin.

No comments:

Post a Comment