Third Light Developer Exchange

Code and templating community forum for developers and software integrators

You are not logged in.

#1 2013-09-25 11:53:12

steve
Third Light Staff
Registered: 2013-06-06
Posts: 73

Uploading using the POST method

Using the postURL address returned by CreateUpload() is the recommended method for efficiently uploading files using the API. The GET based approach incurs a 33% bandwidth overhead base64 encoding the files and also places relatively small limits on the size of files that can be uploaded due to memory limit thresholds.

Using the POST method, files upto 2GB in size can be uploaded on 32bit based IMS servers and 4GB (minus a few K) on 64bit servers.

The call to CreateUpload() will return a URL to which you can post:

e.g. http:// yoursite.com/dofileupload.tlxr?task=pI-NpNGW1GepJt4pAKL2I

Request	{ "apiVersion": "1.0.1", "action": "upload.CreateUpload", "inParams": { "params": { "destination": 17658497420, "synchronous": true, "lifetime": 60, "defaultmetadata": [ ], "editablemetadata": { "caption": "OPTIONAL" }, "allowotheruserupload": true } }, "sessionId": "DpApc,rnnrPYK1X3M1l3G3Q3D6xxTBDy" }
Response	{ "result": { "api": "OK", "action": "OK" }, "outParams": { "uploadKey": "pI-NpNGW1GepJt4pAKL2I", "postURL": "http:\/\/yoursite.com\/dofileupload.tlxr?task=pI-NpNGW1GepJt4pAKL2I" } }

The request also defined which metadata fields are able to accept metadata:

"editablemetadata": { "caption": "OPTIONAL" }

You could alternatively specify that a field should be required

"editablemetadata": { "caption": "OPTIONAL", "keywords", "REQUIRED" }

The files you want to upload can be given an identifier of your choice. In the example below we use 'file_contentsX'.

file_contents0 = @example_assets2/sub1/beavis.jpg

Metadata can also be included in the POST body by appending the keyword fieldname to the identifier:

file_contents0_caption = Friendly cat

IMS file references are not returned when using POST but blocking is supported until the file is sucessfully imported. Using uploadKey returned by CreateUpload() you can then call GetUploadResult() to obtain file references.

Reference Example

  • This script makes use of the PHP client

  • You must use IMS 6.0.15-1 or greater

<?php

// Upload files using API POST URL method

ob_start(); //buffer output

// Customise these values to match your system

// URL of the IMS site
$strIMSSite = "http://yoursite.com";

// API key generated from Configuration -> Site Options -> IMS API
$strAPIKey = "IJPtL39u8vMfntBgVm7bvGDGUXRRu8FC";

// Source folder
$strSourceFolder = "example_assets";  

// Target folder
$nDestinationFolder = 17658497420;

// Display request and response data
// Choices are "DisplayRequestAndResponseJSON", "DisplayRequestAndResponseArray" or ""
$arrExtraParams = array("DEBUG"=> "DisplayRequestAndResponseJSON");

// Metadata to add the upload files
$strCaption = "Uploaded via the API";

// End of custom section

chdir(__DIR__);

require_once("../imsapiclient.php");
require_once("displaysupport.php");


