Changeset 11524


Ignore:
Timestamp:
Dec 12, 2010, 6:22:11 PM (11 years ago)
Author:
charles
Message:

(trunk) #1538 "Make Web UI URL configurable" -- added to trunk. Patch by wereHamster

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/daemon/remote.c

    r11523 r11524  
    4141#define DEFAULT_HOST "localhost"
    4242#define DEFAULT_PORT atoi(TR_DEFAULT_RPC_PORT_STR)
     43#define DEFAULT_URL TR_DEFAULT_RPC_URL_STR "rpc/"
    4344
    4445#define ARGUMENTS "arguments"
     
    208209                "       "
    209210        MY_NAME " [host:port] [options]\n"
     211                "       "
     212        MY_NAME " [http://host:port/transmission/] [options]\n"
    210213                "\n"
    211214                "See the man page for detailed explanations and many examples.";
     
    15921595
    15931596static int
    1594 processResponse( const char * host, int port, const void * response, size_t len )
     1597processResponse( const char * rpcurl, const void * response, size_t len )
    15951598{
    15961599    tr_benc top;
     
    16551658                    status |= EXIT_FAILURE;
    16561659                else {
    1657                     printf( "%s:%d responded: \"%s\"\n", host, port, str );
     1660                    printf( "%s responded: \"%s\"\n", rpcurl, str );
    16581661                    if( strcmp( str, "success") )
    16591662                        status |= EXIT_FAILURE;
     
    16941697
    16951698static int
    1696 flush( const char * host, int port, tr_benc ** benc )
     1699flush( const char * rpcurl, tr_benc ** benc )
    16971700{
    16981701    CURLcode res;
     
    17011704    struct evbuffer * buf = evbuffer_new( );
    17021705    char * json = tr_bencToStr( *benc, TR_FMT_JSON_LEAN, NULL );
    1703     char * url = tr_strdup_printf( "http://%s:%d/transmission/rpc", host, port );
    17041706
    17051707    curl = tr_curl_easy_init( buf );
    1706     curl_easy_setopt( curl, CURLOPT_URL, url );
     1708    curl_easy_setopt( curl, CURLOPT_URL, rpcurl );
    17071709    curl_easy_setopt( curl, CURLOPT_POSTFIELDS, json );
    17081710    curl_easy_setopt( curl, CURLOPT_TIMEOUT, getTimeoutSecs( json ) );
     
    17131715    if(( res = curl_easy_perform( curl )))
    17141716    {
    1715         tr_nerr( MY_NAME, "(%s) %s", url, curl_easy_strerror( res ) );
     1717        tr_nerr( MY_NAME, "(%s) %s", rpcurl, curl_easy_strerror( res ) );
    17161718        status |= EXIT_FAILURE;
    17171719    }
     
    17221724        switch( response ) {
    17231725            case 200:
    1724                 status |= processResponse( host, port, EVBUFFER_DATA(buf), EVBUFFER_LENGTH(buf) );
     1726                status |= processResponse( rpcurl, EVBUFFER_DATA(buf), EVBUFFER_LENGTH(buf) );
    17251727                break;
    17261728            case 409:
     
    17301732                curl_easy_cleanup( curl );
    17311733                curl = NULL;
    1732                 flush( host, port, benc );
     1734                flush( rpcurl, benc );
    17331735                benc = NULL;
    17341736                break;
     
    17411743
    17421744    /* cleanup */
    1743     tr_free( url );
    17441745    tr_free( json );
    17451746    evbuffer_free( buf );
     
    17881789
    17891790static int
    1790 processArgs( const char * host, int port, int argc, const char ** argv )
     1791processArgs( const char * rpcurl, int argc, const char ** argv )
    17911792{
    17921793    int c;
     
    18081809            {
    18091810                case 'a': /* add torrent */
    1810                     if( sset != 0 ) status |= flush( host, port, &sset );
    1811                     if( tadd != 0 ) status |= flush( host, port, &tadd );
    1812                     if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( host, port, &tset ); }
     1811                    if( sset != 0 ) status |= flush( rpcurl, &sset );
     1812                    if( tadd != 0 ) status |= flush( rpcurl, &tadd );
     1813                    if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( rpcurl, &tset ); }
    18131814                    tadd = tr_new0( tr_benc, 1 );
    18141815                    tr_bencInitDict( tadd, 3 );
     
    18421843
    18431844                case 't': /* set current torrent */
    1844                     if( tadd != 0 ) status |= flush( host, port, &tadd );
    1845                     if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( host, port, &tset ); }
     1845                    if( tadd != 0 ) status |= flush( rpcurl, &tadd );
     1846                    if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( rpcurl, &tset ); }
    18461847                    tr_strlcpy( id, optarg, sizeof( id ) );
    18471848                    break;
     
    18851886            fields = tr_bencDictAddList( args, "fields", 0 );
    18861887
    1887             if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( host, port, &tset ); }
    1888 
     1888            if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( rpcurl, &tset ); }
     1889           
    18891890            switch( c )
    18901891            {
     
    19191920            }
    19201921
    1921             status |= flush( host, port, &top );
     1922            status |= flush( rpcurl, &top );
    19221923        }
    19231924        else if( stepMode == MODE_SESSION_SET )
     
    21202121                tr_bencDictAddBool( args, "move", FALSE );
    21212122                addIdArg( args, id );
    2122                 status |= flush( host, port, &top );
     2123                status |= flush( rpcurl, &top );
    21232124                break;
    21242125            }
     
    21322133                tr_bencDictAddStr( top, "method", "session-get" );
    21332134                tr_bencDictAddInt( top, "tag", TAG_SESSION );
    2134                 status |= flush( host, port, &top );
     2135                status |= flush( rpcurl, &top );
    21352136                break;
    21362137            }
     
    21442145                    tr_bencDictAddStr( top, "method", "torrent-start" );
    21452146                    addIdArg( tr_bencDictAddDict( top, ARGUMENTS, 1 ), id );
    2146                     status |= flush( host, port, &top );
     2147                    status |= flush( rpcurl, &top );
    21472148                }
    21482149                break;
     
    21572158                    tr_bencDictAddStr( top, "method", "torrent-stop" );
    21582159                    addIdArg( tr_bencDictAddDict( top, ARGUMENTS, 1 ), id );
    2159                     status |= flush( host, port, &top );
     2160                    status |= flush( rpcurl, &top );
    21602161                }
    21612162                break;
     
    21782179                tr_bencInitDict( top, 1 );
    21792180                tr_bencDictAddStr( top, "method", "blocklist-update" );
    2180                 status |= flush( host, port, &top );
     2181                status |= flush( rpcurl, &top );
    21812182                break;
    21822183            }
     
    21872188                tr_bencDictAddStr( top, "method", "session-stats" );
    21882189                tr_bencDictAddInt( top, "tag", TAG_STATS );
    2189                 status |= flush( host, port, &top );
     2190                status |= flush( rpcurl, &top );
    21902191                break;
    21912192            }
     
    21962197                tr_bencDictAddStr( top, "method", "port-test" );
    21972198                tr_bencDictAddInt( top, "tag", TAG_PORTTEST );
    2198                 status |= flush( host, port, &top );
     2199                status |= flush( rpcurl, &top );
    21992200                break;
    22002201            }
     
    22022203            {
    22032204                tr_benc * top;
    2204                 if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( host, port, &tset ); }
     2205                if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( rpcurl, &tset ); }
    22052206                top = tr_new0( tr_benc, 1 );
    22062207                tr_bencInitDict( top, 2 );
    22072208                tr_bencDictAddStr( top, "method", "torrent-reannounce" );
    22082209                addIdArg( tr_bencDictAddDict( top, ARGUMENTS, 1 ), id );
    2209                 status |= flush( host, port, &top );
     2210                status |= flush( rpcurl, &top );
    22102211                break;
    22112212            }
     
    22132214            {
    22142215                tr_benc * top;
    2215                 if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( host, port, &tset ); }
     2216                if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( rpcurl, &tset ); }
    22162217                top = tr_new0( tr_benc, 1 );
    22172218                tr_bencInitDict( top, 2 );
    22182219                tr_bencDictAddStr( top, "method", "torrent-verify" );
    22192220                addIdArg( tr_bencDictAddDict( top, ARGUMENTS, 1 ), id );
    2220                 status |= flush( host, port, &top );
     2221                status |= flush( rpcurl, &top );
    22212222                break;
    22222223            }
     
    22312232                tr_bencDictAddBool( args, "delete-local-data", c=='R' );
    22322233                addIdArg( args, id );
    2233                 status |= flush( host, port, &top );
     2234                status |= flush( rpcurl, &top );
    22342235                break;
    22352236            }
     
    22442245                tr_bencDictAddBool( args, "move", TRUE );
    22452246                addIdArg( args, id );
    2246                 status |= flush( host, port, &top );
     2247                status |= flush( rpcurl, &top );
    22472248                break;
    22482249            }
     
    22562257    }
    22572258
    2258     if( tadd != 0 ) status |= flush( host, port, &tadd );
    2259     if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( host, port, &tset ); }
    2260     if( sset != 0 ) status |= flush( host, port, &sset );
     2259    if( tadd != 0 ) status |= flush( rpcurl, &tadd );
     2260    if( tset != 0 ) { addIdArg( tr_bencDictFind( tset, ARGUMENTS ), id ); status |= flush( rpcurl, &tset ); }
     2261    if( sset != 0 ) status |= flush( rpcurl, &sset );
    22612262    return status;
    22622263}
    22632264
    2264 /* [host:port] or [host] or [port] */
     2265/* [host:port] or [host] or [port] or [http://host:port/transmission/] */
    22652266static void
    2266 getHostAndPort( int * argc, char ** argv, char ** host, int * port )
     2267getHostAndPortAndRpcUrl( int * argc, char ** argv,
     2268                         char ** host, int * port, char ** rpcurl )
    22672269{
    22682270    if( *argv[1] != '-' )
     
    22712273        const char * s = argv[1];
    22722274        const char * delim = strchr( s, ':' );
    2273         if( delim )   /* user passed in both host and port */
     2275        if( !strncmp(s, "http://", 7 ) )   /* user passed in full rpc url */
     2276        {
     2277            *rpcurl = tr_strdup_printf( "%s/rpc/", s );
     2278        }
     2279        else if( delim )   /* user passed in both host and port */
    22742280        {
    22752281            *host = tr_strndup( s, delim - s );
     
    22972303    int port = DEFAULT_PORT;
    22982304    char * host = NULL;
     2305    char * rpcurl = NULL;
    22992306    int exit_status = EXIT_SUCCESS;
    23002307
     
    23082315    tr_formatter_speed_init( SPEED_K, SPEED_K_STR, SPEED_M_STR, SPEED_G_STR, SPEED_T_STR );
    23092316
    2310     getHostAndPort( &argc, argv, &host, &port );
     2317    getHostAndPortAndRpcUrl( &argc, argv, &host, &port, &rpcurl );
    23112318    if( host == NULL )
    23122319        host = tr_strdup( DEFAULT_HOST );
    2313 
    2314     exit_status = processArgs( host, port, argc, (const char**)argv );
     2320    if( rpcurl == NULL )
     2321        rpcurl = tr_strdup_printf( "http://%s:%d%s", host, port, DEFAULT_URL );
     2322
     2323    exit_status = processArgs( rpcurl, argc, (const char**)argv );
    23152324
    23162325    tr_free( host );
     2326    tr_free( rpcurl );
    23172327    return exit_status;
    23182328}
  • trunk/libtransmission/rpc-server.c

    r11398 r11524  
    6262    tr_bool            isWhitelistEnabled;
    6363    tr_port            port;
     64    char *             url;
    6465    struct in_addr     bindAddress;
    6566    struct evhttp *    httpd;
     
    467468    const char * webClientDir = tr_getWebClientDir( server->session );
    468469
    469     assert( !strncmp( req->uri, "/transmission/web/", 18 ) );
    470 
    471470    if( !webClientDir || !*webClientDir )
    472471    {
     
    486485        char * subpath;
    487486
    488         subpath = tr_strdup( req->uri + 18 );
     487        subpath = tr_strdup( req->uri + strlen( server->url ) + 4 );
    489488        if(( pch = strchr( subpath, '?' )))
    490489            *pch = '\0';
     
    627626            send_simple_response( req, 401, "Unauthorized User" );
    628627        }
    629         else if( !strcmp( req->uri, "/transmission/web" )
    630                || !strcmp( req->uri, "/transmission/clutch" )
    631                || !strcmp( req->uri, "/" ) )
    632         {
    633             evhttp_add_header( req->output_headers, "Location", "/transmission/web/" );
     628        else if( strncmp( req->uri, server->url, strlen( server->url ) ) )
     629        {
     630            const char * protocol = "http";
     631            const char * host = evhttp_find_header( req->input_headers, "Host" );
     632            char * location = tr_strdup_printf( "%s://%s%sweb/", protocol, host, server->url );
     633            evhttp_add_header( req->output_headers, "Location", location );
    634634            send_simple_response( req, HTTP_MOVEPERM, NULL );
    635         }
    636         else if( !strncmp( req->uri, "/transmission/web/", 18 ) )
     635            tr_free( location );
     636        }
     637        else if( !strncmp( req->uri + strlen( server->url ), "web/", 4 ) )
    637638        {
    638639            handle_web_client( req, server );
    639         }
    640         else if( !strncmp( req->uri, "/transmission/upload", 20 ) )
    641         {
    642             handle_upload( req, server );
    643640        }
    644641#ifdef REQUIRE_SESSION_ID
     
    663660        }
    664661#endif
    665         else if( !strncmp( req->uri, "/transmission/rpc", 17 ) )
     662        else if( !strncmp( req->uri + strlen( server->url ), "rpc", 3 ) )
    666663        {
    667664            handle_rpc( req, server );
     665        }
     666        else if( !strncmp( req->uri + strlen( server->url ), "upload", 6 ) )
     667        {
     668            handle_upload( req, server );
    668669        }
    669670        else
     
    764765
    765766void
    766 tr_rpcSetWhitelist( tr_rpc_server * server,
    767                     const char    * whitelistStr )
     767tr_rpcSetUrl( tr_rpc_server * server, const char * url )
     768{
     769    char * tmp = server->url;
     770    server->url = tr_strdup( url );
     771    dbgmsg( "setting our URL to [%s]", server->url );
     772    tr_free( tmp );
     773}
     774
     775const char*
     776tr_rpcGetUrl( const tr_rpc_server * server )
     777{
     778    return server->url ? server->url : "";
     779}
     780
     781void
     782tr_rpcSetWhitelist( tr_rpc_server * server, const char * whitelistStr )
    768783{
    769784    void * tmp;
     
    771786
    772787    /* keep the string */
    773     tr_free( server->whitelistStr );
     788    tmp = server->whitelistStr;
    774789    server->whitelistStr = tr_strdup( whitelistStr );
     790    tr_free( tmp );
    775791
    776792    /* clear out the old whitelist entries */
     
    819835
    820836void
    821 tr_rpcSetUsername( tr_rpc_server * server,
    822                    const char *    username )
    823 {
    824     tr_free( server->username );
     837tr_rpcSetUsername( tr_rpc_server * server, const char * username )
     838{
     839    char * tmp = server->username;
    825840    server->username = tr_strdup( username );
    826841    dbgmsg( "setting our Username to [%s]", server->username );
     842    tr_free( tmp );
    827843}
    828844
     
    891907        deflateEnd( &s->stream );
    892908#endif
     909    tr_free( s->url );
    893910    tr_free( s->sessionId );
    894911    tr_free( s->whitelistStr );
     
    925942    assert( found );
    926943    s->port = i;
     944
     945    found = tr_bencDictFindStr( settings, TR_PREFS_KEY_RPC_URL, &str );
     946    assert( found );
     947    s->url = tr_strdup( str );
    927948
    928949    found = tr_bencDictFindBool( settings, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, &boolVal );
     
    960981    if( s->isEnabled )
    961982    {
    962         tr_ninf( MY_NAME, _( "Serving RPC and Web requests on port %d" ), (int) s->port );
     983        tr_ninf( MY_NAME, _( "Serving RPC and Web requests on port 127.0.0.1:%d%s" ), (int) s->port, s->url );
    963984        tr_runInEventThread( session, startServer, s );
    964985
  • trunk/libtransmission/rpc-server.h

    r9868 r11524  
    3535tr_port         tr_rpcGetPort( const tr_rpc_server * server );
    3636
     37void            tr_rpcSetUrl( tr_rpc_server * server,
     38                              const char    * url );
     39
     40const char *    tr_rpcGetUrl( const tr_rpc_server * server );
     41
    3742int             tr_rpcSetTest( const tr_rpc_server   * server,
    3843                               const char            * whitelist,
  • trunk/libtransmission/session.c

    r11516 r11524  
    285285    tr_bencDictAddBool( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED,    TRUE );
    286286    tr_bencDictAddInt ( d, TR_PREFS_KEY_RPC_PORT,                 atoi( TR_DEFAULT_RPC_PORT_STR ) );
     287    tr_bencDictAddStr ( d, TR_PREFS_KEY_RPC_URL,                  TR_DEFAULT_RPC_URL_STR );
    287288    tr_bencDictAddStr ( d, TR_PREFS_KEY_SCRIPT_TORRENT_DONE_FILENAME, "" );
    288289    tr_bencDictAddBool( d, TR_PREFS_KEY_SCRIPT_TORRENT_DONE_ENABLED, FALSE );
     
    346347    tr_bencDictAddStr ( d, TR_PREFS_KEY_RPC_PASSWORD,             tr_sessionGetRPCPassword( s ) );
    347348    tr_bencDictAddInt ( d, TR_PREFS_KEY_RPC_PORT,                 tr_sessionGetRPCPort( s ) );
     349    tr_bencDictAddStr ( d, TR_PREFS_KEY_RPC_URL,                  tr_sessionGetRPCUrl( s ) );
    348350    tr_bencDictAddStr ( d, TR_PREFS_KEY_RPC_USERNAME,             tr_sessionGetRPCUsername( s ) );
    349351    tr_bencDictAddStr ( d, TR_PREFS_KEY_RPC_WHITELIST,            tr_sessionGetRPCWhitelist( s ) );
     
    23282330
    23292331void
     2332tr_sessionSetRPCUrl( tr_session * session,
     2333                     const char * url )
     2334{
     2335    assert( tr_isSession( session ) );
     2336
     2337    tr_rpcSetUrl( session->rpcServer, url );
     2338}
     2339
     2340const char*
     2341tr_sessionGetRPCUrl( const tr_session * session )
     2342{
     2343    assert( tr_isSession( session ) );
     2344
     2345    return tr_rpcGetUrl( session->rpcServer );
     2346}
     2347
     2348void
    23302349tr_sessionSetRPCCallback( tr_session * session,
    23312350                          tr_rpc_func  func,
  • trunk/libtransmission/transmission.h

    r11522 r11524  
    143143#define TR_DEFAULT_RPC_WHITELIST          "127.0.0.1"
    144144#define TR_DEFAULT_RPC_PORT_STR                "9091"
     145#define TR_DEFAULT_RPC_URL_STR       "/transmission/"
    145146#define TR_DEFAULT_PEER_PORT_STR              "51413"
    146147#define TR_DEFAULT_PEER_SOCKET_TOS_STR            "0"
     
    191192#define TR_PREFS_KEY_RPC_PORT                      "rpc-port"
    192193#define TR_PREFS_KEY_RPC_USERNAME                  "rpc-username"
     194#define TR_PREFS_KEY_RPC_URL                       "rpc-url"
    193195#define TR_PREFS_KEY_RPC_WHITELIST_ENABLED         "rpc-whitelist-enabled"
    194196#define TR_PREFS_KEY_SCRIPT_TORRENT_DONE_FILENAME  "script-torrent-done-filename"
     
    421423    @see tr_sessionSetRPCPort */
    422424tr_port tr_sessionGetRPCPort( const tr_session * session );
     425
     426/**
     427 * @brief Specify which base URL to use.
     428 *
     429 * @detail The RPC API is accessible under <url>/rpc, the web interface under
     430 * <url>/web.
     431 *
     432 *  @see tr_sessionGetRPCUrl
     433 */
     434void tr_sessionSetRPCUrl( tr_session  * session,
     435                          const char * url );
     436
     437/**
     438 * @brief Get the base URL.
     439 * @see tr_sessionInit()
     440 * @see tr_sessionSetRPCUrl
     441 */
     442const char* tr_sessionGetRPCUrl( const tr_session * session );
    423443
    424444/**
  • trunk/web/javascript/transmission.js

    r11390 r11524  
    18061806                                tr.remote.addTorrentByUrl($('#torrent_upload_url').val(), { paused: paused });
    18071807                        } else {
    1808                                 args.url = '/transmission/upload?paused=' + paused;
     1808                                args.url = '../upload?paused=' + paused;
    18091809                                args.type = 'POST';
    18101810                                args.data = { 'X-Transmission-Session-Id' : tr.remote._token };
  • trunk/web/javascript/transmission.remote.js

    r11191 r11524  
    1111
    1212// Constants
    13 RPC._Root                   = '/transmission/rpc';
     13RPC._Root                   = '../rpc';
    1414RPC._DaemonVersion          = 'version';
    1515RPC._Encryption             = 'encryption';
Note: See TracChangeset for help on using the changeset viewer.