File Coverage

blib/lib/CGI/XMLPost.pm
Criterion Covered Total %
statement 28 61 45.9
branch 3 12 25.0
condition 2 19 10.5
subroutine 9 14 64.2
pod 10 10 100.0
total 52 116 44.8


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