cookie

Discussion in 'Perl Misc' started by George Mpouras, Feb 24, 2014.

  1. I want to send a cookie to users’ browser (using the CGI) after
    evaluating a form. The problem is that you can send a cookie only at the
    header and the forms can be only after start_html . any idea ?
     
    George Mpouras, Feb 24, 2014
    #1
    1. Advertisements

  2. George Mpouras

    Scott Bryce Guest


    This isn't a Perl question, but...

    Unless you are evaluating the form input on the client side, sending the
    form and sending the cookie happen during two different transactions, so
    there is no problem.

    1) Send the form.
    2) Receive the user input.
    3) Evaluate the user input and send the cookie with the response.
     
    Scott Bryce, Feb 24, 2014
    #2
    1. Advertisements

  3. * George Mpouras wrote in comp.lang.perl.misc:
    The Cookie either has to be set from the `<form action='...'>` or has to
    be set dynamically e.g. using JavaScript.
     
    Bjoern Hoehrmann, Feb 24, 2014
    #3
  4. Στις 24/2/2014 21:01, ο/η Scott Bryce έγÏαψε:

    The only Perl question is how to write it in C better and compile it.
    Back to the subject now, you can not do what you said using the CGI from
    the same script. I am thinking of an ugly workaround but I 'ld like to
    avoid it.
     
    George Mpouras, Feb 24, 2014
    #4
  5. George Mpouras

    John Bokma Guest

    1) is done by the user's browser.

    You really mean you want to do all 3 from the same script?
     
    John Bokma, Feb 24, 2014
    #5
  6. Στις 24/2/2014 21:04, ο/η Bjoern Hoehrmann έγÏαψε:
    Sending the cookie from <form action ...> sounds interesting but I do
    not think it is supported from Perl module CGI.

    I want to process user selections before sending the cookie.

    What I am thinking is at form action, to POST everything to an other
    page (a script actually) which also send the cookie.

    The ideal would be from the same script

    submit form -> process user selections -> send the cookie
     
    George Mpouras, Feb 24, 2014
    #6
  7. that was the idea ...
     
    George Mpouras, Feb 24, 2014
    #7
  8. George Mpouras

    John Bokma Guest

    I think you want:


    user/browser CGI

    requests URL ------------------>

    <------------------------------- page with FORM

    fills in form

    POSTs form -------------------->

    analyzes data received

    <------------------------------ cookie + HTML (if data OK)

    ?

    If you want to fill in a form on someone else's site you can use
    something like LWP::UserAgent. This is complicated (dealing processing
    that can takes time, etc.) but not impossible.
     
    John Bokma, Feb 24, 2014
    #8
  9. George Mpouras

    Scott Bryce Guest


    I was thinking of sending the web page containing the form to the
    browser in the first place before the user sees it and fills it out. The
    OP seems to think he has to send the cookie at the same time.
     
    Scott Bryce, Feb 24, 2014
    #9
  10. George Mpouras

    Scott Bryce Guest

    You do understand, don't you, that not all CGI functions have to use the
    CGI module? Many people, myself included, use the CGI module to parse
    the data coming to the script, but do no use it for anything that is
    sent back to the browser.
     
    Scott Bryce, Feb 24, 2014
    #10
  11. George Mpouras

    Scott Bryce Guest


    So the script needs some way to determine whether it should be
    processing input from your form, or sending the HTML containing the form
    to the browser in the first place. A hidden input field can be used to
    identify the form.

    Parse the data input that is sent to the script.

    If it does not appear to have been sent from the form, send the HTML
    page containing the form.

    If it does appear to have been sent from the form, validate the data.

    If the data validates, process the data, and send a response along with
    your cookie.

    If the data does not validate, send an error message back to the browser
    along with the form with the user's data pre-filled in.

    And remember that the data being sent to the script could be coming from
    anywhere and contain anything. It does not have to be coming from your
    form. You want to look at it pretty carefully before you assume that it
    is safe to process it.
     
    Scott Bryce, Feb 24, 2014
    #11
  12. Στις 24/2/2014 23:39, ο/η Scott Bryce έγÏαψε:



    well here is the flow.

    1) at the very start (before the header) I check if the user have the
    cookie and if contain a valid data. In this case the user is redirected
    immediately to the "final" page

    2) In case there is no cookie, or if the cookie data are not valid, The
    user must fill a form.
    If the form data validated successfully, then a cookie must be sent at
    user's browser , and redirected to the final page (here is the
    difficulty is to send the cookie after the submission and validation)


    thats all.
     
    George Mpouras, Feb 24, 2014
    #12
  13. George Mpouras

    John Bokma Guest

    So you set the cookie and redirect (untested)

    print $cgi->redirect(
    -cookie => $cookie,
    -status => '301 Moved Permanently'
    -uri => 'http://example.com/formok.html'
    );

    -cookie is not documented (?), but a quick peek at the source of CGI.pm
    gives me the impression that this is supported.
     
    John Bokma, Feb 24, 2014
    #13
  14. Item 2 is really items 2 and 3, as telling the user to fill out a form,
    and processing the form when/if they do so, are two different things.

    Here is a direct translation of your requirements. You did not specify
    what should happen if the user submitted the form but it was invalid, I
    just threw an fatal error, but you could just redisplay the form.

    It is not so nice to have the redirect in two different places, but as I
    said it is direct translation of your requirements.

    In particular, if you don't print the header too early, you will not
    have a problem with the header having been printed too early. Simply
    delay printing the header until until you know you don't need to redirect.

    #!/usr/bin/perl
    use CGI;
    use CGI::Carp qw(fatalsToBrowser);
    use strict;

    my $cgi=new CGI;

    if ($cgi->cookie('valid') eq 'valid') {
    print $cgi->redirect("/final");
    exit;
    };

    if (not $cgi->param()) {
    print $cgi->header(), $cgi->start_html(), $cgi->start_form();
    print $cgi->textfield('foo');
    print $cgi->submit();
    exit;
    };

    if ($cgi->param('foo') eq 'valid') {
    print $cgi->redirect(
    -uri => "/final",
    -cookie=>$cgi->cookie('valid','valid')
    );
    exit;
    };

    die "Form was submitted, but was not valid";
     
    Xho Jingleheimerschmidt, Feb 25, 2014
    #14
  15. Στις 25/2/2014 05:29, ο/η Xho Jingleheimerschmidt έγÏαψε:

    Xho,

    I hope you understand that you can not redirect if you print the header
    I hope you understand that you can not send a cookie after the header is
    printed.

    your code do not come even close to work.
    It is very tricky and can not be done without very carefully design and
    testing.
     
    George Mpouras, Feb 25, 2014
    #15
  16. I haven't tested this myself but the code above will neither try to set
    a cookie after printing the header nor try to redirect. That's possibly
    somewhat non-obvious because all processing logic 'hides' itself in
    if-blocks.
     
    Rainer Weikusat, Feb 25, 2014
    #16
  17. George Mpouras

    $Bill Guest

    This is all pretty simple. Don't generate any HTML until
    you have finished all your processing. Then send your
    header and any cookies followed by your HTML code.

    And you don't really need CGI to send back the HTML/form/header/cookie,
    you can do all that just by printing it - just need a blank line after
    the header lines.
     
    $Bill, Feb 25, 2014
    #17
  18. Tho cookie is sent *in* the header. That's what Xho's script does. Your
    objections are pointless.

    (I agree that CGI.pm makes it a bit hard to see what happens. For
    learning it would probably be better to print the headers and the html.)
    You obviously didn't try it. It works.
    Actually it's rather simple if you understand the request-response
    nature of HTTP and that the CGI script is invoked for each request.

    Try to understand what the script does for these requests:

    ------------------------------------------------------------------------
    GET /xho.cgi HTTP/1.0

    ------------------------------------------------------------------------
    POST /xho.cgi HTTP/1.0
    Content-Type: application/x-www-form-urlencoded

    valid=invalid
     
    Peter J. Holzer, Feb 25, 2014
    #18

  19. Well I try it. Not only this but several other similar or not
    variations. I also can see the requests , but I can not see any cookie
    at Firefox cookies.sqlite

    I do not know, maybe I am doing something wrong, but I end up to
    conclusion that you can not send any cookie (at lease through CGI) after
    the header is printed

    For not messing this post , I will post a stripped down variation of my
    latest try
     
    George Mpouras, Feb 25, 2014
    #19
  20. #!/usr/bin/perl
    use strict;
    use warnings;
    use CGI qw/:standard -compile -nosticky/; $CGI::DISABLE_UPLOADS=1;
    use CGI::Carp qw/fatalsToBrowser/;
    my
    $cgi = new CGI;
    $cgi->autoEscape(1);


    # First lets check if there is already a cookie at user browser
    my %cookie_data = $cgi->cookie('LastActions');

    if ((exists $cookie_data{Book}) && (exists $cookie_data{Time}))
    {
    # some code goes here
    print CGI::redirect("http://www.cpan.org");
    exit
    }

    print
    $cgi->header(
    -type => 'text/html',
    -charset => 'UTF-8',
    -encoding => 'UTF-8',
    '-Content-Language' => 'el',
    -lang => 'el-Greek',
    -expires => '+10h',
    -nph => 0,
    -status => '200 ok'),

    $cgi->start_html(
    -title => 'Department Library',
    -text => '#000080',
    -bgcolor => 'white',
    -head => Link({-rel=>'shortcut icon', -type=>'image/png',
    -href=>'/favicon.ico'}));



    print STDOUT<<STOP_PRINTING;
    <style type="text/css">
    ..formfield { font-family: tahoma; font-size: 9pt; font-weight: 600;
    color:#191970 ; background-color: #F0FFF0 }
    ..formbutton { font-family: tahoma; font-size: 9pt; font-weight: 700;
    color:#191970 ; background-color: #F0F8FF }
    </style>
    STOP_PRINTING



    print $cgi->start_multipart_form(-method=>'POST',
    -enctype=>'multipart/form-data', -target=>'_self');


    print q'<table
    style="position:absolute;left:200px;top:150px;width:600px;z-index:0;"
    cellpadding="0" cellspacing="1">
    <tr><td colspan="2">'. $cgi->h3("Book check Application") .'</td></tr>
    <tr><td style="height: 50px;"></td><td></td></tr>
    <tr><td style="height: 40px; width: 80px;">Book</td><td>'.

    $cgi->textfield
    (
    -name => 'Book',
    -default => '',
    -override => 1,
    -maxlength => 80,
    -size => 30,
    -class => 'formfield'
    )

    ..'</td></tr>
    <tr><td style="height: 40px; width: 80px;">Shelf</td><td>'.

    $cgi->textfield
    (
    -name => 'Shelf',
    -default => '',
    -override => 1,
    -maxlength => 80,
    -size => 30,
    -class => 'formfield'
    )


    ..'</td></tr>
    <tr><td style="height: 40px;"></td><td></td></tr>
    <tr><td colspan="2">'.

    $cgi->submit( -name =>'SUBMIT', -value=>"Check",
    -class=>'formbutton'). '&nbsp;&nbsp;&nbsp'.
    $cgi->defaults(-name =>'RESET', -value=>"Reset", -class=>'formbutton')

    ..'</td></tr>
    </table>';



    print $cgi->end_multipart_form();

    if ( defined $cgi->param('SUBMIT') )
    {
    print $cgi->redirect( -uri => "http://www.cpan.org", -cookie =>
    cookie(-name=>'LastActions', -path=>'/', -secure=>0, -expires=>'+2h',
    -value=>{ Book => $cgi->param('Book'), Shelf => $cgi->param('Shelf') } ) );
    exit;
    }



    print $cgi->end_html();
    exit 0;
     
    George Mpouras, Feb 25, 2014
    #20
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.