2 * Helper method for urllib to fetch the proxy configuration settings
3 * using the SystemConfiguration framework.
6 #include <SystemConfiguration/SystemConfiguration.h>
9 cfnum_to_int32(CFNumberRef num
)
13 CFNumberGetValue(num
, kCFNumberSInt32Type
, &result
);
18 cfstring_to_pystring(CFStringRef ref
)
22 s
= CFStringGetCStringPtr(ref
, kCFStringEncodingUTF8
);
24 return PyUnicode_DecodeUTF8(
28 CFIndex len
= CFStringGetLength(ref
);
33 buf
= PyMem_Malloc(len
*4);
39 ok
= CFStringGetCString(ref
,
41 kCFStringEncodingUTF8
);
46 result
= PyUnicode_DecodeUTF8(
47 buf
, strlen(buf
), NULL
);
56 get_proxy_settings(PyObject
* mod
__attribute__((__unused__
)))
58 CFDictionaryRef proxyDict
= NULL
;
59 CFNumberRef aNum
= NULL
;
60 CFArrayRef anArray
= NULL
;
61 PyObject
* result
= NULL
;
65 proxyDict
= SCDynamicStoreCopyProxies(NULL
);
71 result
= PyDict_New();
72 if (result
== NULL
) goto error
;
74 if (&kSCPropNetProxiesExcludeSimpleHostnames
!= NULL
) {
75 aNum
= CFDictionaryGetValue(proxyDict
,
76 kSCPropNetProxiesExcludeSimpleHostnames
);
78 v
= PyBool_FromLong(1);
80 v
= PyBool_FromLong(cfnum_to_int32(aNum
));
83 v
= PyBool_FromLong(1);
86 if (v
== NULL
) goto error
;
88 r
= PyDict_SetItemString(result
, "exclude_simple", v
);
89 Py_DECREF(v
); v
= NULL
;
90 if (r
== -1) goto error
;
92 anArray
= CFDictionaryGetValue(proxyDict
,
93 kSCPropNetProxiesExceptionsList
);
94 if (anArray
!= NULL
) {
95 CFIndex len
= CFArrayGetCount(anArray
);
98 if (v
== NULL
) goto error
;
100 r
= PyDict_SetItemString(result
, "exceptions", v
);
102 if (r
== -1) goto error
;
104 for (i
= 0; i
< len
; i
++) {
105 CFStringRef aString
= NULL
;
107 aString
= CFArrayGetValueAtIndex(anArray
, i
);
108 if (aString
== NULL
) {
109 PyTuple_SetItem(v
, i
, Py_None
);
112 PyObject
* t
= cfstring_to_pystring(aString
);
114 PyTuple_SetItem(v
, i
, Py_None
);
117 PyTuple_SetItem(v
, i
, t
);
123 CFRelease(proxyDict
);
127 if (proxyDict
) CFRelease(proxyDict
);
133 set_proxy(PyObject
* proxies
, char* proto
, CFDictionaryRef proxyDict
,
134 CFStringRef enabledKey
,
135 CFStringRef hostKey
, CFStringRef portKey
)
139 aNum
= CFDictionaryGetValue(proxyDict
, enabledKey
);
140 if (aNum
&& cfnum_to_int32(aNum
)) {
141 CFStringRef hostString
;
143 hostString
= CFDictionaryGetValue(proxyDict
, hostKey
);
144 aNum
= CFDictionaryGetValue(proxyDict
, portKey
);
148 PyObject
* h
= cfstring_to_pystring(hostString
);
152 int32_t port
= cfnum_to_int32(aNum
);
153 v
= PyUnicode_FromFormat("http://%U:%ld",
156 v
= PyUnicode_FromFormat("http://%U", h
);
160 r
= PyDict_SetItemString(proxies
, proto
,
174 get_proxies(PyObject
* mod
__attribute__((__unused__
)))
176 PyObject
* result
= NULL
;
178 CFDictionaryRef proxyDict
= NULL
;
180 proxyDict
= SCDynamicStoreCopyProxies(NULL
);
181 if (proxyDict
== NULL
) {
185 result
= PyDict_New();
186 if (result
== NULL
) goto error
;
188 r
= set_proxy(result
, "http", proxyDict
,
189 kSCPropNetProxiesHTTPEnable
,
190 kSCPropNetProxiesHTTPProxy
,
191 kSCPropNetProxiesHTTPPort
);
192 if (r
== -1) goto error
;
193 r
= set_proxy(result
, "https", proxyDict
,
194 kSCPropNetProxiesHTTPSEnable
,
195 kSCPropNetProxiesHTTPSProxy
,
196 kSCPropNetProxiesHTTPSPort
);
197 if (r
== -1) goto error
;
198 r
= set_proxy(result
, "ftp", proxyDict
,
199 kSCPropNetProxiesFTPEnable
,
200 kSCPropNetProxiesFTPProxy
,
201 kSCPropNetProxiesFTPPort
);
202 if (r
== -1) goto error
;
203 r
= set_proxy(result
, "gopher", proxyDict
,
204 kSCPropNetProxiesGopherEnable
,
205 kSCPropNetProxiesGopherProxy
,
206 kSCPropNetProxiesGopherPort
);
207 if (r
== -1) goto error
;
209 CFRelease(proxyDict
);
212 if (proxyDict
) CFRelease(proxyDict
);
217 static PyMethodDef mod_methods
[] = {
219 "_get_proxy_settings",
220 (PyCFunction
)get_proxy_settings
,
226 (PyCFunction
)get_proxies
,
235 static struct PyModuleDef mod_module
= {
236 PyModuleDef_HEAD_INIT
,
253 PyInit__scproxy(void)
255 return PyModule_Create(&mod_module
);