Как бы ни ругали модуль CGI, я особо никогда не прислушивался к аргументам, потому что пользовался им только тогда, когда учился программированию для веба.
В основном я использовал самописный парсер HTTP-запроса, который проработал почти без изменений больше пяти лет. Парсер умел разбирать все, в том числе и multipart/form-data, хотя и написан он не слишком высокопарно.
Потом, когда пришел UTF-8, потребовался mod_perl, а самописному парсеру стало все труднее справляться с запросами, я заменил его библиотекой libapreq2. Libapreq — это Apache HTTP Server Request Library. Это модуль, который собирается в отдельную библиотеку и подключается к Апачу:
LoadModule apreq_module modules/mod_apreq2.so
Установка весьма простая, однако следует помнить, что для установки сопутствующих Perl-модулей требуется вызывать не ./configure, a perl Makefile.PL:
perl Makefile.PL --with-apache2-apxs=/path/to/apache2/bin/apxs
В каталоге modules появится соответствующие бинарные библиотеки, а Perl получит модули для работы с ней, в частности, Apache2::Request.
Миграция с CGI или любого другого парсера на libapeq2 проходит гладко, поскольку, собственно, и задачи формулируются весьма просто: получить переменную из запроса или прочитать куку.
my $req = new Apache2::Request($this->{'r'});
$p{$_} = $req->param($_) for $req->param();
Так же просто читать куки и еще более просто получать прикрепленные файлы:
my $upload = $req->upload($param);
Итого: если у вас mod_perl, пользуйтесь libapreq.