ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-FCP/FCP.pm
(Generate patch)

Comparing Net-FCP/FCP.pm (file contents):
Revision 1.6 by root, Mon Sep 8 00:36:44 2003 UTC vs.
Revision 1.8 by root, Mon Sep 8 01:47:31 2003 UTC

31package Net::FCP; 31package Net::FCP;
32 32
33use Carp; 33use Carp;
34use IO::Socket::INET; 34use IO::Socket::INET;
35 35
36$VERSION = 0.03; 36$VERSION = 0.04;
37 37
38sub event_reg_cb { 38sub event_reg_cb {
39 my ($obj) = @_; 39 my ($obj) = @_;
40 require Event; 40 require Event;
41 41
70 70
71sub tolc($) { 71sub tolc($) {
72 local $_ = shift; 72 local $_ = shift;
73 s/(?<=[a-z])(?=[A-Z])/_/g; 73 s/(?<=[a-z])(?=[A-Z])/_/g;
74 lc $_; 74 lc $_;
75}
76
77=item $meta = Net::FCP::parse_metadata $string
78
79Parse a metadata string and return it.
80
81The metadata will be a hashref with key C<version> (containing
82the mandatory version header entries).
83
84All other headers are represented by arrayrefs (they can be repeated).
85
86Since this is confusing, here is a rather verbose example of a parsed
87manifest:
88
89 (
90 version => { revision => 1 },
91 document => [
92 {
93 "info.format" => "image/jpeg",
94 name => "background.jpg",
95 "redirect.target" => "freenet:CHK\@ZcagI,ra726bSw"
96 },
97 {
98 "info.format" => "text/html",
99 name => ".next",
100 "redirect.target" => "freenet:SSK\@ilUPAgM/TFEE/3"
101 },
102 {
103 "info.format" => "text/html",
104 "redirect.target" => "freenet:CHK\@8M8Po8ucwI,8xA"
105 }
106 ]
107 )
108
109=cut
110
111sub parse_metadata {
112 my $meta;
113
114 my $data = shift;
115 if ($data =~ /^Version\015?\012/gc) {
116 my $hdr = $meta->{version} = {};
117
118 for (;;) {
119 while ($data =~ /\G([^=\015\012]+)=([^\015\012]*)\015?\012/gc) {
120 my ($k, $v) = ($1, $2);
121 $hdr->{tolc $k} = $v;
122 }
123
124 if ($data =~ /\GEndPart\015?\012/gc) {
125 } elsif ($data =~ /\GEnd\015?\012/gc) {
126 last;
127 } elsif ($data =~ /\G([A-Za-z0-9.\-]+)\015?\012/gcs) {
128 push @{$meta->{tolc $1}}, $hdr = {};
129 } elsif ($data =~ /\G(.*)/gcs) {
130 die "metadata format error ($1)";
131 }
132 }
133 }
134
135 #$meta->{tail} = substr $data, pos $data;
136
137 $meta;
75} 138}
76 139
77=item $fcp = new Net::FCP [host => $host][, port => $port] 140=item $fcp = new Net::FCP [host => $host][, port => $port]
78 141
79Create a new virtual FCP connection to the given host and port (default 142Create a new virtual FCP connection to the given host and port (default
187=cut 250=cut
188 251
189_txn generate_chk => sub { 252_txn generate_chk => sub {
190 my ($self, $metadata, $data) = @_; 253 my ($self, $metadata, $data) = @_;
191 254
192 $self->txn (generate_chk => data => "$data$metadata", meta_data_length => length $metadata); 255 $self->txn (generate_chk => data => "$data$metadata", metadata_length => length $metadata);
193}; 256};
194 257
195=item $txn = $fcp->txn_generate_svk_pair 258=item $txn = $fcp->txn_generate_svk_pair
196 259
197=item ($public, $private) = @{ $fcp->generate_svk_pair } 260=item ($public, $private) = @{ $fcp->generate_svk_pair }
248 $self->txn (get_size => URI => $uri); 311 $self->txn (get_size => URI => $uri);
249}; 312};
250 313
251=item $txn = $fcp->txn_client_get ($uri [, $htl = 15 [, $removelocal = 0]]) 314=item $txn = $fcp->txn_client_get ($uri [, $htl = 15 [, $removelocal = 0]])
252 315
253=item ($data, $metadata) = @{ $fcp->client_get ($uri, $htl, $removelocal) 316=item ($metadata, $data) = @{ $fcp->client_get ($uri, $htl, $removelocal)
254 317
255Fetches a (small, as it should fit into memory) file from freenet. 318Fetches a (small, as it should fit into memory) file from
319freenet. C<$meta> is the metadata (as returned by C<parse_metadata> or
320C<undef>).
256 321
257Due to the overhead, a better method to download big fiels should be used. 322Due to the overhead, a better method to download big files should be used.
258 323
259 my ($data, $meta) = @{ 324 my ($meta, $data) = @{
260 $fcp->client_get ( 325 $fcp->client_get (
261 "freenet:CHK@hdXaxkwZ9rA8-SidT0AN-bniQlgPAwI,XdCDmBuGsd-ulqbLnZ8v~w" 326 "freenet:CHK@hdXaxkwZ9rA8-SidT0AN-bniQlgPAwI,XdCDmBuGsd-ulqbLnZ8v~w"
262 ) 327 )
263 }; 328 };
264 329
355 } else { 420 } else {
356 last; 421 last;
357 } 422 }
358 } elsif ($self->{buf} =~ s/^DataChunk\015?\012Length=([0-9a-fA-F]+)\015?\012Data\015?\012//) { 423 } elsif ($self->{buf} =~ s/^DataChunk\015?\012Length=([0-9a-fA-F]+)\015?\012Data\015?\012//) {
359 $self->{datalen} = hex $1; 424 $self->{datalen} = hex $1;
360 } elsif ($self->{buf} =~ s/^([a-zA-Z]+)\015?\012(.*?)\015?\012EndMessage\015?\012//s) { 425 } elsif ($self->{buf} =~ s/^([a-zA-Z]+)\015?\012(?:(.+?)\015?\012)?EndMessage\015?\012//s) {
361 $self->rcv ($1, { 426 $self->rcv ($1, {
362 map { my ($a, $b) = split /=/, $_, 2; ((Net::FCP::tolc $a), $b) } 427 map { my ($a, $b) = split /=/, $_, 2; ((Net::FCP::tolc $a), $b) }
363 split /\015?\012/, $2 428 split /\015?\012/, $2
364 }); 429 });
365 } else { 430 } else {
491 556
492sub rcv_data_found { 557sub rcv_data_found {
493 my ($self, $attr) = @_; 558 my ($self, $attr) = @_;
494 559
495 $self->{datalength} = hex $attr->{data_length}; 560 $self->{datalength} = hex $attr->{data_length};
496 $self->{metalength} = hex $attr->{meta_data_length}; 561 $self->{metalength} = hex $attr->{metadata_length};
562}
563
564sub rcv_restarted {
565 # nop, maybe feedback
497} 566}
498 567
499sub eof { 568sub eof {
500 my ($self) = @_; 569 my ($self) = @_;
501 #use PApp::Util; warn PApp::Util::dumpval $self; 570
502 my $data = delete $self->{data}; 571 my $data = delete $self->{data};
572 my $meta = Net::FCP::parse_metadata substr $data, 0, $self->{metalength}, "";
573
503 $self->set_result ([ 574 $self->set_result ([$meta, $data]);
504 (substr $data, 0, $self->{datalength}-$self->{metalength}),
505 (substr $data, $self->{datalength}-$self->{metalength}),
506 ]);
507} 575}
508 576
509=back 577=back
510 578
511=head1 SEE ALSO 579=head1 SEE ALSO

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines