Changeset 5829


Ignore:
Timestamp:
May 13, 2008, 5:31:09 PM (14 years ago)
Author:
charles
Message:

more work on rpc. bug fixes, regression tests, and spec tweaks.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/rpc-json-spec.txt

    r5827 r5829  
    88   The JSON terminology in RFC 4627 is used. "array" is equivalent
    99   to a benc list; "object" is equivalent to a benc dictionary;
    10    an object's "strings" are the dictionary's keys,
    11    and an object's "members" are its string/value pairs.
     10   an object's "keys" are the dictionary's string keys,
     11   and an object's "members" are its key/value pairs.
    1212
    13132.  Message Format
     
    1515   Messages are formatted in a subset of JSON that understands
    1616   arrays, maps, strings, and whole numbers with no exponentials --
    17    in short, the subset of JSON easily represented in benc.
    18    floating-point numbers are represented as strings.
    19    booleans are represented as integers where 0 is false and 1 is true.
    20 
    21    Messages are represented as a JSON objects.  There are two types:
     17   in short, the subset of JSON easily represented as bencoded data.
     18   Floating-point numbers are represented as strings.
     19   Booleans are represented as integers where 0 is false and 1 is true.
     20
     21   Messages are represented as JSON objects.  There are two types:
    2222   requests (described in 2.1) and responses (described in 2.2).
    2323
     
    4747                 "torrent-remove", "torrent-verify"
    4848
    49    Request arguments: "ids", a list of unique torrent ids, sha1 hash strings,
     49   Request arguments: "ids", a list of torrent id integers, sha1 hash strings,
    5050                      or both.  These are the torrents that the request will
    5151                      be applied to.  If "ids" is ommitted, the request is
    5252                      applied to all torrents.
    5353
    54    Response arguments: none.
     54   Response arguments: none
    5555
    56563.2.  Torrent Info Requests
     
    7272         "arguments": { "ids": [ 7, 10 ] }
    7373         "method": "torrent-info",
    74          "tag": 666
     74         "tag": 39693
    7575      }
    7676
     
    7878
    7979      {
    80          "tag": 666
     80         "tag": 39693
    8181         "result": "success",
    8282         "arguments": {
     
    109109
    110110   Response arguments: "status", an array of objects based on
    111    libtransmission's tr_stat struct but which differ the following ways:
    112 
    113    (1) tr_stat's "tracker" field is omitted
    114    (2) a new string, "announce-url", is added
    115    (3) a new string, "scrape-url", is added
     111   libtransmission's tr_stat struct but which differ in the following ways:
     112
     113   (1) tr_stat's "tracker" field is omitted.
     114   (2) a new string, "announce-url", is added.
     115   (3) a new string, "scrape-url", is added.
    116116
    1171173.4.  Adding a Torrent
     
    123123   string             | value type & description
    124124   -------------------+-------------------------------------------------
    125    "paused"           | boolean   if true, don't start the torrent
    126125   "destination"      | string    path to download the torrent to
    127126   "filename"         | string    location of the .torrent file
     127   "paused"           | boolean   if true, don't start the torrent
    128128   "peer-limit"       | int       maximum number of peers
    129129
     
    131131
    132132   Response arguments: on success, a "torrent-added" object in the
    133                        form of one of 3.1's tr_info objects.
     133                       form of one of 3.2's tr_info objects.
    134134
    1351353.5.  Other torrent settings
     
    1731733.6.1.  Mutators
    174174
    175     Method name: "torrent-set-file"
     175    Method name: "torrent-set-priorities"
    176176    Request arguments: 3.1's "ids", plus one or more of 3.6's arguments
    177177    Response arguments: none
     
    1791793.6.2.  Accessors
    180180
    181     Method name: "torrent-get-file"
     181    Method name: "torrent-get-priorities"
    182182    Request arguments: none
    183    Response arguments: A "torrents" list of objects containing all
    184                        of 3.6's arguments plus the torrent's "id" int.
     183    Response arguments: A "torrents" list of objects containing all
     184                        of 3.6's arguments plus the torrent's "id" int.
    185185   
    1861864.   Session Status Requests
     
    192192   "encryption"               | string   "required", "preferred", "tolerated"
    193193   "peer-limit"               | int      maximum global number of peers
     194   "pex-allowed"              | boolean  true means allow pex in public torrents
    194195   "port"                     | int      port number
    195196   "port-forwarding-enabled"  | boolean  true means enabled.
    196    "pex-allowed"              | boolean  true means allow pex in public torrents
    197197   "speed-limit-down"         | int      max global download speed (in KiB/s)
    198198   "speed-limit-down-enabled" | int      max global download speed (in KiB/s)
  • trunk/libtransmission/bencode-test.c

    r5828 r5829  
    276276{
    277277    char * serialized = tr_rison2json( rison_str, -1 );
    278 #if 0
    279278fprintf( stderr, " expected: [%s]\n", expected );
    280279fprintf( stderr, "      got: [%s]\n", serialized );
    281 #endif
    282280    check( !strcmp( serialized, expected ) );
    283281    tr_free( serialized );
     
    294292    rison = "(a:0,b:foo,c:'23skidoo')";
    295293    expected = "{ \"a\": 0, \"b\": \"foo\", \"c\": \"23skidoo\" }";
     294    if(( val = testRISONSnippet( rison, expected )))
     295        return val;
     296
     297    rison = "(method:torrent-info)";
     298    expected = "{ \"method\": \"torrent-info\" }";
    296299    if(( val = testRISONSnippet( rison, expected )))
    297300        return val;
  • trunk/libtransmission/json.c

    r5828 r5829  
    205205                case ':': evbuffer_add_printf( out, "\": "); mode = VAL_BEGIN; break;
    206206                case '!': mode = ESCAPE_UNQUOTED_STRING; break;
     207                case ')': if( IN_OBJECT ) { evbuffer_add_printf( out, "\" }"); mode = OTHER; break; }
    207208                case ',': if( IN_OBJECT ) { evbuffer_add_printf( out, "\", "); mode = STRING_BEGIN; break; }
    208209                          /* fallthrough */
  • trunk/libtransmission/rpc.c

    r5828 r5829  
    7070typedef void( *tor_func )( tr_torrent * tor );
    7171
    72 static void callTorrentFunc( tr_handle * h, tr_benc * args_in, tor_func func )
     72static void
     73callTorrentFunc( tr_handle * h, tr_benc * args_in, tor_func func )
    7374{
    7475    int i, torrentCount;
     
    165166            tr_bencDictAddInt( t, "lastAnnounceTime", s->lastAnnounceTime );
    166167            tr_bencDictAddInt( t, "nextAnnounceTime", s->nextAnnounceTime );
    167             tr_bencDictAddInt( t, "nextManualAnnounceTime", s->nextManualAnnounceTime );
     168            tr_bencDictAddInt( t, "nextManualAnnounceTime",
     169                                                s->nextManualAnnounceTime );
    168170    }
    169171
     
    172174    return NULL;
    173175}
     176
     177/**
     178***
     179**/
    174180
    175181static void
     
    203209
    204210static void
    205 serializeInfo( const tr_torrent * tor, tr_benc * d )
     211addInfo( const tr_torrent * tor, tr_benc * d )
    206212{
    207213    const tr_info * inf = tr_torrentInfo( tor );
    208214    tr_bencInitDict( d, 14 );
    209     tr_bencDictAddInt( d, "id", tor->uniqueId );
    210     tr_bencDictAddStr( d, "torrent", inf->torrent );
    211     tr_bencDictAddStr( d, "hashString", inf->hashString );
    212     tr_bencDictAddStr( d, "name", inf->name );
    213215    tr_bencDictAddStr( d, "comment", inf->comment ? inf->comment : "" );
    214216    tr_bencDictAddStr( d, "creator", inf->creator ? inf->creator : "" );
     217    tr_bencDictAddInt( d, "dateCreated", inf->dateCreated );
     218    tr_bencDictAddStr( d, "hashString", inf->hashString );
     219    tr_bencDictAddInt( d, "id", tor->uniqueId );
     220    tr_bencDictAddInt( d, "isMultifile", inf->isMultifile );
    215221    tr_bencDictAddInt( d, "isPrivate", inf->isPrivate );
    216     tr_bencDictAddInt( d, "isMultifile", inf->isMultifile );
    217     tr_bencDictAddInt( d, "dateCreated", inf->dateCreated );
     222    tr_bencDictAddStr( d, "name", inf->name );
     223    tr_bencDictAddInt( d, "pieceCount", inf->pieceCount );
    218224    tr_bencDictAddInt( d, "pieceSize", inf->pieceSize );
    219     tr_bencDictAddInt( d, "pieceCount", inf->pieceCount );
     225    tr_bencDictAddStr( d, "torrent", inf->torrent );
    220226    tr_bencDictAddInt( d, "totalSize", inf->totalSize );
    221227    addFiles   ( inf, tr_bencDictAddList( d, "files", inf->fileCount ) );
    222     addTrackers( inf, tr_bencDictAddList( d, "files", inf->trackerCount ) );
     228    addTrackers( inf, tr_bencDictAddList( d, "trackers", inf->trackerCount ) );
    223229}
    224230
     
    228234    int i, torrentCount;
    229235    tr_torrent ** torrents = getTorrents( handle, args_in, &torrentCount );
    230     tr_benc * list = tr_bencDictAddList( args_out, "status", torrentCount );
     236    tr_benc * list = tr_bencDictAddList( args_out, "info", torrentCount );
    231237
    232238    for( i=0; i<torrentCount; ++i )
    233         serializeInfo( torrents[i], tr_bencListAdd( list ) );
     239        addInfo( torrents[i], tr_bencListAdd( list ) );
    234240
    235241    tr_free( torrents );
    236242    return NULL;
    237243}
     244
     245/**
     246***
     247**/
    238248
    239249static const char*
     
    346356
    347357static const char*
    348 torrentGetFile( tr_handle * handle, tr_benc * args_in, tr_benc * args_out )
     358torrentGetPriorities( tr_handle * handle, tr_benc * args_in, tr_benc * args_out )
    349359{
    350360    int i, torrentCount;
     
    357367        tr_benc * d = tr_bencListAddDict( list, 6 );
    358368        tr_bencDictAddInt( d, "id", tor->uniqueId );
    359         buildFileList( tor, d, "priority-high", testFileHigh );
     369        buildFileList( tor, d, "download", testFileDownload );
     370        buildFileList( tor, d, "no-download", testFileDND );
    360371        buildFileList( tor, d, "priority-low", testFileLow );
    361372        buildFileList( tor, d, "priority-normal", testFileNormal );
    362         buildFileList( tor, d, "download", testFileDownload );
    363         buildFileList( tor, d, "no-download", testFileDND );
     373        buildFileList( tor, d, "priority-high", testFileHigh );
    364374    }
    365375
     
    371381setFilePriorities( tr_torrent * tor, int priority, tr_benc * list )
    372382{
    373     const int n = tr_bencListSize( list );
    374383    int i;
    375384    int64_t tmp;
    376385    int fileCount = 0;
     386    const int n = tr_bencListSize( list );
    377387    tr_file_index_t * files = tr_new0( tr_file_index_t, n );
    378388
     
    390400setFileDLs( tr_torrent * tor, int do_download, tr_benc * list )
    391401{
    392     const int n = tr_bencListSize( list );
    393402    int i;
    394403    int64_t tmp;
    395404    int fileCount = 0;
     405    const int n = tr_bencListSize( list );
    396406    tr_file_index_t * files = tr_new0( tr_file_index_t, n );
    397407
     
    407417
    408418static const char*
    409 torrentSetFile( tr_handle * h, tr_benc * args_in, tr_benc * args_out UNUSED )
     419torrentSetPriorities( tr_handle * h, tr_benc * args_in, tr_benc * args_out UNUSED )
    410420{
    411421    int i, torrentCount;
     
    452462        ctor = tr_ctorNew( h );
    453463        tr_ctorSetMetainfoFromFile( ctor, filename );
     464        if( tr_bencDictFindStr( args_in, "destination", &str ) )
     465            tr_ctorSetDestination( ctor, TR_FORCE, str );
    454466        if( tr_bencDictFindInt( args_in, "paused", &i ) )
    455467            tr_ctorSetPaused( ctor, TR_FORCE, i );
    456468        if( tr_bencDictFindInt( args_in, "peer-limit", &i ) )
    457469            tr_ctorSetPeerLimit( ctor, TR_FORCE, i );
    458         if( tr_bencDictFindStr( args_in, "destination", &str ) )
    459             tr_ctorSetDestination( ctor, TR_FORCE, str );
    460470        tor = tr_torrentNew( h, ctor, &err );
    461471        tr_ctorFree( ctor );
    462472
    463473        if( tor )
    464             serializeInfo( tor, tr_bencDictAdd( args_out, "torrent-added" ) );
     474            addInfo( tor, tr_bencDictAdd( args_out, "torrent-added" ) );
    465475        else if( err == TR_EDUPLICATE )
    466476            return "duplicate torrent";
     
    484494    if( tr_bencDictFindInt( args_in, "peer-limit", &i ) )
    485495        tr_sessionSetPeerLimit( h, i );
     496    if( tr_bencDictFindInt( args_in, "pex-allowed", &i ) )
     497        tr_sessionSetPexEnabled( h, i );
    486498    if( tr_bencDictFindInt( args_in, "port", &i ) )
    487499        tr_sessionSetPublicPort( h, i );
    488500    if( tr_bencDictFindInt( args_in, "port-forwarding-enabled", &i ) )
    489501        tr_sessionSetPortForwardingEnabled( h, i );
    490     if( tr_bencDictFindInt( args_in, "pex-allowed", &i ) )
    491         tr_sessionSetPexEnabled( h, i );
    492502    if( tr_bencDictFindInt( args_in, "speed-limit-down", &i ) )
    493503        tr_sessionSetSpeedLimit( h, TR_DOWN, i );
     
    518528    tr_bencDictAddInt( d, "peer-limit",
    519529                          tr_sessionGetPeerLimit( h ) );
     530    tr_bencDictAddInt( d, "pex-allowed",
     531                          tr_sessionIsPexEnabled( h ) );
    520532    tr_bencDictAddInt( d, "port",
    521533                          tr_sessionGetPublicPort( h ) );
    522534    tr_bencDictAddInt( d, "port-forwarding-enabled",
    523535                          tr_sessionIsPortForwardingEnabled( h ) );
    524     tr_bencDictAddInt( d, "pex-allowed",
    525                           tr_sessionIsPexEnabled( h ) );
    526536    tr_bencDictAddInt( d, "speed-limit-up",
    527537                          tr_sessionGetSpeedLimit( h, TR_UP ) );
     
    550560typedef const char* (handler)( tr_handle*, tr_benc*, tr_benc* );
    551561
    552 struct request_handler
    553 {
    554     const char * method;
     562struct method
     563{
     564    const char * name;
    555565    handler * func;
    556 } request_handlers[] = {
     566} methods[] = {
    557567    { "torrent-start", torrentStart },
    558568    { "torrent-stop", torrentStop },
     
    564574    { "torrent-set", torrentSet },
    565575    { "torrent-get", torrentGet },
    566     { "torrent-set-file", torrentSetFile },
    567     { "torrent-get-file", torrentGetFile },
     576    { "torrent-set-priorities", torrentSetPriorities },
     577    { "torrent-get-priorities", torrentGetPriorities },
    568578    { "session-set", sessionSet },
    569579    { "session-get", sessionGet }
     
    593603        result = "no method name";
    594604    else {
    595         const int n = TR_N_ELEMENTS( request_handlers );
     605        const int n = TR_N_ELEMENTS( methods );
    596606        for( i=0; i<n; ++i )
    597             if( !strcmp( str, request_handlers[i].method ) )
     607            if( !strcmp( str, methods[i].name ) )
    598608                break;
    599609        result = i==n
    600610            ? "method name not recognized"
    601             : (*request_handlers[i].func)( handle, args_in, args_out );
     611            : (*methods[i].func)( handle, args_in, args_out );
    602612    }
    603613
     
    640650                           int               * response_len )
    641651{
    642     char * json = tr_rison2json( request_rison, request_len );
    643     char * ret = tr_rpc_request_exec_json( handle, json, -1, response_len );
    644     tr_free( json );
     652    char * ret = NULL;
     653    tr_benc top;
     654    int have_content;
     655    char * request = tr_strndup( request_rison, request_len );;
     656
     657fprintf( stderr, "passed in: --> %s <--\n", request );
     658    /* possibly convert o-rison to rison */
     659    if( request && ( *request != '(' ) )
     660    {
     661        const int n = strlen( request );
     662        char * tmp = tr_new( char, n + 3 );
     663        tmp[0] = '(';
     664        memcpy( tmp+1, request, n );
     665        tmp[n+1] = ')';
     666        tmp[n+2] = '\0';
     667        tr_free( request );
     668        request = tmp;
     669    }
     670fprintf( stderr, "after o-rison conversion: --> %s <--\n", request );
     671
     672    /* convert rison to json */
     673    {
     674        char * tmp = tr_rison2json( request, strlen( request ) );
     675        tr_free( request );
     676        request = tmp;
     677    }
     678fprintf( stderr, "after json conversion: --> %s <--\n", request );
     679
     680    /* parse the json */
     681    have_content = !tr_jsonParse( request, request+strlen(request), &top, NULL );
     682    if( have_content )
     683    {
     684        /* for convenience' sake, our URI rpc notation allows the
     685         * `args' object to be declared implicitly... */
     686        tr_benc tmp, *args;
     687        int64_t i;
     688        const char * str;
     689        tr_bencInitDict( &tmp, 3 );
     690        if( tr_bencDictFindInt( &top, "tag", &i ) )
     691            tr_bencDictAddInt( &tmp, "tag", i );
     692        if( tr_bencDictFindStr( &top, "method", &str ) )
     693            tr_bencDictAddStr( &tmp, "method", str );
     694        args = tr_bencDictAdd( &tmp, "args" );
     695        *args = top;
     696tr_bencPrint( &tmp);
     697        ret = request_exec( handle, &tmp, response_len );
     698        tr_bencInitInt( args, 0 );
     699        tr_bencFree( &tmp );
     700        tr_bencFree( &top );
     701    }
     702
     703    tr_free( request );
    645704    return ret;
    646705}
Note: See TracChangeset for help on using the changeset viewer.