PDA

View Full Version : How to: Stream a pdf from the WebApp.exe to the browser?



Marco
27-Jul-2005, 02:29 AM
Hi all,

I've got a bunch of PDF documents that need to be downloadable from an
WebApp website, by clicking on a link.

This could be very simple, if I could just place these pdf files in an
'images' like directory and just create a href to the files.

Sadly enough, this is not good enough;
Lets say that the pdf's are insurance policy documents. Under no
circumstances should your document be available to others. Just long
unable to guess filenames could be an option, but still way to unsafe.

What I really need is a way, how I can direct_input the .pdf file in
the WO, then return the binary as a function_return, then in the asp,
it puts it in a variable and streams it to the client.

Is this possible? Can anybody give me a start?

Regards,
Marco Kuipers
South Australia

Ian Telfer
27-Jul-2005, 02:46 AM
Hi Marco,

What we do in one system where we need people to be able to do a similar
task is to send out a link to that person that it only valid for a short
period of time, the link they come back with has an encryption that gets
them just to that document. As the key is 32 chars in length, randomly
generated & only available for a short time, that may be enough.

Just a thought.

Ian

Marco Kuipers wrote:
> Hi all,
>
> I've got a bunch of PDF documents that need to be downloadable from an
> WebApp website, by clicking on a link.
>
> This could be very simple, if I could just place these pdf files in an
> 'images' like directory and just create a href to the files.
>
> Sadly enough, this is not good enough;
> Lets say that the pdf's are insurance policy documents. Under no
> circumstances should your document be available to others. Just long
> unable to guess filenames could be an option, but still way to unsafe.
>
> What I really need is a way, how I can direct_input the .pdf file in
> the WO, then return the binary as a function_return, then in the asp,
> it puts it in a variable and streams it to the client.
>
> Is this possible? Can anybody give me a start?
>
> Regards,
> Marco Kuipers
> South Australia
>

Marco
27-Jul-2005, 02:53 AM
Ian,

I was thinking about having the webapp.exe copy the pdf to a public
location, then sending the link back to the asp, have the asp redirect
to the url, then delete the file.

But still, timing issues are going to be a headache I think and I
would really really be happy if I can return the binary in my wo call.

The size of the PDF is about 30 to 50k.

Cheers,
Marco

starzen
27-Jul-2005, 06:34 AM
Marco

i havent done this with WA but in general you need to completely take over
the returning of data and change the content type of the return and then
return the data. if you telnet into a web server and download a PDF file
that way you can see what that would look like.


--
Michael Salzlechner
StarZen Technologies, Inc
http://www.starzen.com
DataFlex Addon products, consulting

Nick Wright
27-Jul-2005, 06:45 PM
Marco,

I would get the PDF file out of a SOAP Envelope, from a webservice, you
could then keep the pdf in a secure location, and authenticate each request
from the webservice against the client, the PDF file would of course be in a
BASE64 node of the xml. Then use the ASP to to directly output the contents
of the xml soap request.

I looked into this a short tyime ago knowing we will also need something
like this soon, I haven't tried it but I reckon it's possible.

There are tricks to convert Base64 in ASP, a snippet I kept is below, you
need to fill it out but the crucial bit is there:

<%
Set oDoc = Server.CreateObject("MSXML2.DOMDocument.4.0")
oDoc.async = false
oDoc.ValidateOnParse = false
:
:
Set oNode = oDoc.selectSingleNode("//def:GetImageAsBase64Result")
oNode.dataType = "bin.base64"
Response.ContentType="application/pdf"
Response.AddHeader "Content-Disposition", "filename=whatever.pdf"
Response.BinaryWrite oNode.nodeTypedValue
%>


Nick


"Marco Kuipers" <marco.kuipers@nci.com.au> wrote in message
news:jidee15krigkutgr20ahhv5lid1o59vj9a@4ax.com...
> Hi all,
>
> I've got a bunch of PDF documents that need to be downloadable from an
> WebApp website, by clicking on a link.
>
> This could be very simple, if I could just place these pdf files in an
> 'images' like directory and just create a href to the files.
>
> Sadly enough, this is not good enough;
> Lets say that the pdf's are insurance policy documents. Under no
> circumstances should your document be available to others. Just long
> unable to guess filenames could be an option, but still way to unsafe.
>
> What I really need is a way, how I can direct_input the .pdf file in
> the WO, then return the binary as a function_return, then in the asp,
> it puts it in a variable and streams it to the client.
>
> Is this possible? Can anybody give me a start?
>
> Regards,
> Marco Kuipers
> South Australia
>

Knut Sparhell
28-Jul-2005, 02:37 AM
Marco Kuipers wrote:

> I've got a bunch of PDF documents that need to be downloadable from an
> WebApp website, by clicking on a link.
>
> This could be very simple, if I could just place these pdf files in an
> 'images' like directory and just create a href to the files.
>
> Sadly enough, this is not good enough;
> Lets say that the pdf's are insurance policy documents. Under no
> circumstances should your document be available to others. Just long
> unable to guess filenames could be an option, but still way to unsafe.
>
> What I really need is a way, how I can direct_input the .pdf file in
> the WO, then return the binary as a function_return, then in the asp,
> it puts it in a variable and streams it to the client.
>
> Is this possible? Can anybody give me a start?

