Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

CGI.pm not good practice, so what is good, modern, practice for reading CGI paramters?

by leszekdubiel (Scribe)
on May 24, 2021 at 08:32 UTC ( [id://11132946]=perlquestion: print w/replies, xml ) Need Help??

leszekdubiel has asked for the wisdom of the Perl Monks concerning the following question:

My CGI script gets data from html forms. Forms that deliver data are encoded in many different ways:

  • GET
  • POST, application/x-www-form-urlencoded
  • POST, multipart/form-data
  • POST, text-plain

I need to read all parameters from <input type="text" .... Current solution is:

#!/usr/bin/perl use CGI; my $q = CGI->new; my %params = map { $_ => $q->param($_) } $q->param(); ...

If CGI.pm is deprecated, then what is better solution that is as simple as CGI.pm? I don't want to put much boilerplate, or make huge application -- just read parameters in the most simple way.

Here is a CGI script for testing: lustra.pl/cgitest.pl, and this is source code of that script:

#!/usr/bin/perl use CGI; use JSON; my $q = CGI->new; my %headers = map { $_ => $q->http($_) } $q->http(); my %params = map { $_ => $q->param($_) } $q->param(); my %environ = map { ($_, $ENV{$_}) } grep { ! /ROOT|PATH|REMOTE|FILENAME|SERVER|SSL/ } keys %ENV; print <<HTML; Content-Type: text/html; charset=utf-8 <!DOCTYPE HTML> <html> <body> <pre> @{[ JSON->new->pretty->canonical->encode({ headers => \%headers, params => \%params, environ => \%environ, }) ]} </pre> <form method="get"> <input type="submit"> <input name="about" value="method get"> <input name="myname" value="Alfa"> <input name="myage" value="32"> <input name="unicode-test" value="&#260;&#262;&#280;&#321;&#323;Ó& +#346;&#377;&#377;&#379;-&#261;&#263;&#281;&#322;&#324;ó&#347;&#378;&# +380;-&#960;œ©ß&#8592;&#8595;&#8594;&#601;&#331;æð„”µ&#8804;&#8805;»«§ +½€¢³²&#8800;"> </form> <form method="post"> <input type="submit"> <input name="about" value="method post"> <input name="myname" value="Beta"> <input name="myage" value="44"> <input name="unicode-test" value="&#260;&#262;&#280;&#321;&#323;Ó& +#346;&#377;&#377;&#379;-&#261;&#263;&#281;&#322;&#324;ó&#347;&#378;&# +380;-&#960;œ©ß&#8592;&#8595;&#8594;&#601;&#331;æð„”µ&#8804;&#8805;»«§ +½€¢³²&#8800;"> </form> <form method="post" enctype="application/x-www-form-urlencoded"> <input type="submit"> <input name="about" value="method post, x-www-form-urlencoded"> <input name="myname" value="Gamma"> <input name="myage" value="12"> <input name="unicode-test" value="&#260;&#262;&#280;&#321;&#323;Ó& +#346;&#377;&#377;&#379;-&#261;&#263;&#281;&#322;&#324;ó&#347;&#378;&# +380;-&#960;œ©ß&#8592;&#8595;&#8594;&#601;&#331;æð„”µ&#8804;&#8805;»«§ +½€¢³²&#8800;"> </form> <form method="post" enctype="multipart/form-data"> <input type="submit"> <input name="about" value="method post, multipart/form-data"> <input name="myname" value="Teta"> <input name="myage" value="66"> <input name="unicode-test" value="&#260;&#262;&#280;&#321;&#323;Ó& +#346;&#377;&#377;&#379;-&#261;&#263;&#281;&#322;&#324;ó&#347;&#378;&# +380;-&#960;œ©ß&#8592;&#8595;&#8594;&#601;&#331;æð„”µ&#8804;&#8805;»«§ +½€¢³²&#8800;"> </form> <form method="post" enctype="text-plain"> <input type="submit"> <input name="about" value="method post, text-plain"> <input name="myname" value="Omega"> <input name="myage" value="45"> <input name="unicode-test" value="&#260;&#262;&#280;&#321;&#323;Ó& +#346;&#377;&#377;&#379;-&#261;&#263;&#281;&#322;&#324;ó&#347;&#378;&# +380;-&#960;œ©ß&#8592;&#8595;&#8594;&#601;&#331;æð„”µ&#8804;&#8805;»«§ +½€¢³²&#8800;"> </form> </body> </html> HTML
  • Comment on CGI.pm not good practice, so what is good, modern, practice for reading CGI paramters?
  • Select or Download Code

Replies are listed 'Best First'.
Re: CGI.pm not good practice, so what is good, modern, practice for reading CGI paramters? (updated)
by haukex (Archbishop) on May 24, 2021 at 09:20 UTC

      Thank you. CGI::Simple -- this is what I was looking for. :)

        Nope. Substituting CGI::Simple in place of CGI is missing the point.
Re: CGI.pm not good practice, so what is good, modern, practice for reading CGI paramters?
by marto (Cardinal) on May 24, 2021 at 08:40 UTC

      Thank you. I've read CGI::Alternatives, but for example in Mojolicious it is not that simple, because you have to define routing, paths, and start "application".

      I wan't library to look at environment (is it GET or POST? if POST, then what is form encoding?), then parse CGI parameters and make them available as hash, or as functions to list all names and get all values. Maybe in that simple case CGI.pl i still a way to go, and is going to be supported many years from now on...

Re: CGI.pm not good practice, so what is good, modern, practice for reading CGI paramters?
by vincent_veyron (Sexton) on May 25, 2021 at 14:51 UTC

    With Apache, you can use Apache2::Request (https://metacpan.org/pod/Apache2::Request); in a mod_perl module, it works like in cgi.pm:

    package xxxxxxxx; use strict ; use warnings ; use utf8 ; use Apache2::Const -compile => qw( OK REDIRECT ) ; sub handler { binmode(STDOUT, ":utf8") ; my $r = shift ; my $req = Apache2::Request->new( $r ) ; #récupérer les arguments my (%args, @args) ; #recherche des paramètres de la requête @args = $req->param ; for ( @args ) { $args{ $_ } = Encode::decode_utf8( $req->param($_) ) ; } [.....] }

    https://compta.libremen.com

    Logiciel libre de comptabilité générale en partie double

      No, stick with CGI.pm for your cgis even on apache, even with mod_perl, read the porting guidelines
Re: CGI.pm not good practice, so what is good, modern, practice for reading CGI paramters?
by Anonymous Monk on May 24, 2021 at 12:57 UTC
    If CGI.pm is deprecated, then what is better solution that is as simple as CGI.pm?

    The idea is not to get rid of CGI.pm per se, it's to get rid of multi-entrypoint (per-file) CGI-based architectures, instead having (1) all routes in more or less once place, making it much harder to leave sensitive endpoint not protected by a requirement to authorize and (2) template-based page rendering as opposed to print "<html>", ... mixed with domain-specific logic, which some CGI.pm-based scripts are famous for.

    So if you want to have a single script to be called by your web-server using the CGI protocol, you can still use CGI.pm, but please also consider templates. See also: XY problem. What are you trying to build using this CGI script?

      The idea is not to get rid of CGI.pm per se

      It partly is, though. While your points about CGI application architecture in general are valid, I think they also miss the reasons why CGI.pm specifically is no longer recommended. See "CGI.pm Has Been Removed From the Perl Core" in CGI.pm and the section "HTML Generation functions should no longer be used" right below that, as well as all the links therein to the various discussions. IMHO, one of the things CGI.pm suffers from is having to drag around backward-compatible features (like ISINDEX support, just to name another one).

      Old-style CGI scripts sometimes still can be useful, but I certainly advocate for modern frameworks as well, especially if the application grows beyond one or two scripts.

      A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11132946]
Approved by marto
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-18 02:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found