view release on metacpan or search on metacpan
2012-02-07 1.079
- Errors output to the stderr are now derived directly from $@ not from any
parsed version of it.
2012-02-02 1.078
- Fixed installation problem that came up in v1.075
(compilation root was missing leading forward slash on non-windows systems).
2012-02-01 1.077
- Loath to add a mime-types-all-knowing dependency, we have a small list of
common mime-types (html, css, js, etc).
- Added mime for html and svg.
2012-02-01 1.076
- Now, the 'content-type' header is set correctly for ASP4::UserAgent responses.
- Works correctly under ASP4::PSGI (images, css, javascript all show up).
2012-02-01 1.075
- Now, works on Windows!
- eric.hayes++
2012-01-30 1.074
- Explicit calls to $Session->save() are no longer necessary.
2012-01-23 1.073
--- #YAML:1.0
name: ASP4
version: 1.087
abstract: Fast, Simple, Scalable Web Development
author:
- John Drago <jdrago_999@yahoo.com>
license: artistic
distribution_type: module
test_requires:
Test::More: 0
Test::Memory::Cycle: 0
Time::HiRes: 0
HTML::Form: 0
requires:
common::sense: 0
Data::Properties::YAML: 0
Cwd: 0
Digest::MD5: 0
README.markdown view on Meta::CPAN
message => 'this is a test message'
);
To send an HTML email do the following:
use MIME::Base64;
$Server->Mail(
from => 'foo@bar.com',
to => 'bar@foo.com',
subject => 'Hello, world!',
'content-type' => 'text/html',
'content-transfer-encoding' => 'base64',
message => encode_base64(<<"HTML")
<html>
<body>
<p>This is an html email.</p>
<p>You can see that <b>this text is bold</b>.</p>
</body>
</html>
HTML
);
README.markdown view on Meta::CPAN
my $errors = $Session->{validation_errors} || { };
$::err = sub {
my $field = shift;
my $error = $errors->{$field} or return;
%><span class="field_error"><%= $Server->HTMLEncode( $error ) %></span><%
};
%>
<form id="register_form" method="post" action="/handlers/myapp.register">
<p>
<label>Email:</label>
<input type="text" name="email" value="<%= $Server->HTMLEncode( $Form->{email} ) %>" />
<% $::err->("email"); %>
</p>
<p>
<label>Password:</label>
<input type="password" name="password" />
<% $::err->("password"); %>
</p>
<p>
<label>Confirm Password:</label>
<input type="password" name="password2" />
<% $::err->("password2"); %>
</p>
<p>
<input type="submit" value="Register Now" />
</p>
</form>
</asp:Content>
The form submits to the URL `/handlers/app.register` which means `handlers/app/register.pm`
File: `handlers/app/register.pm`
package app::register;
README.markdown view on Meta::CPAN
foreach my $user ( @users ) {
%>
<option value="<%= $user->id %>"><%= $Server->HTMLEncode( $user->email ) %></option>
<%
}# end foreach()
%>
</select>
</p>
<p>
<label>Subject:</label>
<input type="text" name="subject" maxlength="100" />
</p>
<p>
<label>Message:</label><br/>
<textarea name="body"></textarea>
</p>
<p>
<input type="submit" value="Send Message" />
</p>
</form>
</div>
</asp:Content>
The form submits to `/handlers/app.send` which maps to `handlers/app/send.pm`
File: `handlers/app/send.pm`
package app::send;
inc/Module/Install/Metadata.pm view on Meta::CPAN
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
my @scalar_keys = qw{
name
module_name
abstract
author
version
distribution_type
tests
installdirs
};
my @tuple_keys = qw{
configure_requires
build_requires
requires
recommends
bundles
inc/Module/Install/Metadata.pm view on Meta::CPAN
while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
$self->feature( $name, @$mods );
}
return $self->{values}{features}
? @{ $self->{values}{features} }
: ();
}
sub no_index {
my $self = shift;
my $type = shift;
push @{ $self->{values}{no_index}{$type} }, @_ if $type;
return $self->{values}{no_index};
}
sub read {
my $self = shift;
$self->include_deps( 'YAML::Tiny', 0 );
require YAML::Tiny;
my $data = YAML::Tiny::LoadFile('META.yml');
lib/ASP4.pm view on Meta::CPAN
message => 'this is a test message'
);
To send an HTML email do the following:
use MIME::Base64;
$Server->Mail(
from => 'foo@bar.com',
to => 'bar@foo.com',
subject => 'Hello, world!',
'content-type' => 'text/html',
'content-transfer-encoding' => 'base64',
message => encode_base64(<<"HTML")
<html>
<body>
<p>This is an html email.</p>
<p>You can see that <b>this text is bold</b>.</p>
</body>
</html>
HTML
);
lib/ASP4.pm view on Meta::CPAN
my $errors = $Session->{validation_errors} || { };
$::err = sub {
my $field = shift;
my $error = $errors->{$field} or return;
%><span class="field_error"><%= $Server->HTMLEncode( $error ) %></span><%
};
%>
<form id="register_form" method="post" action="/handlers/myapp.register">
<p>
<label>Email:</label>
<input type="text" name="email" value="<%= $Server->HTMLEncode( $Form->{email} ) %>" />
<% $::err->("email"); %>
</p>
<p>
<label>Password:</label>
<input type="password" name="password" />
<% $::err->("password"); %>
</p>
<p>
<label>Confirm Password:</label>
<input type="password" name="password2" />
<% $::err->("password2"); %>
</p>
<p>
<input type="submit" value="Register Now" />
</p>
</form>
</asp:Content>
The form submits to the URL C</handlers/app.register> which means C<handlers/app/register.pm>
File: C<handlers/app/register.pm>
package app::register;
lib/ASP4.pm view on Meta::CPAN
foreach my $user ( @users ) {
%>
<option value="<%= $user->id %>"><%= $Server->HTMLEncode( $user->email ) %></option>
<%
}# end foreach()
%>
</select>
</p>
<p>
<label>Subject:</label>
<input type="text" name="subject" maxlength="100" />
</p>
<p>
<label>Message:</label><br/>
<textarea name="body"></textarea>
</p>
<p>
<input type="submit" value="Send Message" />
</p>
</form>
</div>
</asp:Content>
The form submits to C</handlers/app.send> which maps to C<handlers/app/send.pm>
File: C<handlers/app/send.pm>
package app::send;
lib/ASP4/ErrorHandler.pm view on Meta::CPAN
sub send_error
{
my ($s, $error) = @_;
$Server->Mail(
To => $Config->errors->mail_errors_to,
From => $Config->errors->mail_errors_from,
Subject => "ASP4: Error in @{[ $ENV{HTTP_HOST} ]}@{[ $ENV{REQUEST_URI} ]}",
'content-type' => 'text/html',
'content-transfer-encoding' => 'base64',
Message => encode_base64( $s->error_html($error) ),
smtp => $Config->errors->smtp_server,
);
}# end send_error()
sub error_html
{
my ($s, $error) = @_;
my $msg = <<"ERROR";
<!DOCTYPE html>
<html>
<head><title>500 Server Error</title>
<meta charset="utf-8" />
<style type="text/css">
HTML,BODY {
background-color: #FFFFFF;
}
HTML,BODY,P,DIV {
font-family: Arial, Helvetica, Sans-Serif;
}
HTML,BODY,P,PRE,DIV {
font-size: 12px;
}
H1 {
lib/ASP4/FileUpload.pm view on Meta::CPAN
=head2 FileSize
The size of the uploaded file in bytes.
=head2 FileHandle
Returns a filehandle (open for reading) pointing to the uploaded file.
=head2 ContentType
The C<content-type> header supplied by the browser for the uploaded file.
=head2 FileContents
The contents of the uploaded file.
=head1 PUBLIC METHODS
=head2 SaveAs( $path )
Writes the contents of the uploaded file to C<$path>. Will throw an exception if
lib/ASP4/HTTPContext.pm view on Meta::CPAN
sub session { shift->{session} }
sub config { shift->{config} }
sub stash { shift->{stash} }
# More advanced:
sub is_subrequest { shift->{is_subrequest} }
sub cgi { shift->{cgi} }
sub r { shift->{r} }
sub handler { shift->{handler} }
sub headers_out { shift->{headers_out} }
sub content_type { my $s = shift; $s->r->content_type( @_ ) }
sub status { my $s = shift; $s->r->status( @_ ) }
sub did_send_headers { shift->{did_send_headers} }
sub did_end {
my $s = shift;
@_ ? $s->{did_end} = shift : $s->{did_end};
}
sub rprint {
my ($s,$str) = @_;
$s->buffer->add( $str );
lib/ASP4/Mock/RequestRec.pm view on Meta::CPAN
use ASP4::ConfigLoader;
use Scalar::Util 'weaken';
sub new
{
my ($class, %args) = @_;
my $s = bless {
status => 200,
content_type => 'text/plain',
buffer => '',
document_root => ASP4::ConfigLoader->load()->web->www_root,
headers_in => { },
headers_out => { },
uri => $args{uri} || $ENV{REQUEST_URI},
args => $args{args} || $ENV{QUERY_STRING},
pnotes => { },
method => $args{method},
pool => ASP4::Mock::Pool->new(),
connection => ASP4::Mock::Connection->new(),
lib/ASP4/Mock/RequestRec.pm view on Meta::CPAN
sub connection { shift->{connection} }
sub headers_out { shift->{headers_out} }
sub headers_in { shift->{headers_in} }
sub err_headers_out { shift->{err_headers_out} }
sub buffer { shift->{buffer} } # Not documented:
# Public methods:
sub print { my ($s,$str) = @_; $s->{buffer} .= $str; }
sub content_type
{
my ($s, $type) = @_;
return $s->headers_out->{'content-type'} unless $type;
$s->headers_out->{'content-type'} = $type;
}# end content_type()
sub rflush { }
1;# return true:
=pod
=head1 NAME
ASP4::Mock::RequestRec - Mimic an Apache2::RequestRec object
lib/ASP4/Mock/RequestRec.pm view on Meta::CPAN
Returns a hashref representing the outgoing headers.
=head2 err_headers_out( )
Returns a hashref representing the outgoing headers.
=head2 status( [$new_status] )
Sets or gets the status code for the response. 200 for "OK", 301 for "Moved" - 404 for "not found" etc.
=head2 content_type( [$new_content_type] )
Sets or gets the mime-header for the outgoing response. Default is C<text/plain>.
=head1 PUBLIC METHODS
=head2 print( $str )
Adds C<$str> to the outgoing response buffer.
=head2 rflush( )
lib/ASP4/ModPerl.pm view on Meta::CPAN
{
my ($class, $r) = @_;
$ENV{DOCUMENT_ROOT} = $r->document_root;
$ENV{REMOTE_ADDR} = $r->connection->get_remote_host();
$ENV{HTTP_HOST} = $r->hostname;
my $context = ASP4::HTTPContext->new();
$r->pool->cleanup_register(sub { $context->DESTROY });
if( ($r->headers_in->{'content-type'}||'') =~ m/multipart\/form\-data/ )
{
$context->{r} = $r;
if( $@ )
{
warn $@;
$r->status( 500 );
return $r->status;
}# end if()
my $handler_class = eval {
lib/ASP4/Request.pm view on Meta::CPAN
is the same as:
$ENV{HTTP_HOST}
=head2 FileUpload( $fieldname )
Returns a L<ASP4::FileUpload> object that corresponds to the fieldname specified.
So...if your form has this:
<input type="file" name="my_uploaded_file" />
Then you would get to it like this:
my $upload = $Request->FileUpload('my_uploaded-file');
=head2 Header( $name )
Returns the value of an incoming http request header by the given name.
=head1 BUGS
lib/ASP4/Response.pm view on Meta::CPAN
use HTTP::Date qw( time2str );
use ASP4::HTTPContext;
use ASP4::Mock::RequestRec;
sub new
{
my $s = bless {
_status => 200,
_expires => 0,
_content_type => 'text/html',
_expires_absolute => time2str( time() ),
}, shift;
$s->Status( $s->Status );
$s->Expires( $s->Expires );
$s->ContentType( $s->ContentType );
return $s;
}# end new()
sub context { ASP4::HTTPContext->current }
sub ContentType
{
my $s = shift;
if( @_ )
{
my $type = shift;
$s->{_content_type} = $type;
$s->context->r->content_type( $type );
$s->SetHeader( 'content-type' => $type );
}
else
{
return $s->{_content_type};
}# end if()
}# end ContentType()
sub Expires
{
my $s = shift;
if( my $value = shift )
{
my $time;
if( my ($num,$type) = $value =~ m/^(\-?\d+)([MHD])$/ )
{
my $expires;
if( $type eq 'M' ) {
# Minutes:
$expires = time() + ( $num * 60 );
}
elsif( $type eq 'H' ) {
# Hours:
$expires = time() + ( $num * 60 * 60 );
}
elsif( $type eq 'D' ) {
# Days:
$expires = time() + ( $num * 60 * 60 * 24 );
}# end if()
$time = $expires;
}
else
{
$time = $value;
}# end if()
lib/ASP4/Response.pm view on Meta::CPAN
sub End
{
my $s = shift;
if( $s->Status =~ m{^2} )
{
$s->Flush;
}
else
{
delete $s->context->headers_out->{'content-type'};
}# end if()
# Would be nice to somehow stop all execution:
$s->context->did_end( 1 );
}# end End()
sub Flush
{
my $s = shift;
lib/ASP4/Response.pm view on Meta::CPAN
$args{path} ||= '/';
my @parts = ( );
push @parts, $s->context->server->URLEncode($args{name}) . '=' . $s->context->server->URLEncode($args{value});
unless( $args{domain} eq '*' )
{
push @parts, 'domain=' . $s->context->server->URLEncode($args{domain});
}# end unless()
push @parts, 'path=' . $args{path};
if( $args{expires} )
{
if( my ($num,$type) = $args{expires} =~ m/^(\-?\d+)([MHD])$/ )
{
my $expires;
if( $type eq 'M' ) {
# Minutes:
$expires = time() + ( $num * 60 );
}
elsif( $type eq 'H' ) {
# Hours:
$expires = time() + ( $num * 60 * 60 );
}
elsif( $type eq 'D' ) {
# Days:
$expires = time() + ( $num * 60 * 60 * 24 );
}# end if()
push @parts, 'expires=' . time2str( $expires );
}
else
{
push @parts, 'expires=' . time2str( $args{expires} );
}# end if()
}# end if()
lib/ASP4/Response.pm view on Meta::CPAN
# Read-only:
my $expires_on = $Response->ExpiresAbsolute;
=head1 DESCRIPTION
The C<$Response> object offers a unified interface to send content back to the client.
=head1 PROPERTIES
=head2 ContentType( [$type] )
Sets or gets the C<content-type> header for the response. Examples are C<text/html>, C<image/gif>, C<text/csv>, etc.
=head2 Status( [$status] )
Sets or gets the C<Status> header for the response. See L<http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html> for details.
B<NOTE:> Only the numeric part is necessary - eg: 200, 301, 404, etc.
=head2 Headers()
Returns the L<HTTP::Headers> object that will be used for the outgoing response.
lib/ASP4/Server.pm view on Meta::CPAN
# Email someone:
$Server->Mail(
To => 'jim@bob.com',
From => 'Joe Jangles <joe@jangles.net>',
Subject => 'Test Email',
Message => "Hello There!",
);
# Avoid XSS:
<input type="text" name="foo" value="<%= $Server->HTMLEncode( $Form->{foo} ) %>" />
# Proper URLs:
<a href="foo.asp?bar=<%= $Server->URLEncode($Form->{bar}) %>">Click</a>
=head1 DESCRIPTION
The C<$Server> object provides some utility methods that don't really fit anywhere
else, but are still important.
=head1 PUBLIC METHODS
lib/ASP4/SimpleCGI.pm view on Meta::CPAN
}
else
{
$params{$k} = $v;
}# end if()
}# end foreach()
}# end if()
if( $args{body} )
{
my $body = HTTP::Body->new( $args{content_type}, $args{content_length} );
$body->add( $args{body} );
# Parse form values:
my $form_info = $body->param || { };
if( keys(%$form_info) )
{
foreach( keys(%$form_info) )
{
$params{$_} = $form_info->{$_};
}# end foreach()
lib/ASP4/SimpleCGI.pm view on Meta::CPAN
=head1 NAME
ASP4::SimpleCGI - Basic CGI functionality
=head1 SYNOPSIS
use ASP4::SimpleCGI;
my $cgi = ASP4::SimpleCGI->new(
content_type => 'multipart/form-data',
content_length => 1200,
querystring => 'mode=create&uploadID=234234',
body => ...
);
my $val = $cgi->param('mode');
foreach my $key ( $cgi->param )
{
print $key . ' --> ' . $cgi->param( $key ) . "\n";
}# end foreach()
lib/ASP4/SimpleCGI.pm view on Meta::CPAN
in the API enironment.
C<ASP4::SimpleCGI> uses L<HTTP::Body> under the hood.
=head1 PUBLIC METHODS
=head2 new( %args )
Returns a new C<ASP4::SimpleCGI> object.
C<%args> can contain C<content_type>, C<content_length>, C<querystring> and C<body>.
=head2 param( [$key] )
If C<$key> is given, returns the value of the form or querystring parameter by that name.
If C<$key> is not given, returns a list of all parameter names.
=head2 escape( $str )
Returns a URL-encoded version of C<$str>.
lib/ASP4/StaticHandler.pm view on Meta::CPAN
$Response->Status( 404 );
$Response->End;
return 404;
}# end unless()
open my $ifh, '<', $file
or die "Cannot open '$file' for reading: $!";
local $/;
$Response->SetHeader('content-length' => (stat($file))[7] );
my ($ext) = $file =~ m{\.([^\.]+)$};
my %types = (
swf => 'application/x-shockwave-flash',
xml => 'text/xml',
jpg => 'image/jpeg',
jpeg => 'image/jpeg',
png => 'image/png',
bmp => 'image/bmp',
gif => 'image/gif',
json => 'application/x-json',
css => 'text/css',
pdf => 'application/x-pdf',
js => 'text/javascript',
svg => 'image/svg+xml',
html => 'text/html',
);
my $type = $types{lc($ext)} || 'application/octet-stream';
$Response->ContentType( $type );
my ($filename) = $file =~ m{([^/]+)$};
my $disp = lc($type) eq 'pdf' ? 'attachment' : 'inline';
$Response->SetHeader('content-disposition' => qq($disp; filename="$filename"; yay=yay;));
$Response->Write( scalar(<$ifh>) );
close($ifh);
}# end run()
1;# return true:
lib/ASP4/UserAgent.pm view on Meta::CPAN
chdir( $s->{cwd} );
my $temp_referrer = $ENV{HTTP_REFERER};
my $req = $form->click;
my $referer = $ENV{HTTP_REFERER};
%ENV = (
%{ $s->{env} },
HTTP_REFERER => $referer || '',
DOCUMENT_ROOT => $s->config->web->www_root,
REQUEST_METHOD => uc( $req->method ),
CONTENT_TYPE => $form->enctype ? $form->enctype : 'application/x-www-form-urlencoded',
HTTP_COOKIE => $s->http_cookie,
REQUEST_URI => $form->action,
);
my $cgi = $s->_setup_cgi( $req );
my ($uri_no_args, $querystring) = split /\?/, $req->uri;
my $r = ASP4::Mock::RequestRec->new( uri => $uri_no_args, args => $querystring );
my $current_is_subrequest = $ASP4::HTTPContext::_instance ? $ASP4::HTTPContext::_instance->{is_subrequest} ? 1 : 0 : 0;
$s->{context} = ASP4::HTTPContext->new( is_subrequest => $current_is_subrequest ? 1 : 0 );
return do {
local $ASP4::HTTPContext::_instance = $s->context;
lib/ASP4/UserAgent.pm view on Meta::CPAN
# Cookies:
$req->header( 'Cookie' => $ENV{HTTP_COOKIE} = $s->http_cookie );
if( $ENV{REQUEST_METHOD} =~ m/^post$/i )
{
# Set up the basic params:
return ASP4::SimpleCGI->new(
querystring => $ENV{QUERY_STRING},
body => $req->content,
content_type => $req->headers->{'content-type'},
content_length => $req->headers->{'content-length'},
);
}
else
{
# Simple 'GET' request:
return ASP4::SimpleCGI->new( querystring => $ENV{QUERY_STRING} );
}# end if()
}# end _setup_cgi()
t/010-basic/090-everything.t view on Meta::CPAN
use ASP4::API;
my $api = ASP4::API->new;
ok( my $res = $api->ua->get('/everything/step01.asp'), "Got res");
ok(
$res = $api->ua->get('/handlers/dev.headers'), "Got headers res again"
);
is(
$res->header('content-type') => 'text/x-test'
);
is(
$res->header('content-length') => 3000
);
is(
$res->content => "X"x3000
);
# static:
{
t/htdocs/index.asp view on Meta::CPAN
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ASP4 Installed</title>
<style type="text/css">
HTML, BODY {
margin: 0px;
padding: 0px;
border: 0px;
font-size: 14px;
font-family: Verdana, Arial, Sans-Serif;
background-color: #333333;
color: #000000;
width: 100%;
height: 100%;
t/htdocs/useragent/simple-form.asp view on Meta::CPAN
<html>
<body>
<form name="form1" action="/useragent/simple-form.asp" method="post">
Color: <input type="text" name="color" value="<%= $Server->HTMLEncode( $Form->{color} ) %>" ><br>
Pet's Name: <input type="text" name="pet_name" value="<%= $Server->HTMLEncode( $Form->{pet_name} ) %>"><br>
<br>
<input type="submit" value="Submit" >
</form>
</body>
</html>
t/htdocs/useragent/upload-form.asp view on Meta::CPAN
%>
<form name="form1">
<%= $file->FileName %> -- <%= $file->FileExtension %> -- <%= $file->FileSize %><br/>
<textarea name="file_contents"><%= $file->FileContents %></textarea>
</form>
<%
}
else
{
%>
<form name="form1" action="/useragent/upload-form.asp" method="post" enctype="multipart/form-data">
<input type="file" name="filename">
<br>
<input type="submit" value="Submit" >
</form>
<%
}# end if()
%>
</body>
</html>