(trunk) #3817 "use the OS' proxy support" -- implemented for libtransmission, transmission-gtk

This commit is contained in:
Charles Kerr 2010-12-10 18:51:05 +00:00
parent fb106b541c
commit 0e9247b84a
6 changed files with 173 additions and 4 deletions

View File

@ -35,10 +35,13 @@
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <curl/curl.h>
#include <libtransmission/transmission.h>
#include <libtransmission/rpcimpl.h>
#include <libtransmission/utils.h>
#include <libtransmission/version.h>
#include <libtransmission/web.h>
#include "actions.h"
#include "add-dialog.h"
@ -528,6 +531,116 @@ checkfilenames( int argc, char **argv )
return g_slist_reverse( ret );
}
#ifdef HAVE_GCONF2
static void
applyDesktopProxySettings( CURL * easy, GConfClient * client, const char * host_key, const char * port_key )
{
int port;
GConfValue * value;
if(( value = gconf_client_get( client, host_key, NULL )))
{
const char * url = gconf_value_get_string( value );
if( url && *url )
{
char * scheme = NULL;
if( !tr_urlParse( url, strlen( url ), &scheme, NULL, NULL, NULL ) )
{
if( !gtr_strcmp0( scheme, "socks4" ) )
curl_easy_setopt( easy, CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4 );
else if( !gtr_strcmp0( scheme, "socks5" ) )
curl_easy_setopt( easy, CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5 );
else if( !gtr_strcmp0( scheme, "http" ) )
curl_easy_setopt( easy, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTP );
}
curl_easy_setopt( easy, CURLOPT_PROXY, url );
if( port_key != NULL )
if(( value = gconf_client_get( client, port_key, NULL )))
if(( port = gconf_value_get_int( value )))
curl_easy_setopt( easy, CURLOPT_PROXYPORT, (long)port );
tr_free( scheme );
}
}
}
#endif
static void
curlConfigFunc( tr_session * session UNUSED, void * vcurl UNUSED, const char * destination )
{
#ifdef HAVE_GCONF2
const char * str;
GConfValue * value;
CURL * easy = vcurl;
gboolean use_http_proxy = TRUE;
GConfClient * client = gconf_client_get_default( );
/* get GNOME's proxy mode */
if(( value = gconf_client_get( client, "/system/proxy/mode", NULL )))
{
char * mode = g_strdup( gconf_value_get_string( value ) );
if( !gtr_strcmp0( mode, "auto" ) )
{
applyDesktopProxySettings( easy, client, "/system/proxy/autoconfig_url", NULL );
use_http_proxy = FALSE;
}
else if( !gtr_strcmp0( mode, "manual" ))
{
char * scheme = NULL;
if( !tr_urlParse( destination, strlen( destination ), &scheme, NULL, NULL, NULL ) )
{
if( !gtr_strcmp0( scheme, "ftp" ) )
{
applyDesktopProxySettings( easy, client, "/system/proxy/ftp_host", "/system/proxy/ftp_port" );
use_http_proxy = FALSE;
}
else if( !gtr_strcmp0( scheme, "https" ) )
{
applyDesktopProxySettings( easy, client, "/system/proxy/secure_host", "/system/proxy/secure_port" );
use_http_proxy = FALSE;
}
}
tr_free( scheme );
}
g_free( mode );
}
/* if this the proxy hasn't been handled yet and "use_http_proxy" is disabled, then don't use a proxy */
if( use_http_proxy )
if(( value = gconf_client_get( client, "/system/http_proxy/use_http_proxy", NULL )))
use_http_proxy = gconf_value_get_bool( value ) != 0;
if( use_http_proxy )
{
applyDesktopProxySettings( easy, client, "/system/http_proxy/host", "/system/http_proxy/port" );
if((( value = gconf_client_get( client, "/system/http_proxy/use_authentication", NULL ))) && gconf_value_get_bool( value ))
{
const char * user = NULL;
const char * pass = NULL;
if(( value = gconf_client_get( client, "/system/http_proxy/authentication_user", NULL )))
user = str = gconf_value_get_string( value );
if(( value = gconf_client_get( client, "/system/http_proxy/authentication_password", NULL )))
pass = str = gconf_value_get_string( value );
if( ( user != NULL ) && ( pass != NULL ) )
{
char * userpass = g_strdup_printf( "%s:%s", user, pass );
curl_easy_setopt( easy, CURLOPT_PROXYUSERPWD, userpass );
g_free( userpass );
}
}
}
#endif
}
int
main( int argc, char ** argv )
{
@ -660,6 +773,8 @@ main( int argc, char ** argv )
/* initialize the libtransmission session */
session = tr_sessionInit( "gtk", configDir, TRUE, pref_get_all( ) );
tr_sessionSetWebConfigFunc( session, curlConfigFunc );
pref_flag_set( TR_PREFS_KEY_ALT_SPEED_ENABLED, tr_sessionUsesAltSpeed( session ) );
pref_int_set( TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( session ) );
cbdata->core = tr_core_new( session );

View File

@ -1112,7 +1112,7 @@ onCorePrefsChanged( TrCore * core UNUSED, const char * key, gpointer gdata )
}
static void
peerPageDestroyed( gpointer gdata, GObject * dead UNUSED )
networkPageDestroyed( gpointer gdata, GObject * dead UNUSED )
{
struct network_page_data * data = gdata;
if( data->prefsTag > 0 )
@ -1146,8 +1146,26 @@ onPortTest( GtkButton * button UNUSED, gpointer vdata )
tr_core_port_test( data->core );
}
static void
onGNOMEClicked( GtkButton * button, gpointer vdata UNUSED )
{
GError * err = NULL;
if( !g_spawn_command_line_async( "gnome-network-properties", &err ) )
{
GtkWidget * d = gtk_message_dialog_new( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( button ) ) ),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"%s", err->message );
g_signal_connect_swapped( d, "response", G_CALLBACK( gtk_widget_destroy ), d );
gtk_widget_show( d );
g_clear_error( &err );
}
}
static GtkWidget*
peerPage( GObject * core )
networkPage( GObject * core )
{
int row = 0;
const char * s;
@ -1178,7 +1196,7 @@ peerPage( GObject * core )
g_signal_connect( w, "clicked", G_CALLBACK(onPortTest), data );
hig_workarea_add_row( t, &row, NULL, h, NULL );
data->prefsTag = g_signal_connect( TR_CORE( core ), "prefs-changed", G_CALLBACK( onCorePrefsChanged ), data );
g_object_weak_ref( G_OBJECT( t ), peerPageDestroyed, data );
g_object_weak_ref( G_OBJECT( t ), networkPageDestroyed, data );
s = _( "Pick a _random port every time Transmission is started" );
w = new_check_button( s, TR_PREFS_KEY_PEER_PORT_RANDOM_ON_START, core );
@ -1196,6 +1214,13 @@ peerPage( GObject * core )
w = new_spin_button( TR_PREFS_KEY_PEER_LIMIT_GLOBAL, core, 1, 3000, 5 );
hig_workarea_add_row( t, &row, _( "Maximum peers _overall:" ), w, NULL );
hig_workarea_add_section_divider( t, &row );
hig_workarea_add_section_title( t, &row, _( "Options" ) );
w = gtk_button_new_with_mnemonic( _( "Launch GNOME Network Preferences" ) );
g_signal_connect( w, "clicked", G_CALLBACK( onGNOMEClicked ), data );
hig_workarea_add_row( t, &row, _( "Pro_xies:" ), w, NULL );
hig_workarea_finish( t, &row );
return t;
}
@ -1234,7 +1259,7 @@ tr_prefs_dialog_new( GObject * core,
privacyPage( core ),
gtk_label_new ( _( "Privacy" ) ) );
gtk_notebook_append_page( GTK_NOTEBOOK( n ),
peerPage( core ),
networkPage( core ),
gtk_label_new ( _( "Network" ) ) );
gtk_notebook_append_page( GTK_NOTEBOOK( n ),
desktopPage( core ),

View File

@ -2471,3 +2471,13 @@ tr_sessionSetTorrentDoneScript( tr_session * session, const char * scriptFilenam
session->torrentDoneScript = tr_strdup( scriptFilename );
}
}
/***
****
***/
void
tr_sessionSetWebConfigFunc( tr_session * session, void (*func)(tr_session*, void*, const char* ) )
{
session->curl_easy_config_func = func;
}

View File

@ -44,6 +44,8 @@ struct tr_bindsockets;
struct tr_cache;
struct tr_fdInfo;
typedef void ( tr_web_config_func )( tr_session * session, void * curl_pointer, const char * url );
struct tr_turtle_info
{
/* TR_UP and TR_DOWN speed limits */
@ -190,6 +192,8 @@ struct tr_session
void * buffer;
tr_bool bufferInUse;
tr_web_config_func * curl_easy_config_func;
};
static inline tr_port

View File

@ -172,6 +172,9 @@ createEasy( tr_session * s, struct tr_web_task * task )
if( task->range )
curl_easy_setopt( e, CURLOPT_RANGE, task->range );
if( s->curl_easy_config_func != NULL )
s->curl_easy_config_func( s, e, task->url );
tr_free( cookie_filename );
return e;
}

View File

@ -24,6 +24,18 @@ typedef enum
}
tr_web_close_mode;
/**
* This is a mechanism for adjusting your CURL* object to match
* the host OS's platform-dependent settings.
*
* A use case for this function is to call curl_easy_setopt() on curl_pointer.
*
* Examples of curl_easy_setopt() can be found at
* http://curl.haxx.se/libcurl/c/curl_easy_setopt.html()
*/
void tr_sessionSetWebConfigFunc( tr_session * session, void (*config)(tr_session * session, void * curl_pointer, const char * url ) );
void tr_webClose( tr_session * session, tr_web_close_mode close_mode );
typedef void ( tr_web_done_func )( tr_session * session,