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

I've been making an experimental webpage via nginx perl modules (not CGI!), and while I've been successfull on presenting the input page to the client (a main input field, some side fields, the send/reset buttons), I had ran into some problems with reciving the data.
Let's imagine a hypothetical scenario: a user fills in the tables and sends a POST request to the server, with the request headers containing a "content-type" field (which sould be "multipart/form-data" and the data, which should have been formated as per standarts and contain the stuff (text, image, other) that the user had put in the tables. The server, upon reciving the request, does actions as dictated by the code, with one of them being to prosess (use) data contained with the request.
In order to properly use the data, you have to extract it, and to do so, you use a parser. However, the multipart content type specification is too large to make a parser that will parse the input properly all by myself in a short time. I have set my eyes upon MIME::Parser, however I haven't been able to find documentation that I could understand (or apply), nor could I find other people asking the same (or close) questions (And when I can find them, the answer usually involves CGI, which I've decided to not use from the begining of the project).
Am I missing something, or had I overlooked a more simple solution?
  • Comment on Parse multipart/form-data with MIME::Parser

Replies are listed 'Best First'.
Re: Parse multipart/form-data with MIME::Parser
by choroba (Archbishop) on Apr 22, 2021 at 00:06 UTC
    > CGI, which I've decided to not use

    Good for you! What did you use instead?

    There are modules that do most of the work for you. For example, using Plack::Request, which is still rather low level, you can just write:

    #!/usr/bin/perl use strict; use warnings; use Plack::Request; sub { my $req = 'Plack::Request'->new(shift); my %method = ( GET => sub { [<DATA>] }, POST => sub { ['Hello ', $req->body_parameters->{text}] }); my $action = $method{ $req->method } or return [405, [Allow => join ', ', keys %method], []] +; return [200, ['Content-type' => 'text/html'], $action->()] } __DATA__ <html><body> <form method=post> Your name: <input name=text> <p> <input type=submit value=Submit> </form> </body></html>

    Update: This code is wrong, see jcb's note.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      Is there some kind of memoization magic in there or will that only return the form once, since it reads <DATA> but does not save the array anywhere?

        You are right, it doesn't work when you try to reload a page. Sorry.

        Here's a fix:

        my @template = <DATA>; sub { my $req = 'Plack::Request'->new(shift); my %method = ( GET => sub { \@template }, ...

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      I use nginx in the module, which is loaded by nginx, but I'm willing to add another use function since the most that the nginx module can do related to the problem is to display the related header part, and I don't feel like rewriting everything for a PSGI server or adding another full-fledged engine just to do one thing.