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 PyString_FromString(s
);
27 CFIndex len
= CFStringGetLength(ref
);
30 result
= PyString_FromStringAndSize(NULL
, len
*4);
32 ok
= CFStringGetCString(ref
,
33 PyString_AS_STRING(result
),
34 PyString_GET_SIZE(result
),
35 kCFStringEncodingUTF8
);
40 _PyString_Resize(&result
,
41 strlen(PyString_AS_STRING(result
)));
49 get_proxy_settings(PyObject
* mod
__attribute__((__unused__
)))
51 CFDictionaryRef proxyDict
= NULL
;
52 CFNumberRef aNum
= NULL
;
53 CFArrayRef anArray
= NULL
;
54 PyObject
* result
= NULL
;
58 proxyDict
= SCDynamicStoreCopyProxies(NULL
);
64 result
= PyDict_New();
65 if (result
== NULL
) goto error
;
67 if (&kSCPropNetProxiesExcludeSimpleHostnames
!= NULL
) {
68 aNum
= CFDictionaryGetValue(proxyDict
,
69 kSCPropNetProxiesExcludeSimpleHostnames
);
71 v
= PyBool_FromLong(0);
73 v
= PyBool_FromLong(cfnum_to_int32(aNum
));
76 v
= PyBool_FromLong(1);
79 if (v
== NULL
) goto error
;
81 r
= PyDict_SetItemString(result
, "exclude_simple", v
);
82 Py_DECREF(v
); v
= NULL
;
83 if (r
== -1) goto error
;
85 anArray
= CFDictionaryGetValue(proxyDict
,
86 kSCPropNetProxiesExceptionsList
);
87 if (anArray
!= NULL
) {
88 CFIndex len
= CFArrayGetCount(anArray
);
91 if (v
== NULL
) goto error
;
93 r
= PyDict_SetItemString(result
, "exceptions", v
);
95 if (r
== -1) goto error
;
97 for (i
= 0; i
< len
; i
++) {
98 CFStringRef aString
= NULL
;
100 aString
= CFArrayGetValueAtIndex(anArray
, i
);
101 if (aString
== NULL
) {
102 PyTuple_SetItem(v
, i
, Py_None
);
105 PyObject
* t
= cfstring_to_pystring(aString
);
107 PyTuple_SetItem(v
, i
, Py_None
);
110 PyTuple_SetItem(v
, i
, t
);
116 CFRelease(proxyDict
);
120 if (proxyDict
) CFRelease(proxyDict
);
126 set_proxy(PyObject
* proxies
, char* proto
, CFDictionaryRef proxyDict
,
127 CFStringRef enabledKey
,
128 CFStringRef hostKey
, CFStringRef portKey
)
132 aNum
= CFDictionaryGetValue(proxyDict
, enabledKey
);
133 if (aNum
&& cfnum_to_int32(aNum
)) {
134 CFStringRef hostString
;
136 hostString
= CFDictionaryGetValue(proxyDict
, hostKey
);
137 aNum
= CFDictionaryGetValue(proxyDict
, portKey
);
141 PyObject
* h
= cfstring_to_pystring(hostString
);
145 int32_t port
= cfnum_to_int32(aNum
);
146 v
= PyString_FromFormat("http://%s:%ld",
147 PyString_AS_STRING(h
),
150 v
= PyString_FromFormat("http://%s",
151 PyString_AS_STRING(h
));
155 r
= PyDict_SetItemString(proxies
, proto
,
169 get_proxies(PyObject
* mod
__attribute__((__unused__
)))
171 PyObject
* result
= NULL
;
173 CFDictionaryRef proxyDict
= NULL
;
175 proxyDict
= SCDynamicStoreCopyProxies(NULL
);
176 if (proxyDict
== NULL
) {
180 result
= PyDict_New();
181 if (result
== NULL
) goto error
;
183 r
= set_proxy(result
, "http", proxyDict
,
184 kSCPropNetProxiesHTTPEnable
,
185 kSCPropNetProxiesHTTPProxy
,
186 kSCPropNetProxiesHTTPPort
);
187 if (r
== -1) goto error
;
188 r
= set_proxy(result
, "https", proxyDict
,
189 kSCPropNetProxiesHTTPSEnable
,
190 kSCPropNetProxiesHTTPSProxy
,
191 kSCPropNetProxiesHTTPSPort
);
192 if (r
== -1) goto error
;
193 r
= set_proxy(result
, "ftp", proxyDict
,
194 kSCPropNetProxiesFTPEnable
,
195 kSCPropNetProxiesFTPProxy
,
196 kSCPropNetProxiesFTPPort
);
197 if (r
== -1) goto error
;
198 r
= set_proxy(result
, "gopher", proxyDict
,
199 kSCPropNetProxiesGopherEnable
,
200 kSCPropNetProxiesGopherProxy
,
201 kSCPropNetProxiesGopherPort
);
202 if (r
== -1) goto error
;
204 CFRelease(proxyDict
);
207 if (proxyDict
) CFRelease(proxyDict
);
212 static PyMethodDef mod_methods
[] = {
214 "_get_proxy_settings",
215 (PyCFunction
)get_proxy_settings
,
221 (PyCFunction
)get_proxies
,
228 void init_scproxy(void)
230 (void)Py_InitModule4("_scproxy", mod_methods
, NULL
, NULL
, PYTHON_API_VERSION
);