restcoldfusiongoogle-cloud-storagecloudtls1.2

Upload pdf file to GCS with REST API - Coldfusion


I'm trying to upload a pdf file to GCS REST API with Coldfusion. My code is as follows. I get the same error every time. When I try a png file instead of a pdf, it works fine.

<cffunction name="uploadFileToCloudStorage" access="remote" returnformat="JSON" returntype="any">
    <cfargument name="bucket_name" default="" />
    <cfargument name="object_name" default="" />
    <cfargument name="object_location" default=""/>
    <cfargument name="object_content_type" default="application/pdf" />
    <cfargument name="access_token" required="true" />
        
    <cffile action="readBinary" file="#arguments.object_location#" variable="fileContent">
        
    <cfset endpoint = "https://storage.googleapis.com/upload/storage/v1/b/#arguments.bucket_name#/o?name=#arguments.object_name#&uploadType=media" />

    <cfhttp result="result" method="POST" charset="utf-8" url="#endpoint#" timeout="60">
        <cfhttpparam type="header" name="Content-Type" value="#arguments.object_content_type#" />
        <cfhttpparam type="header" name="Authorization" value="Bearer #arguments.access_token#" />
        <cfhttpparam type="body" value="#fileContent#" />
    </cfhttp>
    <cfreturn replace(serializeJSON(result), '//', '') />
</cffunction>

The result is:

{
    "Mimetype": "Unable to determine MIME type of file.",
    "Errordetail": "I/O Exception: Received fatal alert: record_overflow",
    "Filecontent": "Connection Failure",
    "Statuscode": "Connection Failure.  Status code unavailable.",
    "Responseheader": {},
    "Text": true,
    "Charset": "",
    "Header": ""
}

for the first time. If i try again, the result is:

{
    "Mimetype": "Unable to determine MIME type of file.",
    "Errordetail": "I/O Exception: Connection reset",
    "Filecontent": "Connection Failure",
    "Statuscode": "Connection Failure.  Status code unavailable.",
    "Responseheader": {},
    "Text": true,
    "Charset": "",
    "Header": ""
}

I tried base64 and the result is the same. I tried read instead of readBinary with cffile and the result is still the same.


Solution

  • It is a TLS problem. When I add these two lines of code, it worked:

    <cfset security = createObject("java", "java.lang.System") />
    <cfset security.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2") />
    

    Full code:

    <cffunction name="uploadFileToCloudStorage" access="remote" returnformat="JSON" returntype="any">
        <cfargument name="bucket_name" default="" />
        <cfargument name="object_name" default="" />
        <cfargument name="object_location" default=""/>
        <cfargument name="object_content_type" default="" />
        <cfargument name="access_token" required="true" />
    
        <cfset fileContent = FileReadBinary('#arguments.object_location#') />
        
        <cfset endpoint = "https://storage.googleapis.com/upload/storage/v1/b/#arguments.bucket_name#/o?uploadType=media&name=#arguments.object_name#" />
    
        <cfset security = createObject("java", "java.lang.System") />
        <cfset security.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2") />
        
        <cfhttp result="result" method="POST" charset="utf-8" url="#endpoint#" timeout="60">
            <cfhttpparam type="header" name="Authorization" value="Bearer #arguments.access_token#" />
            <cfhttpparam type="header" name="Content-Type" value="#arguments.object_content_type#" />
            <cfhttpparam type="body" value="#fileContent#" />
        </cfhttp>
    
        <cfreturn result />
    </cffunction>