Sample code for 30+ languages & platforms
PureBasic

Google Drive - Resumable Upload

See more Google Drive Examples

Demonstrates how to do a resumable upload to Google Drive.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkJsonObject.pb"
IncludeFile "CkHttp.pb"
IncludeFile "CkUrl.pb"
IncludeFile "CkHttpRequest.pb"
IncludeFile "CkHttpResponse.pb"
IncludeFile "CkStringBuilder.pb"

Procedure ChilkatExample()

    success.i = 0

    ; This example requires the Chilkat API to have been previously unlocked.
    ; See Global Unlock Sample for sample code.

    success = 1

    ; This example uses a previously obtained access token having permission for the 
    ; Google Drive scope. 
    ; See Get Google Drive OAuth2 Access Token

    http.i = CkHttp::ckCreate()
    If http.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkHttp::setCkAuthToken(http, "GOOGLE_DRIVE_ACCESS_TOKEN")

    ; First we want to initiate the resumable upload.
    ; We send a POST to get a session URI, which will be used to upload the file, and resume if needed.

    ; Our POST will look like this:

    ; POST https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable HTTP/1.1
    ; Authorization: Bearer [YOUR_AUTH_TOKEN]          <-- Chilkat automatically adds this header because the AuthToken property was set.
    ; Content-Length: 38                               <-- Chilkat will automatically add this header.
    ; Content-Type: application/json; charset=UTF-8    <-- This is the type of this POST, and is specified in the call to HttpJson.
    ; X-Upload-Content-Type: application/zip           <-- The type of file we'll be uploading
    ; X-Upload-Content-Length: 1366807                 <-- The size of the file we'll be uploading
    ; 
    ; {
    ;   "name": "myObject"
    ; }

    CkHttp::ckSetRequestHeader(http,"X-Upload-Content-Type","application/zip")
    CkHttp::ckSetRequestHeader(http,"X-Upload-Content-Length","1366807")

    json.i = CkJsonObject::ckCreate()
    If json.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkJsonObject::ckUpdateString(json,"name","myZip")

    resp.i = CkHttpResponse::ckCreate()
    If resp.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkHttp::ckHttpJson(http,"POST","https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable",json,"application/json",resp)
    If success = 0
        Debug CkHttp::ckLastErrorText(http)
        CkHttp::ckDispose(http)
        CkJsonObject::ckDispose(json)
        CkHttpResponse::ckDispose(resp)
        ProcedureReturn
    EndIf

    statusCode.i = CkHttpResponse::ckStatusCode(resp)
    If statusCode <> 200
        Debug CkHttpResponse::ckBodyStr(resp)
        Debug "response status = " + Str(statusCode)
        CkHttp::ckDispose(http)
        CkJsonObject::ckDispose(json)
        CkHttpResponse::ckDispose(resp)
        ProcedureReturn
    EndIf

    ; The session URI is in the "Location" response header:
    sbSessionUri.i = CkStringBuilder::ckCreate()
    If sbSessionUri.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkStringBuilder::ckAppend(sbSessionUri,CkHttpResponse::ckGetHeaderField(resp,"Location"))
    sessionUri.s = CkStringBuilder::ckGetAsString(sbSessionUri)
    Debug "Session URI: " + sessionUri

    ; Here's a sample session URI:  https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=AEnB2UrszR8lDqlo3mtXJw_0rYI_Hi1oVh1NPFcLfoyBq9NcSjk85kFopoZaVEgT38OSmLl0XsObPf4iCSJwHlrOvvIJQ_ckIQ

    ; -----------------------------------------------------------------------------
    ; The next step is to upload the file using the session URI:

    ; We'll send a PUT that looks like this:

    ; PUT https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
    ; Content-Length: 1366807
    ; Content-Type: application/zip
    ; 
    ; [BYTES 0-1366806]

    ; First remove the X-Upload-Content-Type and X-Upload-Content-Length request headers we specified earlier, so they don't get sent with subsequent requests.
    CkHttp::ckClearHeaders(http)

    ; Because the file is likely large, we'll use HttpSReq which allows to to pass an HTTP request object where the body can be streamed directly from a file.
    req.i = CkHttpRequest::ckCreate()
    If req.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkHttpRequest::setCkContentType(req, "application/zip")
    CkHttpRequest::setCkHttpVerb(req, "PUT")

    url.i = CkUrl::ckCreate()
    If url.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkUrl::ckParseUrl(url,sessionUri)

    CkHttpRequest::setCkPath(req, CkUrl::ckPathWithQueryParams(url))
    Debug "Path with Query Param: " + CkUrl::ckPathWithQueryParams(url)

    ; Specify that the request body is to be streamed directly from a file.
    success = CkHttpRequest::ckStreamBodyFromFile(req,"qa_data/zips/big.zip")
    If success = 0
        Debug CkHttpRequest::ckLastErrorText(req)
        CkHttp::ckDispose(http)
        CkJsonObject::ckDispose(json)
        CkHttpResponse::ckDispose(resp)
        CkStringBuilder::ckDispose(sbSessionUri)
        CkHttpRequest::ckDispose(req)
        CkUrl::ckDispose(url)
        ProcedureReturn
    EndIf

    success = CkHttp::ckHttpSReq(http,CkUrl::ckHost(url),CkUrl::ckPort(url),CkUrl::ckSsl(url),req,resp)
    If success = 0
        Debug CkHttp::ckLastErrorText(http)
        CkHttp::ckDispose(http)
        CkJsonObject::ckDispose(json)
        CkHttpResponse::ckDispose(resp)
        CkStringBuilder::ckDispose(sbSessionUri)
        CkHttpRequest::ckDispose(req)
        CkUrl::ckDispose(url)
        ProcedureReturn
    EndIf

    Debug CkHttpResponse::ckBodyStr(resp)
    Debug "response status = " + Str(CkHttpResponse::ckStatusCode(resp))

    ; Sample output:

    ; {
    ;  "kind": "drive#file",
    ;  "id": "1rx20i53eurtkVQ-RT7Ry8Ct85PgPYMET",
    ;  "name": "myZip",
    ;  "mimeType": "application/zip"
    ; }
    ; 
    ; response status = 200


    CkHttp::ckDispose(http)
    CkJsonObject::ckDispose(json)
    CkHttpResponse::ckDispose(resp)
    CkStringBuilder::ckDispose(sbSessionUri)
    CkHttpRequest::ckDispose(req)
    CkUrl::ckDispose(url)


    ProcedureReturn
EndProcedure