how to close STDIN

L

Larry

Hi,

i have a script running on a web server (Apache) that accepts data
from STDIN and saves it:

#!/perl

use IO::Handle '_IONBF';
use constant BUFSIZE => 1024 * 2;

my $io = new IO::Handle;

if ( $io->fdopen(fileno(STDIN),"r") )
{
while($io->read($buf, BUFSIZE))
{
# ... save $buf ...
}
$io->close;
}

__END__;

I decided to check out if a user can upload to this script or else my
web server would screw up. So I put this on top of my script:

if ($ENV{"HTTP_USER_PASS"} ne 'mypassword')
{
close STDIN;
exit;
}

then I sent a couple of MBs of data thru http without the USER_PASS
header, i was struck by my finding out the script sort of died but I was
still sending raw data to the script...I though close STDIN would drop
the connection, too bad it didn't...how can I sort this out?

thanks
 
P

Peter J. Holzer

i have a script running on a web server (Apache) that accepts data
from STDIN and saves it:

#!/perl
[no "use CGI" other module which might do something under the hood]
if ($ENV{"HTTP_USER_PASS"} ne 'mypassword')
{
close STDIN;
exit;
}

Your script not only closes stdin, it also exits.

then I sent a couple of MBs of data thru http without the USER_PASS
header, i was struck by my finding out the script sort of died but I was
still sending raw data to the script...

You can't send it to the script, since the script is already dead. You
might still be sending it to the web server. That makes it a web server
specific question and you should ask in an Apache group.

hp
 
L

Larry

Peter J. Holzer said:
You can't send it to the script, since the script is already dead. You
might still be sending it to the web server. That makes it a web server
specific question and you should ask in an Apache group.

well, the thing is i tried to send the data to the following:

#!/usr/bin/perl

use strict;
use warnings;
use CGI;
my $q = new CGI();

$CGI::DISABLE_UPLOADS = 1;

print "content-type: text/plain\n\n";

__END__;

it just keeps on accetping the data...so i tried ps -ux on the web server

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
claudio 531 0.0 0.0 0 0 ? Z 19:13 0:00 [receiver.cgi]
<defunct>

what is <defunct>?? i tried to kill it, yet i didnt get...thats so
strange!
 
B

Ben Morrow

Quoth Larry said:
Peter J. Holzer said:
You can't send it to the script, since the script is already dead. You
might still be sending it to the web server. That makes it a web server
specific question and you should ask in an Apache group.

well, the thing is i tried to send the data to the following:

#!/usr/bin/perl

use strict;
use warnings;
use CGI;
my $q = new CGI();

$CGI::DISABLE_UPLOADS = 1;

print "content-type: text/plain\n\n";

__END__;

it just keeps on accetping the data...so i tried ps -ux on the web server

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
claudio 531 0.0 0.0 0 0 ? Z 19:13 0:00 [receiver.cgi]
<defunct>

what is <defunct>?? i tried to kill it, yet i didnt get...thats so
strange!

The <defunct> (and the STAT Z: Z is for 'zombie') mean that the process
has exitted, but its parent hasn't waited for it yet. Since the process
is already dead, you can't kill it again :). Presumably the httpd child
is receiving all the uploaded data and just throwing it away, and once
it's finished it'll perform the wait(2).

Ben
 
L

Larry

Ben Morrow said:
Presumably the httpd child
is receiving all the uploaded data and just throwing it away, and once
it's finished it'll perform the wait(2).

hopefully. Do you think that may affect/screw up my web server? I mean
the httpd child throwing the data away...
 
L

Larry

Peter J. Holzer said:
You can't send it to the script, since the script is already dead.

ok, so back to my question...is ok to close STDIN and exit in order to
stop my script if a user fails to auth?

thanks
 
R

RedGrittyBrick

Larry said:
hopefully. Do you think that may affect/screw up my web server? I mean
the httpd child throwing the data away...

No, it may waste resources though.

If you need to authenticate uploaders you might find it better to use
the web-server's authentication and authorisation mechanisms (e.g. see
Apache's .htaccess). That ought to prevent the situation you describe.
 
C

C.DeRykus

ok, so back to my question...is ok to close STDIN and exit in order to
stop my script if a user fails to auth?

But if authentication fails, you could return a "401 Unauthorized"
before you even begin reading:

if ( $ENV{"HTTP_USER_PASS"} ne ... ) {
print $q->header(
-status="401 Unauthorized"), ...,
"Wrong password....";
} else {
if ( $io->fdopen(fileno(STDIN),"r") )
{
... # read
}
}
exit;
 
P

Petr Vileta \(fidokomik\)

C.DeRykus said:
But if authentication fails, you could return a "401 Unauthorized"
before you even begin reading:

if ( $ENV{"HTTP_USER_PASS"} ne ... ) {
print $q->header(
-status="401 Unauthorized"), ...,
"Wrong password....";

Or you can simply write

if ( $ENV{"HTTP_USER_PASS"} ne ... ) {
print "Status: 401 Unauthorized\n\n");
exit;
}
 
L

Larry

C.DeRykus said:
Of course, this won't alleviate the data push,
but at least you'll be failing gracefully with
the appropriate status.

that's what I'm worring about...
 
C

C.DeRykus

that's what I'm worring about...

Reviewing CGI docs, I think the problem may
be that you'll need to set $CGI::pOST_MAX and
check cgi_error before you start reading, eg

use CGI;
my $q = new CGI();
$CGI::MAX_POST = ...;

my $q = CGI->new;
if ( my $error = $q->cgi_error ) {
print $q->start_html, $error,...
exit;
}


Hopefully only a partial transfer has occurred before CGI.pm
sees the content length and throws an error. Here're the
relevant lines from CGI.pm:

if (($POST_MAX > 0)
&& ($content_length > $POST_MAX)) {
#discard the post, unread
$self->cgi_error(
"413 Request entity too large");
...
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top