File Coverage

blib/lib/JSORB/Server/Simple.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package JSORB::Server::Simple;
2 4     4   42634 use Moose;
  0            
  0            
3              
4             use HTTP::Server::Simple;
5             use HTTP::Request;
6             use HTTP::Response;
7              
8             use Try::Tiny;
9             use JSON::RPC::Common::Marshal::HTTP;
10              
11             our $VERSION = '0.04';
12             our $AUTHORITY = 'cpan:STEVAN';
13              
14             with 'MooseX::Traits';
15              
16             has 'dispatcher' => (
17             is => 'ro',
18             isa => 'JSORB::Dispatcher::Path',
19             required => 1,
20             );
21              
22             has 'host' => (
23             is => 'ro',
24             isa => 'Str',
25             default => sub { 'localhost' },
26             );
27              
28             has 'port' => (
29             is => 'ro',
30             isa => 'Int',
31             default => sub { 9999 },
32             );
33              
34             has 'request_marshaler' => (
35             is => 'ro',
36             isa => 'JSON::RPC::Common::Marshal::HTTP',
37             default => sub {
38             JSON::RPC::Common::Marshal::HTTP->new
39             },
40             );
41              
42             has 'handler' => (
43             is => 'ro',
44             isa => 'CodeRef',
45             lazy => 1,
46             builder => 'build_handler',
47             );
48              
49             has 'server_engine' => (
50             is => 'ro',
51             isa => 'Moose::Meta::Class',
52             lazy => 1,
53             default => sub {
54             my $self = shift;
55             my $handler = $self->handler;
56             Moose::Meta::Class->create_anon_class(
57             superclasses => [ 'HTTP::Server::Simple' ],
58             methods => {
59             'setup' => sub {
60             my ($self, %setup) = @_;
61             $self->{'__setup__'} = \%setup;
62             },
63             'headers' => sub {
64             my ($self, $headers) = @_;
65             $self->{'__headers__'} = $headers;
66             },
67             'handler' => sub {
68             my $self = shift;
69             my $output = $handler->(
70             HTTP::Request->new(
71             $self->{'__setup__'}->{'method'},
72             $self->{'__setup__'}->{'request_uri'},
73             $self->{'__headers__'}
74             )
75             )->as_string;
76             chomp($output);
77             $self->stdio_handle->print( "HTTP/1.0 $output" );
78             }
79             }
80             );
81             },
82             );
83              
84             sub prepare_handler_args { () }
85              
86             sub build_handler {
87             my $self = shift;
88             my $m = $self->request_marshaler;
89             my $d = $self->dispatcher;
90             return sub {
91             my $request = shift;
92             try {
93             my $call = $m->request_to_call($request);
94             my $result = $d->handler(
95             $call,
96             $self->prepare_handler_args($call, $request)
97             );
98             $m->result_to_response($result);
99             } catch {
100             # NOTE:
101             # should this return a JSONRPC error?
102             # or is the standard HTTP Error okay?
103             # - SL
104             HTTP::Response->new( 500, 'Internal Server Error', [], $_ );
105             };
106             }
107             }
108              
109             # NOTE:
110             # we need to initialize the server
111             # engine so that it can be run
112             # after a fork() such as in our
113             # tests. Otherwise the laziness
114             # messes things up. However it needs
115             # to be lazy in order to use the
116             # other attributes when creating
117             # itself.
118             # -SL
119             sub BUILD { (shift)->server_engine }
120              
121             sub _setup_server {
122             my $self = shift;
123             my $server = $self->server_engine->name->new;
124             $server->port( $self->port );
125             $server->host( $self->host );
126             $server;
127             }
128              
129             sub run { (shift)->_setup_server->run }
130             sub background { (shift)->_setup_server->background }
131              
132             __PACKAGE__->meta->make_immutable;
133              
134             no Moose; 1;
135              
136             __END__
137              
138             =pod
139              
140             =head1 NAME
141              
142             JSORB::Server::Simple - A simple HTTP server for JSORB
143              
144             =head1 DESCRIPTION
145              
146             This is just a simple JSORB server built on top of
147             L<HTTP::Server::Simple>. This is probably best used for
148             development and small standalone apps but probably not in
149             heavy production use (hence the ::Simple).
150              
151             =head1 BUGS
152              
153             All complex software has bugs lurking in it, and this module is no
154             exception. If you find a bug please either email me, or add the bug
155             to cpan-RT.
156              
157             =head1 AUTHOR
158              
159             Stevan Little E<lt>stevan.little@iinteractive.comE<gt>
160              
161             =head1 COPYRIGHT AND LICENSE
162              
163             Copyright 2008-2010 Infinity Interactive, Inc.
164              
165             L<http://www.iinteractive.com>
166              
167             This library is free software; you can redistribute it and/or modify
168             it under the same terms as Perl itself.
169              
170             =cut