how to close STDIN

Discussion in 'Perl Misc' started by Larry, Oct 11, 2008.

  1. Larry

    Larry Guest

    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
     
    Larry, Oct 11, 2008
    #1
    1. Advertising

  2. On 2008-10-11 14:42, Larry <> wrote:
    > 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
     
    Peter J. Holzer, Oct 11, 2008
    #2
    1. Advertising

  3. Larry

    Larry Guest

    In article <>,
    "Peter J. Holzer" <> wrote:

    > 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!
     
    Larry, Oct 11, 2008
    #3
  4. Larry

    Ben Morrow Guest

    Quoth Larry <>:
    > In article <>,
    > "Peter J. Holzer" <> wrote:
    >
    > > 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

    --
    All persons, living or dead, are entirely coincidental.
    Kurt Vonnegut
     
    Ben Morrow, Oct 11, 2008
    #4
  5. Larry

    Larry Guest

    In article <>,
    Ben Morrow <> wrote:

    > 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...
     
    Larry, Oct 12, 2008
    #5
  6. Larry

    Larry Guest

    In article <>,
    "Peter J. Holzer" <> wrote:

    > 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
     
    Larry, Oct 12, 2008
    #6
  7. Larry wrote:
    > In article <>,
    > Ben Morrow <> wrote:
    >
    >> 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...


    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.


    --
    RGB
     
    RedGrittyBrick, Oct 12, 2008
    #7
  8. Larry

    C.DeRykus Guest

    On Oct 12, 5:57 am, Larry <> wrote:
    > In article <>,
    > "Peter J. Holzer" <> wrote:
    >
    > > 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?
    >


    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;

    --
    Charles DeRykus
     
    C.DeRykus, Oct 13, 2008
    #8
  9. Larry

    C.DeRykus Guest

    On Oct 13, 3:13 pm, "C.DeRykus" <> wrote:
    > On Oct 12, 5:57 am, Larry <> wrote:
    >
    > > In article <>,
    > > "Peter J. Holzer" <> wrote:

    >
    > > > 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?

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


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

    --
    Charles DeRykus
     
    C.DeRykus, Oct 13, 2008
    #9
  10. C.DeRykus wrote:
    > On Oct 12, 5:57 am, Larry <> wrote:
    > 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;
    }


    --
    Petr Vileta, Czech republic
    (My server rejects all messages from Yahoo and Hotmail.
    Send me your mail from another non-spammer site please.)
    Please reply to <petr AT practisoft DOT cz>
     
    Petr Vileta \(fidokomik\), Oct 14, 2008
    #10
  11. Larry

    Larry Guest

    In article
    <>,
    "C.DeRykus" <> wrote:

    > 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...
     
    Larry, Oct 14, 2008
    #11
  12. Larry

    C.DeRykus Guest

    On Oct 14, 3:11 am, Larry <> wrote:
    > In article
    > <>,
    >
    > "C.DeRykus" <> wrote:
    > > 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...


    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");
    ...
    }

    --
    Charles DeRykus
     
    C.DeRykus, Oct 14, 2008
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Johnathan Doe

    peek at stdin, flush stdin

    Johnathan Doe, May 15, 2004, in forum: C Programming
    Replies:
    5
    Views:
    25,075
    Chatoyer
    May 17, 2013
  2. Charlie Zender

    Reading stdin once confuses second stdin read

    Charlie Zender, Jun 19, 2004, in forum: C Programming
    Replies:
    6
    Views:
    794
    Dan Pop
    Jun 21, 2004
  3. Ben
    Replies:
    2
    Views:
    1,354
    jacob navia
    Aug 29, 2009
  4. Terry Cooper
    Replies:
    7
    Views:
    428
    Janos Sebok
    Jun 9, 2009
  5. Iñaki Baz Castillo
    Replies:
    7
    Views:
    877
    Iñaki Baz Castillo
    Jan 12, 2010
Loading...

Share This Page