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 aNum
= CFDictionaryGetValue(proxyDict
,
68 kSCPropNetProxiesExcludeSimpleHostnames
);
70 v
= PyBool_FromLong(0);
72 v
= PyBool_FromLong(cfnum_to_int32(aNum
));
74 if (v
== NULL
) goto error
;
76 r
= PyDict_SetItemString(result
, "exclude_simple", v
);
77 Py_DECREF(v
); v
= NULL
;
78 if (r
== -1) goto error
;
80 anArray
= CFDictionaryGetValue(proxyDict
,
81 kSCPropNetProxiesExceptionsList
);
82 if (anArray
!= NULL
) {
83 CFIndex len
= CFArrayGetCount(anArray
);
86 if (v
== NULL
) goto error
;
88 r
= PyDict_SetItemString(result
, "exceptions", v
);
90 if (r
== -1) goto error
;
92 for (i
= 0; i
< len
; i
++) {
93 CFStringRef aString
= NULL
;
95 aString
= CFArrayGetValueAtIndex(anArray
, i
);
96 if (aString
== NULL
) {
97 PyTuple_SetItem(v
, i
, Py_None
);
100 PyObject
* t
= cfstring_to_pystring(aString
);
102 PyTuple_SetItem(v
, i
, Py_None
);
105 PyTuple_SetItem(v
, i
, t
);
111 CFRelease(proxyDict
);
115 if (proxyDict
) CFRelease(proxyDict
);
121 set_proxy(PyObject
* proxies
, char* proto
, CFDictionaryRef proxyDict
,
122 CFStringRef enabledKey
,
123 CFStringRef hostKey
, CFStringRef portKey
)
127 aNum
= CFDictionaryGetValue(proxyDict
, enabledKey
);
128 if (aNum
&& cfnum_to_int32(aNum
)) {
129 CFStringRef hostString
;
131 hostString
= CFDictionaryGetValue(proxyDict
, hostKey
);
132 aNum
= CFDictionaryGetValue(proxyDict
, portKey
);
136 PyObject
* h
= cfstring_to_pystring(hostString
);
140 int32_t port
= cfnum_to_int32(aNum
);
141 v
= PyString_FromFormat("http://%s:%ld",
142 PyString_AS_STRING(h
),
145 v
= PyString_FromFormat("http://%s",
146 PyString_AS_STRING(h
));
150 r
= PyDict_SetItemString(proxies
, proto
,
164 get_proxies(PyObject
* mod
__attribute__((__unused__
)))
166 PyObject
* result
= NULL
;
168 CFDictionaryRef proxyDict
= NULL
;
170 proxyDict
= SCDynamicStoreCopyProxies(NULL
);
171 if (proxyDict
== NULL
) {
175 result
= PyDict_New();
176 if (result
== NULL
) goto error
;
178 r
= set_proxy(result
, "http", proxyDict
,
179 kSCPropNetProxiesHTTPEnable
,
180 kSCPropNetProxiesHTTPProxy
,
181 kSCPropNetProxiesHTTPPort
);
182 if (r
== -1) goto error
;
183 r
= set_proxy(result
, "https", proxyDict
,
184 kSCPropNetProxiesHTTPSEnable
,
185 kSCPropNetProxiesHTTPSProxy
,
186 kSCPropNetProxiesHTTPSPort
);
187 if (r
== -1) goto error
;
188 r
= set_proxy(result
, "ftp", proxyDict
,
189 kSCPropNetProxiesFTPEnable
,
190 kSCPropNetProxiesFTPProxy
,
191 kSCPropNetProxiesFTPPort
);
192 if (r
== -1) goto error
;
193 r
= set_proxy(result
, "gopher", proxyDict
,
194 kSCPropNetProxiesGopherEnable
,
195 kSCPropNetProxiesGopherProxy
,
196 kSCPropNetProxiesGopherPort
);
197 if (r
== -1) goto error
;
199 CFRelease(proxyDict
);
202 if (proxyDict
) CFRelease(proxyDict
);
207 static PyMethodDef mod_methods
[] = {
209 "_get_proxy_settings",
210 (PyCFunction
)get_proxy_settings
,
216 (PyCFunction
)get_proxies
,
223 void init_scproxy(void)
225 (void)Py_InitModule4("_scproxy", mod_methods
, NULL
, NULL
, PYTHON_API_VERSION
);