root/trunk/examples/mogilefs-dav.pl

Revision 1117, 5.2 kB (checked in by hachi, 1 year ago)

Editor modelines

  • Property svn:executable set to *
Line 
1 #!/usr/bin/perl
2
3 # hachi 20070227
4 # This is a partially finished server implemented using Net::DAV::Server and the FilePaths plugin for MogileFS.
5
6 use strict;
7 use warnings;
8
9 use HTTP::Daemon;
10 #use Filesys::Virtual::MogileFS; # Below for the time being
11 use Net::DAV::Server;
12
13 my $filesys = Filesys::Virtual::MogileFS->new;
14 my $webdav = Net::DAV::Server->new();
15
16 $webdav->filesys($filesys);
17
18 my $d = HTTP::Daemon->new(
19     LocalAddr => '0.0.0.0',
20     LocalPort => 8008,
21     ReuseAddr => 1) || die $!;
22
23 print $d->url . "\n";
24
25 while (my $c = $d->accept) {
26     while (my $request = $c->get_request) {
27         my $response = eval { $webdav->run($request) };
28         warn "EVAL: $@" if $@;
29         $c->send_response($response);
30     }
31     $c->close;
32     undef $c;
33 }
34
35 package Filesys::Virtual::MogileFS;
36
37 use strict;
38 use warnings;
39
40 use lib 'cvs/mogilefs/api/perl/MogileFS-Client/lib';
41 use lib 'cvs/mogilefs/api/perl/MogileFS-Client-FilePaths/lib';
42
43 use base 'Filesys::Virtual';
44
45 use Fcntl qw(:mode);
46 use LWP::Simple;
47 use MogileFS::Client::FilePaths;
48 use Tie::Handle::HTTP;
49
50 sub new {
51     my $class = shift;
52     my $self = bless {
53         cwd => '/',
54     }, (ref $class || $class);
55
56     my $mogclient = MogileFS::Client::FilePaths->new(
57         hosts => ['127.0.0.1:7001'],
58         domain => "filepaths",
59     );
60
61     die unless $mogclient;
62
63     $self->{mogclient} = $mogclient;
64
65     return $self;
66 }
67
68 sub mogclient { return $_[0]->{mogclient}; }
69
70 sub open_write {
71     my $self = shift;
72     my $path = $self->_fixup_path(shift);
73
74     open(my $handle, "+>", undef) or die("Couldn't open a tempfile?: $!");
75
76     # Look at me, I'm graham barr!
77     *{$handle} = \$path;
78
79     return $handle;
80 }
81
82 sub close_write {
83     my $self = shift;
84     my $handle = shift;
85
86     my $size = (stat($handle))[7];
87
88     my $path = ${*{$handle}{SCALAR}};
89     my $mog_handle = $self->mogclient->new_file($path, 'temp', $size,
90                                                 {
91                                                     meta => {
92                                                                 mtime => scalar(time),
93                                                             },
94                                                 });
95
96     seek($handle, 0, 0) or die("Couldn't seek to 0");
97
98     while (sysread $handle, my $buffer, 1024) {
99         print $mog_handle $buffer;
100     }
101     close $handle;
102     close $mog_handle;
103 }
104
105 sub open_read {
106     my $self = shift;
107     my $path = $self->_fixup_path(shift);
108
109     my @paths = $self->mogclient->get_paths($path);
110
111     return unless @paths;
112
113     my $handle = Tie::Handle::HTTP->new($paths[0]);
114
115     return $handle;
116 }
117
118 sub close_read {
119     my $self = shift;
120     my $handle = shift;
121
122     close $handle;
123 }
124
125 sub list {
126     my $self = shift;
127     my $path = $self->_fixup_path(shift);
128
129     my @listing = $self->mogclient->list($path);
130
131     return unless @listing;
132
133     my @files = map {$_->{name}} @listing;
134
135     return @files;
136 }
137
138 my @dir_stat = (
139     e => 1,
140     d => 1,
141 );
142
143 my @file_stat = (
144     e => 1,
145     d => 0,
146     s => 1025,
147 );
148
149 sub MODE_DIR  () { S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO }
150 sub MODE_FILE () { S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH }
151
152 sub stat {
153     my $self = shift;
154     my $path = $self->_fixup_path(shift);
155
156     my $mogclient = $self->mogclient;
157
158     my @paths = $mogclient->get_paths($path);
159
160     if (@paths) {
161         if (my ($content_type, $document_length, $modified_time, $expires, $server) = head($paths[0])) {
162             return ($$, 0, MODE_FILE, 1, 0, 0, undef, $document_length, time, $modified_time, $^T, 512, 512);
163         }
164         return ($$, 0, MODE_FILE, 1, 0, 0, undef, 1024, time, $^T, $^T, 512, 512);
165     }
166
167     my @listing = $mogclient->list($path);
168
169     if (scalar(@listing) || $path eq '/') {
170         return ($$, 0, MODE_DIR, 1, 0, 0, undef, 1024, time, $^T, $^T, 512, 512);
171     }
172
173     return;
174 }
175
176 <<EOT;
177 0 dev
178 1 ino
179 2 mode
180 3 nlink
181 4 uid
182 5 gid
183 6 rdev
184 7 size
185 8 atime
186 9 mtime
187 10 ctime
188 11 blksize
189 12 blocks
190 EOT
191
192
193 sub test {
194     my $self = shift;
195     my $test = shift;
196     my $path = $self->_fixup_path(shift);
197     warn "Test: $test on $path\n" if 0;
198
199     my @stat = $self->stat($path);
200
201     return 0 unless @stat;
202
203     my $tests = {
204         'e' => sub {
205             return 1;
206         },
207         's' => sub {
208             return $stat[7];
209         },
210         'f' => sub {
211             return S_ISREG($stat[2]);
212         },
213         'd' => sub {
214             return S_ISDIR($stat[2]);
215         },
216         'r' => sub {
217             return 1;
218         },
219     };
220
221     if (exists $tests->{$test}) {
222         my $result = $tests->{$test}->();
223         warn "Result: $result\n" if 0;
224         return $result;
225     }
226
227     warn "No test defined for $test on file $path\n";
228 }
229
230 sub cwd {
231     my $self = shift;
232     my $cwd = $self->{cwd};
233     return $cwd;
234 }
235
236 sub chdir {
237     my $self = shift;
238     my $path = shift;
239     return $self->{cwd} = $path;
240 }
241
242 sub delete {
243     my $self = shift;
244     my $path = $self->_fixup_path(shift);
245
246     $self->mogclient->delete($path);
247 }
248
249 sub _fixup_path {
250     my $self = shift;
251     my $path = shift;
252
253     unless (defined $path) {
254         $path = '';
255     }
256
257     if ($path =~ m!^/!) {
258         return $path;
259     }
260
261     my $cwd = $self->{cwd};
262     $cwd =~ s!/*$!/!;
263     return "${cwd}${path}";
264 }
265
266 1;
267
268 # vim: filetype=perl softtabstop=4 expandtab
Note: See TracBrowser for help on using the browser.