![]() |
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 |
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 |
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. | |
Re: Getting CGI to read from a different STDIN source
Brilliant, both of you. Thanks!
|
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! |
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\\ |
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. |
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.