getting pdf with cfhttp throwing base64 error [duplicate] - coldfusion

I have a URL that goes to a pdf file. In my coldfusion page, I want to allow the user to download the file (using the open/save dialog or however that particular browser handles it).
This is the code I have so far:
<cfset tempFile = getTempFile(getTempDirectory(), 'testfile') />
<cfhttp url="myUrl/myFile.pdf" method="get" file="#tempFile#"/>
<cfheader name="Content-Disposition" value="attachment; filename=myFile.pdf">
<cfcontent type="application/pdf" file="#tempFile#">
This seems to work... but when I try to open the file it tells me something's wrong with the file. What am I doing wrong?

file attribute: Do not specify the path to the directory in this attribute; use
the path attribute.
Try separating the file name and path:
<!--- hard coded for clarity --->
<cfhttp url="http://www.somesite.com/path/testFile.pdf"
method="get"
getAsBinary="yes"
path="c:/test/"
file="testFile.pdf"/>
<cfheader name="Content-Disposition" value="attachment; filename=myFile.pdf" />
<cfcontent type="application/pdf" file="c:/test/testFile.pdf" />
For smaller files you might skip the temp file and use <cfcontent variable..>
<cfhttp url="http://download.macromedia.com/pub/documentation/en/coldfusion/mx7/cfmx7_cfml_qref.pdf"
method="get"
getAsBinary="yes" />
<cfheader name="Content-Disposition" value="attachment; filename=myFile.pdf" />
<cfcontent type="application/pdf" variable="#cfhttp.fileContent#" />
Update: Dynamic example using a temp file
<cfset tempDir = getTempDirectory() />
<cfset tempFile = getFileFromPath(getTempFile(tempDir, "testfile")) />
<!--- uncomment to verify paths
<cfoutput>
tempDir = #tempDir#<br />
tempFile = #tempFile#<br />
</cfoutput>
<cfabort />
--->
<cfhttp url="http://download.macromedia.com/pub/documentation/en/coldfusion/mx7/cfmx7_cfml_qref.pdf"
method="get"
getAsBinary="yes"
path="#tempDir#"
file="#tempFile#" />
<cfheader name="Content-Disposition" value="attachment; filename=myFile.pdf" />
<cfcontent type="application/pdf" file="#tempDir#/#tempFile#" />

As far as I know, your coding is fine in Google Chrome. In IE, error message prompt. It's because of "file path" cannot support for URL path. Should use directory path instead of URL path.

Related

How to download a pdf file from Dropbox API response

I am getting a response from Coldbox API in ColdFusion but I am unable to convert this response to PDF in Coldfusion. I have attached an image of the response below.
Here is my code:
<cfhttp result="get" method="POST" url="https://content.dropboxapi.com/2/files/download" getAsBinary="yes" >
<cfhttpparam type="header"name="Authorization" value="#token#">
<cfhttpparam type="header" name="Dropbox-API-Arg" value="#serializeJSON(pathData)#">
</cfhttp>
<cfheader name="content-disposition" value="inline; filename=test.pdf" />
<cfheader name="content-transfer-encoding" value="binary" />
<cfcontent type="application/pdf" variable="#get.Filecontent#" reset="true" />
I want to Hit API and download the file in next tab.
Let me know If anyone can help me to fix that issue.
Thanks.

How to return cfdocument pdf file and server to the user in the browser?

