blob: ae53a7a697d77c13eb5c3aa4dfca4bacc4817535 [file] [log] [blame]
/*
*
* libproxy - A library for proxy configuration
*
* Copyright (C) 2010-2011 Intel Corporation. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms and conditions of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus.h>
#include "proxy.h"
struct _pxProxyFactory {
DBusConnection *conn;
};
pxProxyFactory *px_proxy_factory_new(void)
{
pxProxyFactory *factory;
factory = malloc(sizeof(*factory));
if (factory == NULL)
return NULL;
memset(factory, 0, sizeof(*factory));
factory->conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
if (factory->conn == NULL) {
free(factory);
return NULL;
}
dbus_connection_set_exit_on_disconnect(factory->conn, FALSE);
return factory;
}
void px_proxy_factory_free(pxProxyFactory *factory)
{
if (factory == NULL)
return;
dbus_connection_close(factory->conn);
free(factory);
}
static char **extract_result(const char *str)
{
char **result;
result = malloc(sizeof(char *) * 2);
if (result == NULL)
return NULL;
result[0] = NULL;
result[1] = NULL;
if (strcasecmp(str, "DIRECT") == 0) {
result[0] = strdup("direct://");
return result;
}
if (strncasecmp(str, "PROXY ", 6) == 0) {
int len = strlen(str + 6) + 8;
result[0] = malloc(len);
if (result[0] != NULL)
sprintf(result[0], "http://%s", str + 6);
return result;
}
if (strncasecmp(str, "SOCKS ", 6) == 0) {
int len = strlen(str + 6) + 9;
result[0] = malloc(len);
if (result[0] != NULL)
sprintf(result[0], "socks://%s", str + 6);
return result;
}
if (strncasecmp(str, "SOCKS4 ", 7) == 0) {
int len = strlen(str + 7) + 10;
result[0] = malloc(len);
if (result[0] != NULL)
sprintf(result[0], "socks4://%s", str + 7);
return result;
}
if (strncasecmp(str, "SOCKS5 ", 7) == 0) {
int len = strlen(str + 7) + 10;
result[0] = malloc(len);
if (result[0] != NULL)
sprintf(result[0], "socks5://%s", str + 7);
return result;
}
return result;
}
char **px_proxy_factory_get_proxies(pxProxyFactory *factory, const char *url)
{
DBusMessage *msg, *reply;
const char *str = NULL;
char *scheme, *host, *port, *path, **result;
if (factory == NULL)
return NULL;
if (url == NULL)
return NULL;
msg = dbus_message_new_method_call("org.pacrunner",
"/org/pacrunner/client", "org.pacrunner.Client",
"FindProxyForURL");
if (msg == NULL)
goto direct;
scheme = strdup(url);
if (scheme == NULL) {
dbus_message_unref(msg);
goto direct;
}
host = strstr(scheme, "://");
if (host != NULL) {
*host = '\0';
host += 3;
} else {
dbus_message_unref(msg);
goto direct;
}
path = strchr(host, '/');
if (path != NULL)
*(path++) = '\0';
port = strrchr(host, ':');
if (port != NULL) {
char *end;
int tmp __attribute__ ((unused));
tmp = strtol(port + 1, &end, 10);
if (*end == '\0')
*port = '\0';
}
dbus_message_append_args(msg, DBUS_TYPE_STRING, &url,
DBUS_TYPE_STRING, &host, DBUS_TYPE_INVALID);
free(scheme);
reply = dbus_connection_send_with_reply_and_block(factory->conn,
msg, -1, NULL);
dbus_message_unref(msg);
if (reply == NULL)
goto direct;
dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &str,
DBUS_TYPE_INVALID);
if (str == NULL || strlen(str) == 0)
str = "DIRECT";
result = extract_result(str);
dbus_message_unref(reply);
return result;
direct:
result = malloc(sizeof(char *) * 2);
if (result == NULL)
return NULL;
result[0] = strdup("direct://");
result[1] = NULL;
return result;
}