try
{               
        BeginHTMLPage();
        $strPostURL = isset($_POST["posturl"])?$_POST["posturl"] : "";
        
        if($strPostURL =="")
        {
                $objAPI = new IMSApiClient($strIMSSite, $strAPIKey, $arrExtraParams);

                $arrInParams = array("params" =>
                                                        array(
                                                                "destination" => $nDestinationFolder,
                                                                "synchronous" => true,
                                                                "lifetime" => 60,
                                                                "defaultmetadata" => array(),
                                                                "editablemetadata" => array("caption"=>"OPTIONAL"),
                                                                "allowotheruserupload" => true          
                                                        )
                                                );

                $arrOutParams = $objAPI->Upload_CreateUpload($arrInParams);
                $strUploadKey = $arrOutParams['uploadKey'];
                $strPostURL = $arrOutParams['postURL']; 
                
                $strSessionId = $objAPI->GetSessionKey();

                ?>
                <table>
                <tr><td>Purpose</td><td>Use the URL returned by CreateUpload() as a POST target for uploading files and adding metadata</td></tr>
                <tr><td>Source Folder</td><td><?php echo $strSourceFolder ?></td></tr>
                <tr><td>Target Folder Id</td><td><?php echo $nDestinationFolder ?></td></tr>
                <tr><td>Post URL</td><td><?php echo $strPostURL ?></td></tr>
                </table>
                <?php
                                
                DisplayOutput("<b>Notes</b>");
                DisplayOutput("Site terms and conditions must be disabled");
                
                ?>
                        
                <form method="post" name="form1">
                <input type="hidden" name="posturl" value="<?php echo $strPostURL?>">
                <p></p>
                <input type="submit" value="Upload Files" />
                </form>
                <?php
                EndHTMLPage();
                
        }
        else
        {
                try
                {
                        function CreateFileListFromFolder($strSourceFolder)
                        {
                                $arrParentNode = scandir($strSourceFolder);
                                foreach($arrParentNode as $value)
                                {
                                        if($value === '.' || $value === '..') {continue;}
                                        if(is_file("$strSourceFolder/$value")) {$result[]="@$strSourceFolder/$value";continue;}
                                        foreach(CreateFileListFromFolder("$strSourceFolder/$value") as $value)
                                        {
                                                $result[]= $value;
                                        }
                                }
                                return ($result);
                        }

                        $arrFilesWithPath = CreateFileListFromFolder($strSourceFolder);
                        DisplayOutputArrayHTML($arrFilesWithPath, "Contents found in folder '$strSourceFolder'");    

                        $post_fields = array();

                        $counter=0;
                        foreach($arrFilesWithPath as $file)
                        {
                                // Files are included in the POST data using this form:
                                // <identifier> <@path_to_file>
                                // e.g. filecontents0 = @exampleassets/beavis.jpg
                                
                                $fieldname = 'file_contents'. $counter;
                                
                                $post_fields[$fieldname] = $file;
                                
                                // Metadata can be included in the POST data using this form
                                // <identifier_fieldname> <value>
                                // e.g. filecontents0_caption = "Uploaded through the API"
                                
                                $strMetadatafieldname = $fieldname . "_caption";
                                $post_fields[$strMetadatafieldname] = $strCaption;
                                
                                $counter++;
                        }
                        
                        DisplayOutputArrayHTML($post_fields, "Fields included within POST");
                        
                        $ch = curl_init();
                        
                        curl_setopt($ch, CURLOPT_URL,$strPostURL);
                        curl_setopt($ch, CURLOPT_POST, 1);
                        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                        curl_setopt($ch, CURLOPT_HEADER, 1);
                        curl_setopt($ch, CURLOPT_VERBOSE, 1);
                        
                        $result=curl_exec ($ch);
                        
                        DisplayOutputHTML($result, "Output from curl");
                        DisplayOutputArrayHTML(curl_getinfo($ch), "Extra information from curl transfer");
        

                        curl_close ($ch);
                }
                catch(Exception $e)
                {
                        echo $e->getMessage();
                }
        }       
}
catch(IMSApiClientException $e)
{
    header("HTTP/1.1 500 Internal Server Error");
    echo "<!DOCTYPE html>\n<html><head><title>Error</title></head><body><h1>Error: ".get_class($e)."</h1><p>".$e->getMessage()."</p></body></html>";
    echo"<pre>";
    print_r($e);
    echo"</pre>";
}

Offline

#2 2017-07-05 12:23:51

thirdlight
Third Light Staff
Registered: 2013-06-06
Posts: 19

Re: Uploading using the POST method

If you're not using PHP, you may be interested in just seeing the JSON involved in doing an upload. The simplest approach is to use a synchronous, blocking upload (and just uploading one file keeps things simple). In particular, you don't need to use the @filename convention above, and in the simplest case you can do an upload in just two calls.

Step 1 - Get an upload form

You need to use CreateUpload() to get an upload task started. Let's say I want to put a file into folder 43061728670 and I've already got a session, wSaPurKpmwEyVQvu3zmwdXuzlSzQOIFq. I can use this request:

Request:

{"apiVersion": "1.0", "action": "upload.CreateUpload", "inParams": { "params": { "destination": 43061728670, "synchronous": true, "allowotheruserupload": true  } }, "sessionId": "wSaPurKpmwEyVQvu3zmwdXuzlSzQOIFq" }

Here's the response:

 {"result":{"api":"OK","action":"OK","timings":{"initTime":59,"setupTime":11,"methodTime":63,"totalTime":133}},"outParams":{"uploadKey":"LfY81LfL2Q7LztNHT","postURL":"https:\/\/example.thirdlight.com\/dofileupload.tlxr?task=LfY81LfL2Q7LztNHT"}}

Take the response and extract the postURL. Add "&ajax=1", so that in this example you'd have:

https://example.thirdlight.com/dofileupload.tlxr?task=LfY81LfL2Q7LztNHT&ajax=1

Step 2 - Post your file as multipart/form data to the URL

For example, you can use this HTML as a test:

<form action='https://example.thirdlight.com/dofileupload.tlxr?task=LfY81LfL2Q7LztNHT&ajax=1' method='post' enctype='multipart/form-data'>
<input type='file' name='file0'>
<input type='submit'>
</form>

The name of the file input is not significant. When you submit this form, you should receive an AJAX response:

 {"error": false}

The file will now be in your target folder (in this example, the folder id is 43061728670). If you receive any errors, things to check include whether your user account (as associated with the session you've used) requires upload approvals or has any metadata requirements.

Step 3 - Optionally, get the uploaded file's reference number

When your file has been uploaded, you might want to use the reference number (for example, to set some metadata or do other API work). The quickest way is to use the GetUploadResult() method, and send the task ID.

Request:

 {"apiVersion": "1.0", "action": "upload.GetUploadResult", "inParams": { "uploadKey": "LfY81LfL2Q7LztNHT" }, "sessionId": "wSaPurKpmwEyVQvu3zmwdXuzlSzQOIFq" }

Result:

 {"result":{"api":"OK","action":"OK","timings":{"initTime":65,"setupTime":10,"methodTime":11,"totalTime":86}},"outParams":{"succeeded":{"filename.jpg":"43075872955"},"failed":[],"error":false,"count":1}}

In this case, the reference number is 43075872955.

Offline

Board footer