--- Input/cdaudio/cdaudio.c
+++ Input/cdaudio/cdaudio.c
@@ -216,6 +216,10 @@
 	xmms_cfg_read_string(cfgfile, "CDDA", "name_format", &cdda_cfg.name_format);
 	xmms_cfg_read_boolean(cfgfile, "CDDA", "use_cddb", &cdda_cfg.use_cddb);
 	xmms_cfg_read_string(cfgfile, "CDDA", "cddb_server", &cdda_cfg.cddb_server);
+	xmms_cfg_read_boolean(cfgfile, "CDDA", "use_cddb_proxy", &cdda_cfg.use_cddb_proxy);
+	xmms_cfg_read_string(cfgfile, "CDDA", "cddb_proxy", &cdda_cfg.cddb_proxy);
+	xmms_cfg_read_int(cfgfile, "CDDA", "cddb_proxy_port", &cdda_cfg.cddb_proxy_port);
+
 #ifdef WITH_CDINDEX
 	xmms_cfg_read_boolean(cfgfile, "CDDA", "use_cdin", &cdda_cfg.use_cdin);
 #else
@@ -228,6 +232,11 @@
 		cdda_cfg.cdin_server = g_strdup("www.cdindex.org");
 	if (!cdda_cfg.cddb_server)
 		cdda_cfg.cddb_server = g_strdup(CDDB_DEFAULT_SERVER);
+	if (!cdda_cfg.cddb_proxy)
+		cdda_cfg.cddb_proxy = g_strdup("");
+	if (!cdda_cfg.cddb_proxy_port)
+		cdda_cfg.cddb_proxy_port = 3128;
+
 	if (!cdda_cfg.name_format)
 		cdda_cfg.name_format = g_strdup("%p - %t");
 }
--- Input/cdaudio/cdaudio.h
+++ Input/cdaudio/cdaudio.h
@@ -110,6 +110,9 @@
 	char *cddb_server;
 	int cddb_protocol_level;
 	gboolean use_cddb;
+	gchar *cddb_proxy;
+	gint cddb_proxy_port;
+	gboolean use_cddb_proxy;
 
 	char *cdin_server;
 	gboolean use_cdin;
--- Input/cdaudio/cddb.c
+++ Input/cdaudio/cddb.c
@@ -26,6 +26,7 @@
 #include <gtk/gtk.h>
 #include <stdarg.h>
 #include <dirent.h>
+#include <stdlib.h> /* atoi() */
 #include <pthread.h>
 #include "xmms/i18n.h"
 
@@ -154,7 +155,7 @@
 	gint sock;
 	gchar *status;
 	
-	if((sock = http_open_connection(server, 80)) == 0)
+	if((sock = http_open_connection(server, port)) == 0)
 		status = "Failed";
 	else
 		status = "OK";
@@ -176,19 +177,47 @@
 	gchar buffer[256];
 	gchar **response;
 	gint i;
+	gchar *host=NULL;
+	gint port;
 
-	if((sock = cddb_http_open_connection(server, 80)) == 0)
+	if (cdda_cfg.use_cddb_proxy 
+	    && cdda_cfg.cddb_proxy!=NULL 
+	    && strlen(cdda_cfg.cddb_proxy)){
+		host=cdda_cfg.cddb_proxy;
+		port=cdda_cfg.cddb_proxy_port;
+	}
+	else {
+		host=server;
+		port=80;
+	}
+	if(host==NULL){
 		return FALSE;
+	}
+
+	sock = cddb_http_open_connection(host, port);
+
+	if (sock == 0)
+	    return FALSE;
 
 	offsets = cddb_generate_offset_string(info);
 
 	cddb_log("Sending query-command. Disc ID: %08x", cdda_cddb_compute_discid(info));
 
-	getstr = g_strdup_printf(
-		"GET /~cddb/cddb.cgi?cmd=cddb+query+%08x+%d+%s+%d%s&proto=%d HTTP/1.0\r\n\r\n",
-		cdda_cddb_compute_discid(info), info->last_track - info->first_track + 1,
-		offsets, (info->leadout.minute * 60 + info->leadout.second),
-		cddb_generate_hello_string(), cdda_cfg.cddb_protocol_level);
+	if (cdda_cfg.use_cddb_proxy){
+		getstr = g_strdup_printf(
+			"GET http://%s/~cddb/cddb.cgi?cmd=cddb+query+%08x+%d+%s+%d%s&proto=%d HTTP/1.0\r\n\r\n",
+			server,
+			cdda_cddb_compute_discid(info), info->last_track - info->first_track + 1,
+			offsets, (info->leadout.minute * 60 + info->leadout.second),
+			cddb_generate_hello_string(), cdda_cfg.cddb_protocol_level);
+	}
+	else {
+		getstr = g_strdup_printf(
+			"GET /~cddb/cddb.cgi?cmd=cddb+query+%08x+%d+%s+%d%s&proto=%d HTTP/1.0\r\n\r\n",
+			cdda_cddb_compute_discid(info), info->last_track - info->first_track + 1,
+			offsets, (info->leadout.minute * 60 + info->leadout.second),
+			cddb_generate_hello_string(), cdda_cfg.cddb_protocol_level);
+	}
 
 	g_free(offsets);
 	write(sock, getstr, strlen(getstr));
