Matt S Trout > Web-Simple-0.020 > Web::Simple::Application



Annotate this POD


New  5
Open  1
View/Report Bugs
Source   Latest Release: Web-Simple-0.031


Web::Simple::Application - A base class for your Web-Simple application


This is a base class for your Web::Simple application. You probably don't need to construct this class yourself, since Web::Simple does the 'heavy lifting' for you in that regards.


This class exposes the following public methods.


Merges with the config initializer to provide configuration information for your application. For example:

  sub default_config {
      title => 'Bloggery',
      posts_dir => $FindBin::Bin.'/posts',

Now, the config attribute of $self will be set to a HashRef containing keys 'title' and 'posts_dir'.

The keys from default_config are merged into any config supplied, so if you construct your application like:

    config => { title => 'Spoon', environment => 'dev' }

then config will contain:

    title => 'Spoon',
    posts_dir => '/path/to/myapp/posts',
    environment => 'dev'


The run_if_script method is designed to be used at the end of the script or .pm file where your application class is defined - for example:

  #!/usr/bin/env perl
  use Web::Simple 'HelloWorld';

    package HelloWorld;

    sub dispatch_request {
      sub (GET) {
        [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world!' ] ]
      sub () {
        [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ]


This returns a true value, so your file is now valid as a module - so

  require '';

  my $hw = HelloWorld->new;

will work fine (and you can rename it to lib/ later to make it a real use-able module).

However, it detects if it's being run as a script (via testing $0) and if so attempts to do the right thing.

If run under a CGI environment, your application will execute as a CGI.

If run under a FastCGI environment, your application will execute as a FastCGI process (this works both for dynamic shared-hosting-style FastCGI and for apache FastCgiServer style setups).

If run from the commandline with a URL path, it runs a GET request against that path -

  $ perl -Ilib examples/hello-world/hello-world.cgi /
  200 OK
  Content-Type: text/plain
  Hello world!

You can also provide a method name -

  $ perl -Ilib examples/hello-world/hello-world.cgi POST /
  405 Method Not Allowed
  Content-Type: text/plain
  Method not allowed

For a POST or PUT request, pairs on the command line will be treated as form variables. For any request, pairs on the command line ending in : are treated as headers, and 'Content:' will set the request body -

  $ ./myapp POST / Accept: text/html form_field_name form_field_value
  $ ./myapp POST / Content-Type: text/json Content: '{ "json": "here" }'

The body of the response is sent to STDOUT and the headers to STDERR, so

  $ ./myapp GET / >index.html

will generally do the right thing.

To send basic authentication credentials, use user:pass@ syntax -

  $ ./myapp GET bob:secret@/protected/path

Additionally, you can treat the file as though it were a standard PSGI application file (*.psgi). For example you can start up up with plackup


or starman



This method is called by "run_if_script" to create the PSGI app coderef for use via Plack and plackup. If you want to globally add middleware, you can override this method:

  use Web::Simple 'HelloWorld';
  use Plack::Builder;
    package HelloWorld;

    around 'to_psgi_app', sub {
      my ($orig, $self) = (shift, shift);
      my $app = $self->$orig(@_); 
      builder {
        enable ...; ## whatever middleware you want

This method can also be used to mount a Web::Simple application within a separate *.psgi file -

  use strictures 1;
  use Plack::Builder;
  use WSApp;
  use AnotherWSApp;

  builder {
    mount '/' => WSApp->to_psgi_app;
    mount '/another' => AnotherWSApp->to_psgi_app;

This method can be called as a class method, in which case it implicitly calls ->new, or as an object method ... in which case it doesn't.


Used for running your application under stand-alone CGI and FCGI modes.

I should document this more extensively but run_if_script will call it when you need it, so don't worry about it too much.


  my $res = $app->run_test_request(GET => '/' => %headers);

  my $res = $app->run_test_request(POST => '/' => %headers_or_form);

  my $res = $app->run_test_request($http_request);

Accepts either an HTTP::Request object or ($method, $path) and runs that request against the application, returning an HTTP::Response object.

If the HTTP method is POST or PUT, then a series of pairs can be passed after this to create a form style message body. If you need to test an upload, then create an HTTP::Request object by hand or use the POST subroutine provided by HTTP::Request::Common.

If you prefix the URL with 'user:pass@' this will be converted into an Authorization header for HTTP basic auth:

  my $res = $app->run_test_request(
              GET => 'bob:secret@/protected/resource'

If pairs are passed where the key ends in :, it is instead treated as a headers, so:

  my $res = $app->run_test_request(
              POST => '/',
             'Accept:' => 'text/html',
              some_form_key => 'value'

will do what you expect. You can also pass a special key of Content: to set the request body:

  my $res = $app->run_test_request(
              POST => '/',
              'Content-Type:' => 'text/json',
              'Content:' => '{ "json": "here" }',


See Web::Simple for authors.


See Web::Simple for the copyright and license.

syntax highlighting: