Copy link to clipboard
Copied
I have been evaluating CF 2016 before purchasing to upgrade our server.
One of the key interactions we have always had was between CF and ActivePDF Toolkit.
I have spoken with ActivePDF support, and they have recreated the same issue I am reporting here with CF 2016.
After using the ActivePDF Toolkit function "Get_OutputByteStream" to put the manipulated PDF into a binary data variable (variable name "pdf"), I then pass that variable into CFCONTENT to display it in the user's browser.
<cfcontent type="application/pdf" variable="#pdf#">
However, the result is now a CF error page which says:
"[S is not a supported variable type. The variable is expected to contain binary data."
It has been verified that Get_OutputByteStream in ActivePDF is creating a good PDF by writing the variable named "pdf" to a pdf file on the server.
As a side note, I also noticed and verified with ActivePDF that CF 2016 cannot seem to handle COM properly, so I have to used the .NET integration in working with ActivePDF Toolkit. That is not a big deal but worth mentioning. However, no workaround can be found for the CFCONTENT issue mentioned above.
We have always used CFOBJECT to create the Toolkit object using the following code, which no longer works.
<CFOBJECT ACTION="Create"
TYPE="COM"
Class = APToolkit.Object
NAME="TK">
Copy link to clipboard
Copied
<cfcontent type="application/pdf" variable="#pdf#">
However, the result is now a CF error page which says:
"[S is not a supported variable type. The variable is expected to contain binary data."
Try
<cfcontent type="application/pdf" variable="#toBinary(pdf)#">
Copy link to clipboard
Copied
The "pdf" variable is already converted into Binary Data by ActivePDF by the time it gets to cfcontent, so using toBinary only has CF trying to make binary data of binary data. The result (abbreviated):
The parameter 1 of function ToBinary, which is now %PDF-1.5 %âãÏÓ 3 0 obj << /Type /ExtGState /CA 0.5 /ca 0.5>> endobj 301 0 obj << /Type /Catalog /Pages 30 0 R /Metadata 6 0 R /StructTreeRoot 31 0 R /MarkInfo 5 0 R >> endobj 302 0 obj << /Type /ObjStm /Length 2855 /First 1747 /N 200 /Filter /FlateDecode >> stream xœíšQo�¹r…ÿÊyL�"Ö©"‹$ ��}×»�V6#)@�
To demonstrate the variable is already binary data, if I just flat out dump the PDF variable on the page with <cfoutput>#pdf#</cfoutput> it will show this (abbreviated):
%PDF-1.5 %âãÏÓ 3 0 obj << /Type /ExtGState /CA 0.5 /ca 0.5>> endobj 301 0 obj << /Type /Catalog /Pages 30 0 R /Metadata 6 0 R /StructTreeRoot 31 0 R /MarkInfo 5 0 R >> endobj 302 0 obj << /Type /ObjStm /Length 2854 /First 1747 /N 200 /Filter /FlateDecode >> stream xœíšAo 9’…ÿÊ;Î VŒ A I@
Copy link to clipboard
Copied
Just curious. What does ActivePDF do that CF can't natively do when it comes to PDF creation/manipulation? It seems, to me, to be an unnecessary third-party library, unless it has features that CF PDF capabilities don't. I'm not entirely familiar with CFPDF or other CF processes for creating/changing/accessing PDF documents, so I'm asking to better understand why ActivePDF is so critical to your project.
V/r,
^_^
Copy link to clipboard
Copied
In our medical application, we are stamping patient information at various positions on a PDF. We can control positions the text goes, pages the stamping occurs, barcodes, etc. Many of these forms are manipulated and generated through Memory, so that the variable forms never touch our server storage. I have not seen where CFPDF has come of age to handle all of these type of things. We have had this medical application since CF7 making adjustments over time because of customer demand and CF server and ActivePDF Toolkit changes over time. CFCONTENT should be able to take binary data equivalent to a PDF file and render it in CFCONTENT through variable name.
ActivePDF Toolkit does far more than I mentioned above, and we use it for many other things. We have replaced a few ActivePDF Toolkit functions over time with CFPDF (very few), but it has happened before.
Copy link to clipboard
Copied
If the content is already in binary form then you could try
<cfheader name="Content-Disposition" value="inline; filename=myFile.pdf">
<cfcontent type="application/pdf" variable="#pdf#">
or
<cfset myPDF = binaryEncode(pdf,'base64')>
<cfheader name="Content-Disposition" value="inline; filename=myFile.pdf">
<cfcontent type="application/pdf" variable="#toBinary(myPDF)#">
Copy link to clipboard
Copied
When I try:
<cfheader name="Content-Disposition" value="inline; filename=myFile.pdf">
<cfcontent type="application/pdf" variable="#pdf#">
CF returns the error:
Attribute validation error for tag cfcontent. java.lang.String is not a supported variable type. The variable is expected to contain binary data.
As a note, if I output the #pdf# variable it looks like PDF binary data that leads with:
%PDF-1.5 %âãÏÓ 3 0 obj << /Type /ExtGState /CA 0.5 /ca 0.5>> endobj 301 0 obj << /Type /Catalog /Pages 30 0 R /Metadata 6 0 R /StructTreeRoot 31 0 R /MarkInfo 5 0 R >> endobj 302 0 obj << /Type /ObjStm /Length 2857 /First 1747 /N 200 /Filter /FlateDecode >>
When I try:
<cfset myPDF = binaryEncode(pdf,'base64')>
<cfheader name="Content-Disposition" value="inline; filename=myFile.pdf">
<cfcontent type="application/pdf" variable="#toBinary(myPDF)#">
CF returns the error:
Parameter 1 of the BinaryEncode function, which is now %PDF-1.5 %âãÏÓ 3 0 obj << /Type /ExtGState /CA 0.5 /ca 0.5>> endobj 301 0 obj << /Type /Catalog /Pages 30 0 R /Metadata 6 0 R /StructTreeRoot 31 0 R /MarkInfo 5 0 R >> endobj 302 0 obj << /Type /ObjStm /Length 2856 /First 1747 /N 200 /Filter /FlateDecode >> ----- several lines of binary data stuff ending with "must be a valid binary object."
I notice there is a space in the %PDF-1.5 % and wonder if that could be causing the problem for Coldfusion. Not sure how to remove it, as a standard ReplaceNoCase on the variable does not do it.
Copy link to clipboard
Copied
Odd. Let's rule out the fact that Coldfusion may be attempting to send the data to the browser while still writing it.
Test all of the suggestions we have given, and your own original code, but then adding a named lock:
<cflock name="pdfLock" type="exclusive" timeout="5">
<!--- code that creates the pdf variable --->
</cflock>
<cflock name="pdfLock" type="exclusive" timeout="5">
<!--- the cfcontent code --->
</cflock>
Copy link to clipboard
Copied
I tried your suggestion along with the variations previously mentioned.
ColdFusion is still giving the same error:
"Attribute validation error for tag cfcontent. java.lang.String is not a supported variable type. The variable is expected to contain binary data."
One thing I am doing before creating the CF variable with ActivePDF Toolkit is creating the PDF on the disk drive to verify it looks good in Adobe Reader. I have also, as I mentioned before, outputted the variable to see at least the beginning of the binary code.
At the moment the only oddity (other than the error) is that ActivePDF Toolkit is using "%PDF-1.5%" as the header on the file, if it is written from toolkit memory to disk drive but "%PDF-1.5 %" if written from toolkit memory to CF variable. I have read that it is recommended to C++ programmers that they should watch for a PDF header to always start with %PDF-1.X, where X can be various version numbers, so programmers often look for that to know the data that follows is a binary PDF. However, if Adobe Coldfusion is looking for %PDF-1.X% instead of just %PDF-1.X then that space could pose an issue.
I am trying to set up a call with ActivePDF on Monday afternoon to talk more about this issue.
I am not sure if anyone here knows how to slightly modify the binary data of a PDF to replicate this issue, but that could be helpful.
Copy link to clipboard
Copied
After opening 3 PDFs in a text editor, I can see a space - in fact a new line - in the header you mention. The files have these headers:
%PDF-1.4
%µµµµ
%PDF-1.3
%âãÏÓ
%PDF-1.5
%µµµµ
When I made the replacements %PDF-1.5%µµµµ and %PDF-1.5 %µµµµ in the third file, and saved the contents as two respective PDF files, I could open them in Adobe Reader. So I think the issue is caused by something else. I'm looking into it some more.
Copy link to clipboard
Copied
mahancm wrote:
When I try:
<cfheader name="Content-Disposition" value="inline; filename=myFile.pdf">
<cfcontent type="application/pdf" variable="#pdf#">
CF returns the error:
Attribute validation error for tag cfcontent. java.lang.String is not a supported variable type. The variable is expected to contain binary data.
What if you first write the contents to a file, then read off the PDF. For example,
<cffile action="write" file="#expandpath('pdfString.pdf')#" output="#pdf#" >
<cfheader name="Content-Disposition" value="attachment;filename=myfile.pdf" />
<cfcontent file="#expandpath('pdfString.pdf')#" type="application/pdf" />
Copy link to clipboard
Copied
Sorry for the delay with the holidays. I will be able to check on this in the next couple of days.
I know that I can write to a PDF with ActivePDF's function and then use CF to display that PDF to the user. However, I do not want to incur that I/O penalty in writing to the hard drive.
I will try your other alternative above and let you know. ActivePDF is still looking into it on their end as well over the next week and a half.
Copy link to clipboard
Copied
I tried your suggestion above and it created a PDF file of the exact size (in KB) as the ActivePDF function I called with Coldfusion to write a PDF from the ActivePDF Toolkit. However, the file created using your suggestion above could not be opened. Adobe Reader says it is damaged and not able to be repaired.
If I view the two PDF's in notepad side by side they look exactly the same as I scroll down to the bottom. At the very end there is one extra blank line after the %%EOF in the CFFILE generated PDF. I tried removing it because it was the only difference I could perceive, but it was the same result. I didn't check every binary symbol, but I did spot check beginning of lines and noted all the initial symbols were the same; they lined up perfectly.
I should hear something about ActivePDF support investigation of it later next week.
Copy link to clipboard
Copied
That brings me to another idea. What about just doing this (assuming there is nothing else on the page):
<cfheader name="Content-Disposition" value="inline; filename=myFile.pdf">
<cfheader name="Content-Type" value="application/pdf">
<cfoutput>#ToString(pdf)#</cfoutput>
Copy link to clipboard
Copied
In this suggestion (example):
<cfheader name="Content-Disposition" value="inline; filename=myFile.pdf">
<cfheader name="Content-Type" value="application/pdf">
<cfoutput>#ToString(pdf)#</cfoutput>
The file begins to launch Adobe Reader in the browser but complains: File does not begin with '%PDF-'
I am not entirely sure how we get from the PDF variable to getPageContext().getResponse() in your other example.
I would see the first part of it begin something like:
HttpServletResponse.setHeader("Content-Disposition", "attachment; filename=myfile.pdf");
response.setContentType("application/pdf");
Are we putting this code inside of <script></script>?
I will be out of the office the next few days, but will be back on Tuesday to recheck. I am hoping to hear something back from ActivePDF later next week as well.
Copy link to clipboard
Copied
In my last post, I meant something like this:
httpServletResponse = getPageContext().getResponse();
httpServletResponse.setHeader("Content-Disposition", "inline; filename=myDoc.pdf");
httpServletResponse.setContentType("application/pdf");
outputStream = httpServletResponse.getOutputStream();
etc.
But that is just another version of the code we have discussed so far, that is:
<cfheader name="Content-Disposition" value="inline; filename=myFile.pdf">
<cfcontent type="application/pdf" variable="#pdf#">
That should work! Otherwise there is likely a bug somewhere.
Copy link to clipboard
Copied
Hello
I would like to know whether we could get some assistance with regards to this issue. We are able to provide you with evaluation key of ActivePDF toolkit and the script that we have trouble with. So far, we have tested with Classic ASP as well ASP.net and C# applications. They all work. The issue is with ColdFusion.
Copy link to clipboard
Copied
Otherwise, we may have to start by considering pdf as an OutputByteStream. We could then use the Java method for sending the output from InputStream and OutputStream to the browser. In Coldfusion, the object javax.servlet.ServletResponse would then be getPageContext().getResponse().