Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Getting CGI to read from a different STDIN source (http://www.velocityreviews.com/forums/t885062-getting-cgi-to-read-from-a-different-stdin-source.html)

Bill Gerba 02-08-2004 05:00 AM

Getting CGI to read from a different STDIN source
 
Hi,

I've run into a problem with CGI.pm. I want to use my own generic
code to actually capture the raw POST data from a form submission and
store the whole thing to a file. After I've caught the entire POST
stream, I then want to load all of the data from the file back into
STDIN and create a new CGI object that will read the data in there and
parse it out for me. Attached is the code that I'm using, and I'm
submitting from a very simple HTML form with a few text boxes and
select widgets (Perl 5.6.1 and Apache on Linux, if it's important).

#!/usr/bin/perl -w
use strict;
use Data::Dumper;
use CGI;

# First, grab the HTTP POST stream and dump it into a file.
my ($TMP,$DATA);
open($TMP,">","posted_data.txt");
while (read STDIN, $DATA, 1024) {
print $TMP $DATA;
}
close $TMP;

# Next, open the file into STDIN so CGI.pm can read it
open(STDIN,"posted_data.txt") or die "can't open temp file: $!";
$| = 1;

# Print out the data from the HTTP POST as CGI sees it.
my $cc = new CGI;
my %v = $cc->Vars;
print $cc->header();
print Dumper(\%v);


When I run this, it saves the file correctly (all of the data and
headers are there), but I get a cryptic error message: "Filehandle
STDOUT opened only for input at test.cgi line 22."

AFAIK, I'm not doing anything at all to STDOUT, and CGI doesn't seem
to think that there's anything in STDIN at all. But if I don't make
the CGI object and just do a while (<STDIN>) { print; } I get all of
my data out fine. What am I doing wrong, and how can I get CGI to see
the data in STDIN?

TIA,

Bill

Bob Walton 02-08-2004 07:30 PM

Re: Getting CGI to read from a different STDIN source
 
Bill Gerba wrote:

....
> I've run into a problem with CGI.pm. I want to use my own generic
> code to actually capture the raw POST data from a form submission and
> store the whole thing to a file. After I've caught the entire POST



Check out the CGI docs under the section "CREATING A NEW QUERY OBJECT
FROM AN INPUT FILE". That will let you do what you want, as in the
marked-up code below. BTW, I duplicated your problem with your code
under Windoze 98SE, except it didn't give any error message about STDOUT.


> stream, I then want to load all of the data from the file back into
> STDIN and create a new CGI object that will read the data in there and
> parse it out for me. Attached is the code that I'm using, and I'm
> submitting from a very simple HTML form with a few text boxes and
> select widgets (Perl 5.6.1 and Apache on Linux, if it's important).
>
> #!/usr/bin/perl -w
> use strict;
> use Data::Dumper;
> use CGI;
>
> # First, grab the HTTP POST stream and dump it into a file.
> my ($TMP,$DATA);
> open($TMP,">","posted_data.txt");


----------------------------------^
Missing or die ... clause.


> while (read STDIN, $DATA, 1024) {
> print $TMP $DATA;
> }
> close $TMP;
>
> # Next, open the file into STDIN so CGI.pm can read it
> open(STDIN,"posted_data.txt") or die "can't open temp file: $!";


open(IN, "posted_data.txt") or ...

#I didn't try it using STDIN as a filehandle, but it just
#seems nice not to mess with STDIN.


> $| = 1;


Line not needed.


>
> # Print out the data from the HTTP POST as CGI sees it.
> my $cc = new CGI(\*IN);


------------------^^^^^^


> my %v = $cc->Vars;
> print $cc->header();
> print Dumper(\%v);
>
>
> When I run this, it saves the file correctly (all of the data and
> headers are there), but I get a cryptic error message: "Filehandle
> STDOUT opened only for input at test.cgi line 22."
>
> AFAIK, I'm not doing anything at all to STDOUT, and CGI doesn't seem
> to think that there's anything in STDIN at all. But if I don't make
> the CGI object and just do a while (<STDIN>) { print; } I get all of
> my data out fine. What am I doing wrong, and how can I get CGI to see
> the data in STDIN?

....
> Bill
>


--
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl


Ben Morrow 02-08-2004 07:58 PM

Re: Getting CGI to read from a different STDIN source
 

see@sig.invalid wrote:
> Bill Gerba wrote:
> open(IN, "posted_data.txt") or ...


open my $IN, "posted_data.txt" or die ...;

> > my $cc = new CGI(\*IN);

> ------------------^^^^^^


my $cc = new CGI($IN);

Ben

--
Musica Dei donum optimi, trahit homines, trahit deos. |
Musica truces mollit animos, tristesque mentes erigit. | ben@morrow.me.uk
Musica vel ipsas arbores et horridas movet feras. |

Bill Gerba 02-09-2004 05:35 AM

Re: Getting CGI to read from a different STDIN source
 
Brilliant, both of you. Thanks!

Bill Gerba 02-13-2004 09:28 PM

Re: Getting CGI to read from a different STDIN source
 
Well, my problems continue. According to the docs, when you create a
CGI object using new CGI($FH), the file (or list, or hash, or
whatever) can ONLY contain data in either key=value format or a URI
encoding scheme. However, in the example below, I'm slurping all of
STDIN into a file, which includes things like the HTTP headers.
Consequently, when I run the script below, CGI dumps everything into
one huge variable full of crap.

Is it possible to take this entire file and have CGI successfully
parse it out?

A related question is: what's the difference between my $IN filehandle
and the original STDIN when the data is posted to the CGI script? Is
Apache stripping out the headers or something?

Also, it's worth noting that I'm trying this with a
multipart/form-data HTTP file upload, so there could be different (or
multiple) content-length headers in the POSTed data.

Here's the code:

#!/usr/bin/perl -w
use strict;
use Data::Dumper;
use CGI;

# First, grab the HTTP POST stream and dump it into a file.
my ($TMP,$DATA);
open($TMP,">","posted_data.txt") or die "can't open posted_data file:
$!";
while (read STDIN, $DATA, 1024) {
print $TMP $DATA;
}
close $TMP;

# Make a CGI object taking data from a filehandle $IN
my $IN;
open($IN,"posted_data.txt") or die "can't open temp file: $!";

# Print out the data from the HTTP POST as CGI sees it.
my $cc = new CGI($IN);
my %v = $cc->Vars;
print $cc->header();
print Dumper(\%v);

exit(0);


If you want to try this yourself, here's the HTML form that I'm using
to submit to the CGI:


<HTML>
<HEAD>
<TITLE>FireCast ClientCenter : Upload Files</TITLE>
</HEAD>
<BODY>
<form enctype="multipart/form-data" action="/cgi-bin/uptest.pl"
method="POST">

<table border=0 align="left" cellpadding=3>
<tr><td><input type="file" name="upfile1"></td></tr>
<tr><td><input type="file" name="upfile2"></td></tr>
<tr>
<td colspan=2 align="center">
<input type="hidden" name="sessionid" value="1234">
<input type='hidden' name='mode' value='upload'>
<input type="submit" value="Upload">
</td>
</tr>
</table>
</form>
</BODY>
</HTML>



Thanks again!

Brian McCauley 02-13-2004 10:11 PM

Re: Getting CGI to read from a different STDIN source
 
junkmail@wirespring.com (Bill Gerba) writes:

> Well, my problems continue. According to the docs, when you create a
> CGI object using new CGI($FH), the file (or list, or hash, or
> whatever) can ONLY contain data in either key=value format or a URI
> encoding scheme. However, in the example below, I'm slurping all of
> STDIN into a file, which includes things like the HTTP headers.
> Consequently, when I run the script below, CGI dumps everything into
> one huge variable full of crap.
>
> Is it possible to take this entire file and have CGI successfully
> parse it out?


You could just open the file as STDIN

> A related question is: what's the difference between my $IN filehandle
> and the original STDIN when the data is posted to the CGI script?


The orginal STDIN is the speical standard input file handle.

> my $IN;
> open($IN,"posted_data.txt") or die "can't open temp file: $!";
>
> # Print out the data from the HTTP POST as CGI sees it.
> my $cc = new CGI($IN);


How about

# Untested
open(STDIN,"posted_data.txt") or die "can't open temp file: $!";
my $cc = new CGI;

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\

Bill Gerba 02-14-2004 08:05 PM

Re: Getting CGI to read from a different STDIN source
 
Brian McCauley <nobull@mail.com> wrote in message news:<u9r7wyiq9f.fsf@wcl-l.bham.ac.uk>...
>
> You could just open the file as STDIN
>

....
>
> How about
>
> # Untested
> open(STDIN,"posted_data.txt") or die "can't open temp file: $!";
> my $cc = new CGI;


This was the first thing I tried. In my first post I noted that when
I do this I not only get an empty CGI object, but I also get a
peculiar message about STDOUT being opened for output only.

nobull@mail.com 02-16-2004 01:26 PM

Re: Getting CGI to read from a different STDIN source
 
junkmail@wirespring.com (Bill Gerba) wrote in message news:<7f2e88c6.0402141205.5c345731@posting.google. com>...
> Brian McCauley <nobull@mail.com> wrote in message news:<u9r7wyiq9f.fsf@wcl-l.bham.ac.uk>...
> >
> > You could just open the file as STDIN
> >

> ...
> >
> > How about
> >
> > # Untested
> > open(STDIN,"posted_data.txt") or die "can't open temp file: $!";
> > my $cc = new CGI;

>
> This was the first thing I tried. In my first post I noted that when
> I do this I not only get an empty CGI object, but I also get a
> peculiar message about STDOUT being opened for output only.


Sorry I missed the start of this thread originally.

I've gone back a copied the test script from the OP onto my web
server. I made only one small change - I added a chdir("/tmp")
because my httpd is not configured to set CGIs' CWD to a writable
directory. It worked perfectly.

Are you sure that your httpd _is_ configured to set CGIs' CWD to a
writable directory?

Are you sure you are using CGI at all (and not something like mod_perl
+ Apache::Registry)?


All times are GMT. The time now is 02:27 PM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57