Solved

save a PDF file submitted from adobe reader to cfm

Posted on 2004-08-31
19
4,865 Views
Last Modified: 2013-12-24
I am trying to save a PDF file (which I am being passed from a adobe pdf submit service as I think a binary stream) in a browser, I just want the PDF to saved so I can attach it and email it.   What CFM should I use to retrieve the submitted pdf content in a binary and retain a  valid pdf file ?- I found the below code here as one answer but it is not doing binary stuff.  The problem I am having is that the pdf that I reconstruct is .close. looking but not valid; I think I see it is losing carriage returns or something it is not good please point me an the correct binary in statements...

I think I need to do what this person did but with CFM
http://www.experts-exchange.com/Web/WebDevSoftware/Q_21102554.html


<cfscript>
pc = GetPageContext();
req = pc.getRequest();
readerObj = req.getReader();

output = '';
line = readerObj.readLine();
while (isDefined("line")) {
        output = output & line;
        line = readerObj.readLine();
}
readerObj.close();
</cfscript>
<cfoutput>#output#
</cfoutput>

I also tried this but the content was empty?.....content [empty string]

<cfset x = GetHttpRequestData()>
<cfoutput><hr><cfdump var="#x#"><br></cfoutput>


struct
content [empty string]  
headers struct
ACCEPT image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/x-shockwave-flash, application/msword, application/vnd.ms-excel, */*  
ACCEPT-ENCODING gzip, deflate  
ACCEPT-LANGUAGE en-us  
CACHE-CONTROL no-cache  
CONNECTION Keep-Alive  
CONTENT-LENGTH 158289  
CONTENT-TYPE application/pdf  
COOKIE CFID=129137; CFTOKEN=45168361; SC_ID=; TOMANYATTEMPTMSG=  
USER-AGENT Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)  
 
method POST  
protocol HTTP/1.1  


0
Comment
Question by:madpuppy
  • 7
  • 5
  • 3
  • +1
19 Comments
 
LVL 1

Expert Comment

by:slushe
ID: 11956079
If I understand correctly, you want to catch an incoming binary stream into a PDF file.

This is very similar to when you want to store binary files in a mySql database (images, video, etc) field such as a BLOB, and then read it out and create a file out of it, except in reverse.

You will definitely have to use the cfcontent command.  Google "cfcontent examples" without the quotes to see the different ways of implementing:  I've included a few below, I think you'll know what you're looking for right away if you're already doing something this far out ;)



- - -

Example :

Returning MIME Content Types with Cold Fusion <CFCONTENT>

The <CFCONTENT> tag has two attributes. The mandatory TYPE attribute specifies which MIME Content Type is being returned by the current template. The optional FILE attribute dynamically inserts a file from the Web server into the output stream.

The following example demonstrates the use of <CFCONTENT> to output the image of an employee where the path to the image (i.e. C:\images\steve.jpeg) is stored in the field employees.photo:

<CFQUERY NAME="GetEmployeeImageFile" DATASOURCE="A2Zbooks">
     SELECT photo FROM employees
     WHERE employees.employeeid=#URL.employeeid#
</CFQUERY>
<CFCONTENT TYPE="image/jpeg" FILE="#GetEmployeeImageFile.photo#">


- - -

CF DOCS shows: http://www.edgewebhosting.net/cfdocs/CFML_Language_Reference/2_ColdFusion_Tags/lr2_022.htm

that the cfcontent type tag is to set what kind of data is being returned.  Concievably, you should be able to pipe it inbound just as easily.

- - -

http://www.mail-archive.com/cf-list@kcfusion.org/msg01540.html seems to have a good dialogue too that might be helpful

Hope that helps,
s
0
 

Author Comment

by:madpuppy
ID: 11957407
Well I guess I could look at blob processing and see if it is the same it is kinda like fetching a pdf from a blob, I have done all that before in a query except it the pdf stream is arriving from  a post from a submit button that is sent from the inside of a pdf form when you set up a pdf form button you can have it submit the whold pdf to the url, I have no other control over the post.  This code works but the file it builds is no longer a good pdf file becasue of the line by line processing ruins the pdf comming in.

<cfscript>
pc = GetPageContext();
req = pc.getRequest();
readerObj = req.getReader();

output = '';
line = readerObj.readLine();
while (isDefined("line")) {
        output = output & line;
        line = readerObj.readLine();
}
readerObj.close();
</cfscript>
<cfoutput>#output#
</cfoutput>

In any case I have given up on this and now I am submitting the form as html and builidng a fdf from the submit and now merging this on the server to a new flattened pdf and emailing that pdf back. I seems to work fine. but still it would nice to know how to get the content correctly I will try putting in into CFCONTENT with like a readerObj.readAll();  I am  not very good at java io servlet command stuff

 
0
 

Author Comment

by:madpuppy
ID: 11957422
I will be gone for a few days but I would love to see if anyone has a good command for getting the
readerObj content  into a var for processing...
0
 
LVL 1

Expert Comment

by:slushe
ID: 11960019
Yeah, as I thought about it over the day (done a lot of PDF/cf stuff last few months), you could treat the variable of what the post returns via cfhttp (or using the code you already have in cfscript) like you would a blob variable.  Just set the variable type, and then pipe the stream into a file.

I'd probably use something a bit more robust than cfhttp.  I like cfhttp5 a lot, it does multithreaded requests and doesn't bog down. Concievably, using something like that, you could take the returned byte stream from the POST, pipe it straight into a variable, throw the cfcontent declaration on it, and save it to a file, or a db if you so chose.  Nice way to pull a lot of pdfs off a site, or automatically store a pdf that is generated for you.

If you're away for a few days -- I'll be looking at this PDF stuff this weekend for another project I'm working on, I'll post anything more that would help towards a proof of concept.  This should work without any pitfalls, as CF generally excels in this kind of stuff.
0
 

Author Comment

by:madpuppy
ID: 12021273
now I guess the question more defined is how to pipe the raw stream out from java.io  req.getReader(); and into that blob var using cfcontent or  cfhttp....not using readline() cause it messes it up, my work around seems cheesy but works.
0
 
LVL 1

Expert Comment

by:slushe
ID: 12023529
is there a reason you can't dump the req.getReader straight into a variable in cf, set the cfcontent type, and then write the field out to a file so the integrity is maintained.

If you could share the pdf outputter, I wouldn't mind trying it out just to make it work..

0
 

Author Comment

by:madpuppy
ID: 12031673
I tried that using cfcontent  with type = application/pdf and it was not working for me, what is the best way to share the pdf putputter ? it is just a test "coffee survey" document made as a simple pdf form with sampling of a type in text, radio and checkbox then a button that submits/mouse up posts action to a website url and cfm file indicated with the full pdf option radio checked. You would have to change the url and work your own .cfm to work this. the cfm you saw from what I posted above but the output is not a valid pdf anymore. let me know thank you!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12031885
You posted a pointer to this in the Java TA. Not familiar with CF, but do i take it that you can include Java code?
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 86

Expert Comment

by:CEHJ
ID: 12031957
Well for the moment, i'll assume that the answer to that is yes, as i don't want to have to save the example i've just written ;-) You can't use a Reader, as a pdf file is 'binary' and character decoding will trash the file.

InputStream in = request.getInputStream();
final int BUF_SIZE = 1 << 10 << 3; // 8k buffer
byte[] buffer = new byte[BUF_SIZE];
int bytesRead = 0;
FileOutputStream out = new FileOutputStream("x.pdf");
while ((bytesRead = in.read(buffer)) > -1) {
      out.write(buffer, 0, bytesRead);
}
in.close();
out.close();
0
 

Author Comment

by:madpuppy
ID: 12032382
Nope I do not think I can write NATIVE java but I do think you are getting me closer getting me away from readerObj thanks.. I looked around and I think I can do some things like these examples...

http://cephas.net/blog/2003/06/

http://www.houseoffusion.com/cf_lists/index.cfm?method=messages&threadid=24306&forumid=4

below is what I tried,  but again i am in deep unfamiliar water this is what I tried and I got errors only..

<cfscript>
pc = GetPageContext();
req = pc.getRequest();
inputsr  = req.getInputStream();

// get a BufferedReader object
input = CreateObject("java", "java.io.BufferedReader");

// call the BufferedReader constructor
input.init(inputsr);


output = '';
// loop over result by reading line by line
run = true;
while (run) {
   // read the result line by line
   resultLine = input.readLine();
   if (len(resultLine) GT 0) {
      output = output & resultLine;
   } else {
      run = false;
   }
}  

</cfscript>

I am not at all sure that this inputsr  = req.getInputStream();
is a valid command...
0
 

Author Comment

by:madpuppy
ID: 12032439

I found this page on what I can do with JAVA and CFML but this is hurting my SQL brain - I need an expert !


http://livedocs.macromedia.com/coldfusion/6/Developing_ColdFusion_MX_Applications_with_CFML/Java5.htm#1160838
0
 
LVL 5

Expert Comment

by:Daij-Djan
ID: 12033649
Buffer it using a BufferedReader and then output it all at once
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12034009
As i mentioned earlier, Java Readers should *not* be used. I'm not familiar with CF/Java interaction, but wrapping the code i gave you in a simple bean-like Java class will probably be easiest
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 444 total points
ID: 12034067
You can use this wrapper class. You'll need to call (or maybe set bean-like properties) setDestinationFile with the path to the file you need to save and setInputStream with the request's input stream. I'll let you do the CF tags ;-)



public class FileCopier {
      private InputStream in;
      private String destinationFile;
      
      public FileCopier(){}
      
      public void setInputStream(InputStream in) {
            this.in = in;
      }
      
      public void setDestinationFile(String destinationFile) {
            this.destinationFile = destinationFile;
      }
      
      public int copy() {
            FileOutputStream out = null;
            int bytesRead = 0;
            try {
                  final int BUF_SIZE = 1 << 10 << 3; // 8k buffer
                  byte[] buffer = new byte[BUF_SIZE];
                  
                  out = new FileOutputStream(destinationFile);
                  while ((bytesRead = in.read(buffer)) > -1) {
                        out.write(buffer, 0, bytesRead);
                  }
            }
            finally {
                  try {
                        in.close();
                        out.close();
                  }
                  catch(IOException e) {
                        /* ignore */
                  }
                  return bytesRead;
            }
      }
      
}
0
 
LVL 5

Expert Comment

by:Daij-Djan
ID: 12036385
AH :) sorry, didnt see you comment about readers
0
 

Author Comment

by:madpuppy
ID: 12036784
Ok No readers! granted that your code would work if I complie , get the server admin to put it where it should go and then  call it using cfobject setting the file to go to... but OHGAWD I hate to be difficult, but how can this be so much effort to get a post that you already have already in  GetPageContext();  out to a file ...This seems a bit over the top of something so basic like this. I might as well just do the fdf merge up on the server as it has less data traffic. I would have thought that someone else had tired this before and had a simple answer, one that did not require compiles and moving file to places that I do not have permission.  I also have GetPageContext.forward and .include available in cf.  Oh well, I will wait a bit and see if any other more CF based or script solutions arrive but if not then give it to you as it is an answer just not a simple snippet of script one I was expecting. :,(
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12037549
I'd be surprised too if there's no component you can use already. Have a look at this for instance:

http://www.devarticles.com/c/a/Cold-Fusion/Multiple-File-Upload-with-CFFILE/
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

This is a guide to setting up a new WHM/cPanel Server to be used for web hosting accounts. It is intended for web hosting company administrators and dedicated server owners. For under $99 per month (considering normal rate of Big Data Cetnters like …
Meet the world's only “Transparent Cloud™” from Superb Internet Corporation. Now, you can experience firsthand a cloud platform that consistently outperforms Amazon Web Services (AWS), IBM’s Softlayer, and Microsoft’s Azure when it comes to CPU and …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now