Merge pull request #2636 from youknowone/scproxy

module _scproxy
This commit is contained in:
Jeong YunWon
2021-05-13 03:38:50 +09:00
committed by GitHub
5 changed files with 195 additions and 2 deletions

View File

@@ -96,8 +96,7 @@ jobs:
- if: runner.os == 'macOS'
name: run cpython tests (macOS lightweight)
run:
target/release/rustpython -m test -v -x
test_http_cookiejar test_robotparser
target/release/rustpython -m test -v
- if: runner.os == 'Windows'
name: run cpython tests (windows partial - fixme)
run:

38
Cargo.lock generated
View File

@@ -313,6 +313,22 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "core-foundation"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
[[package]]
name = "cpuid-bool"
version = "0.1.2"
@@ -2058,6 +2074,7 @@ dependencies = [
"socket2",
"sre-engine",
"static_assertions",
"system-configuration",
"termios",
"thiserror",
"thread_local",
@@ -2361,6 +2378,27 @@ dependencies = [
"syn",
]
[[package]]
name = "system-configuration"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd4bc0637a2b8c0b1a5145cca3e21b707865edc7e32285771536af1ade129468"
dependencies = [
"bitflags",
"core-foundation",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "269e271436d8e4bb2621c535a11fe03d5d012f74b19af72f80288f3a72f6180a"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "target-lexicon"
version = "0.11.2"

View File

@@ -135,6 +135,9 @@ dns-lookup = "1.0"
[target.'cfg(all(unix, not(target_os = "redox")))'.dependencies]
termios = "0.3"
[target.'cfg(target_os = "macos")'.dependencies]
system-configuration = "0.4"
[target.'cfg(windows)'.dependencies]
winreg = "0.8.0"
schannel = "0.1"

View File

@@ -62,6 +62,8 @@ mod pwd;
// libc is missing constants on redox
#[cfg(all(unix, not(target_os = "redox")))]
mod resource;
#[cfg(target_os = "macos")]
mod scproxy;
#[cfg(not(target_arch = "wasm32"))]
mod select;
#[cfg(not(target_arch = "wasm32"))]
@@ -186,5 +188,9 @@ pub fn get_module_inits() -> StdlibMap {
"_winapi" => winapi::make_module,
"winreg" => winreg::make_module,
}
#[cfg(target_os = "macos")]
{
"_scproxy" => scproxy::make_module,
}
}
}

147
vm/src/stdlib/scproxy.rs Normal file
View File

@@ -0,0 +1,147 @@
pub(crate) use _scproxy::make_module;
#[pymodule]
mod _scproxy {
// straight-forward port of Modules/_scproxy.c
use crate::builtins::{PyDictRef, PyStr};
use crate::pyobject::{IntoPyObject, ItemProtocol, PyResult};
use crate::VirtualMachine;
use system_configuration::core_foundation::{
array::CFArray,
base::{CFType, FromVoid, TCFType},
dictionary::CFDictionary,
number::CFNumber,
string::{CFString, CFStringRef},
};
use system_configuration::sys::{
dynamic_store_copy_specific::SCDynamicStoreCopyProxies, schema_definitions::*,
};
fn proxy_dict() -> Option<CFDictionary<CFString, CFType>> {
// Py_BEGIN_ALLOW_THREADS
let proxy_dict = unsafe { SCDynamicStoreCopyProxies(std::ptr::null()) };
// Py_END_ALLOW_THREADS
if proxy_dict.is_null() {
None
} else {
Some(unsafe { CFDictionary::wrap_under_create_rule(proxy_dict) })
}
}
#[pyfunction]
fn _get_proxy_settings(vm: &VirtualMachine) -> PyResult<Option<PyDictRef>> {
let proxy_dict = if let Some(p) = proxy_dict() {
p
} else {
return Ok(None);
};
let result = vm.ctx.new_dict();
let v = 0
!= proxy_dict
.find(unsafe { kSCPropNetProxiesExcludeSimpleHostnames })
.and_then(|v| v.downcast::<CFNumber>())
.and_then(|v| v.to_i32())
.unwrap_or(0);
result.set_item("exclude_simple", vm.ctx.new_bool(v), vm)?;
if let Some(an_array) = proxy_dict
.find(unsafe { kSCPropNetProxiesExceptionsList })
.and_then(|v| v.downcast::<CFArray>())
{
let v = an_array
.into_iter()
.map(|s| {
unsafe { CFType::from_void(*s) }
.downcast::<CFString>()
.map(|s| {
let a_string: std::borrow::Cow<str> = (&s).into();
PyStr::from(a_string.into_owned())
})
.into_pyobject(vm)
})
.collect();
result.set_item("exceptions", vm.ctx.new_tuple(v), vm)?;
}
Ok(Some(result))
}
#[pyfunction]
fn _get_proxies(vm: &VirtualMachine) -> PyResult<Option<PyDictRef>> {
let proxy_dict = if let Some(p) = proxy_dict() {
p
} else {
return Ok(None);
};
let result = vm.ctx.new_dict();
let set_proxy = |result: &PyDictRef,
proto: &str,
enabled_key: CFStringRef,
host_key: CFStringRef,
port_key: CFStringRef|
-> PyResult<()> {
let enabled = 0
!= proxy_dict
.find(enabled_key)
.and_then(|v| v.downcast::<CFNumber>())
.and_then(|v| v.to_i32())
.unwrap_or(0);
if enabled {
if let Some(host) = proxy_dict
.find(host_key)
.and_then(|v| v.downcast::<CFString>())
{
let h = std::borrow::Cow::<str>::from(&host);
let v = if let Some(port) = proxy_dict
.find(port_key)
.and_then(|v| v.downcast::<CFNumber>())
.and_then(|v| v.to_i32())
{
format!("http://{}:{}", h, port)
} else {
format!("http://{}", h)
};
result.set_item(proto, vm.ctx.new_str(v), vm)?;
}
}
Ok(())
};
unsafe {
set_proxy(
&result,
"http",
kSCPropNetProxiesHTTPEnable,
kSCPropNetProxiesHTTPProxy,
kSCPropNetProxiesHTTPPort,
)?;
set_proxy(
&result,
"https",
kSCPropNetProxiesHTTPSEnable,
kSCPropNetProxiesHTTPSProxy,
kSCPropNetProxiesHTTPSPort,
)?;
set_proxy(
&result,
"ftp",
kSCPropNetProxiesFTPEnable,
kSCPropNetProxiesFTPProxy,
kSCPropNetProxiesFTPPort,
)?;
set_proxy(
&result,
"gopher",
kSCPropNetProxiesGopherEnable,
kSCPropNetProxiesGopherProxy,
kSCPropNetProxiesGopherPort,
)?;
}
Ok(Some(result))
}
}