Example: Chunked File Upload to OneDrive
This example demonstrates how to use the Uniface UHTTP component to upload a file to OneDrive by submitting a request to the OneDrive API.
To use the OneDrive API, you need to have an app to sign into. You must register your app and when you do, you receive an ID and a secret. The user must interactively sign in and enable and allow certain access levels. Further credentials are then obtained.
Users sign in with the REST API. The GET
and POST
methods can be used, and responses are in JSON.
For information about the OneDrive API, see https://developer.microsoft.com/en-us/onedrive
Upload a Large File to OneDrive, in Chunks
Note: This example does not show or document the
steps required to register your OneDrive application or the authentication protocol that is
required to obtain the access token. It assumes that the access token is assigned to a component
variable (vAccessToken
)
- Create an instance of the UHTTP component and set its processing flag to 15. This instructs UHTTP to ignore host and peer verification, and send headers on all methods when the SEND operation is used.
- Specify the location and file to upload.
- Get the size of the file. This is needed in
order to specify the
Range
header.In this example,
POST
is used to create a session for the download and obtain information such as the upload URL. The information is returned in JSON. - You need to declare a chunked file upload to
OneDrive by creating an upload session using the URL
https://api.onedrive.com/v1.0/drive/root:/file:/upload.createSession
. You will need to set authorization headers. - Send the request for a chunked upload session to OneDrive using the SEND operation.
variables ; Component variables: ; handle vUhttp ; string vAccessToken string vFileDir, vFile, vCloudFile ; source and target information for upload file string vUrl, vContents, vMethod, vResponseStatus ; parameters for SEND operation string vSendStatus, vFileStatus ; status variables for error handling struct vReply endvariables ; Create UHTTP instance and set its processing flags newinstance "UHTTP", $vUhttp$ $vUhttp$->SET_FLAGS(15) ; Specify the directory and file name to upload vFileDir = "<Upload Directory>" vFile = "<Very Big File>" vCloudFile = vFile ; Get the file size vContents = $fileproperties("%%vDirUsed%%%%%vFile", "FILESIZE") vTotal = "*" if (vContents[1,8] = "FILESIZE") vTotal = vContents[10, 99999] endif ; ********** Create an upload session ************** ; Prepare the SEND parameters to create a chunked upload session vUrl = $concat("https://api.onedrive.com/v1.0", "drive/root:/", vCloudFile, ":/upload.createSession") vMethod = "POST" vContents = "" vResponseStatus = "" vHeaders = "" putitem/id/case vHeaders, "Authorization", "Bearer %%$vAccessToken$" putitem/id/case vHeaders, "Host", "api.onedrive.com" putitem/id/case vHeaders, "Connection", "Keep-Alive" putitem/id/case vHeaders, "Content-Length", "0" ; Send the request for a chunked upload session $vUhttp$->SEND(vUrl, vMethod, "", "", vHeaders, vContents, vResponseStatus) vSendStatus = $status ; Handle possible errors and define the target URL for the upload file if (vSendStatus < 0) putmess "Local error. $status=%%vSendStatus" else if (vSendStatus < 200 || vSendStatus > 299) putmess "Unexpected reply. %%vSendStatus%%% %%vContents" return else jsonToStruct vReply, vContents vUrl = vReply->uploadUrl endif endif ; ********** Upload the file ************** ; Define the chunk size vOptions = "chunk=320k" ; Upload the file, repeating for each chunk repeat ; load the file contents $vUhttp$->LOAD_FILE_CONTENTS("%%vFileDir%%%%%vFile", vOptions) vFileStatus = $status if (vFileStatus < 0) putmess "Could not load contents from file %%$status" return endif ; get the range $vUhttp$->GET_INFO("range", vRange) if ($status < 0) putmess "Could not get range of file chunk %%$status" return endif ; Add the total length vRange = $concat(vRange, "/", vTotal) ; Prepare the SEND parameters vMethod = "PUT" vContents = "" vResponseStatus = "" vHeaders = "" putitem/id/case vHeaders, "Authorization", "Bearer %%$vAccessToken$" putitem/id/case vHeaders, "Host", "api.onedrive.com" putitem/id/case vHeaders, "Content-Length", "%%vFileStatus" putitem/id/case vHeaders, "Content-Type", "application/octet-stream" putitem/id/case vHeaders, "Content-Range", "%%vRange" putitem/id/case vHeaders, "Connection", "Keep-Alive" ; Send the upload fragment $vUhttp$->SEND(vUrl, vMethod, "", "", vHeaders, vContents, vResponseStatus) vSendStatus = $status ; status 201 means finished and 202 is fragment received if (vSendStatus = 201 || vSendStatus = 202) jsonToStruct vReply, vContents if (vSendStatus = 202) vRange = vReply->nextExpectedRanges putmess "%%vSendStatus%%% nextExpectedRanges %%vRange" elseif (vSendStatus = 201) vCloudFile = vReply->name $vUhttp$->CLOSE_FILE() putmess "New file created %%vCloudFile%%%, %%(vReply->id)" break endif else putmess "Upload fragment error $status=%%vSendStatus" $vUhttp$->CLOSE_FILE() ; cancel the session return endif until (1 != 1) ; forever