@@ -233,13 +262,36 @@
 {
 	int level = 0, sock, n;
 	char *str, buffer[256];
-
-	if((sock = cddb_http_open_connection(server, 80)) == 0)
-		return 0;
-		
-	str = g_strdup_printf(
-		"GET /~cddb/cddb.cgi?cmd=stat%s&proto=1 HTTP/1.0\r\n\r\n",
-		cddb_generate_hello_string());
+ 	gchar *host=NULL;
+ 	gint port;
+  
+ 	if (cdda_cfg.use_cddb_proxy 
+ 	    && cdda_cfg.cddb_proxy!=NULL 
+ 	    && strlen(cdda_cfg.cddb_proxy)){
+ 		host=cdda_cfg.cddb_proxy;
+ 		port=cdda_cfg.cddb_proxy_port;
+ 	}
+ 	else {
+ 		host=server;
+ 		port=80;
+ 	}
+ 	if(host==NULL){
+  		return 0;
+ 	}
+ 
+ 	if((sock = cddb_http_open_connection(host, port)) == 0)
+ 		return 0;
+ 
+ 	if (cdda_cfg.use_cddb_proxy){
+ 		str = g_strdup_printf(
+ 			"GET http://%s/~cddb/cddb.cgi?cmd=stat%s&proto=1 HTTP/1.0\r\n\r\n",
+ 			server, cddb_generate_hello_string());
+ 	}
+ 	else{
+ 		str = g_strdup_printf(
+ 			"GET /~cddb/cddb.cgi?cmd=stat%s&proto=1 HTTP/1.0\r\n\r\n",
+ 			cddb_generate_hello_string());
+ 	}
 		
 	write(sock, str, strlen(str));
 	g_free(str);
@@ -280,17 +332,42 @@
 	gchar *realstr, *temp;
 	gint len, command, bufs;
 	gint num, oldnum;
+	gchar *host=NULL;
+	gint port;
+
+	if (cdda_cfg.use_cddb_proxy 
+	    && cdda_cfg.cddb_proxy!=NULL 
+	    && strlen(cdda_cfg.cddb_proxy)){
+		host=cdda_cfg.cddb_proxy;
+		port=cdda_cfg.cddb_proxy_port;
+	}
+	else {
+		host=server;
+		port=80;
+	}
+	if(host==NULL){
+		return FALSE;
+	}
 	
-	if((sock = cddb_http_open_connection(server, 80)) == 0)
+	if((sock = cddb_http_open_connection(host, port)) == 0)
 		return FALSE;
 
 	cddb_log("Sending read-command. Disc ID: %08x. Category: %s",
 		 cddb_info->discid, cddb_info->category);
 
-	readstr = g_strdup_printf(
-		"GET /~cddb/cddb.cgi?cmd=cddb+read+%s+%08x%s&proto=%d HTTP/1.0\r\n\r\n",
-		cddb_info->category, cddb_info->discid, cddb_generate_hello_string(),
-		cdda_cfg.cddb_protocol_level);
+	if (cdda_cfg.use_cddb_proxy){
+		readstr = g_strdup_printf(
+			"GET http://%s/~cddb/cddb.cgi?cmd=cddb+read+%s+%08x%s&proto=%d HTTP/1.0\r\n\r\n",
+			server,
+			cddb_info->category, cddb_info->discid, cddb_generate_hello_string(),
+			cdda_cfg.cddb_protocol_level);
+	}
+	else{
+		readstr = g_strdup_printf(
+			"GET /~cddb/cddb.cgi?cmd=cddb+read+%s+%08x%s&proto=%d HTTP/1.0\r\n\r\n",
+			cddb_info->category, cddb_info->discid, cddb_generate_hello_string(),
+			cdda_cfg.cddb_protocol_level);
+	}
 
 	write(sock, readstr, strlen(readstr));
 	g_free(readstr);
@@ -411,15 +488,39 @@
 	gchar buffer[256];
 	gchar **message;
 	GList *list = NULL;
+	gchar *host=NULL;
+	gint port;
+
+	if (cdda_cfg.use_cddb_proxy 
+	    && cdda_cfg.cddb_proxy!=NULL 
+	    && strlen(cdda_cfg.cddb_proxy)){
+		host=cdda_cfg.cddb_proxy;
+		port=cdda_cfg.cddb_proxy_port;
+	}
+	else {
+		host=server;
+		port=80;
+	}
+	if(host==NULL){
+		return NULL;
+	}
 	
-	if((sock = cddb_http_open_connection(server, 80)) == 0)
+	if((sock = cddb_http_open_connection(host, port)) == 0)
 		return NULL;
 
 	cddb_log("Sending sites-command");
 
-	getstr = g_strdup_printf(
-		"GET /~cddb/cddb.cgi?cmd=sites%s&proto=%d HTTP/1.0\r\n\r\n",
-		cddb_generate_hello_string(), protocol_level);
+	if (cdda_cfg.use_cddb_proxy){
+		getstr = g_strdup_printf(
+			"GET http://%s/~cddb/cddb.cgi?cmd=sites%s&proto=%d HTTP/1.0\r\n\r\n",
+			server,
+			cddb_generate_hello_string(), protocol_level);
+	}
+	else{
+		getstr = g_strdup_printf(
+			"GET /~cddb/cddb.cgi?cmd=sites%s&proto=%d HTTP/1.0\r\n\r\n",
+			cddb_generate_hello_string(), protocol_level);
+	}
 
 	write(sock, getstr, strlen(getstr));
 	g_free(getstr);
@@ -674,6 +775,25 @@
 	}
 }
 
