make the request/response messages a little terser. add per-torrent speed limit toggles. rename ipc -> rpc.

This commit is contained in:
Charles Kerr 2008-05-12 23:51:17 +00:00
parent 48874c0619
commit 17b9dc7462
4 changed files with 96 additions and 104 deletions

View File

@ -18,46 +18,45 @@
floating-point numbers are represented as strings.
booleans are represented as integers where 0 is false and 1 is true.
There are only two message types: request and response. Both
are JSON objects with two members: "headers" (described in 2.1)
and "body" (described in 2.2 - 2.3).
Messages are represented as a JSON objects. There are two types:
requests (described in 2.1) and responses (described in 2.2).
2.1. Headers
2.1. Requests
Message headers support two members:
(1) A required "type" string whose value must be "request" or "response".
(2) An optional "tag" integer supplied by requests for their own use.
Responses MUST include the request tag's verbatim.
Requests supports three keys:
2.2. Request Body
(1) A required "method" string telling the name of the method to invoke
(2) An optional "arguments" object of name/value pairs
(3) An optional "tag" integer used for clients to track responses.
If provided by a request, the response MUST include the same tag.
Request bodies support two members:
(1) A required "name" string telling the name of the request.
(2) An optional "arguments" object of name/value pairs.
2.2. Responses
2.3. Response Body
Reponses support three keys:
All response bodies support two members:
(1) A required "result" string whose value must be "success" on success,
and may be "no-permission", "bad-format", or "error" on failure.
(2) An optional "arguments" object of name/value pairs.
The contents of these arguments depend on the request's name.
or an error string on failure.
(2) An optional "arguments" object of name/value pairs
(3) An optional "tag" integer as described in 2.1.
3. Torrent Requests
3.1. Torrent Action Requests
Request names: "torrent-start", "torrent-stop",
"torrent-remove", "torrent-verify"
Method names: "torrent-start", "torrent-stop",
"torrent-remove", "torrent-verify"
Request arguments: "ids", a list of unique torrent ids, sha1 hash strings,
or both. These are the torrents that the request will
be applied to. If "ids" is ommitted, the request is
applied to all torrents.
Response arguments: none.
3.2. Torrent Info Requests
Request name: "torrent-info".
Method name: "torrent-info".
Request arguments: 3.1's optional "ids" argument.
Response arguments: "info", an array of objects based on libtransmission's
@ -70,53 +69,42 @@
Example Request:
{
"headers": {
"type": "request",
"tag": 666
},
"body": {
"name": "torrent-info",
"arguments": {
"ids": [ 7, 10 ]
}
}
"arguments": { "ids": [ 7, 10 ] }
"method": "torrent-info",
"tag": 666
}
Example Response:
{
"headers": {
"type": "response",
"tag": 666
}
"body": {
"result": "success",
"arguments": {
"info": [
{
"id": 7,
"totalSize": 9803930483,
"pieceCount": 1209233,
"pieceSize": 4096,
"name": "Ubuntu x86_64 DVD",
...
}
{
"id": 10,
"totalSize": 2398480394,
"pieceCount": 83943,
"pieceSize": 12345,
"name": "Ubuntu i386 DVD",
...
}
]
}
"tag": 666
"result": "success",
"arguments": {
"info": [
{
"id": 7,
"totalSize": 9803930483,
"pieceCount": 1209233,
"pieceSize": 4096,
"name": "Ubuntu x86_64 DVD",
...
},
{
"id": 10,
"totalSize": 2398480394,
"pieceCount": 83943,
"pieceSize": 12345,
"name": "Ubuntu i386 DVD",
...
}
]
}
}
3.3. Torrent Status Requests
Request name is "torrent-status".
Method name: "torrent-status"
Request arguments: 3.1's optional "ids" argument.
Response arguments: "status", an array of objects based on
@ -128,12 +116,13 @@
3.4. Adding a Torrent
Request name: "torrent-add"
Method name: "torrent-add"
Request arguments:
string | value type & description
-------------------+-------------------------------------------------
"autostart" | boolean true means to auto-start torrents
"paused" | boolean if true, don't start the torrent
"destination" | string path to download the torrent to
"filename" | string location of the .torrent file
"peer-limit" | int maximum number of peers
@ -147,21 +136,23 @@
Common arguments:
string | value type & description
-------------------+-------------------------------------------------
"peer-limit" | int maximum number of peers
"speed-limit-down" | int maximum download speed (in KiB/s)
"speed-limit-up" | int maximum upload speed (in KiB/s)
string | value type & description
---------------------------+-------------------------------------------------
"peer-limit" | int maximum number of peers
"speed-limit-down" | int maximum download speed (in KiB/s)
"speed-limit-down-enabled" | boolean true if the download speed is limited
"speed-limit-up" | int maximum upload speed (in KiB/s)
"speed-limit-up-enabled" | boolean true if the upload speed is limited
3.5.1. Mutators
Request name: "torrent-set"
Method name: "torrent-set"
Request arguments: 3.1's "ids", plus one or more of 3.5's arguments
Response arguments: none
3.5.2. Accessors
Request name: "torrent-get"
Method name: "torrent-get"
Request arguments: none
Response arguments: A "torrents" list of objects containing all
of 3.5's arguments plus the torrent's "id" int.
@ -181,13 +172,13 @@
3.6.1. Mutators
Request name: "torrent-set-file"
Method name: "torrent-set-file"
Request arguments: 3.1's "ids", plus one or more of 3.6's arguments
Response arguments: none
3.6.2. Accessors
Request name: "torrent-get-file"
Method name: "torrent-get-file"
Request arguments: none
Response arguments: A "torrents" list of objects containing all
of 3.6's arguments plus the torrent's "id" int.
@ -210,13 +201,13 @@
4.2. Mutators
Request name: "session-set"
Method name: "session-set"
Request arguments: one or more of 4.1's arguments
Response arguments: none
4.2. Accessors
Request name: "session-get"
Method name: "session-get"
Request arguments: none
Response arguments: all of 4.1's arguments

View File

@ -16,7 +16,6 @@ libtransmission_a_SOURCES = \
ggets.c \
handshake.c \
inout.c \
ipc.c \
ipcparse.c \
json.c \
list.c \
@ -33,6 +32,7 @@ libtransmission_a_SOURCES = \
publish.c \
ratecontrol.c \
resume.c \
rpc.c \
session.c \
stats.c \
torrent.c \
@ -57,7 +57,6 @@ noinst_HEADERS = \
ggets.h \
handshake.h \
inout.h \
ipc.h \
ipcparse.h \
list.h \
makemeta.h \
@ -74,6 +73,7 @@ noinst_HEADERS = \
publish.h \
ratecontrol.h \
resume.h \
rpc.h \
session.h \
stats.h \
torrent.h \

View File

@ -15,7 +15,7 @@
#include "transmission.h"
#include "bencode.h"
#include "ipc.h"
#include "rpc.h"
#include "torrent.h"
#include "utils.h"
@ -245,14 +245,20 @@ torrentGet( tr_handle * handle, tr_benc * args_in, tr_benc * args_out )
for( i=0; i<torrentCount; ++i )
{
tr_torrent * tor = torrents[i];
tr_benc * d = tr_bencListAddDict( list, 4 );
tr_benc * d = tr_bencListAddDict( list, 6 );
tr_bencDictAddInt( d, "id", tor->uniqueId );
tr_bencDictAddInt( d, "peer-limit",
tr_torrentGetPeerLimit( tor ) );
tr_bencDictAddInt( d, "speed-limit-down",
tr_torrentGetSpeedLimit( tor, TR_DOWN ) );
tr_bencDictAddInt( d, "speed-limit-down-enabled",
tr_torrentGetSpeedMode( tor, TR_DOWN )
== TR_SPEEDLIMIT_SINGLE );
tr_bencDictAddInt( d, "speed-limit-up",
tr_torrentGetSpeedLimit( tor, TR_UP ) );
tr_bencDictAddInt( d, "speed-limit-up-enabled",
tr_torrentGetSpeedMode( tor, TR_UP )
== TR_SPEEDLIMIT_SINGLE );
}
tr_free( torrents );
@ -273,8 +279,14 @@ torrentSet( tr_handle * handle, tr_benc * args_in, tr_benc * args_out UNUSED )
tr_torrentSetPeerLimit( tor, tmp );
if( tr_bencDictFindInt( args_in, "speed-limit-down", &tmp ) )
tr_torrentSetSpeedLimit( tor, TR_DOWN, tmp );
if( tr_bencDictFindInt( args_in, "speed-limit-down-enabled", &tmp ) )
tr_torrentSetSpeedMode( tor, TR_DOWN, tmp ? TR_SPEEDLIMIT_SINGLE
: TR_SPEEDLIMIT_GLOBAL );
if( tr_bencDictFindInt( args_in, "speed-limit-up", &tmp ) )
tr_torrentSetSpeedLimit( tor, TR_UP, tmp );
if( tr_bencDictFindInt( args_in, "speed-limit-up-enabled", &tmp ) )
tr_torrentSetSpeedMode( tor, TR_UP, tmp ? TR_SPEEDLIMIT_SINGLE
: TR_SPEEDLIMIT_GLOBAL );
}
tr_free( torrents );
@ -438,8 +450,8 @@ torrentAdd( tr_handle * h, tr_benc * args_in, tr_benc * args_out )
ctor = tr_ctorNew( h );
tr_ctorSetMetainfoFromFile( ctor, filename );
if( tr_bencDictFindInt( args_in, "autostart", &i ) )
tr_ctorSetPaused( ctor, TR_FORCE, !i );
if( tr_bencDictFindInt( args_in, "paused", &i ) )
tr_ctorSetPaused( ctor, TR_FORCE, i );
if( tr_bencDictFindInt( args_in, "peer-limit", &i ) )
tr_ctorSetPeerLimit( ctor, TR_FORCE, i );
if( tr_bencDictFindStr( args_in, "destination", &str ) )
@ -538,7 +550,7 @@ typedef const char* (handler)( tr_handle*, tr_benc*, tr_benc* );
struct request_handler
{
const char * name;
const char * method;
handler * func;
} request_handlers[] = {
{ "torrent-start", torrentStart },
@ -565,51 +577,40 @@ request_exec( struct tr_handle * handle,
const char * str;
char * out;
tr_benc response;
tr_benc * headers_in = NULL;
tr_benc * body_in = NULL;
tr_benc * args_in = NULL;
tr_benc * headers_out = NULL;
tr_benc * body_out = NULL;
tr_benc * args_in = tr_bencDictFind( request, "args" );
tr_benc * args_out = NULL;
const char * result = NULL;
headers_in = tr_bencDictFind( request, "headers" );
body_in = tr_bencDictFind( request, "body" );
args_in = tr_bencDictFind( body_in, "args" );
/* build the response skeleton */
tr_bencInitDict( &response, 2 );
headers_out = tr_bencDictAddDict( &response, "headers", 2 );
tr_bencDictAddStr( headers_out, "type", "response" );
if( tr_bencDictFindInt( headers_in, "tag", &i ) )
tr_bencDictAddInt( headers_out, "tag", i );
body_out = tr_bencDictAddDict( &response, "body", 2 );
args_out = tr_bencDictAddDict( body_out, "args", 0 );
tr_bencInitDict( &response, 3 );
if( tr_bencDictFindInt( request, "tag", &i ) )
tr_bencDictAddInt( request, "tag", i );
args_out = tr_bencDictAddDict( &response, "args", 0 );
/* parse the request */
if( !tr_bencDictFindStr( body_in, "name", &str ) )
result = "no request name given";
if( !tr_bencDictFindStr( request, "method", &str ) )
result = "no method name";
else {
const int n = TR_N_ELEMENTS( request_handlers );
for( i=0; i<n; ++i )
if( !strcmp( str, request_handlers[i].name ) )
if( !strcmp( str, request_handlers[i].method ) )
break;
result = i==n
? "request name not recognized"
? "method name not recognized"
: (*request_handlers[i].func)( handle, args_in, args_out );
}
/* serialize & return the response */
if( !result )
result = "success";
tr_bencDictAddStr( body_out, "result", result );
out = tr_bencSave( &response, response_len ); /* TODO: json, not benc */
result = "success";
tr_bencDictAddStr( &response, "result", result );
out = tr_bencSaveAsJSON( &response, response_len );
tr_bencFree( &response );
return out;
}
char*
tr_ipc_request_exec( struct tr_handle * handle,
tr_rpc_request_exec( struct tr_handle * handle,
const void * request_json,
int request_len,
int * response_len )

View File

@ -10,13 +10,13 @@
* $Id:$
*/
#ifndef TR_IPC_H
#define TR_IPC_H
#ifndef TR_RPC_H
#define TR_RPC_H
struct tr_handle;
char*
tr_ipc_request_exec( struct tr_handle * handle,
tr_rpc_request_exec( struct tr_handle * handle,
const void * request_json,
int request_len,
int * response_len );