I have function that will generate cfdocument pdf file. Then I would like to return the document and server to the browser. Here is example of the function that generates the pdf file.
<cftry>
<cfdocument format="PDF" filename="file.pdf" overwrite="Yes">
<table>
<tr>
<td>Test</td>
</tr>
</table>
</cfdocument>
<cfset local.fnResults = {file: //Here I'm not sure what I should return}>
<cfcatch type="any">
<cfset local.fnResults = {status : 400, message : "Error! Something went wrong."}>
</cfcatch>
</cftry>
<cfreturn fnResults>
Function above should genrate the file and return PDF in fnResults structure. Then on serve.cfm I have this logic:
<cfset local.Results = genertePDF()>
<cfif structKeyExists(local.Results, "FILEPATH")>
<cfheader name="content-disposition" value="attachment;filename=#local.Results["FILENAME"]#"/>
<!---Add the file content to the output stream:--->
<cfcontent file="#local.Results["FILEPATH"]#" type="application/octet-stream" reset="true"/>
<!---Exit immediately after adding the file content to avoid corrupting it:--->
<cfabort/>
<cfif>
You can ignore the structure of RESULTS since I haven't modified everything. My only problem here is to figure out how to return cfdocument content? If anyone knows how to get this to work please let me know. Thank you.
Change:
<cfheader name="content-disposition" value="attachment;filename=#local.Results["FILENAME"]#"/>
To:
<cfheader name="content-disposition" value="inline;filename=#local.Results["FILENAME"]#"/>
Reference

How do I impove this small caching script

I am getting a list of product ID periodically, and I call these dynamic pages using cfhttp and save the received response as html file in root folder
my script may look like
<cfloop list="#productlist# index="productid" >
<cfhttp url="//domainname.com" result="result" charset="utf-8">
<cfhttpparam type="formfield" name="productid" value="#productid#">
</cfhttp>
<cfset content = result.filecontent>
<cffile action="write" file="#filename#" output="#trim(content)#" />
</cfloop>
Is there any better or optimized way to achive this result?

Error with multiple PDF Generation in CF

I'm getting an error when producing a multi-page PDF.
The pages attribute is not specified for the MERGE action in the cfpdf tag.
The line that is causing the issue is: <cfpdf action="merge" source="#ArrayToList(variables.pdfList)#" destination="promega.pdf" overwrite="yes" />
I tried looking in Adobe's documentation bug cannot find an attribute pages for the merge action. Thoughts?
<!--- Append PDF to list for merge printing later --->
<cfset ArrayAppend(variables.pdfList, "#expandPath('.')#\general.pdf") />
<cfset variables.userAgenda = GetAttendeeSchedule(
variables.event_key,
variables.badgeNum
) />
<!--- Field CFID is the id of the agenda item; use this for certificate selection --->
<cfif variables.userAgenda.recordcount>
<cfloop query="variables.userAgenda">
<cfset variables.title = Trim(variables.userAgenda.CUSTOMFIELDNAMEONFORM) />
<cfpdfform source="#expandPath('.')#\promega_certificate.pdf" destination="#cfid#.pdf" action="populate">
<cfset variables.startdate = replace(CUSTOMFIELDSTARTDATE, "T", " ") />
<cfpdfformparam name="WORKSHOP" value="#variables.title#">
<cfpdfformparam name="NAME" value="#variables.badgeInfo.FirstName# #variables.badgeInfo.LastName#">
<cfpdfformparam name="STARTDATE" value="#DateFormat(variables.startdate, "medium" )#">
</cfpdfform>
<!--- Append PDF to list for merge printing later --->
<cfset ArrayAppend(variables.pdfList, "#expandPath('.')#\#cfid#.pdf") />
</cfloop>
</cfif>
<cfif ArrayLen(variables.pdfList)>
<cfpdf action="merge" source="#ArrayToList(variables.pdfList)#" destination="promega.pdf" overwrite="yes" />
<!--- Delete individual files --->
<cfloop list="#ArrayToList(variables.pdfList)#" index='i'>
<cffile action="delete" file="#i#" />
</cfloop>
<cftry>
<cffile action="delete" file="#expandPath('.')#\general.pdf" />
<cfcatch></cfcatch>
</cftry>
<cfheader name="Content-Disposition" value="attachment;filename=promega.pdf">
<cfcontent type="application/octet-stream" file="#expandPath('.')#\promega.pdf" deletefile="Yes">
<cflocation url="index.cfm" addtoken="false" />
</cfif>
This happens when source is a single file rather than a comma separated list of files. I'm guessing that if it's a single file is is expecting to extract some pages rather than add.
I tried the following on my coldfusion 9 machine and it worked just fine:
<cfset strPath = GetDirectoryFromPath(GetCurrentTemplatePath()) />
<Cfset pdflist = arrayNew(1)>
<Cfset pdflist[1] = "#strPath#page1.pdf">
<Cfset pdflist[2] = "#strPath#page2.pdf">
<cfpdf action="merge" source="#ArrayToList(pdflist)#" destination="#strPath#merged.pdf" overwrite="yes" />
You could try to merge the pages like this and check whether you still get an error:
<cfset strPath = GetDirectoryFromPath(GetCurrentTemplatePath()) />
<Cfset pdflist = arrayNew(1)>
<Cfset pdflist[1] = "#strPath#page1.pdf">
<Cfset pdflist[2] = "#strPath#page2.pdf">
<cfpdf action="merge" destination="#strPath#merged.pdf" overwrite="yes">
<Cfloop from=1 to="#arraylen(pdflist)#" index="x">
<cfpdfparam source="#pdfList[x]#">
</cfloop>
</cfpdf>

Unwanted Facebook button at first time use of my FB application in coldfusion

I am playing around with facebook application, making them in iframe using coldfusion.
Following is the url of my app http://apps.facebook.com/firstones/
Instead of going directly going to the permissions page, it goes to the page shown below in picture.
And after clicking on that big 'Facebook' button it goes to ask for applications permission. And once permissions are granted it takes to my website, where I have hosted the application, instead of opening it in Facebook only.
Following is the code of my canvas url [http://www.dkyadav.com/firstOnes/auth/]
index.cfm
<cfparam name="client_id" default="1234"> <!---same as app_id --->
<cfparam name="redirect_uri" default="http://www.dkyadav.com/firstOnes/auth/">
<cfparam name="redirect_uri_final" default="http://www.dkyadav.com/firstOnes/">
<cfparam name="scope" default="user_education_history,user_hometown,friends_education_history ">
<cfparam name="client_secret" default="56789"> <!---- App_secret key ---->
<cfif not isdefined('url.code')>
<Cflocation url="https://www.facebook.com/dialog/oauth?client_id=#client_id#&redirect_uri=#redirect_uri#&scope=#scope#" >
<Cfelse>
<Cfif isdefined('url.error')>
<Cfoutput>
#url.error#<br />
Access denied.
</Cfoutput>
<cfelse>
<cfoutput>#url.code#<br />
<cfhttp url="https://graph.facebook.com/oauth/access_token" result="token">
<cfhttpparam name="client_id" value="#client_id#" encoded="no" type="url">
<cfhttpparam name="redirect_uri" value="#redirect_uri#" encoded="no" type="url">
<cfhttpparam name="client_secret" value="#client_secret#" encoded="no" type="url">
<cfhttpparam name="code" value="#url.code#" encoded="no" type="url">
</cfhttp>
<cflocation url="#redirect_uri_final#?#token.filecontent#" addtoken="no">
</cfoutput>
</Cfif>
</cfif>
And in http://www.dkyadav.com/firstOnes/index.cfm I look for access_token and have rest of my application.
I does the above said things only for the first time it run. Once its permission get approved, it works normally as expected.
You can try out this app running yourself http://apps.facebook.com/firstones/
Please help and let me know what I am actually missing. Thanks!!
I think the problem you have is that your initial display page on Facebook is actually bursting out of the iframe.
You can see the Javascript doing that on http://www.dkyadav.com/firstOnes/index.cfm in the fbLogin() function:
top.location.href = "https://graph.facebook.com/oauth/authorize?...
top refers to the window at the top of your window hierarchy which in your case will mean the actual Facebook home page with the iframe in it.
Hope that helps!
I think I dont need access_token, I just need oauth_token that I get by Decoding the result I got from submitting my client_id to 'https://www.facebook.com/dialog/oauth....'
Below is the code that I am using:
<cfif isdefined('signed_request')>
<cfoutput>
<cfset b64 = signed_request>
<!--- Split the param by the . --->
<cfset raw_str = ListGetAt(b64, 2, ".")>
<cfset res = Len(raw_str) % 4>
<cfif res eq 2>
<cfset raw_str &= "==">
<cfelseif res eq 3>
<cfset raw_str &= "=">
</cfif>
<!--- Base 64 Decode --->
<cfset result = ToString(BinaryDecode(raw_str, "Base64"))>
<!--- String to JSON --->
<cfset json = DeserializeJSON(result)>
<cfif StructKeyExists(json,'oauth_token')>
<Cfset at = json.oauth_token>
<cfhttp url="https://graph.facebook.com/me/friends?access_token=#at#" result="newsFeed" />
<cfif IsJSON(newsFeed.filecontent)>
<cfset cfData=DeserializeJSON(newsFeed.filecontent)>
<cfdump var = #cfData#>
<cfelse>
filecontent not in json format
</cfif>
<cfelse>
<script>
top.location.href='https://www.facebook.com/dialog/oauth?client_id=12345XXX&redirect_uri=http://apps.facebook.com/test_app/&scope=read_stream,email'
</script>
</cfif>
</cfoutput>
</cfif>