Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Odd difference between

by Xxaxx (Monk)
on May 04, 2001 at 00:54 UTC ( [id://77774]=perlquestion: print w/replies, xml ) Need Help??

Xxaxx has asked for the wisdom of the Perl Monks concerning the following question:

Let me show the form and script then describe the behavior. I'm hoping someone will have experience with this and hopefully a solution.

Here's the form:

<html> <body> <a href="/~newbie/cgi-bin/getpdf2.pl">Click Here for Test 1</a><p> <FORM METHOD="POST" ACTION="/~newbie/cgi-bin/getpdf2.pl"> <INPUT TYPE="SUBMIT" VALUE=" Click here for test 2 "> </FORM> <p> <FORM METHOD="GET" ACTION="/~newbie/cgi-bin/getpdf2.pl"> <INPUT TYPE="SUBMIT" VALUE=" Click here for test 3 "> </FORM> </body> </html>
Here's the script:
#!/usr/bin/perl -w open(PAGE, "</home/username/pdf/ho99-6a.pdf"); print "Content-type: application/pdf\n\n"; my($buffer); while (sysread(PAGE,$buffer,2048)) { syswrite(STDOUT,$buffer,length($buffer)); } close(PAGE); exit;
When running Netscape 4.76 and IE5 each of the form options work as well as the hotlink.

When running Netscape 6 the hotlink and the GET method work but the POST does not.

When running IE 5.5 the hotlink and GET always work and sometimes the POST method works (but not always).

The clue that it's working is the pdf file is loaded and presented for viewing.

The clue that it isn't working is the Adobe plugin is activated but the display is blank.

I find this very bizarre. The best I can figure is that Netscape 6 is somehow handling the caching of pages fetched by GET differently than pages fetched as a response to a POST. As you can see in the script there aren't a lot of moving parts to go haywire.

Is there perhaps a header option which will force the browsers to behave the same when receiving a page from GET and POST?

Thanks in advance.
Claude

Replies are listed 'Best First'.
Re: Odd difference between
by merlyn (Sage) on May 04, 2001 at 01:17 UTC
    You aren't respecting the protocol in your CGI program. All bets are off when you do that.

    I'm gonna sound like a broken record but use CGI.pm. You aren't reading $ENV{CONTENT_LENGTH} bytes from STDIN on a POST. That's bound to upset somebody. CGI.pm will do this for you.

    Also, check the return value of system calls!

    -- Randal L. Schwartz, Perl hacker

      Er, I think Randal's misunderstood something, but since it's Randal, I'll just re-read your post...

      OK, I'm gonna go out on a limb here (expecting to be thrashed at any moment... :)

      As far as I can see, your forms/links do not pass any values to the server in the buffer or query string. All they do is serve one PDF file.

      If so, all you need in your script is:

      print "Content-type: application/pdf\n\n"; open(PAGE, "</home/username/pdf/ho99-6a.pdf") || die("Can't open file +- $!"); print while (<PAGE>); close(PAGE); exit(0);

      You would only need to read the query string / buffer if you actually sent any information.

      The only time I would think you might do this is if the document is stored outside the web root and you can't symlink to it.

      What would involve query_string / buffer would be if you sent a variable to the script. ie, the html was something like:

      <html> <body> <a href="/~newbie/cgi-bin/getpdf2.pl?document=ho99-6a.pdf">Click Here +for Test 1</a><p> <FORM METHOD="POST" ACTION="/~newbie/cgi-bin/getpdf2.pl"> <INPUT TYPE="hidden" NAME="document" VALUE="ho99-6a.pdf"> <INPUT TYPE="SUBMIT" VALUE=" Click here for test 2 "> </FORM> <p> <FORM METHOD="GET" ACTION="/~newbie/cgi-bin/getpdf2.pl"> <INPUT TYPE="hidden" NAME="document" VALUE="ho99-6a.pdf"> <INPUT TYPE="SUBMIT" VALUE=" Click here for test 3 "> </FORM> </body> </html>

      Please kick me. I must be missing something here?!?

      cLive ;-)

        "As far as I can see, your forms/links do not pass any values to the server in the buffer or query string. All they do is serve one PDF file."

        It's twue, it's really twue. (Lily VonShtup)

        The sample script was stripped to the absolute bare essentials. Since I was trying to fix a problem in *gag* authenticate.cgi */gag* and the customer did not want to pay for a total rewrite I started cutting down to the fundamental issue. The fundamental issue being: when a pdf file was feed back to a browser it worked fine with Netscape 4.7 or less and with MSIE 5 or less. But a pdf file feed back to a browser would not work with Netscape 6 and MSIE 5.5

        So I eliminated all subroutines, password monkey business, logging mumbo-jumbo, and everything else getting down to spitting out a pdf file based on a script just being called.

        "Please kick me. I must be missing something here?!?"

        No need. I kicked myself enough running around in circles trying to figure out what these new versions of Netscape were upto.

        Turns out just the Submit button was enough data in the stream to cause a problem.

        Near as I can tell when these new versions of Netscape and MSIE send a POST they go into a "waiting for a request to send data" mode.

        If anything other than a "request to read waiting data" comes back to the browser these new versions seem to eat the first string, figure out that the server is not going to ask for data, then start sending the rest of the incoming bytes to the "render the darn page" subroutines.

        I do believe the first string sent to a new browser after a POST is being dumped. Maybe out of spite for being left hanging around with perfectly good posted data. Maybe because the error recovery from an apparently broken CGI session is not the greatest. The older versions of the browsers managed to send the string on into the rendering subroutines. The newer versions don't seem to do that. Leastwise that is the apparent effect.

        The solution to this is to either use the GET method or: read(STDIN, $forminfo, $content_length, $offset);

        The offending script was using <STDIN> to snarf up the POST data. Apparently there is something happening in the newer browsers such that <STDIN> is not "doing the whole trick" -- at least not in this one form/script combination.

        If I replace the read with <STDIN> the script won't fully function for Netscape 6. And if I put the read() back in the script works fine. Or alternately I can switch the POST method to a GET method.

        I'm sure this isn't the whole story. But with the exception of a zillion and a half Matt's scripts still in use around the internet anyone using CGI.pm (which utilizes a proper read($fh, $$buff, $len, $offset);) should be fine.

        So while rewriting the script from scratch would have solved the problem by incorporating proper use of CGI.pm, I do think there is some value in understanding some of the nuances of what's happening in the innards.

        Claude

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://77774]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (8)
As of 2024-04-19 09:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found