File Coverage

blib/lib/RPC/Any/Server/XMLRPC/HTTP.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 RPC::Any::Server::XMLRPC::HTTP;
2 1     1   24106 use Moose;
  0            
  0            
3             use HTTP::Status qw(RC_OK);
4             use HTTP::Response;
5             use URI::Escape qw(uri_unescape);
6             extends 'RPC::Any::Server::XMLRPC';
7             with 'RPC::Any::Interface::HTTP';
8              
9             has '+_default_headers' => (default => \&DEFAULT_HEADERS);
10              
11             use constant DEFAULT_HEADERS => {
12             Accept => 'text/xml',
13             Content_Type => 'text/xml; charset=UTF-8',
14             };
15              
16             around 'http_content' => sub {
17             my $orig = shift;
18             my $self = shift;
19             my ($request) = @_;
20             my $content = $self->$orig(@_);
21             if (uc($request->method) eq 'GET') {
22             $content = uri_unescape($content);
23             }
24             return $content;
25             };
26              
27             sub decode_input_to_object {
28             my ($self, $request) = @_;
29             my $content = $self->http_content($request);
30             # If we don't pass RPC::XML a UTF-8 tagged string, it doesn't parse
31             # UTF-8 properly.
32             my $content_charset = $request->content_charset || '';
33             if ($content_charset =~ /utf-8/i and !utf8::is_utf8($content)) {
34             utf8::decode($content);
35             }
36             return $self->SUPER::decode_input_to_object($content);
37             }
38              
39             sub encode_output_from_object {
40             my $self = shift;
41             my $output_string = $self->SUPER::encode_output_from_object(@_);
42             my $response = HTTP::Response->new();
43             utf8::encode($output_string) if utf8::is_utf8($output_string);
44             $response->header(Content_Length => length $output_string);
45             $response->code(RC_OK);
46             $response->content($output_string);
47             $response->protocol($self->last_request ? $self->last_request->protocol
48             : 'HTTP/1.0');
49             return $response;
50             }
51              
52             __PACKAGE__->meta->make_immutable;
53              
54             1;
55              
56             __END__
57              
58             =head1 NAME
59              
60             RPC::Any::Server::XMLRPC::HTTP - An XML-RPC server that understands HTTP
61              
62             =head1 SYNOPSIS
63              
64             use RPC::Any::Server::XMLRPC::HTTP;
65             # Create a server where calling Foo.bar will call My::Module->bar.
66             my $server = RPC::Any::Server::XMLRPC::HTTP->new(
67             dispatch => { 'Foo' => 'My::Module' },
68             send_nil => 0,
69             allow_get => 0,
70             );
71             # Read from STDIN and print result, including HTTP headers, to STDOUT.
72             print $server->handle_input();
73              
74             # HTTP servers also take HTTP::Request objects, if you want.
75             my $request = HTTP::Request->new(POST => '/');
76             $request->content('<?xml ... ');
77             print $server->handle_input($request);
78              
79             =head1 DESCRIPTION
80              
81             This is a type of L<RPC::Any::Server::XMLRPC> that understands HTTP.
82             It has all of the features of L<RPC::Any::Server>, L<RPC::Any::Server::XMLRPC>,
83             and L<RPC::Any::Interface::HTTP>. You should see those modules for
84             information on configuring this server and the way it works.
85              
86             For the most part, this implementation ignores HTTP headers on input.
87             However, it can be helpful to specify C<charset=UTF-8> in your
88             Content-Type request header if you want Unicode to be handled properly.
89              
90             =head1 HTTP GET SUPPORT
91              
92             There is no support for HTTP GET in the normal XML-RPC spec. However,
93             if you have C<allow_get> set to 1, then this server will accept
94             a query string that is raw (URI-escaped) XML as its XML-RPC input,
95             during GET requests. So, for example, you could call GET on a URL like:
96              
97             /?%3C%3Fxml%20version%3D%221.0%22%3E%3CmethodCall%3E...
98              
99             (That query string is the url-escaped version of
100             C<< <?xml version="1.0"><methodCall>... >>.)