1 |
NAME |
2 |
Net::FCP - http://freenet.sf.net client protocol |
3 |
|
4 |
SYNOPSIS |
5 |
use Net::FCP; |
6 |
|
7 |
my $fcp = new Net::FCP; |
8 |
|
9 |
my $ni = $fcp->txn_node_info->result; |
10 |
my $ni = $fcp->node_info; |
11 |
|
12 |
DESCRIPTION |
13 |
See <http://freenet.sourceforge.net/index.php?page=fcp> for a |
14 |
description of what the messages do. I am too lazy to document all this |
15 |
here. |
16 |
|
17 |
WARNING |
18 |
This module is alpha. While it probably won't destroy (much :) of your |
19 |
data, it currently falls short of what it should provide (intelligent |
20 |
uri following, splitfile downloads, healing...) |
21 |
|
22 |
IMPORT TAGS |
23 |
Nothing much can be "imported" from this module right now. There are, |
24 |
however, certain "import tags" that can be used to select the event |
25 |
model to be used. |
26 |
|
27 |
Event models are implemented as modules under the "Net::FCP::Event::xyz" |
28 |
class, where "xyz" is the event model to use. The default is "Event" (or |
29 |
later "Auto"). |
30 |
|
31 |
The import tag to use is named "event=xyz", e.g. "event=Event", |
32 |
"event=Glib" etc. |
33 |
|
34 |
You should specify the event module to use only in the main program. |
35 |
|
36 |
If no event model has been specified, FCP tries to autodetect it on |
37 |
first use (e.g. first transaction), in this order: Coro, Event, Glib, |
38 |
Tk. |
39 |
|
40 |
FREENET BASICS |
41 |
Ok, this section will not explain any freenet basics to you, just some |
42 |
problems I found that you might want to avoid: |
43 |
|
44 |
freenet URIs are _NOT_ URIs |
45 |
Whenever a "uri" is required by the protocol, freenet expects a kind |
46 |
of URI prefixed with the "freenet:" scheme, e.g. "freenet:CHK...". |
47 |
However, these are not URIs, as freeent fails to parse them |
48 |
correctly, that is, you must unescape an escaped characters ("%2c" |
49 |
=> ",") yourself. Maybe in the future this library will do it for |
50 |
you, so watch out for this incompatible change. |
51 |
|
52 |
Numbers are in HEX |
53 |
Virtually every number in the FCP protocol is in hex. Be sure to use |
54 |
"hex()" on all such numbers, as the module (currently) does nothing |
55 |
to convert these for you. |
56 |
|
57 |
THE Net::FCP CLASS |
58 |
$meta = Net::FCP::parse_metadata $string |
59 |
Parse a metadata string and return it. |
60 |
|
61 |
The metadata will be a hashref with key "version" (containing the |
62 |
mandatory version header entries) and key "raw" containing the |
63 |
original metadata string. |
64 |
|
65 |
All other headers are represented by arrayrefs (they can be |
66 |
repeated). |
67 |
|
68 |
Since this description is confusing, here is a rather verbose |
69 |
example of a parsed manifest: |
70 |
|
71 |
( |
72 |
raw => "Version...", |
73 |
version => { revision => 1 }, |
74 |
document => [ |
75 |
{ |
76 |
info => { format" => "image/jpeg" }, |
77 |
name => "background.jpg", |
78 |
redirect => { target => "freenet:CHK\@ZcagI,ra726bSw" }, |
79 |
}, |
80 |
{ |
81 |
info => { format" => "text/html" }, |
82 |
name => ".next", |
83 |
redirect => { target => "freenet:SSK\@ilUPAgM/TFEE/3" }, |
84 |
}, |
85 |
{ |
86 |
info => { format" => "text/html" }, |
87 |
redirect => { target => "freenet:CHK\@8M8Po8ucwI,8xA" }, |
88 |
} |
89 |
] |
90 |
) |
91 |
|
92 |
$string = Net::FCP::build_metadata $meta |
93 |
Takes a hash reference as returned by "Net::FCP::parse_metadata" and |
94 |
returns the corresponding string form. If a string is given, it's |
95 |
returned as is. |
96 |
|
97 |
$fcp = new Net::FCP [host => $host][, port => $port][, progress => \&cb] |
98 |
Create a new virtual FCP connection to the given host and port |
99 |
(default 127.0.0.1:8481, or the environment variables "FREDHOST" and |
100 |
"FREDPORT"). |
101 |
|
102 |
Connections are virtual because no persistent physical connection is |
103 |
established. |
104 |
|
105 |
You can install a progress callback that is being called with the |
106 |
Net::FCP object, a txn object, the type of the transaction and the |
107 |
attributes. Use it like this: |
108 |
|
109 |
sub progress_cb { |
110 |
my ($self, $txn, $type, $attr) = @_; |
111 |
|
112 |
warn "progress<$txn,$type," . (join ":", %$attr) . ">\n"; |
113 |
} |
114 |
|
115 |
$txn = $fcp->txn(type => attr => val,...) |
116 |
The low-level interface to transactions. Don't use it. |
117 |
|
118 |
Here are some examples of using transactions: |
119 |
|
120 |
The blocking case, no (visible) transactions involved: |
121 |
|
122 |
my $nodehello = $fcp->client_hello; |
123 |
|
124 |
A transaction used in a blocking fashion: |
125 |
|
126 |
my $txn = $fcp->txn_client_hello; |
127 |
... |
128 |
my $nodehello = $txn->result; |
129 |
|
130 |
Or shorter: |
131 |
|
132 |
my $nodehello = $fcp->txn_client_hello->result; |
133 |
|
134 |
Setting callbacks: |
135 |
|
136 |
$fcp->txn_client_hello->cb( |
137 |
sub { my $nodehello => $_[0]->result } |
138 |
); |
139 |
|
140 |
$txn = $fcp->txn_client_hello |
141 |
$nodehello = $fcp->client_hello |
142 |
Executes a ClientHello request and returns it's results. |
143 |
|
144 |
{ |
145 |
max_file_size => "5f5e100", |
146 |
node => "Fred,0.6,1.46,7050" |
147 |
protocol => "1.2", |
148 |
} |
149 |
|
150 |
$txn = $fcp->txn_client_info |
151 |
$nodeinfo = $fcp->client_info |
152 |
Executes a ClientInfo request and returns it's results. |
153 |
|
154 |
{ |
155 |
active_jobs => "1f", |
156 |
allocated_memory => "bde0000", |
157 |
architecture => "i386", |
158 |
available_threads => 17, |
159 |
datastore_free => "5ce03400", |
160 |
datastore_max => "2540be400", |
161 |
datastore_used => "1f72bb000", |
162 |
estimated_load => 52, |
163 |
free_memory => "5cc0148", |
164 |
is_transient => "false", |
165 |
java_name => "Java HotSpot(_T_M) Server VM", |
166 |
java_vendor => "http://www.blackdown.org/", |
167 |
java_version => "Blackdown-1.4.1-01", |
168 |
least_recent_timestamp => "f41538b878", |
169 |
max_file_size => "5f5e100", |
170 |
most_recent_timestamp => "f77e2cc520" |
171 |
node_address => "1.2.3.4", |
172 |
node_port => 369, |
173 |
operating_system => "Linux", |
174 |
operating_system_version => "2.4.20", |
175 |
routing_time => "a5", |
176 |
} |
177 |
|
178 |
$txn = $fcp->txn_generate_chk ($metadata, $data[, $cipher]) |
179 |
$uri = $fcp->generate_chk ($metadata, $data[, $cipher]) |
180 |
Calculates a CHK, given the metadata and data. $cipher is either |
181 |
"Rijndael" or "Twofish", with the latter being the default. |
182 |
|
183 |
$txn = $fcp->txn_generate_svk_pair |
184 |
($public, $private) = @{ $fcp->generate_svk_pair } |
185 |
Creates a new SVK pair. Returns an arrayref with the public key, the |
186 |
private key and a crypto key, which is just additional entropy. |
187 |
|
188 |
[ |
189 |
"acLx4dux9fvvABH15Gk6~d3I-yw", |
190 |
"cPoDkDMXDGSMM32plaPZDhJDxSs", |
191 |
"BH7LXCov0w51-y9i~BoB3g", |
192 |
] |
193 |
|
194 |
A private key (for inserting) can be constructed like this: |
195 |
|
196 |
SSK@<private_key>,<crypto_key>/<name> |
197 |
|
198 |
It can be used to insert data. The corresponding public key looks |
199 |
like this: |
200 |
|
201 |
SSK@<public_key>PAgM,<crypto_key>/<name> |
202 |
|
203 |
Watch out for the "PAgM"-part! |
204 |
|
205 |
$txn = $fcp->txn_invert_private_key ($private) |
206 |
$public = $fcp->invert_private_key ($private) |
207 |
Inverts a private key (returns the public key). $private can be |
208 |
either an insert URI (must start with "freenet:SSK@") or a raw |
209 |
private key (i.e. the private value you get back from |
210 |
"generate_svk_pair"). |
211 |
|
212 |
Returns the public key. |
213 |
|
214 |
$txn = $fcp->txn_get_size ($uri) |
215 |
$length = $fcp->get_size ($uri) |
216 |
Finds and returns the size (rounded up to the nearest power of two) |
217 |
of the given document. |
218 |
|
219 |
$txn = $fcp->txn_client_get ($uri [, $htl = 15 [, $removelocal = 0]]) |
220 |
($metadata, $data) = @{ $fcp->client_get ($uri, $htl, $removelocal) |
221 |
Fetches a (small, as it should fit into memory) file from freenet. |
222 |
$meta is the metadata (as returned by "parse_metadata" or "undef"). |
223 |
|
224 |
The $uri should begin with "freenet:", but the scheme is currently |
225 |
added, if missing. |
226 |
|
227 |
Due to the overhead, a better method to download big files should be |
228 |
used. |
229 |
|
230 |
my ($meta, $data) = @{ |
231 |
$fcp->client_get ( |
232 |
"freenet:CHK@hdXaxkwZ9rA8-SidT0AN-bniQlgPAwI,XdCDmBuGsd-ulqbLnZ8v~w" |
233 |
) |
234 |
}; |
235 |
|
236 |
$txn = $fcp->txn_client_put ($uri, $metadata, $data, $htl, $removelocal) |
237 |
my $uri = $fcp->client_put ($uri, $metadata, $data, $htl, $removelocal); |
238 |
Insert a new key. If the client is inserting a CHK, the URI may be |
239 |
abbreviated as just CHK@. In this case, the node will calculate the |
240 |
CHK. If the key is a private SSK key, the node will calculcate the |
241 |
public key and the resulting public URI. |
242 |
|
243 |
$meta can be a hash reference (same format as returned by |
244 |
"Net::FCP::parse_metadata") or a string. |
245 |
|
246 |
The result is an arrayref with the keys "uri", "public_key" and |
247 |
"private_key". |
248 |
|
249 |
THE Net::FCP::Txn CLASS |
250 |
All requests (or transactions) are executed in a asynchronous way. For |
251 |
each request, a "Net::FCP::Txn" object is created (worse: a tcp |
252 |
connection is created, too). |
253 |
|
254 |
For each request there is actually a different subclass (and it's |
255 |
possible to subclass these, although of course not documented). |
256 |
|
257 |
The most interesting method is "result". |
258 |
|
259 |
new arg => val,... |
260 |
Creates a new "Net::FCP::Txn" object. Not normally used. |
261 |
|
262 |
$txn = $txn->cb ($coderef) |
263 |
Sets a callback to be called when the request is finished. The |
264 |
coderef will be called with the txn as it's sole argument, so it has |
265 |
to call "result" itself. |
266 |
|
267 |
Returns the txn object, useful for chaining. |
268 |
|
269 |
Example: |
270 |
|
271 |
$fcp->txn_client_get ("freenet:CHK....") |
272 |
->userdata ("ehrm") |
273 |
->cb(sub { |
274 |
my $data = shift->result; |
275 |
}); |
276 |
|
277 |
$txn = $txn->userdata ([$userdata]) |
278 |
Set user-specific data. This is useful in progress callbacks. The |
279 |
data can be accessed using "$txn->{userdata}". |
280 |
|
281 |
Returns the txn object, useful for chaining. |
282 |
|
283 |
$txn->cancel (%attr) |
284 |
Cancels the operation with a "cancel" exception anf the given |
285 |
attributes (consider at least giving the attribute "reason"). |
286 |
|
287 |
UNTESTED. |
288 |
|
289 |
$result = $txn->result |
290 |
Waits until a result is available and then returns it. |
291 |
|
292 |
This waiting is (depending on your event model) not very efficient, |
293 |
as it is done outside the "mainloop". The biggest problem, however, |
294 |
is that it's blocking one thread of execution. Try to use the |
295 |
callback mechanism, if possible, and call result from within the |
296 |
callback (or after is has been run), as then no waiting is |
297 |
necessary. |
298 |
|
299 |
The Net::FCP::Exception CLASS |
300 |
Any unexpected (non-standard) responses that make it impossible to |
301 |
return the advertised result will result in an exception being thrown |
302 |
when the "result" method is called. |
303 |
|
304 |
These exceptions are represented by objects of this class. |
305 |
|
306 |
$exc = new Net::FCP::Exception $type, \%attr |
307 |
Create a new exception object of the given type (a string like |
308 |
"route_not_found"), and a hashref containing additional attributes |
309 |
(usually the attributes of the message causing the exception). |
310 |
|
311 |
$exc->type([$type]) |
312 |
With no arguments, returns the exception type. Otherwise a boolean |
313 |
indicating wether the exception is of the given type is returned. |
314 |
|
315 |
$exc->attr([$attr]) |
316 |
With no arguments, returns the attributes. Otherwise the named |
317 |
attribute value is returned. |
318 |
|
319 |
SEE ALSO |
320 |
<http://freenet.sf.net>. |
321 |
|
322 |
BUGS |
323 |
AUTHOR |
324 |
Marc Lehmann <pcg@goof.com> |
325 |
http://www.goof.com/pcg/marc/ |
326 |
|