5

Has anyone else been able to DELETE purge_everything with CFHTTP? I can't seem to get ColdFusion CFHTTP to successfully purge a CloudFlare zone's cache. But I am able to do other things like list zones, etc. So I know I can successfully CFHTTP to CloudFlare's API.

This is the curl command, which works:

curl -svX DELETE -H 'X-Auth-Email: a@b.c' -H 'X-Auth-Key: XYZ' https://api.cloudflare.com/client/v4/zones/xxxxxxx/purge_cache  -H 'Content-Type: application/json' --data '{"purge_everything":true}'

The error returned is:

{"success":false,"errors":[{"code":1012,"message":"Request must contain one of \"purge_everything\" or \"files\", or \"tags"}],"messages":[],"result":null}

I've tried so many combinations of code... these are the different variables I've tried:

<cfset stFields = '{"purge_everything":true}'>
<cfset stFieldsJson = {"purge_everything":true}>
<cfset stFieldsJson2 = {
    "fields" : {
        "purge_everything"  : true
    }
}>  
<cfset stFieldsJson3 = {
    "purge_everything"  : true,
    "fields" : {
        "purge_everything"  : true
    }
}>  

<cfset tmp = {} />
<cfset tmp['purge_everything'] = true />

... and here are some different combinations of calls I've made...

<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare"  charset="utf-8">
    <cfhttpparam type="header" name="X-Auth-Email" value="a@b.c">
    <cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
    <cfhttpparam type="header" name="Content-Type"  value="application/json; charset=utf-8">
    <cfhttpparam type="header" name="accept"  value="*/*">
    <cfhttpparam type="body" value="#serializeJson(stFieldsJson)#" encoded="false">
</cfhttp>   
<cfdump var="#cFlare#"><Cfflush>

<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare"  charset="utf-8">
    <cfhttpparam type="header" name="X-Auth-Email" value="a@b.c">
    <cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
    <cfhttpparam type="header" name="Content-Type"  value="application/json; charset=utf-8">
    <cfhttpparam type="header" name="accept"  value="*/*">
    <cfhttpparam type="body" value="#serializeJson(stFieldsJson2)#" encoded="false">
</cfhttp>   
<cfdump var="#cFlare#"><Cfflush>

<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare">
    <cfhttpparam type="header" name="X-Auth-Email" value="a@b.c">
    <cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
    <cfhttpparam type="header" name="Content-Type"  value="application/json">
    <cfhttpparam type="header" name="accept"  value="*/*">
    <cfhttpparam type="body" value="#serializeJson(stFieldsJson3)#" encoded="false">
</cfhttp>   
<cfdump var="#cFlare#"><Cfflush>

<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare">
    <cfhttpparam type="header" name="X-Auth-Email" value="a@b.c">
    <cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
    <cfhttpparam type="header" name="Content-Type"  value="application/json">
    <cfhttpparam type="header" name="accept"  value="*/*">
    <cfhttpparam type="body" value="#serializeJson(tmp)#" encoded="false">
</cfhttp>   
<cfdump var="#cFlare#"><Cfflush>

<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare"  charset="utf-8">
    <cfhttpparam type="header" name="X-Auth-Email" value="a@b.c">
    <cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
    <cfhttpparam type="header" name="Content-Type"  value="application/json; charset=utf-8">
    <cfhttpparam type="header" name="accept"  value="*/*">
    <cfhttpparam type="body" value='{"purge_everything":true}' encoded="false">
</cfhttp>   
<cfdump var="#cFlare#"><Cfflush>

<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare"  charset="utf-8">
    <cfhttpparam type="header" name="X-Auth-Email" value="a@b.c">
    <cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
    <cfhttpparam type="header" name="Content-Type"  value="application/json; charset=utf-8">
    <cfhttpparam type="header" name="accept"  value="*/*">
    <cfhttpparam type="body" value='"purge_everything":true' encoded="false">
</cfhttp>   
<cfdump var="#cFlare#"><Cfflush>

<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare"  charset="utf-8">
    <cfhttpparam type="header" name="X-Auth-Email" value="a@b.c">
    <cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
    <cfhttpparam type="header" name="Content-Type"  value="application/json; charset=utf-8">
    <cfhttpparam type="header" name="accept"  value="*/*">
    <cfhttpparam type="body" value='purge_everything' encoded="false">
</cfhttp>   
<cfdump var="#cFlare#"><Cfflush>

I've also tried with and without the 'Encoded' Body attribute, with and without the 'Charset' attribute in all places.

Any help is appreciated.

Jules
  • 1,941
  • 15
  • 18
  • Where did you get the zone identifier from? No Idea what to replace it with or where I find the info for it https://api.cloudflare.com/client/v4/zones/:identifier/purge_cache – Lion789 Jul 05 '16 at 06:01

2 Answers2

2

Not sure which version of CF you are running. However, I suspect you are not doing anything wrong, but that <cfhttp> simply is not sending a body when the method="DELETE", which would make sense given the error message.

A simple way to test it is point your <cfhttp> call to a test page on your local CF server. On the test page dump GetHttpRequestData() so you can view the actual headers and content submitted. (Another option is to use the built in TCPMonitor on an open port, which provides more detail about both request and response. However, for this scenario, the first method is simplest.)

Test Page

<!--- echo request headers and content --->
<cfdump var="#getHTTPRequestData()#">

Request

<!--- simulate request --->
<cfset requestBody["purge_everything"] =  true>
<cfhttp url="http://localhost/testPage.cfm" method="DELETE" result="cFlare"  charset="utf-8" >
    <cfhttpparam type="header" name="X-Auth-Email" value="a@b.c">
    <cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
    <cfhttpparam type="header" name="Content-Type"  value="application/json; charset=utf-8">
    <cfhttpparam type="header" name="accept"  value="*/*">
    <cfhttpparam type="body" value="#serializeJson(requestBody)#" encoded="false">
</cfhttp>  

<!--- display request headers and content --->
<cfoutput>#cFlare.fileContent#</cfoutput>

Notice the content, or body, is empty when method="DELETE"? However, change it to method="POST" and the content magically appears.

GetHttpRequestData() - Method=DELETE

Sending a body with a DELETE request should be valid, so it sounds like a bug. If so, you will need to find a different tool to make the http request, such as invoking curl.exe from cfexecute, or using a custom tag like cfx_http5, or use java classes like as URLConnection or Apache's HTTPClient.

Community
  • 1
  • 1
Leigh
  • 28,765
  • 10
  • 55
  • 103
  • Good sleuthing, and thank you for the suggested workarounds. After posting my question I worked more on it and came to the same conclusion as you - CFHTTP won't post a body when the method is DELETE. – Jules Feb 12 '16 at 13:53
  • 1
    Yes, it sounds like it is not explicitly verboten, so it would be nice if there was some indication cfhttp intends to just ignore the body. At least then folks would not be scratching their heads wondering what went wrong... – Leigh Feb 12 '16 at 15:50
0

After reading up on some docs, it appears that the CloudFlare API is mixing methods in a way that CFHTTP will not.

CloudFlare's API states to use the DELETE method and content type header of "application/json". Their exact example is:

$ curl -X DELETE "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'

However when one uses --data, curl will POST with content-type application/x-www-form-urlencoded. https://curl.haxx.se/docs/manpage.html#-d

CFHTTP however is following specs. POST is used to send data. DELETE is for deleting the URI.

When I CFHTTP with POST I get an error that only DELETE is accepted for the URI. When I CFHTTP with DELETE, no content is being POSTed.

My workaround, without going out of standard CFML, was to use their v1 API. It's working like a champ. https://www.cloudflare.com/docs/client-api.html

Jules
  • 1,941
  • 15
  • 18
  • Where did you get the zone identifier from no idea where to look? – Lion789 Jul 05 '16 at 06:04
  • You first list all your zones: https://api.cloudflare.com/#zone-list-zones From there you find the domain and it's zone id. – Jules Jul 06 '16 at 14:14