+void cdda_cddb_set_proxy(gchar *new_proxy)
+{
+	if (strcmp(cdda_cfg.cddb_proxy, new_proxy))
+	{
+		g_free(cdda_cfg.cddb_proxy);
+		cdda_cfg.cddb_proxy = g_strdup(new_proxy);
+	}
+}
+
+void cdda_cddb_set_proxy_port(gchar *new_proxy_port)
+{
+	gint temp;
+
+	temp = atoi(new_proxy_port); /* WARNING: no error handling here, using strtol() */
+	if (temp != cdda_cfg.cddb_proxy_port)
+	{
+		cdda_cfg.cddb_proxy_port = temp;
+	}
+}
 
 static gchar* cddb_position_string(gchar * input)
 {
--- Input/cdaudio/configure.c
+++ Input/cdaudio/configure.c
@@ -44,11 +44,14 @@
 static GtkWidget *cdda_configure_win;
 static GtkWidget *cdi_name, *cdi_name_override;
 static GtkWidget *cdi_use_cddb, *cdi_cddb_server /*, *cdi_use_cdin, *cdi_cdin_server */;
-
+static GtkWidget *cdi_use_cddb_proxy, *cdi_cddb_proxy, *cdi_cddb_proxy_port;
+ 
 void cdda_cddb_show_server_dialog(GtkWidget *w, gpointer data);
 void cdda_cddb_show_network_window(GtkWidget *w, gpointer data);
 void cdda_cddb_set_server(char *new_server);
-
+void cdda_cddb_set_proxy(gchar *new_proxy);
+void cdda_cddb_set_proxy_port(gchar *new_proxy_port);
+ 
 static GtkWidget* configurewin_add_drive(struct driveinfo *drive, void *nb);
 
 static void cdda_configurewin_ok_cb(GtkWidget * w, gpointer data)
@@ -106,6 +109,9 @@
 
 	cdda_cfg.use_cddb = GET_TB(cdi_use_cddb);
 	cdda_cddb_set_server(gtk_entry_get_text(GTK_ENTRY(cdi_cddb_server)));
+	cdda_cfg.use_cddb_proxy = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cdi_use_cddb_proxy));
+	cdda_cddb_set_proxy(gtk_entry_get_text(GTK_ENTRY(cdi_cddb_proxy)));
+	cdda_cddb_set_proxy_port(gtk_entry_get_text(GTK_ENTRY(cdi_cddb_proxy_port)));
 
 #if 0
 	cdda_cfg.use_cdin = GET_TB(cdi_use_cdin);
