streaming help needed


  • Discourse touched me in a no-no place

    I have a Classic ASP website that produces a particular page in a funky way: clicking a particular link will open a PDF. The PDF has embedded JS that reads encoded information out of the URL, decodes it, and drops the result into a form in the file, producing a personalized output.

    Current browsers have started breaking that--they apparently don't fire the JS, so the user sees a blank form. I need to get this working again.

    My company licenses an ActiveX control--that control has the ability to produce nicely-formatted printed output, and also to create a PDF instead of printing. I could change my page to use the control to create a PDF, but then I run into issues I'm sure some of you anticipated: making sure nobody else can see the PDF, cleaning it up, etc. It occurred to me that rather than producing a file on disk, I could probably stream the data directory to the user. Anyone know of a way to do that that will work in modern browsers and be compatible with my existing stack (i.e., "switch to Apache" is not feasible)?


  • Banned

    @FrostCat said in streaming help needed:

    but then I run into issues I'm sure some of you anticipated: making sure nobody else can see the PDF, cleaning it up, etc.

    Why exactly is this an issue?



  • @FrostCat said in streaming help needed:

    The PDF has embedded JS


  • Discourse touched me in a no-no place

    @Gąska said in streaming help needed:

    Why exactly is this an issue?

    The files will contain personal information. Nobody else should be able to see them. Generating the file on demand and streaming it out to the user means I don't have to worry about that.



  • @Gąska I'm assuming contract terms or other sensitive data. We [my company,not frost] build custom pdfs using html and send them out to echo sign for signing. Pdf is terrible to work with when you're doing custom work.


  • Discourse touched me in a no-no place

    @LB_ said in streaming help needed:

    I didn't design it, but I have to work with it until I can find a better way.


  • Discourse touched me in a no-no place

    @Matches Yes. To keep it simple, let's pretend I'm talking about someone's W-2 (for non-Americans, that's got your name, address, SSN, and how much you made and paid in taxes last year. You have to send a copy of it to the IRS when you file your tax return.)

    Even if sensitive data weren't an issue I'd need a way to clean up files, while making sure someone's file doesn't get deleted while it's being downloaded. Creating the file on demand and streaming it out solves both problems--if the user needs another copy, he can just hit the link and download it again.


  • Banned

    @FrostCat said in streaming help needed:

    The files will contain personal information.

    So does my bank statement, but they still happily generate a static PDF without any additional after-the-fact magic, and they couldn't care less what happens to the file after I download it. Any other approach is :wtf: - either on your part or on whoever forced these ridiculous requirements upon you.


  • ♿ (Parody)

    @Gąska said in streaming help needed:

    So does my bank statement, but they still happily generate a static PDF without any additional after-the-fact magic, and they couldn't care less what happens to the file after I download it.

    He's talking about generating a file and saving it on the server, not about what the user does with it.


  • Discourse touched me in a no-no place

    @Gąska Sounds like your bank's TR:wtf:.

    You are free to think this is a dumb situation, but you're not helping. I have to deal with this, so if all you're going to do is argue with me, please leave the thread. My company likes getting paid.


  • Discourse touched me in a no-no place

    @boomzilla said in streaming help needed:

    He's talking about generating a file and saving it on the server, not about what the user does with it.

    Well, trying to avoid doing that, but yes. What the user does after it's in his browser, I don't care.



  • So what's the problem exactly? Generate the PDF on the server and stream it to the client.


  • Banned

    @boomzilla said in streaming help needed:

    He's talking about generating a file and saving it on the server, not about what the user does with it.

    Oh. I see. It was terribly worded in OP, but now I understand. Sorry for 🔥 .



  • @FrostCat said in streaming help needed:

    @boomzilla said in streaming help needed:

    He's talking about generating a file and saving it on the server, not about what the user does with it.

    Well, trying to avoid doing that, but yes. What the user does after it's in his browser, I don't care.

    Are you trying to avoid saving the file, or keeping the file? If it's the latter, set up a windows service/process that cleans up anything older than 10 minutes, or whatever you deem an appropriate period of time for the user to download the file without having to regenerate it.


  • Discourse touched me in a no-no place

    @russ0519 said in streaming help needed:

    So what's the problem exactly? Generate the PDF on the server and stream it to the client.

    Thanks for telling me to do what I asked how to do.


  • Discourse touched me in a no-no place

    @fwd said in streaming help needed:

    Are you trying to avoid saving the file, or keeping the file? If it's the latter, set up a windows service/process that cleans up anything older than 10 minutes, or whatever you deem an appropriate period of time for the user to download the file without having to regenerate it.

    I would prefer to avoid having to do something like that. My user base would find that difficult.

    To answer your question, I'd prefer, if possible, to simply avoid having a file exist on the server, although "having it exist long enough to send it to the browser and then the page that sent it immediately deletes it" is good enough. Based on experience, regenerating the file isn't something that will tax the server enough to be worth worrying about.


  • Notification Spam Recipient

    This post is deleted!

  • Notification Spam Recipient

    So in other words, you need to generate the PDF on the server and instead of saving it to disk and uploading that, serve it up in a generic in-memory IO stream?



  • @FrostCat said in streaming help needed:

    @russ0519 said in streaming help needed:

    So what's the problem exactly? Generate the PDF on the server and stream it to the client.

    Thanks for telling me to do what I asked how to do.

    We use CF to serve up PDF, so the code goes something like this:

    <cfcontent type="application/pdf" reset="true" variable="#reportBytes#"/>

    We use reportlab to actually generate the PDF in python.

    They have an open source version and a commercial add on. Not sure if the open source version will do what you need, but the commercial one definitely should.

    Edit: Didn't see the part where you said you're using classic ASP, so I guess I'm not much help here.



  • @FrostCat said in streaming help needed:

    @fwd said in streaming help needed:

    Are you trying to avoid saving the file, or keeping the file? If it's the latter, set up a windows service/process that cleans up anything older than 10 minutes, or whatever you deem an appropriate period of time for the user to download the file without having to regenerate it.

    I would prefer to avoid having to do something like that. My user base would find that difficult.

    To answer your question, I'd prefer, if possible, to simply avoid having a file exist on the server, although "having it exist long enough to send it to the browser and then the page that sent it immediately deletes it" is good enough. Based on experience, regenerating the file isn't something that will tax the server enough to be worth worrying about.

    I'm probably out of date but I don't know of any reliable way for the page/user to signal the file can be deleted. Worst case is the user closes the window halfway through the download and you're left in limbo. There are js events to catch the window closing or whatever, but again I don't count those as reliable.

    Since this is classic ASP I don't know how much of the response object you're given to work with, but you'll probably have to clear the default headers, indicate you're providing binary data, then dump all the bytes for the file into the response body. You might have to save to physical file long enough in order to read it back as bytes but that's manageable.



  • @FrostCat said in streaming help needed:

    Anyone know of a way to do that that will work in modern browsers and be compatible with my existing stack (i.e., "switch to Apache" is not feasible)?

    Classic ASP can open raw sockets, so you always have an extreme fallback if nothing else works.

    More seriously, though, this SO question seems to have a mostly complete code sample:

    Set adoStream = CreateObject("ADODB.Stream")
    adoStream.Type = 1
    adoStream.Open()
    
    adoStream.LoadFromFile "C:/path-to-file/" & curUser & curDir
    
    Response.Buffer = true
    Response.CharSet = "UTF-8"
    Response.Clear
    Response.ContentType = "application/pdf"
    
    Do While Not adoStream.eos
        Response.BinaryWrite adoStream.Read(1024 * 8)
        Response.Flush
    Loop
    Response.End()
    adoStream.close
    Set adoStream=nothing
    

    Looks like the key is an object called "adoStream".



  • @blakeyrat Here's another SO page with a code sample on it:

    Also using ADODB.Stream. From what he says, that code works fine.

    All you need to do is populate the stream with your PDF generator instead of from a file.


  • Notification Spam Recipient

    @blakeyrat said in streaming help needed:

    Also using ADODB.Stream.

    Hmm, I guess standard IO streams aren't available in ASP classic then?

    But yes, this was what I (failed to) hinted at.


  • Discourse touched me in a no-no place

    @fwd said in streaming help needed:

    I'm probably out of date but I don't know of any reliable way for the page/user to signal the file can be deleted. Worst case is the user closes the window halfway through the download and you're left in limbo. There are js events to catch the window closing or whatever, but again I don't count those as reliable.

    That's one reason I want to stream the results out. User closes the browser before he's finished? I don't care; he can try again later. What I don't want to do is have to worry about cleaning up files on the server.


  • Discourse touched me in a no-no place

    @blakeyrat said in streaming help needed:

    All you need to do is populate the stream with your PDF generator instead of from a file.

    I'll try to get to testing this out in the next few days. Thanks.


  • Discourse touched me in a no-no place

    @Tsaukpaetra said in streaming help needed:

    So in other words, you need to generate the PDF on the server and instead of saving it to disk and uploading that, serve it up in a generic in-memory IO stream?

    What I need to do is fix the problem that in some modern browsers, the JS embedded in my PDF no longer fires. I will consider any reasonable potential solution within my framework (which basically is "free and also hopefully not something that my customers have to install separately".)

    Generating the PDF server-side is an obvious potential solution. But then I have to consider what to do with the files afterwards, as outlined above, which is what led me to want to stream it directly. I haven't seen yet if the control will let me stream out into an ADOStream. If not, and I have to save a file, I can do that, stream it out, and then immediately delete it, because that, as I mentioned above, isn't likely to be a practical concern.



  • @FrostCat said in streaming help needed:

    Generating the PDF server-side is an obvious potential solution. But then I have to consider what to do with the files afterwards, as outlined above, which is what led me to want to stream it directly. I haven't seen yet if the control will let me stream out into an ADOStream.

    I suppose you need something like .NET's MemoryStream / MFC's CMemFile? No idea how you'd go about it in Classic ASP since thank fuck I've never had to use that - maybe you'd be able to use that MFC class directly.



  • @FrostCat since we're talking about ado, I'm just going to assume access to c#, maybe consider using a pdf library? itextsharp is pretty good, but really any c# library that supports generating pdfs from a template, or using html, or a template+ stamping+flattening should do you just fine. When you generate the document, send it as a byte stream to the user and don't call the save methods.

    You should probably look for a library that supports acrofields if you want to support forms, so users can sign documents easily


  • Discourse touched me in a no-no place

    @Matches said in streaming help needed:

    I'm just going to assume access to c#

    Classic ASP, remember? While I could introduce ASP.Net into the mix (and someday I'd like to rewrite the whole app in that) it's not really feasible right now.

    @Matches said in streaming help needed:

    consider using a pdf library?

    Thing is, I already have an ActiveX control that can generate a PDF for me. We already use it in the GUI app and are paying maintenance on it.

    @Matches said in streaming help needed:

    so users can sign documents easily

    Nice idea, but not a feature we need at this time. The simplest way to think of this is along the lines of "users want to see their pay stub".



  • @FrostCat sounds like you got it under control then, keep at it.


  • Trolleybus Mechanic

    @FrostCat said in streaming help needed:

    @blakeyrat said in streaming help needed:

    All you need to do is populate the stream with your PDF generator instead of from a file.

    I'll try to get to testing this out in the next few days. Thanks.

    I've done this in classic ASP. It works. As long as you:

    • Flush the output buffer first
    • Set the right content header
    • Stream the pdf bytes to the output stream
    • Close the buffer when done

    I'm sure whatever code on SO works fine.

    Writing something to a file system just to stream it is what a chump does. Don't be a chump.


  • Trolleybus Mechanic

    @FrostCat said in streaming help needed:

    Classic ASP, remember? While I could introduce ASP.Net into the mix (and someday I'd like to rewrite the whole app in that) it's not really feasible right now.

    Hacky workaround if you do want to: web service in c# in .net that takes a guid as a key, and streams the file.

    Hell, even a non-web service that is dumbfuckingpage.aspx?guid={guid}, and does the streaming. Both sites have access to the same database.


  • Discourse touched me in a no-no place

    @Lorne-Kates said in streaming help needed:

    Don't be a chump.

    That is, in fact, the goal.



  • @Matches said in streaming help needed:

    since we're talking about ado, I'm just going to assume access to c#

    Dude, it says classic ASP in the OP.

    And ADO originally came from VB6/ASP. It was ported to .net.

    @Matches said in streaming help needed:

    maybe consider using a pdf library?

    He also said he's already using a PDF library.

    @Matches said in streaming help needed:

    When you generate the document, send it as a byte stream to the user and don't call the save methods.

    That's what he was asking how to do!!!


  • Discourse touched me in a no-no place

    @blakeyrat said in streaming help needed:

    That's what he was asking how to do!!!

    0_1467928403763_upload-ec6ba827-cbd5-4b72-a8b3-496d55c1aca4


Log in to reply