|
|
/*
* Helper method for urllib to fetch the proxy configuration settings * using the SystemConfiguration framework. */#include <Python.h>
#include <SystemConfiguration/SystemConfiguration.h>
static int32_tcfnum_to_int32(CFNumberRef num){ int32_t result;
CFNumberGetValue(num, kCFNumberSInt32Type, &result); return result;}
static PyObject*cfstring_to_pystring(CFStringRef ref){ const char* s;
s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8); if (s) { return PyUnicode_DecodeUTF8( s, strlen(s), NULL);
} else { CFIndex len = CFStringGetLength(ref); Boolean ok; PyObject* result; char* buf;
buf = PyMem_Malloc(len*4); if (buf == NULL) { PyErr_NoMemory(); return NULL; }
ok = CFStringGetCString(ref, buf, len * 4, kCFStringEncodingUTF8); if (!ok) { PyMem_Free(buf); return NULL; } else { result = PyUnicode_DecodeUTF8( buf, strlen(buf), NULL); PyMem_Free(buf); } return result; }}
static PyObject*get_proxy_settings(PyObject* mod __attribute__((__unused__))){ CFDictionaryRef proxyDict = NULL; CFNumberRef aNum = NULL; CFArrayRef anArray = NULL; PyObject* result = NULL; PyObject* v; int r;
proxyDict = SCDynamicStoreCopyProxies(NULL); if (!proxyDict) { Py_INCREF(Py_None); return Py_None; }
result = PyDict_New(); if (result == NULL) goto error;
if (&kSCPropNetProxiesExcludeSimpleHostnames != NULL) { aNum = CFDictionaryGetValue(proxyDict, kSCPropNetProxiesExcludeSimpleHostnames); if (aNum == NULL) { v = PyBool_FromLong(0); } else { v = PyBool_FromLong(cfnum_to_int32(aNum)); } } else { v = PyBool_FromLong(0); }
if (v == NULL) goto error;
r = PyDict_SetItemString(result, "exclude_simple", v); Py_DECREF(v); v = NULL; if (r == -1) goto error;
anArray = CFDictionaryGetValue(proxyDict, kSCPropNetProxiesExceptionsList); if (anArray != NULL) { CFIndex len = CFArrayGetCount(anArray); CFIndex i; v = PyTuple_New(len); if (v == NULL) goto error;
r = PyDict_SetItemString(result, "exceptions", v); Py_DECREF(v); if (r == -1) goto error;
for (i = 0; i < len; i++) { CFStringRef aString = NULL;
aString = CFArrayGetValueAtIndex(anArray, i); if (aString == NULL) { PyTuple_SetItem(v, i, Py_None); Py_INCREF(Py_None); } else { PyObject* t = cfstring_to_pystring(aString); if (!t) { PyTuple_SetItem(v, i, Py_None); Py_INCREF(Py_None); } else { PyTuple_SetItem(v, i, t); } } } }
CFRelease(proxyDict); return result;
error: if (proxyDict) CFRelease(proxyDict); Py_XDECREF(result); return NULL;}
static intset_proxy(PyObject* proxies, char* proto, CFDictionaryRef proxyDict, CFStringRef enabledKey, CFStringRef hostKey, CFStringRef portKey){ CFNumberRef aNum;
aNum = CFDictionaryGetValue(proxyDict, enabledKey); if (aNum && cfnum_to_int32(aNum)) { CFStringRef hostString;
hostString = CFDictionaryGetValue(proxyDict, hostKey); aNum = CFDictionaryGetValue(proxyDict, portKey);
if (hostString) { int r; PyObject* h = cfstring_to_pystring(hostString); PyObject* v; if (h) { if (aNum) { int32_t port = cfnum_to_int32(aNum); v = PyUnicode_FromFormat("http://%U:%ld", h, (long)port); } else { v = PyUnicode_FromFormat("http://%U", h); } Py_DECREF(h); if (!v) return -1; r = PyDict_SetItemString(proxies, proto, v); Py_DECREF(v); return r; } }
} return 0;}
static PyObject*get_proxies(PyObject* mod __attribute__((__unused__))){ PyObject* result = NULL; int r; CFDictionaryRef proxyDict = NULL;
proxyDict = SCDynamicStoreCopyProxies(NULL); if (proxyDict == NULL) { return PyDict_New(); }
result = PyDict_New(); if (result == NULL) goto error;
r = set_proxy(result, "http", proxyDict, kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); if (r == -1) goto error; r = set_proxy(result, "https", proxyDict, kSCPropNetProxiesHTTPSEnable, kSCPropNetProxiesHTTPSProxy, kSCPropNetProxiesHTTPSPort); if (r == -1) goto error; r = set_proxy(result, "ftp", proxyDict, kSCPropNetProxiesFTPEnable, kSCPropNetProxiesFTPProxy, kSCPropNetProxiesFTPPort); if (r == -1) goto error; r = set_proxy(result, "gopher", proxyDict, kSCPropNetProxiesGopherEnable, kSCPropNetProxiesGopherProxy, kSCPropNetProxiesGopherPort); if (r == -1) goto error;
CFRelease(proxyDict); return result;error: if (proxyDict) CFRelease(proxyDict); Py_XDECREF(result); return NULL;}
static PyMethodDef mod_methods[] = { { "_get_proxy_settings", (PyCFunction)get_proxy_settings, METH_NOARGS, NULL, }, { "_get_proxies", (PyCFunction)get_proxies, METH_NOARGS, NULL, }, { 0, 0, 0, 0 }};
static struct PyModuleDef mod_module = { PyModuleDef_HEAD_INIT, "_scproxy", NULL, -1, mod_methods, NULL, NULL, NULL, NULL};
#ifdef __cplusplus
extern "C" {#endif
PyObject*PyInit__scproxy(void){ return PyModule_Create(&mod_module);}
#ifdef __cplusplus
}#endif
|