@@ -156,6 +162,9 @@
 	xmms_cfg_write_boolean(cfgfile, "CDDA", "use_cddb", cdda_cfg.use_cddb);
 	xmms_cfg_write_string(cfgfile, "CDDA", "cddb_server", cdda_cfg.cddb_server);
 	xmms_cfg_write_int(cfgfile, "CDDA", "cddb_protocol_level", cdda_cfg.cddb_protocol_level);
+	xmms_cfg_write_boolean(cfgfile, "CDDA", "use_cddb_proxy", cdda_cfg.use_cddb_proxy);
+	xmms_cfg_write_string(cfgfile, "CDDA", "cddb_proxy", cdda_cfg.cddb_proxy);
+	xmms_cfg_write_int(cfgfile, "CDDA", "cddb_proxy_port", cdda_cfg.cddb_proxy_port);
 	xmms_cfg_write_boolean(cfgfile, "CDDA", "use_cdin", cdda_cfg.use_cdin);
 	xmms_cfg_write_string(cfgfile, "CDDA", "cdin_server", cdda_cfg.cdin_server);
 	xmms_cfg_write_default_file(cfgfile);
@@ -488,6 +497,7 @@
 	GtkWidget *cdi_vbox;
 	GtkWidget *cdi_cddb_frame, *cdi_cddb_vbox, *cdi_cddb_hbox;
 	GtkWidget *cdi_cddb_server_hbox, *cdi_cddb_server_label;
+	GtkWidget *cdi_cddb_proxy_hbox, *cdi_cddb_proxy_host_label, *cdi_cddb_proxy_port_label;
 	GtkWidget *cdi_cddb_server_list, *cdi_cddb_debug_win;
 #if 0
 	GtkWidget *cdi_cdin_frame, *cdi_cdin_vbox;
@@ -501,6 +511,8 @@
 	GList *node;
 	int i = 1;
 
+	gchar *temp;
+
 	if (cdda_configure_win)
 		return;
 	
@@ -600,6 +612,36 @@
 	gtk_signal_connect(GTK_OBJECT(cdi_cddb_server_list), "clicked",
 			   GTK_SIGNAL_FUNC(cdda_cddb_show_server_dialog),
 			   cdi_cddb_server);
+ 
+ 	cdi_cddb_proxy_hbox = gtk_hbox_new(FALSE, 10);
+ 	gtk_box_pack_start(GTK_BOX(cdi_cddb_vbox), cdi_cddb_proxy_hbox, FALSE, FALSE, 0);
+ 	cdi_use_cddb_proxy = gtk_check_button_new_with_label(_("Use proxy"));
+ 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cdi_use_cddb_proxy), cdda_cfg.use_cddb_proxy);
+ 	gtk_box_pack_start(GTK_BOX(cdi_cddb_proxy_hbox), cdi_use_cddb_proxy, FALSE, FALSE, 0);
+ 	gtk_widget_show(cdi_use_cddb_proxy);
+
+ 	cdi_cddb_proxy_host_label = gtk_label_new(_("Host:"));
+ 	gtk_widget_show(cdi_cddb_proxy_host_label);
+ 	gtk_box_pack_start(GTK_BOX(cdi_cddb_proxy_hbox), cdi_cddb_proxy_host_label, TRUE, TRUE, 0);
+
+ 
+ 	cdi_cddb_proxy = gtk_entry_new();
+ 	gtk_entry_set_text(GTK_ENTRY(cdi_cddb_proxy), cdda_cfg.cddb_proxy);
+ 	gtk_widget_show(cdi_cddb_proxy);
+ 	gtk_box_pack_start(GTK_BOX(cdi_cddb_proxy_hbox), cdi_cddb_proxy, TRUE, TRUE, 0);
+ 
+ 	cdi_cddb_proxy_port_label = gtk_label_new(_("Port:"));
+ 	gtk_widget_show(cdi_cddb_proxy_port_label);
+ 	gtk_box_pack_start(GTK_BOX(cdi_cddb_proxy_hbox), cdi_cddb_proxy_port_label, TRUE, TRUE, 0);
+ 
+ 	cdi_cddb_proxy_port = gtk_entry_new();
+ 	temp = g_strdup_printf("%d", cdda_cfg.cddb_proxy_port);
+ 	gtk_entry_set_text(GTK_ENTRY(cdi_cddb_proxy_port), temp);
+ 	g_free(temp);
+ 	gtk_widget_show(cdi_cddb_proxy_port);
+ 	gtk_box_pack_start(GTK_BOX(cdi_cddb_proxy_hbox), cdi_cddb_proxy_port, TRUE, TRUE, 0);
+ 
+ 	gtk_widget_show(cdi_cddb_proxy_hbox);
 
 #if 0
 	/*
