Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
570 lines (448 sloc) 17.8 KB
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 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.