-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathRPC
570 lines (449 loc) · 17.9 KB
/
RPC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
Synapse RPC v0.1
This document is subject to change.
HTTP INTERFACE
Synapse listens for HTTP connections on the RPC port and services transfer,
download, and upgrade requests.
Transfer requests are used in conjunction with the TRANSFER_OFFER RPC command;
see its specification for details.
Download requests are used to transfer files from the server to the client. Use
an HTTP GET request on /dl/:id?token=:download_token, where :id is the resource
(typically a file) you wish to download and :download_token is the Base64 encoded
SHA1 hash of the concatenation of the id and the download_token specified in
the server resource.
Upgrade requests initialize websocket connections per the WHATWG websockets
specification and become RPC sessions. The URL for these requests is /. If
synapse is configured with an RPC password, include it via Basic Auth with
any chosen username or using the password query parameter in the url.
The connection is upgraded to a full-duplex websocket stream with JSON messages
encoded in text frames.
DATETIME
Datetimes are encoded in RFC 3339 and ISO 8601, in UTC.
RESOURCES
The server exposes resources and updates to those resources to the client. A
resource might be a torrent, tracker, peer, etc, as indicated by the type
field, and the server assigns a ID to each resource. IDs are deterministic
and can be expected to be consistent across sessions and for the same resource
(i.e. the same given torrent will have the same ID on several different
machines). Fields marked with * are mutable via UPDATE_RESOURCE messages.
All resources also have an implicit field "user_data" which can be used
to store arbitrary user data. Updates to this field will be performed according
to the JSON Merge standard (RFC 7396).
server
{
"download_token": string,
"id": ID,
"type": "server",
"rate_up": number,
"rate_down": number,
"throttle_up": number*, bit/sec OR -1 OR null for unlimited
"throttle_down": number*, bit/sec OR -1 OR null for unlimited
"transferred_up": number,
"transferred_down": number,
"ses_transferred_up": number,
"ses_transferred_down": number,
"free_space": number,
"started": datetime,
}
torrent
{
"id": ID,
"type": "torrent",
"name": string or null if magnet and unknown,
"path": string*,
"created": datetime,
"modified": datetime,
"status": status enum,
"error": string OR null,
"size": number OR null, bytes or null if magnet and unknown
"progress": number, 0..1
"priority": number*, 1..5 default 3
"availability": number, 0..1
"strategy": strategy enum*,
"rate_up": number, bit/sec
"rate_down": number, bit/sec
"throttle_up": number*, bit/sec OR null to use global limit OR -1 to ignore limits
"throttle_down": number*, bit/sec OR null to use global limit OR -1 to ignore limits
"transferred_up": number, total bytes seeded
"transferred_down": number, total bytes leeched
"peers": number, # of peers
"trackers": number, # of trackers
"tracker_urls": [string], # domains of trackers available for this torrent
"pieces": number, # of pieces or null if magnet and unknown
"piece_size": number, # size of each piece or null if magnet and unknown
"piece_field": string, b64 encoded bitfield indicating piece presence
"files": number, # of files or null if magnet and unknown
}
status enum:
"paused": paused by a client
"pending": waiting to begin downloading
"leeching": leeching
"idle": completely downloaded but not seeding
"seeding": seeding
"hashing": hash check in progress
"magnet": torrent still in magnet state, acquiring metadata
"error": see "error" field for details
strategy enum:
"rarest": prioritize rare pieces in download
"sequential": prioritize sequential pieces in download
file
{
"id": ID,
"type": "file",
"torrent_id": ID,
"path": string, Relative to torrent path
"progress": number,
"priority": number*, 1..5 default 3
"availability": number, 0..1
"size": number,
}
peer
{
"id": ID,
"type": "peer",
"torrent_id": ID,
"client_id": string, hex string
"ip": string,
"rate_up": number, bit/sec,
"rate_down": number, bit/sec,
"availability": number, 0..1
}
tracker
{
"id": ID,
"type": "tracker",
"torrent_id": ID,
"url": string,
"error": string or null,
"last_report": datetime,
}
CRITERION OBJECTS
Criteria is supported in some places to do server-side filtering of resources.
A criterion can be specified like so:
{
"field": string, Field to filter for
"op": operation enum,
"value": *, Value to test against
}
Note that criterion are evaluated in the order of "field op value", so
a criterion with field "foo", op "<", and value "10" would be true for all
resources with a field foo less than 10.
When querying the user_data field, nested structures can be selected
using JSON pointers (RFC 6901) syntax, prefixed with "user_data".
For example, in a resource which looks like:
{
"id": "..."
"user_data": {
"foo": {
"bar": "baz"
}
}
}
accessing the "bar" field can be done with a field "user_data/foo/bar".
Additionally, subresources of a torrent resource can be queried via similar
JSON pointer syntax. The requested criterion will be considered to
be true for the torrent if at least one subresource associated with the torrent
matches the criterion.
For example, to filter torrents with at least one tracker associated with "foo.org",
the criterion { "field": "tracker/url", "op": ilike, value: "foo.org"} could be used.
Operation enum:
"==": equal to
"!=": not equal to
">": greater than
">=": greater than or equal to
"<": less than
"<=": less than or equal to
"like": value is a LIKE test with SQL syntax
"ilike": value is an ILIKE test with SQL syntax
"in": value is an array of values for equality test
"!in": value is an array of values for non-equality test
"has": field is an array of fields and contains value (via equality or ilike test)
"!has": field is an array of fields and does not contain value (via equality or ilike test)
MESSAGES
A message sent from either the client->server or server->client will use this
format:
{
"type": string,
"serial": number,
.
.
.
}
The type field is a unique identifier for the message type, and defines the
schema of the remaining fields. The serial is a number allocated by the client
that increments for each message, but may be omitted from server messages. The
server may include a serial in its messages to indicate which message from the
client it pertains to.
RESOURCE MESSAGES
If you know a resource ID is extant, you can query the server for information
about it with these messages.
GET_RESOURCES client->server
Fetches a resource or resources by ID. The server responds with RESOURCES
messages.
{
"type": "GET_RESOURCES",
"ids": [
IDs,
.
.
.
]
}
SUBSCRIBE client->server
Subscribes to changes on a resource or resources. The server will respond with
RESOURCES message(s) to populate the initial set of resources, and will
periodically send additional RESOURCES message(s) to update the client as the
state of these resources changes.
{
"type": "SUBSCRIBE",
"ids": [
IDs,
.
.
.
]
}
UNSUBSCRIBE client->server
Used by the client to indicate it no longer wants updates for these resources.
{
"type": "UNSUBSCRIBE",
"ids": [
IDs,
.
.
.
]
}
UPDATE_RESOURCES server->client
Indicates that the client should update its internal representation of some
resources. Note that the only constraint on the resource type is that
an id field, type field, and at least one other data field be present.
When a client sends a SUBSCRIBE message, the first UPDATE_RESOURCES
response will always contain the complete representation of the subscribed
resources. Following this partial updates will be sent.
{
"type": "UPDATE_RESOURCES",
"serial": number, The serial is only included for responses to GET_RESOURCES and UPDATE_RESOURCE messages
"resources": [
{ ...resource type... },
.
.
.
]
}
FILTER_SUBSCRIBE client->server
Indicates that the client would like to receive updates for all new resources
matching a given criteria. The server will send RESOURCES_EXTANT messages for
any resources that already match, as well as RESOURCES_EXTANT for any resources
that match this criteria in the future and RESOURCES_REMOVED for matching
resources that are made invalid.
{
"type": "FILTER_SUBSCRIBE",
"kind": string, The kind of resource to filter for, defaults to "torrent"
"criteria": [
{ ...criterion object... },
.
.
.
]
}
Because the default kind of criterion is "torrent", a client can receive the
list of valid torrent IDs and subscribe to new/removed torrents by sending
FILTER_SUBSCRIBE upfront.
FILTER_SUBSCRIBE also has special semantics when issued with a serial matching
an existing FILTER_SUBSCRIBE. It will issue a RESOURCES_EXTANT and RESOURCES_REMOVED
messages which indicate the difference between the resources matching the
old filter and the new filter.
FILTER_UNSUBSCRIBE client->server
Indicates that the client would no longer like to be subscribed to a filter.
{
"type": "FILTER_UNSUBSCRIBE",
"filter_serial": number,
}
"filter_serial" should be set to the serial of the FILTER_SUBSCRIBE message the
client wishes to cease its subscription for. Upon unsubscribing, all resource
IDs associated with this filter (and no other active filters) become invalid.
RESOURCES_EXTANT server->client
Sent by the server to indicate that new resources are available.
{
"type": "RESOURCES_EXTANT",
"serial": number, the serial of the relevant client message
"ids": [
IDs,
.
.
.
]
}
RESOURCES_REMOVED server->client
Sent by the server to indicate that some resources are no longer available.
{
"type": "RESOURCES_REMOVED",
"serial": number, the serial of the relevant client message
"ids": [
IDs,
.
.
.
]
}
UPDATE_RESOURCE client->server
The client wishes to make a change to a resource.
{
"type": "UPDATE_RESOURCE",
"resource": { ...resource object... }
}
The client should only send updated fields for mutable resource
fields. The server will follow up with an UPDATE_RESOURCES message
to confirm the changes.
REMOVE_RESOURCE client->server
The client wishes to delete a resource.
{
"type": "REMOVE_RESOURCE",
"id": ID,
"artifacts": bool, optional, delete related artifacts(files for torrents).
}
The semantics of this message vary based on the resource type.
If the resource is a torrent, the torrent is deleted from the client. If the resource is a peer,
the peer will be removed. If the resource is a tracker, the tracker is removed from the torrent.
For other resources, there is no effect (this is subject to change).
On success, the client will be notified of the removal via a RESOURCES_REMOVED message
with the serial of the original message, and any updates from existing subscriptions.
SPECIAL MESSAGES
RPC_VERSION server->client
The version of the RPC protocol being used by the synapse instance.
Minor version differences indicate non-breaking changes, while major
version differences have no compatability guarantees. This message will
be sent to clients when they connect.
{
"type": "RPC_VERSION",
"major": number,
"minor": datetime,
}
TRANSFER_OFFER server->client
Indicates that the server will allow a file transfer over HTTP.
The path to use will be assumed to be known by the client, rather than given
by synapse. By default, synapse will listen for HTTP requests over its RPC port,
and if a websocket upgrade is not initiated, a transfer request is assumed.
The client should initiate an HTTP request using bearer authorization.
This transfer must be initiated wihin the time limit defined by the expires field.
The client should send a POST request containing the binary encoded data.
The client should not attempt to resend this request, even if an error response
is later received. On failure, an error message is issued for the original
message's serial. Successful behavior is dependent on the type of transfer
occurring.
{
"type": "TRANSFER_OFFER",
"serial": number, message serial this is in response to
"expires": datetime,
"token": string, bearer token that should be used to authorize the request
"size": number, bytes, expected size of transfer
}
RESOURCE_PENDING server->client
The client tried to add a resource to the server which is pending acceptance.
There is no guarantee that the resource will ever be fully added.
{
"type": "RESOURCE_PENDING",
"serial": number,
"id": string,
}
UPLOAD_TORRENT client->server
Indicates that the client would like to upload a .torrent file to the server.
The server will respond with a TRANSFER_OFFER message. If successful the server
will add the torrent and the client will be notified via RESOURCES_EXTANT with
the serial set to the initial request's serial. Note that if the client is already subscribed
to torrent updates, it will receive the RESOURCES_EXTANT message twice.
The serial should be used to distinguish the two.
{
"type": "UPLOAD_TORRENT",
"size": number, bytes, size of .torrent file
"path": string, optional download path
"start": boolean, optional, if false torrent will start paused
"import": boolean, optional, if true torrent will be treated as already downloaded
}
UPLOAD_MAGNET client->server
Adds a torrent via its magnet link. If successful the server will add the
torrent and the client will be notified via RESOURCES_EXTANT with the serial set
to the initial request's serial.
{
"type": "UPLOAD_MAGNET",
"uri": string,
"path": string, optional download path
"start": boolean, optional, if false torrent will start paused
}
UPLOAD_FILES client->server
Uploads a file or group of files to the server, presumably for seeding. The
server will issue a TRANSFER_OFFER and the client should upload a tarball.
{
"type": "UPLOAD_FILES",
"size": number, bytes, size of tarball
"path": string absolute or relative to download directory
}
PAUSE_TORRENT client->server
Pauses a torrent.
{
"type": "PAUSE_TORRENT",
"id": ID
}
RESUME_TORRENT client->server
Resumes a torrent.
{
"type": "RESUME_TORRENT",
"id": ID
}
ADD_PEER client->server
Adds a peer to a torrent.
{
"type": "ADD_PEER",
"id": ID,
"ip": string
}
ADD_TRACKER client->server
Adds a tracker to a torrent.
{
"type": "ADD_TRACKER",
"id": ID,
"uri": string
}
UPDATE_TRACKER client->server
Updates a tracker.
{
"type": "UPDATE_TRACKER",
"id": ID
}
VALIDATE_RESOURCES client->server
Validates a list of resources. At the moment only torrents will be
validated, however this may be expanded to includes files in the future.
{
"type": "VALIDATE_RESOURCES",
"ids": [
IDs,
.
.
.
]
}
PURGE_DNS client->server
Purges the current DNS cache of the client.
{
"type": "PURGE_DNS",
}
ERROR MESSAGES
All error messages share a common format and are only sent from server->client.
{
"type": *,
"serial": number, The serial of the offending message
"reason": string, User-friendly error message
}
The various error types are:
UNKNOWN_RESOURCE: the client used a resource ID the server does not recognize
INVALID_RESOURCE: the client used an inappropriate resource type for the operation
INVALID_MESSAGE: the client used an invalid message type
INVALID_SCHEMA: the schema of the message was invalid
INVALID_REQUEST: the message was logically invalid (i.e. string > number)
TRANSFER_FAILED: a transfer initiated by the client failed
PERMISSION_DENIED: the server does not allow this request (i.e. add torrents)
SERVER_ERROR: something went wrong on the server's side, client is not at fault
Note that error handling is not guaranteed to occur if any form of error is detected at
the transport (i.e. WebSocket) or encoding (i.e. JSON) level. Should errors occur
for either the client or server here, the connection may be immediately and uncleanly
closed.