If the "long-unable-to-guess-filename" file is located in a web shared
folder, then it would be unsafe, at least in principle. If it's not
downloadable without going through the ASP script, then I can't see any
real risks on a clean ans tidy system (no test-file.asp left from the
debugging phase). Then, to be sure, you could delete the file
immediately after download.

<% strFile = oYourWebObject.Call("get_ReportFile")
strPath = oYourWebObject.Call("get_ReportPath")
Response.ContentType = "application/pdf"
Response.AddHeader "Content-Disposition", "filename="&strFile
strFile = strPath&"\"&strFile
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1 ' Binary
objStream.LoadFromFile strFile
Response.BinaryWrite objStream.Read
objStream.Close
Set objStream = Nothing
Set objFs = Server.CreateObject("Scripting.FileSystemObject")
Set objFile = objFs.GetFile(strFile)
objFile.Delete
Set objFile = Nothing
Set objFs = Nothing
Response.End
' Or call your webapp to request the delete...
%>

Just make sure the files have read access (or also delete access if
deleting from asp) for the user group that has the IUSER_.. as member,
usually Users. From webapp only SYSTEM need delete access.

I use the ADDB.Stream because it works better than the FileSystemObject
when reading binary files. I don't know why.

This method should be safe against intrusion by foreign malicous
parties, even when using a fixed file name, but then you would of course
have the unacceptable risk of multi user collosion. So, naturally, in
addition, you must use a unique file name for each session. The
sessionId should be handyy to use as a name component.

--
Knut Sparhell, Norway

Thijs Nijhuis
2-Aug-2005, 10:03 AM
Hi Knut,

Excellent example. I tried it and it worked perfectly!!

Three remarks:

1) The 'IUsr_' account needs read rights to the files to be able to stream
them. I don't think this causes a security risk because you can still keep
the files outside your webshare.

2) I experienced problems with large (zip) files (more then 20 MB). I
noticed only one user could download the file at a time. The other had to
wait till the first was finished, but there was no error. Adding the
following line solved the problem:

Response.Buffer = false

I guess the buffer was full.


3) There appears to be a problem with the BinaryWrite and files over 20MB on
Windows 2003 server. Haven't seen it myself but here is the article:
http://support.microsoft.com/default.aspx?scid=kb;en-us;826756

Regards,
Thijs



"Knut Sparhell" <knut@sparhell.no> wrote in message
news:eVma8c0kFHA.5992@dacmail.dataaccess.com...
> Marco Kuipers wrote:
>
>> I've got a bunch of PDF documents that need to be downloadable from an
>> WebApp website, by clicking on a link.
>>
>> This could be very simple, if I could just place these pdf files in an
>> 'images' like directory and just create a href to the files.
>>
>> Sadly enough, this is not good enough;
>> Lets say that the pdf's are insurance policy documents. Under no
>> circumstances should your document be available to others. Just long
>> unable to guess filenames could be an option, but still way to unsafe.
>>
>> What I really need is a way, how I can direct_input the .pdf file in
>> the WO, then return the binary as a function_return, then in the asp,
>> it puts it in a variable and streams it to the client.
>>
>> Is this possible? Can anybody give me a start?
>
> If the "long-unable-to-guess-filename" file is located in a web shared
> folder, then it would be unsafe, at least in principle. If it's not
> downloadable without going through the ASP script, then I can't see any
> real risks on a clean ans tidy system (no test-file.asp left from the
> debugging phase). Then, to be sure, you could delete the file immediately
> after download.
>
> <% strFile = oYourWebObject.Call("get_ReportFile")
> strPath = oYourWebObject.Call("get_ReportPath")
> Response.ContentType = "application/pdf"
> Response.AddHeader "Content-Disposition", "filename="&strFile
> strFile = strPath&"\"&strFile
> Set objStream = Server.CreateObject("ADODB.Stream")
> objStream.Open
> objStream.Type = 1 ' Binary
> objStream.LoadFromFile strFile
> Response.BinaryWrite objStream.Read
> objStream.Close
> Set objStream = Nothing
> Set objFs = Server.CreateObject("Scripting.FileSystemObject")
> Set objFile = objFs.GetFile(strFile)
> objFile.Delete
> Set objFile = Nothing
> Set objFs = Nothing
> Response.End
> ' Or call your webapp to request the delete...
> %>
>
> Just make sure the files have read access (or also delete access if
> deleting from asp) for the user group that has the IUSER_.. as member,
> usually Users. From webapp only SYSTEM need delete access.
>
> I use the ADDB.Stream because it works better than the FileSystemObject
> when reading binary files. I don't know why.
>
> This method should be safe against intrusion by foreign malicous parties,
> even when using a fixed file name, but then you would of course have the
> unacceptable risk of multi user collosion. So, naturally, in addition,
> you must use a unique file name for each session. The sessionId should be
> handyy to use as a name component.
>
> --
> Knut Sparhell, Norway