/usr/local/CPAN/OpenResty/WWW/OpenResty/Embedded.pm
package WWW::OpenResty::Embedded;
use strict;
use warnings;
#use Smart::Comments;
use Carp;
use Params::Util qw( _HASH0 );
use OpenResty::Dispatcher;
use Data::Dumper;
use HTTP::Request;
use HTTP::Response;
use OpenResty::Util qw( new_mocked_cgi );
use CGI::Cookie;
use Test::Base;
use Encode qw(encode is_utf8);
our $Buffer;
our %Cookies;
*Test::Base::Handle::BINMODE = sub {};
sub new {
### @_
my $class = ref $_[0] ? ref shift : shift;
my $params = _HASH0(shift @_) or croak "Invalid params";
### $params
my $server = delete $params->{server} or
croak "No server specified.";
my $timer = delete $params->{timer};
OpenResty::Dispatcher->init;
tie_output(*STDOUT, $Buffer);
bless {
server => $server,
timer => $timer,
}, $class;
}
sub content_type {
$_[0]->{content_type} = $_[1];
}
sub login {
my ($self, $user, $password) = @_;
$self->get("/=/login/$user/$password");
}
sub get {
my $self = shift;
$self->request(undef, 'GET', @_);
}
sub post {
my $self = shift;
my $content = pop;
$self->request($content, 'POST', @_);
}
sub put {
my $self = shift;
my $content = pop;
$self->request($content, 'PUT', @_);
}
sub delete {
my $self = shift;
$self->request(undef, 'DELETE', @_);
}
sub request {
my ($self, $content, $method, $url, $params, $client_ip) = @_;
!defined $params or _HASH0($params) or
die "Params must be a hash: ", Dumper($params), "\n";
if ($params && %$params) {
if ($url =~ /\?/) {
die "? not allowed when params specified.\n";
} else {
my @params;
while (my ($key, $val) = each %$params) {
push @params, "$key=$val";
}
$url .= "?" . join '&', @params;
}
}
my $type = $self->{content_type};
$type ||= 'text/plain';
if ($url !~ /^http:\/\//) {
$url = $self->{server} . $url;
}
my $req = HTTP::Request->new($method);
$req->header('Content-Type' => $type);
$req->header('Accept', '*/*');
$req->url($url);
if ($content) {
if ($method eq 'GET' or $method eq 'HEAD') {
die "HTTP 1.0/1.1 $method request should not have content: $content\n";
}
$req->content($content);
} elsif ($method eq 'POST' or $method eq 'PUT') {
$req->header('Content-Length' => 0);
}
my $timer = $self->{timer};
$timer->start($method) if $timer;
my $res = _request($req, $client_ip);
#my $res = $ua->request($req);
$timer->stop($method) if $timer;
return $res;
}
sub _request {
my ($req, $client_ip) = @_;
my $http_meth = $req->method;
$ENV{REQUEST_METHOD} = $req->method;
my $uri = $req->uri;
#$uri =~ s/ /\%20/g;
$uri =~ s/^http:\/\/[^\/]+//;
if (is_utf8($uri)) {
$uri = encode('utf8', $uri);
}
$ENV{REQUEST_URI} = $uri;
(my $query = $uri) =~ s/(.*?\?)//g;
#$query .= '&';
$ENV{QUERY_STRING} = $query;
if (%Cookies) {
my @vals;
while (my ($key, $val) = each %Cookies) {
push @vals, $val->as_string;
}
$ENV{COOKIE} = join('; ', @vals);
### My cookie: $ENV{COOKIE}
}
my $cgi = new_mocked_cgi($uri, $req->content, $client_ip);
# warn $cgi->remote_host();
$Buffer = undef;
OpenResty::Dispatcher->process_request($cgi);
my $code;
#warn $Buffer;
if (is_utf8($Buffer)) {
$Buffer = encode('utf8', $Buffer);
}
if ($Buffer =~ /^HTTP\/1\.[01] (\d+) (\w+)\r?\n/) {
$code = $1;
} else {
$Buffer = "HTTP/1.1 200 OK\r\n$Buffer";
$code = 200;
}
my $res = HTTP::Response->parse($Buffer); # $code, $msg, $header, $content )
## $res
#warn "---------- res: ", $res->is_success;
my $raw_cookie = $res->header('Set-Cookie');
#warn "RAW Cookie: $raw_cookie\n";
if ($raw_cookie) {
%Cookies = (%Cookies, CGI::Cookie->parse($raw_cookie));
}
### %Cookies
## $raw_cookie
## $Buffer
$res;
}
1;