mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
	
	
		
			262 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			262 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Helper method for urllib to fetch the proxy configuration settings
							 | 
						||
| 
								 | 
							
								 * using the SystemConfiguration framework.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#include <Python.h>
							 | 
						||
| 
								 | 
							
								#include <SystemConfiguration/SystemConfiguration.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int32_t 
							 | 
						||
| 
								 | 
							
								cfnum_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(1);
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											v = PyBool_FromLong(cfnum_to_int32(aNum));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}  else {
							 | 
						||
| 
								 | 
							
										v = PyBool_FromLong(1);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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 int
							 | 
						||
| 
								 | 
							
								set_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
							 | 
						||
| 
								 | 
							
								
							 |