CGI and mod_perl

Speaker: Juerd
Duration: an hour

Dutch Perl Workshop 2004

Probably only works correctly in Mozilla (?:Fire(?:Bird|Fox))? (F11 for full screen) and other Gecko based browsers. On top of that, I use a font that probably almost nobody has :) The slides are generated by a little script(text/plain) that uses a large semi-html-file to create separate files using this template. Het Nederlandse origineel is hier.

Contents

HTTP

HTTP request

HTTP response

HTTP abuse

HTML forms

<form method="POST" action="test.cgi">

HTML > CGI

CGI

A CGI script

CGI + HTML

#!/usr/bin/perl -w
use strict;

use CGI;

my $cgi = CGI->new;
print $cgi->header;

if ($cgi->request_method eq 'POST') {
    do something;
    print <<'END_OF_HTML';
[[[html>
[[[head>
[[[title>Thank you![[[/title>
[[[/head>
[[[body>
Thank you very much for registering!
You will receive a confirmation by email
soon.
[[[/body>
[[[/html>
END_OF_HTML
} else {
    print <<'END_OF_HTML';
[[[html>
[[[head>
[[[title>Register[[[/title>
[[[/head>
[[[body>
Fill in these fields:[[[br>
Preferred user name: [[[input type=text name=user>
Password: [[[input type=password name=pass>[[[br> Again: [[[input type=password name=pass> [[[hr> Name: [[[input type=text name=name>[[[br> Address: [[[input type=text name=address>[[[br> Zip code: [[[input type=text name=zip>[[[br> City: [[[input type=text name=city> [[[hr> Phone number: [[[input type=text name=phone>[[[br> Email address: [[[input type=text name=mail>[[[br> Homepage URL: [[[input type=text name=url> [[[hr> [[[input type=submit value="Send request"> [[[/body> [[[/html> END_OF_HTML }

CGI.pm can make HTML

CGI > Templates

Pages in files

#!/usr/bin/perl -w
use strict;

use CGI;
use File::Slurp;

my $cgi = CGI->new;
print $cgi->header;

if ($cgi->request_method eq 'POST') {
    do something;
    print read_file 'thanks.html';
} else {
    print read_file 'register.html';
}

More flexible with templates

Example

#!/usr/bin/perl -w
use strict;

use CGI;
use HTML::Template;
use File::Slurp;

my $cgi = CGI->new;
print $cgi->header;

if ($cgi->request_method eq 'POST') {
    do something;
    my $template = HTML::Template->new(
        filename => 'thanks.html'
    );
    $template->param(mail => $cgi->param('mail'));
    print $template->output
} else {
    print read_file 'register.html';
}

Templating modules

Templates > Wizards

User interface

Wizards: advantages

Wizards: disadvantages

CGI::Application

Wizards > Sessions

POST problems

Solution: sessions

A session...

Sessions are handy for:

Passing the session id

Modules

Sessions > Cookies

Cookies

Cookie headers

Baking a cookie

use CGI::Cookie;

my $cookie = CGI::Cookie->new(
    -name    => 'session',
    -value   => $session_id,
    -domain  => '.example.com',
    -path    => '/',
    -expires => '+3M'  # 3 months
);

print $cgi->header(
    -cookie => $cookie
);

Eating a cookie

use CGI::Cookie;

my %cookies = CGI::Cookie->fetch;

Cookies > mod_perl

mod_perl

Endless interpreter: disadvantages

Preventing problems

use strict;

Stupid question

When can you skip use strict; in mod_perl or a module?

Stupid question

When can you skip use strict; in mod_perl or a module?

If you can't answer that question yourself:

NEVER!

Why strict?

CGI scripts in mod_perl

mod_perl

CGI scripts in mod_perl

Migrating to mod_perl

mod_perl is CGI compatible

... by default

$r

CGI vs mod_perl

mod_perl 'scripts'

Apache::Registry

Your own handler

Example

package Apache::MyHandler
use Apache::Constants qw(OK);

sub handler {
    my $r = shift;

    $r->send_http_header('text/plain');
    $r->print('example');
    
    return OK;
}

1;

httpd.conf

PerlModule Apache::MyHandler
  • e.g. for *.qhtml:
    <Files *.qhtml>
    PerlHandler Apache::MyHandler
    </Files>
  • e.g. with 1 location (to replace a script)
    <Location /foo/bar>
    PerlHandler Apache::MyHandler
    </Location>
  • Look out in mod_perl

    Modules in mod_perl

    mod_perl alternatives

    mod_perl > end

    CPAN

    Mentioned modules

    Links

    End