This is a simple, self-contained web server. It listens on port 32090 and serves a small form. It reports the contents of the form after it has been submitted.
#!/usr/bin/perl # Create CGI requests from HTTP::Requests, specifically the sort of # requests that come from POE::Component::Server::HTTP. use warnings; use strict; use POE; use POE::Component::Server::HTTP; use CGI ":standard"; # Start an HTTP server. Run it until it's done, typically forever, # and then exit the program. POE::Component::Server::HTTP->new( Port => 32090, ContentHandler => { '/' => \&root_handler, '/post/' => \&post_handler, } ); POE::Kernel->run(); exit 0; # Handle root-level requests. Populate the HTTP response with a CGI # form. sub root_handler { my ($request, $response) = @_; $response->code(RC_OK); $response->content( start_html("Sample Form") . start_form( -method => "post", -action => "/post/", -enctype => "application/x-www-form-urlencoded", ) . "Foo: " . textfield("foo") . br() . "Bar: " . popup_menu( -name => "bar", -values => [1, 2, 3, 4, 5], -labels => { 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five' } ) . br() . submit("submit", "submit") . end_form() . end_html() ); return RC_OK; } # Handle simple CGI parameters. # # This code was contributed by Andrew Chen. It handles GET and POST, # but it does not handle %ENV-based CGI things. It does not handle # cookies, for instance. Neither does it handle file uploads. sub post_handler { my ($request, $response) = @_; # This code creates a CGI query. my $q; if ($request->method() eq 'POST') { $q = new CGI($request->content); } else { $request->uri() =~ /\?(.+$)/; if (defined($1)) { $q = new CGI($1); } else { $q = new CGI; } } # The rest of this handler displays the values encapsulated by the # object. $response->code(RC_OK); $response->content(start_html("Posted Values") . "Foo = " . $q->param("foo") . br() . "Bar = " . $q->param("bar") . end_html()); return RC_OK; }
Another idea is to setup the $ENV variables yourself.
# note I've only tested GET and POST requests # ... I haven't tried multi-part formdata yet. sub new_cgi { my $request = shift; local %ENV; require Sys::Hostname; require URI; require IO::Scalar; require CGI; #server global $ENV{SERVER_SOFTWARE} = __PACKAGE__; $ENV{SERVER_NAME} = Sys::Hostname::hostname; $ENV{GATEWAY_INTERFACE} = 'CGI/1.1'; my $uri = URI->new($request->uri); #request specific $ENV{SERVER_PROTOCOL} = $request->server if defined $request->server; $ENV{SERVER_PORT} = '32090'; $ENV{REQUEST_METHOD} = $request->method; $ENV{PATH_INFO} = $uri->path; $ENV{PATH_TRANSLATED} = $uri->path; $ENV{SCRIPT_NAME} = $uri->path; $ENV{QUERY_STRING} = $uri->query if ($request->method eq 'GET'); #remote host data #there's nothing obvious on how to get #this data in the HTTP::Request docs #$ENV{REMOTE_HOST} = undef; #$ENV{REMOTE_ADDR} = undef; #$ENV{AUTH_TYPE} = undef; #$ENV{REMOTE_USER} = undef; #$ENV{REMOTE_IDENT} = undef; #these are the biggies $ENV{CONTENT_TYPE} = join('; ', $request->content_type) || ''; $ENV{CONTENT_LENGTH} = $request->content_length; # tie the content to STDIN ... this is the secret sauce of the CGI Spec our $content = $request->content; tie *STDIN, 'IO::Scalar', \$content; $ENV{COOKIE} = $request->header('Cookie') if $request->header('Cookie'); return CGI->new(); }