Phil
Phil

Reputation: 4069

Convert this cuRL to CFHTTP - Azure NotificationHub

I'm trying to get push working from a ColdFusion script using the Azure REST API. There is a working PHP script located here and I have tried to convert the PHP to ColdFusion. Below is the code I have so far, and everything seems to be correct to me, I'm not getting any errors. However, the result in cfhttp.FileContent is just an empty string and I get no notification. can anyone point out my mistake?

    <cfset CONNECTION_STRING = "Endpoint=sb://mypushnamespacehere.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=mysharedaccesskeyhere">
    <cfset API_VERSION = "?api-version=2015-01">
    <cfset connectionStringParts = ListToArray(CONNECTION_STRING,';','YES')>
    <cfset ENDPOINT = "https" & #connectionStringParts[1].substring(11)#>
    <cfset HUBPATH = "myhubpathname">
    <cfset sasKEYNAME = #connectionStringParts[2].substring(20)#>
    <cfset sasKEYVALUE = #connectionStringParts[3].substring(16)#>

    <cfset URI = #ENDPOINT# & #HUBPATH# & "/messages" & API_VERSION>

    <cfset TARGET_URI = #Lcase(URLEncodedFormat(URI))#>
    <cfset EXPIRES = int(createObject('java', 'java.lang.System').currentTimeMillis()/1000)>
    <cfset EXPIRES_IN_MINS = 60>
    <cfset EXPIRES = EXPIRES + EXPIRES_IN_MINS * 60>

    <cfset TO_SIGN = #TARGET_URI# & Chr(13) & Chr(10) & #EXPIRES#>
    <cfset SIGNATURE_HMAC = #HMAC(TO_SIGN, sasKEYVALUE, 'HmacSHA256')#>
    <cfset SIGNATURE = #EncodeForURL(binaryEncode(binaryDecode(SIGNATURE_HMAC, 'hex'), 'base64'))#>

    <cfset TOKEN = "SharedAccessSignature sr=" & #TARGET_URI# & "&sig=" & #SIGNATURE# & "&se=" & #EXPIRES# & "&skn=" & #sasKEYNAME#>

    <cftry>
        <!--- Create our requestBody --->
        <cfset requestBody = '{
                                "data" : {
                                    "message" : "Hello from ColdFusion"
                                    }
                                }'>
        <!--- Send Push --->
        <cfhttp method="post" url="#URI#">    
            <cfhttpparam type="header" name="Authorization" value="#TOKEN#">
            <cfhttpparam type="header" name="Content-Type" value="application/json">    
            <cfhttpparam type="header" name="ServiceBusNotification-Format" value="gcm">
            <cfhttpparam type="body" encoded="false" value="#trim(requestBody)#">
        </cfhttp>   
        <!--- Parse JSON Response to determine if call was successful --->
        <cfdump var=#cfHttp.FileContent#>
    <!--- Catch any errors, return false --->
    <cfcatch type="any">
        <cfdump var=#cfcatch#>
    </cfcatch>
    </cftry> 

UPDATE

I tested using the SIGNATURE that the PHP script generates and it worked from ColdFusion. So it is something with the way I'm generating the SIGNATURE variable that is not matching up to how PHP generates it.

Here is what PHP does...

$targetUri = strtolower(rawurlencode(strtolower($uri)));
$expires = time();
$expiresInMins = 60;
$expires = $expires + $expiresInMins * 60;
$toSign = $targetUri . "\n" . $expires;

$signature = rawurlencode(base64_encode(hash_hmac('sha256', $toSign, $this->sasKeyValue, TRUE)));

$token = "SharedAccessSignature sr=" . $targetUri . "&sig=" . $signature . "&se=" . $expires . "&skn=" . $this->sasKeyName;

Upvotes: 2

Views: 195

Answers (1)

Phil
Phil

Reputation: 4069

Figured it out. In PHP, the "\n" for a newline works fine, but when I was converting it over to ColdFusion I was using Chr(13) & Chr(10). Took the Chr(13) out and only used Chr(10) and it works great now.

Updated

<cfset TO_SIGN = TARGET_URI & Chr(13) & Chr(10) & EXPIRES>

to

<cfset TO_SIGN = TARGET_URI & Chr(10) & EXPIRES>

Upvotes: 3

Related Questions