File Coverage

blib/lib/HTTP/DAVServer.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             #!/Applications/Alloy/Library/bin/perl
2              
3 1     1   20495 use strict;
  1         2  
  1         37  
4 1     1   5 use warnings;
  1         3  
  1         69  
5              
6             package HTTP::DAVServer;
7              
8             our $VERSION=0.1;
9              
10             =head1 NAME
11              
12             HTTP::DAVServer - allows you to write server-side functions to accept, process and respond to WebDAV client requests. WebDAV - RFC 2518 - is a protocol which allows clients to manipulate files on a remote server using HTTP.
13              
14             =head1 SYNOPSIS
15              
16             In your favorite NPH CGI script ( for now )
17              
18             use HTTP::DAVServer;
19             HTTP::DAVServer->handle;
20              
21             You will need to add directives to Apache to request that certain methods be
22             handled by the CGI script:
23              
24             Script PROPFIND /cgi-bin/nph-webdav
25             Script PUT /cgi-bin/nph-webdav
26            
27             See INSTALL for more details. See INSTALL for important warning!
28              
29             =head1 MODULE STATUS
30              
31             This module is a prototype. Please see INSTALL for important warnings. You should try this module
32             if you're interested in developing a customized WebDAV server and you want to use Perl to do
33             most or all of fancy footwork behind the scenes.
34              
35             My short term goal is to provide a reference implementation of a WebDAV server which can be subclassed
36             for specific implementation features. Information to resolve any of the following bugs is most welcome! I will
37             be fixing all the failed items in copymove next.
38              
39             Litmus test results:
40              
41             http and basic tests are good, some errors on copymove and propfind. proppatch not done so skips lots of tests.
42              
43             -> running `http':
44             0. init.................. pass
45             1. begin................. pass
46             2. expect100............. pass
47             3. finish................ pass
48             <- summary for `http': of 4 tests run: 4 passed, 0 failed. 100.0%
49              
50             -> running `basic':
51             0. init.................. pass
52             1. begin................. pass
53             2. options............... WARNING: server does not claim Class 2 compliance
54             ...................... pass (with 1 warning)
55             3. put_get............... pass
56             4. put_get_utf8_segment.. pass
57             5. mkcol_over_plain...... pass
58             6. delete................ pass
59             7. delete_null........... pass
60             8. mkcol................. pass
61             9. mkcol_again........... pass
62             10. delete_coll........... pass
63             11. mkcol_no_parent....... pass
64             12. mkcol_with_body....... pass
65             13. finish................ pass
66             <- summary for `basic': of 14 tests run: 14 passed, 0 failed. 100.0%
67             -> 1 warning was issued.
68              
69             -> running `copymove':
70             0. init.................. pass
71             1. begin................. pass
72             2. copy_init............. pass
73             3. copy_simple........... FAIL
74             4. copy_overwrite........ WARNING: COPY-on-existing fails with 412
75             ...................... FAIL
76             5. copy_cleanup.......... pass
77             6. copy_coll............. FAIL
78             7. move.................. FAIL
79             8. move_coll............. FAIL
80             9. move_cleanup.......... pass
81             10. finish................ pass
82             <- summary for `copymove': of 11 tests run: 6 passed, 5 failed. 54.5%
83             -> 1 warning was issued.
84              
85             -> running `props':
86             0. init.................. pass
87             1. begin................. pass
88             2. propfind_invalid...... pass
89             3. propfind_invalid2..... pass
90             4. propfind_d0........... FAIL (No responses returned)
91             5. propinit.............. pass
92             6. propset............... FAIL (PROPPATCH on `/litmus/litmus/prop': 400 Bad Request)
93             7. propget............... SKIPPED
94             8. propmove.............. SKIPPED
95             9. propget............... SKIPPED
96             10. propdeletes........... SKIPPED
97             11. propget............... SKIPPED
98             12. propreplace........... SKIPPED
99             13. propget............... SKIPPED
100             14. propnullns............ SKIPPED
101             15. propget............... SKIPPED
102             16. prophighunicode....... SKIPPED
103             17. propget............... SKIPPED
104             18. propvalnspace......... SKIPPED
105             19. propwformed........... pass
106             20. propinit.............. pass
107             21. propmanyns............ FAIL (PROPPATCH on `/litmus/litmus/prop': 400 Bad Request)
108             22. propget............... FAIL (PROPFIND on `/litmus/litmus/prop': 400 Bad Request)
109             23. propcleanup........... pass
110             24. finish................ pass
111             -> 12 tests were skipped.
112             <- summary for `props': of 13 tests run: 9 passed, 4 failed. 69.2%
113              
114             =head1 DEPENDENCIES
115              
116             This code requires:
117              
118             XML::Simple
119             XML::SAX (for namespace support in XML::Simple)
120             DateTime (THE new Date and Time support in Perl)
121              
122             =cut
123              
124              
125 1     1   1973 use CGI qw();
  1         16660  
  1         24  
126              
127 1     1   366 use XML::Simple qw();
  0            
  0            
128             use DateTime qw();
129              
130             sub dateEpoch { DateTime->from_epoch( epoch =>$_[0] )->iso8601 }
131              
132             our $WARN =1;
133             our $TRACE =1;
134             our $PUBLIC=1;
135              
136             use HTTP::DAVServer::AuthDigest qw();
137              
138             our ($ROOT, $HOST) = ("", "");
139              
140             sub handle {
141              
142             my $self=shift;
143              
144             if ($TRACE) {
145             eval "use Data::Dumper;";
146             no warnings;
147             $Data::Dumper::Indent=1;
148             $Data::Dumper::Sortkeys=1;
149             }
150              
151             $ROOT=$ENV{'DOCUMENT_ROOT'};
152             $ROOT =~ s#/+$##;
153             $HOST =$ENV{'HTTP_HOST'};
154              
155             my $r=new CGI;
156             my $method =$r->request_method;
157             my $contLen=$ENV{'CONTENT_LENGTH'} || 0;
158              
159             my $responder="${self}::Respond";
160             eval "use $responder";
161             die "LOADRESPOND error $@\n" if $@;
162              
163             $responder->badRequest($r, "NOHANDLE", $method) unless $responder->handles( $method );
164              
165             $responder->badRequest($r, "MISSCONT") if $responder->hasContent( $method ) == 1 && $contLen == 0;
166             if ($responder->hasContent( $method ) == 0 && $contLen != 0) {
167             $method eq "MKCOL" && $responder->unsupported($r);
168             $responder->badRequest($r, "HASCONT" );
169             }
170              
171             $responder->challenge($r) unless $PUBLIC
172             || $ENV{'REMOTE_USER'}
173             || HTTP::DAVServer::AuthDigest::authenticate( sub { return $_[0] } );
174              
175             my $request={};
176             if ($contLen && $method ne "PUT") {
177              
178             $responder->badRequest($r) unless $r->content_type eq "text/xml";
179              
180             $request = eval {
181              
182             if ($TRACE) {
183             local undef $/;
184             my $xmlin=<>;
185             warn "REQUEST XML:\n$xmlin\n";
186             XML::Simple::XMLin( $xmlin, nsexpand => 1 );
187             } else {
188             XML::Simple::XMLin( "-", nsexpand => 1 );
189             }
190              
191             };
192              
193             $responder->badRequest($r, "BADXML", $@) if $@;
194              
195              
196             }
197              
198             warn ("ENV: ", Dumper (\%ENV), "METHOD: $method\nSUBMITTED XML: ", Dumper ($request)) if $TRACE;
199              
200             my $url=CGI::Util::unescape($ENV{'REQUEST_URI'});
201             $url=~s#/+$##;
202              
203             eval "use ${self}::$method";
204             $responder->serverError( $r, "LOAD$method", $@ ) if $@;
205             "${self}::$method"->handle( $r, $url, $responder, $request );
206              
207             }
208              
209             =head1 SUPPORT
210              
211             For technical support please email to jlawrenc@cpan.org ...
212             for faster service please include "HTTP::DAVServer" and "help" in your subject line.
213              
214             =head1 AUTHOR
215              
216             Jay J. Lawrence - jlawrenc@cpan.org
217             Infonium Inc., Canada
218             http://www.infonium.ca/
219              
220             =head1 COPYRIGHT
221              
222             Copyright (c) 2003 Jay J. Lawrence, Infonium Inc. All rights reserved.
223             This program is free software; you can redistribute
224             it and/or modify it under the same terms as Perl itself.
225              
226             The full text of the license can be found in the
227             LICENSE file included with this module.
228              
229             =head1 ACKNOWLEDGEMENTS
230              
231             Thank you to the authors of my prequisite modules. With out your help this code
232             would be much more difficult to write!
233              
234             XML::Simple - Grant McLean
235             XML::SAX - Matt Sergeant
236             DateTime - Dave Rolsky
237              
238             Also the authors of litmus, a very helpful tool indeed!
239              
240             =head1 SEE ALSO
241              
242             HTTP::DAV, HTTP::Webdav, http://www.webdav.org/, RFC 2518
243              
244             =cut
245              
246             1;