File Coverage

blib/lib/CGI/XMLPost.pm
Criterion Covered Total %
statement 25 58 43.1
branch 3 12 25.0
condition 2 19 10.5
subroutine 8 13 61.5
pod 10 10 100.0
total 48 112 42.8


line stmt bran cond sub pod time code
1             package CGI::XMLPost;
2              
3 1     1   444 use strict;
  1         1  
  1         22  
4 1     1   3 use warnings;
  1         1  
  1         21  
5              
6 1     1   2 use Carp;
  1         1  
  1         598  
7              
8             our $VERSION = '1.6';
9              
10             # Ripped off from CGI.pm
11              
12             our $CRLF;
13              
14             my $EBCDIC = "\t" ne "\011";
15              
16             if ($^O eq 'VMS')
17             {
18             $CRLF = "\n";
19             }
20             elsif ($EBCDIC)
21             {
22             $CRLF= "\r\n";
23             }
24             else
25             {
26             $CRLF = "\015\012";
27             }
28              
29             =head1 NAME
30              
31             CGI::XMLPost - receive XML file as an HTTP POST
32              
33             =head1 SYNOPSIS
34              
35             use CGI::XMLPost;
36              
37             my $xmlpost = CGI::XMLPost->new();
38              
39             my $xml = $xmlpost->data();
40              
41             # ... do something with $xml
42              
43             =head1 DESCRIPTION
44              
45             CGI::XMLPost is a lightweight module for receiving XML documents in the
46             body of an HTTP request. It provides some utility methods that make it
47             easier to work in a CGI environment without requiring any further modules.
48              
49             =head1 METHODS
50              
51              
52             =over 4
53              
54             =cut
55              
56              
57             =item new
58              
59             This is the constructor of the class. If it succeeds in reading the POST
60             data correct it will return a a blessed object - otherwise undef.
61              
62             The arguments are in the form of a hash reference - the keys are :
63              
64             =over 2
65              
66             =item strict
67              
68             If this is set to a true value then the HTTP request method and content type
69             are checked. If the first is not POST and the second does not match 'xml$'
70             then the method will return undef.
71              
72             =back
73              
74             =cut
75              
76             sub new
77             {
78 1     1 1 355 my ( $proto, $args ) = @_;
79              
80 1   33     8 my $class = ref($proto) || $proto;
81              
82            
83 1         3 my $self = bless {}, $class;
84              
85 1 50       4 if ( $args->{strict} )
86             {
87 1 50 33     2 if ( $self->request_method() ne 'POST' or $self->content_type !~ /xml$/ )
88             {
89 0         0 return undef;
90             }
91             }
92              
93 1         3 my $cl = $self->content_length();
94              
95 1 50       21 if ( sysread( STDIN, $self->{_data}, $cl) == $cl )
96             {
97 1         4 return $self;
98             }
99             }
100              
101             =item content_type
102              
103             Returns the content type of the HTTP request.
104              
105             =cut
106              
107             sub content_type
108             {
109 2     2 1 2 my ( $self ) = @_;
110              
111 2         12 return $ENV{CONTENT_TYPE};
112             }
113              
114             =item request_method
115              
116             Returns the request method of the HTTP request.
117              
118             =cut
119              
120             sub request_method
121             {
122 1     1 1 2 my ( $self ) = @_;
123              
124 1         8 return $ENV{REQUEST_METHOD};
125             }
126              
127              
128             =item content_length
129              
130             Returns the content length of the request.
131              
132             =cut
133              
134             sub content_length
135             {
136 2     2 1 3 my ( $self ) = @_;
137              
138 2         5 return $ENV{CONTENT_LENGTH};
139             }
140              
141             =item data
142              
143             Returns the data as read from the body of the HTTP request.
144              
145             =cut
146              
147             sub data
148             {
149 1     1 1 243 my ( $self ) = @_;
150              
151 1         5 return $self->{_data};
152             }
153              
154             =item encoding
155              
156             Gets or sets the encoding used in the response. The default is utf-8
157              
158             =cut
159              
160             sub encoding
161             {
162 0     0 1   my ( $self, $encoding ) = @_;
163              
164 0 0         if ( defined $encoding )
165             {
166 0           $self->{_encoding} = $encoding;
167             }
168              
169 0   0       return $self->{_encoding} || 'utf-8';
170             }
171              
172             =item header
173              
174             Returns a header suitable to be used in an HTTP response. The arguments are
175             in the form of key/value pairs - valid keys are :
176              
177             =over 2
178              
179             =item status
180              
181             The HTTP status code to be returned - the default is 200 (OK).
182              
183             =item type
184              
185             The content type of the response - the default is 'application/xml'.
186              
187             =back
188              
189             =cut
190              
191             sub header
192             {
193 0     0 1   my ( $self, %args ) = @_;
194              
195 0           my @header;
196              
197 0   0       $self->{status} = $args{status} || 200;
198              
199 0           push @header, "Status: $self->{status}";
200              
201 0   0       $self->{type} = $args{type} || 'application/xml';
202              
203 0           my $charset = $self->encoding();
204              
205 0           push @header, "Content-Type: $self->{type}; charset=$charset";
206              
207 0           my $header = join $CRLF, @header;
208              
209 0           $header .= $CRLF x 2;
210              
211 0           return $header;
212              
213             }
214              
215             my %status_codes = (
216             200 => "OK",
217             405 => "Method Not Allowed",
218             415 => "Unsupported Media Type",
219             400 => "Bad Request",
220             );
221              
222             =item response
223              
224             Returns a string that is suitable to be sent in the body of the response.
225             The default is to return an XML string of the form :
226              
227            
228            
229             $status
230             $text
231            
232            
233             Where $status is the status code used in the header as described above and
234             $text is the desciptive text for that status. If a different text is required
235             this can be supplied with the argument key 'text'.
236              
237             =cut
238              
239             sub response
240             {
241 0     0 1   my ( $self, %args ) = @_;
242              
243 0   0       my $status = $self->{status} || 200;
244 0   0       my $text = $args{text} || $status_codes{$status};
245              
246 0   0       my $type = $self->{type} || 'application/xml';
247              
248 0           my $response;
249              
250 0           my $encoding = $self->encoding();
251              
252 0 0         if ( $type =~ /xml$/i )
253             {
254 0           $response =<
255            
256            
257             $status
258             $text
259            
260             EOX
261             }
262             else
263             {
264 0           $response = $text;
265             }
266 0           return $response;
267             }
268              
269             =item remote_address
270              
271             Remotes the address of the remote peer if it is known.
272              
273             =cut
274              
275             sub remote_address
276             {
277 0     0 1   my ( $self ) = @_;
278 0           return $ENV{REMOTE_ADDRESS};
279             }
280              
281             =item as_xpath
282              
283             Returns an XML::XPath object inititialized with the received XML or a false
284             value if XML::XPath is not present or the parse failed.
285              
286             =cut
287              
288             sub as_xpath
289             {
290 0     0 1   my ( $self ) = @_;
291              
292 0           my $got_xpath = undef;
293              
294             eval
295 0           {
296 0           require XML::XPath;
297 0           $got_xpath = 1;
298             };
299              
300 0 0         return $got_xpath ? XML::XPath->new(xml => $self->data()) : undef;
301             }
302              
303             1;
304             __END__