mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Use configured HTTP clients for all MCP OAuth requests (#35814)
## What changed - Require callers to provide an HTTP client for MCP OAuth discovery and login, removing the separate direct `reqwest` path. - Use the shared `http` and `url` types throughout the MCP client and drop its direct `reqwest` dependency. - Preserve configured MCP headers when routing OAuth discovery through the provided client. ## Testing - Add coverage that routed OAuth discovery forwards configured headers. GitOrigin-RevId: 1345f56bd794626533133447597a5908e57b9b48
This commit is contained in:
Generated
-7
@@ -1145,12 +1145,8 @@
|
||||
"jiff-tzdb_0.1.6": "{\"dependencies\":[],\"features\":{}}",
|
||||
"jiff_0.2.23": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0.81\"},{\"features\":[\"serde\"],\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"kind\":\"dev\",\"name\":\"chrono-tz\",\"req\":\"^0.10.0\"},{\"kind\":\"dev\",\"name\":\"hifitime\",\"req\":\"^3.9.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"humantime\",\"req\":\"^2.1.0\"},{\"kind\":\"dev\",\"name\":\"insta\",\"req\":\"^1.39.0\"},{\"name\":\"jiff-static\",\"req\":\"=0.2.23\",\"target\":\"cfg(any())\"},{\"name\":\"jiff-static\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"jiff-tzdb\",\"optional\":true,\"req\":\"^0.1.6\"},{\"name\":\"jiff-tzdb-platform\",\"optional\":true,\"req\":\"^0.1.3\",\"target\":\"cfg(any(windows, target_family = \\\"wasm\\\"))\"},{\"name\":\"js-sys\",\"optional\":true,\"req\":\"^0.3.50\",\"target\":\"cfg(all(any(target_arch = \\\"wasm32\\\", target_arch = \\\"wasm64\\\"), target_os = \\\"unknown\\\"))\"},{\"default_features\":false,\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"log\",\"req\":\"^0.4.21\"},{\"default_features\":false,\"name\":\"portable-atomic\",\"req\":\"^1.10.0\",\"target\":\"cfg(not(target_has_atomic = \\\"ptr\\\"))\"},{\"default_features\":false,\"name\":\"portable-atomic-util\",\"req\":\"^0.2.4\",\"target\":\"cfg(not(target_has_atomic = \\\"ptr\\\"))\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0.3\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.203\"},{\"default_features\":false,\"name\":\"serde_core\",\"optional\":true,\"req\":\"^1.0.221\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.117\"},{\"kind\":\"dev\",\"name\":\"serde_yaml\",\"req\":\"^0.9.34\"},{\"kind\":\"dev\",\"name\":\"tabwriter\",\"req\":\"^1.4.0\"},{\"features\":[\"local-offset\",\"macros\",\"parsing\"],\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3.36\"},{\"kind\":\"dev\",\"name\":\"time-tz\",\"req\":\"^2.0.0\"},{\"kind\":\"dev\",\"name\":\"tzfile\",\"req\":\"^0.1.3\"},{\"kind\":\"dev\",\"name\":\"walkdir\",\"req\":\"^2.5.0\"},{\"name\":\"wasm-bindgen\",\"optional\":true,\"req\":\"^0.2.70\",\"target\":\"cfg(all(any(target_arch = \\\"wasm32\\\", target_arch = \\\"wasm64\\\"), target_os = \\\"unknown\\\"))\"},{\"default_features\":false,\"features\":[\"Win32_Foundation\",\"Win32_System_Time\"],\"name\":\"windows-sys\",\"optional\":true,\"req\":\">=0.52.0, <=0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"alloc\":[\"serde_core?/alloc\",\"portable-atomic-util/alloc\"],\"default\":[\"std\",\"tz-system\",\"tz-fat\",\"tzdb-bundle-platform\",\"tzdb-zoneinfo\",\"tzdb-concatenated\",\"perf-inline\"],\"js\":[\"dep:wasm-bindgen\",\"dep:js-sys\"],\"logging\":[\"dep:log\"],\"perf-inline\":[],\"serde\":[\"dep:serde_core\"],\"static\":[\"static-tz\",\"jiff-static?/tzdb\"],\"static-tz\":[\"dep:jiff-static\"],\"std\":[\"alloc\",\"log?/std\",\"serde_core?/std\"],\"tz-fat\":[\"jiff-static?/tz-fat\"],\"tz-system\":[\"std\",\"dep:windows-sys\"],\"tzdb-bundle-always\":[\"dep:jiff-tzdb\",\"alloc\"],\"tzdb-bundle-platform\":[\"dep:jiff-tzdb-platform\",\"alloc\"],\"tzdb-concatenated\":[\"std\"],\"tzdb-zoneinfo\":[\"std\"]}}",
|
||||
"jiff_0.2.24": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0.81\"},{\"features\":[\"serde\"],\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"kind\":\"dev\",\"name\":\"chrono-tz\",\"req\":\"^0.10.0\"},{\"kind\":\"dev\",\"name\":\"hifitime\",\"req\":\"^3.9.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"humantime\",\"req\":\"^2.1.0\"},{\"kind\":\"dev\",\"name\":\"insta\",\"req\":\"^1.39.0\"},{\"name\":\"jiff-static\",\"req\":\"=0.2.24\",\"target\":\"cfg(any())\"},{\"name\":\"jiff-static\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"jiff-tzdb\",\"optional\":true,\"req\":\"^0.1.6\"},{\"name\":\"jiff-tzdb-platform\",\"optional\":true,\"req\":\"^0.1.3\",\"target\":\"cfg(any(windows, target_family = \\\"wasm\\\"))\"},{\"name\":\"js-sys\",\"optional\":true,\"req\":\"^0.3.50\",\"target\":\"cfg(all(any(target_arch = \\\"wasm32\\\", target_arch = \\\"wasm64\\\"), target_os = \\\"unknown\\\"))\"},{\"default_features\":false,\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"log\",\"req\":\"^0.4.21\"},{\"default_features\":false,\"name\":\"portable-atomic\",\"req\":\"^1.10.0\",\"target\":\"cfg(not(target_has_atomic = \\\"ptr\\\"))\"},{\"default_features\":false,\"name\":\"portable-atomic-util\",\"req\":\"^0.2.4\",\"target\":\"cfg(not(target_has_atomic = \\\"ptr\\\"))\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0.3\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.203\"},{\"default_features\":false,\"name\":\"serde_core\",\"optional\":true,\"req\":\"^1.0.221\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.117\"},{\"kind\":\"dev\",\"name\":\"serde_yaml\",\"req\":\"^0.9.34\"},{\"kind\":\"dev\",\"name\":\"tabwriter\",\"req\":\"^1.4.0\"},{\"features\":[\"local-offset\",\"macros\",\"parsing\"],\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3.36\"},{\"kind\":\"dev\",\"name\":\"time-tz\",\"req\":\"^2.0.0\"},{\"kind\":\"dev\",\"name\":\"tzfile\",\"req\":\"^0.1.3\"},{\"kind\":\"dev\",\"name\":\"walkdir\",\"req\":\"^2.5.0\"},{\"name\":\"wasm-bindgen\",\"optional\":true,\"req\":\"^0.2.70\",\"target\":\"cfg(all(any(target_arch = \\\"wasm32\\\", target_arch = \\\"wasm64\\\"), target_os = \\\"unknown\\\"))\"},{\"default_features\":false,\"features\":[\"Win32_Foundation\",\"Win32_System_Time\"],\"name\":\"windows-sys\",\"optional\":true,\"req\":\">=0.52.0, <=0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"alloc\":[\"serde_core?/alloc\",\"portable-atomic-util/alloc\"],\"default\":[\"std\",\"tz-system\",\"tz-fat\",\"tzdb-bundle-platform\",\"tzdb-zoneinfo\",\"tzdb-concatenated\",\"perf-inline\"],\"js\":[\"dep:wasm-bindgen\",\"dep:js-sys\"],\"logging\":[\"dep:log\"],\"perf-inline\":[],\"serde\":[\"dep:serde_core\"],\"static\":[\"static-tz\",\"jiff-static?/tzdb\"],\"static-tz\":[\"dep:jiff-static\"],\"std\":[\"alloc\",\"log?/std\",\"serde_core?/std\"],\"tz-fat\":[\"jiff-static?/tz-fat\"],\"tz-system\":[\"std\",\"dep:windows-sys\"],\"tzdb-bundle-always\":[\"dep:jiff-tzdb\",\"alloc\"],\"tzdb-bundle-platform\":[\"dep:jiff-tzdb-platform\",\"alloc\"],\"tzdb-concatenated\":[\"std\"],\"tzdb-zoneinfo\":[\"std\"]}}",
|
||||
"jni-macros_0.22.4": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"javac\",\"req\":\"^0.1.0\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"kind\":\"build\",\"name\":\"rustc_version\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"rusty-fork\",\"req\":\"^0.3.0\"},{\"name\":\"simd_cesu8\",\"req\":\"^1.0.1\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2.0\"},{\"kind\":\"dev\",\"name\":\"thiserror\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1\"}],\"features\":{}}",
|
||||
"jni-sys-macros_0.4.1": "{\"dependencies\":[{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}",
|
||||
"jni-sys_0.3.0": "{\"dependencies\":[],\"features\":{}}",
|
||||
"jni-sys_0.4.1": "{\"dependencies\":[{\"name\":\"jni-sys-macros\",\"req\":\"^0.4.1\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1\"}],\"features\":{}}",
|
||||
"jni_0.21.1": "{\"dependencies\":[{\"name\":\"cesu8\",\"req\":\"^1.1.0\"},{\"name\":\"cfg-if\",\"req\":\"^1.0.0\"},{\"name\":\"combine\",\"req\":\"^4.1.0\"},{\"name\":\"java-locator\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"jni-sys\",\"req\":\"^0.3.0\"},{\"name\":\"libloading\",\"optional\":true,\"req\":\"^0.7\"},{\"name\":\"log\",\"req\":\"^0.4.4\"},{\"name\":\"thiserror\",\"req\":\"^1.0.20\"},{\"kind\":\"dev\",\"name\":\"assert_matches\",\"req\":\"^1.5.0\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"rusty-fork\",\"req\":\"^0.3.0\"},{\"kind\":\"build\",\"name\":\"walkdir\",\"req\":\"^2\"},{\"features\":[\"Win32_Globalization\"],\"name\":\"windows-sys\",\"req\":\"^0.45.0\",\"target\":\"cfg(windows)\"},{\"kind\":\"dev\",\"name\":\"bytemuck\",\"req\":\"^1.13.0\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[],\"invocation\":[\"java-locator\",\"libloading\"]}}",
|
||||
"jni_0.22.4": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"assert_matches\",\"req\":\"^1.5.0\"},{\"kind\":\"dev\",\"name\":\"bytemuck\",\"req\":\"^1.13.0\",\"target\":\"cfg(windows)\"},{\"name\":\"cfg-if\",\"req\":\"^1.0.0\"},{\"name\":\"combine\",\"req\":\"^4.1.0\"},{\"features\":[\"html_reports\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7\"},{\"name\":\"java-locator\",\"optional\":true,\"req\":\"^0.1.3\",\"target\":\"cfg(not(target_os = \\\"android\\\"))\"},{\"kind\":\"dev\",\"name\":\"javac\",\"req\":\"^0.1.0\"},{\"name\":\"jni-macros\",\"req\":\"=0.22.4\"},{\"name\":\"jni-sys\",\"req\":\"^0.4.1\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"libloading\",\"optional\":true,\"req\":\"^0.8\",\"target\":\"cfg(not(target_os = \\\"android\\\"))\"},{\"name\":\"log\",\"req\":\"^0.4.4\"},{\"kind\":\"dev\",\"name\":\"rusty-fork\",\"req\":\"^0.3.0\"},{\"name\":\"simd_cesu8\",\"req\":\"^1.1.1\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1\"},{\"name\":\"thiserror\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1\"},{\"kind\":\"build\",\"name\":\"walkdir\",\"req\":\"^2\"},{\"name\":\"windows-link\",\"req\":\"^0.2\",\"target\":\"cfg(windows)\"},{\"features\":[\"Win32_System_Threading\",\"Win32_Foundation\"],\"kind\":\"dev\",\"name\":\"windows-sys\",\"req\":\"^0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"_cfg_test\":[],\"default\":[],\"invocation\":[\"dep:java-locator\",\"dep:libloading\"]}}",
|
||||
"jobserver_0.1.34": "{\"dependencies\":[{\"features\":[\"std\"],\"name\":\"getrandom\",\"req\":\"^0.3.2\",\"target\":\"cfg(windows)\"},{\"name\":\"libc\",\"req\":\"^0.2.171\",\"target\":\"cfg(unix)\"},{\"features\":[\"fs\"],\"kind\":\"dev\",\"name\":\"nix\",\"req\":\"^0.28.0\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.10.1\"}],\"features\":{}}",
|
||||
"js-sys_0.3.82": "{\"dependencies\":[{\"default_features\":false,\"name\":\"once_cell\",\"req\":\"^1.12\"},{\"default_features\":false,\"name\":\"wasm-bindgen\",\"req\":\"=0.2.105\"}],\"features\":{\"default\":[\"std\"],\"std\":[\"wasm-bindgen/std\"]}}",
|
||||
"js-sys_0.3.85": "{\"dependencies\":[{\"default_features\":false,\"name\":\"once_cell\",\"req\":\"^1.12\"},{\"default_features\":false,\"name\":\"wasm-bindgen\",\"req\":\"=0.2.108\"}],\"features\":{\"default\":[\"std\"],\"std\":[\"wasm-bindgen/std\"]}}",
|
||||
@@ -1443,8 +1439,6 @@
|
||||
"rustls-native-certs_0.8.3": "{\"dependencies\":[{\"name\":\"openssl-probe\",\"req\":\"^0.2\",\"target\":\"cfg(all(unix, not(target_os = \\\"macos\\\")))\"},{\"features\":[\"std\"],\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.10\"},{\"kind\":\"dev\",\"name\":\"ring\",\"req\":\"^0.17\"},{\"kind\":\"dev\",\"name\":\"rustls\",\"req\":\"^0.23\"},{\"kind\":\"dev\",\"name\":\"rustls-webpki\",\"req\":\"^0.103\"},{\"name\":\"schannel\",\"req\":\"^0.1\",\"target\":\"cfg(windows)\"},{\"name\":\"security-framework\",\"req\":\"^3\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"kind\":\"dev\",\"name\":\"serial_test\",\"req\":\"^3\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.5\"},{\"kind\":\"dev\",\"name\":\"untrusted\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.18\"}],\"features\":{}}",
|
||||
"rustls-pki-types_1.14.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"crabgrind\",\"req\":\"=0.1.9\",\"target\":\"cfg(all(target_os = \\\"linux\\\", target_arch = \\\"x86_64\\\"))\"},{\"name\":\"web-time\",\"optional\":true,\"req\":\"^1\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"dep:zeroize\"],\"default\":[\"alloc\"],\"std\":[\"alloc\"],\"web\":[\"web-time\"]}}",
|
||||
"rustls-pki-types_1.14.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"crabgrind\",\"req\":\"=0.1.9\",\"target\":\"cfg(all(target_os = \\\"linux\\\", target_arch = \\\"x86_64\\\"))\"},{\"name\":\"web-time\",\"optional\":true,\"req\":\"^1\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"dep:zeroize\"],\"default\":[\"alloc\"],\"std\":[\"alloc\"],\"web\":[\"web-time\"]}}",
|
||||
"rustls-platform-verifier-android_0.1.1": "{\"dependencies\":[],\"features\":{}}",
|
||||
"rustls-platform-verifier_0.7.0": "{\"dependencies\":[{\"name\":\"android_logger\",\"optional\":true,\"req\":\"^0.15\",\"target\":\"cfg(target_os = \\\"android\\\")\"},{\"name\":\"base64\",\"optional\":true,\"req\":\"^0.22\"},{\"name\":\"core-foundation\",\"req\":\"^0.10\",\"target\":\"cfg(any(target_vendor = \\\"apple\\\"))\"},{\"name\":\"core-foundation-sys\",\"req\":\"^0.8\",\"target\":\"cfg(any(target_vendor = \\\"apple\\\"))\"},{\"default_features\":false,\"name\":\"jni\",\"req\":\"^0.22\",\"target\":\"cfg(target_os = \\\"android\\\")\"},{\"default_features\":false,\"name\":\"jni\",\"optional\":true,\"req\":\"^0.22.4\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"once_cell\",\"req\":\"^1.9\",\"target\":\"cfg(target_os = \\\"android\\\")\"},{\"name\":\"once_cell\",\"optional\":true,\"req\":\"^1.9\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"rustls\",\"req\":\"^0.23.27\"},{\"default_features\":false,\"features\":[\"ring\"],\"kind\":\"dev\",\"name\":\"rustls\",\"req\":\"^0.23\"},{\"name\":\"rustls-native-certs\",\"req\":\"^0.8\",\"target\":\"cfg(all(unix, not(target_os = \\\"android\\\"), not(target_vendor = \\\"apple\\\"), not(target_arch = \\\"wasm32\\\")))\"},{\"name\":\"rustls-platform-verifier-android\",\"req\":\"^0.1.0\",\"target\":\"cfg(target_os = \\\"android\\\")\"},{\"name\":\"security-framework\",\"req\":\"^3.5.0\",\"target\":\"cfg(any(target_vendor = \\\"apple\\\"))\"},{\"name\":\"security-framework-sys\",\"req\":\"^2.15\",\"target\":\"cfg(any(target_vendor = \\\"apple\\\"))\"},{\"default_features\":false,\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.103\",\"target\":\"cfg(all(unix, not(target_os = \\\"android\\\"), not(target_vendor = \\\"apple\\\"), not(target_arch = \\\"wasm32\\\")))\"},{\"default_features\":false,\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.103\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"default_features\":false,\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.103\",\"target\":\"cfg(target_os = \\\"android\\\")\"},{\"name\":\"webpki-root-certs\",\"req\":\"^1\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"kind\":\"dev\",\"name\":\"webpki-root-certs\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"Win32_Foundation\",\"Win32_Security_Cryptography\"],\"name\":\"windows-sys\",\"req\":\">=0.52.0, <0.62.0\",\"target\":\"cfg(windows)\"}],\"features\":{\"cert-logging\":[\"base64\"],\"dbg\":[],\"docsrs\":[\"jni\",\"once_cell\"],\"ffi-testing\":[\"android_logger\",\"rustls/ring\"]}}",
|
||||
"rustls-webpki_0.103.13": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.14\"},{\"kind\":\"dev\",\"name\":\"base64\",\"req\":\"^0.22\"},{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"kind\":\"dev\",\"name\":\"bzip2\",\"req\":\"^0.6\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"^1.17.2\"},{\"default_features\":false,\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.12\"},{\"default_features\":false,\"features\":[\"aws_lc_rs\"],\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14.2\"},{\"default_features\":false,\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"untrusted\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.18.1\"}],\"features\":{\"alloc\":[\"ring?/alloc\",\"pki-types/alloc\"],\"aws-lc-rs\":[\"dep:aws-lc-rs\",\"aws-lc-rs/aws-lc-sys\",\"aws-lc-rs/prebuilt-nasm\"],\"aws-lc-rs-fips\":[\"dep:aws-lc-rs\",\"aws-lc-rs/fips\"],\"aws-lc-rs-unstable\":[\"aws-lc-rs\",\"aws-lc-rs/unstable\"],\"default\":[\"std\"],\"ring\":[\"dep:ring\"],\"std\":[\"alloc\",\"pki-types/std\"]}}",
|
||||
"rustls_0.23.36": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.14\"},{\"kind\":\"dev\",\"name\":\"base64\",\"req\":\"^0.22\"},{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"brotli\",\"optional\":true,\"req\":\"^8\"},{\"name\":\"brotli-decompressor\",\"optional\":true,\"req\":\"^5.0.0\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11\"},{\"default_features\":false,\"features\":[\"default-hasher\",\"inline-more\"],\"name\":\"hashbrown\",\"optional\":true,\"req\":\"^0.15\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.8\"},{\"kind\":\"dev\",\"name\":\"log\",\"req\":\"^0.4.8\"},{\"kind\":\"dev\",\"name\":\"macro_rules_attribute\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"num-bigint\",\"req\":\"^0.4.4\"},{\"default_features\":false,\"features\":[\"alloc\",\"race\"],\"name\":\"once_cell\",\"req\":\"^1.16\"},{\"features\":[\"alloc\"],\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.12\"},{\"default_features\":false,\"features\":[\"pem\",\"aws_lc_rs\"],\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"kind\":\"build\",\"name\":\"rustversion\",\"optional\":true,\"req\":\"^1.0.6\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2.5.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3.6\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.103.5\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.17\"},{\"name\":\"zeroize\",\"req\":\"^1.8\"},{\"name\":\"zlib-rs\",\"optional\":true,\"req\":\"^0.5\"}],\"features\":{\"aws-lc-rs\":[\"aws_lc_rs\"],\"aws_lc_rs\":[\"dep:aws-lc-rs\",\"webpki/aws-lc-rs\",\"aws-lc-rs/aws-lc-sys\",\"aws-lc-rs/prebuilt-nasm\"],\"brotli\":[\"dep:brotli\",\"dep:brotli-decompressor\",\"std\"],\"custom-provider\":[],\"default\":[\"aws_lc_rs\",\"logging\",\"prefer-post-quantum\",\"std\",\"tls12\"],\"fips\":[\"aws_lc_rs\",\"aws-lc-rs?/fips\",\"webpki/aws-lc-rs-fips\"],\"logging\":[\"log\"],\"prefer-post-quantum\":[\"aws_lc_rs\"],\"read_buf\":[\"rustversion\",\"std\"],\"ring\":[\"dep:ring\",\"webpki/ring\"],\"std\":[\"webpki/std\",\"pki-types/std\",\"once_cell/std\"],\"tls12\":[],\"zlib\":[\"dep:zlib-rs\"]}}",
|
||||
"rustls_0.23.40": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.14\"},{\"kind\":\"dev\",\"name\":\"base64\",\"req\":\"^0.22\"},{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"brotli\",\"optional\":true,\"req\":\"^8\"},{\"name\":\"brotli-decompressor\",\"optional\":true,\"req\":\"^5.0.0\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11\"},{\"default_features\":false,\"features\":[\"default-hasher\",\"inline-more\"],\"name\":\"hashbrown\",\"optional\":true,\"req\":\"^0.15\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.8\"},{\"kind\":\"dev\",\"name\":\"log\",\"req\":\"^0.4.8\"},{\"kind\":\"dev\",\"name\":\"macro_rules_attribute\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"num-bigint\",\"req\":\"^0.4.4\"},{\"default_features\":false,\"features\":[\"alloc\",\"race\"],\"name\":\"once_cell\",\"req\":\"^1.16\"},{\"features\":[\"alloc\"],\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.12\"},{\"default_features\":false,\"features\":[\"pem\",\"aws_lc_rs\"],\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"kind\":\"build\",\"name\":\"rustversion\",\"optional\":true,\"req\":\"^1.0.6\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2.5.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3.6\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.103.5\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.17\"},{\"name\":\"zeroize\",\"req\":\"^1.8\"},{\"name\":\"zlib-rs\",\"optional\":true,\"req\":\"^0.6\"}],\"features\":{\"aws-lc-rs\":[\"aws_lc_rs\"],\"aws_lc_rs\":[\"dep:aws-lc-rs\",\"webpki/aws-lc-rs\",\"aws-lc-rs/aws-lc-sys\",\"aws-lc-rs/prebuilt-nasm\"],\"brotli\":[\"dep:brotli\",\"dep:brotli-decompressor\",\"std\"],\"custom-provider\":[],\"default\":[\"aws_lc_rs\",\"logging\",\"prefer-post-quantum\",\"std\",\"tls12\"],\"fips\":[\"aws_lc_rs\",\"aws-lc-rs?/fips\",\"webpki/aws-lc-rs-fips\"],\"logging\":[\"log\"],\"prefer-post-quantum\":[\"aws_lc_rs\"],\"read_buf\":[\"rustversion\",\"std\"],\"ring\":[\"dep:ring\",\"webpki/ring\"],\"std\":[\"webpki/std\",\"pki-types/std\",\"once_cell/std\"],\"tls12\":[],\"zlib\":[\"dep:zlib-rs\"]}}",
|
||||
@@ -1527,7 +1521,6 @@
|
||||
"signature_2.2.0": "{\"dependencies\":[{\"name\":\"derive\",\"optional\":true,\"package\":\"signature_derive\",\"req\":\"^2\"},{\"default_features\":false,\"name\":\"digest\",\"optional\":true,\"req\":\"^0.10.6\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"default_features\":false,\"name\":\"rand_core\",\"optional\":true,\"req\":\"^0.6.4\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"sha2\",\"req\":\"^0.10\"}],\"features\":{\"alloc\":[],\"std\":[\"alloc\",\"rand_core?/std\"]}}",
|
||||
"simd-adler32_0.3.8": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"adler\",\"req\":\"^1.0.2\"},{\"kind\":\"dev\",\"name\":\"adler32\",\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{\"const-generics\":[],\"default\":[\"std\",\"const-generics\"],\"nightly\":[],\"std\":[]}}",
|
||||
"simd-adler32_0.3.9": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"adler\",\"req\":\"^1.0.2\"},{\"kind\":\"dev\",\"name\":\"adler32\",\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"features\":[\"small_rng\"],\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{\"const-generics\":[],\"default\":[\"std\",\"const-generics\"],\"nightly\":[],\"std\":[]}}",
|
||||
"simd_cesu8_1.1.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"cesu8\",\"req\":\"^1.1.0\"},{\"features\":[\"html_reports\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5.1\"},{\"kind\":\"build\",\"name\":\"rustc_version\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"name\":\"simdutf8\",\"req\":\"^0.1.4\"}],\"features\":{\"bench\":[],\"default\":[\"std\"],\"nightly\":[],\"std\":[\"simdutf8/std\"]}}",
|
||||
"simdutf8_0.1.5": "{\"dependencies\":[],\"features\":{\"aarch64_neon\":[],\"aarch64_neon_prefetch\":[],\"default\":[\"std\"],\"hints\":[],\"public_imp\":[],\"std\":[]}}",
|
||||
"similar_2.7.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bstr\",\"optional\":true,\"req\":\"^1.5.0\"},{\"kind\":\"dev\",\"name\":\"console\",\"req\":\"^0.15.0\"},{\"kind\":\"dev\",\"name\":\"insta\",\"req\":\"^1.10.0\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.130\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.68\"},{\"name\":\"unicode-segmentation\",\"optional\":true,\"req\":\"^1.7.1\"},{\"name\":\"web-time\",\"optional\":true,\"req\":\"^1.1\"}],\"features\":{\"bytes\":[\"bstr\",\"text\"],\"default\":[\"text\"],\"inline\":[\"text\"],\"text\":[],\"unicode\":[\"text\",\"unicode-segmentation\",\"bstr?/unicode\",\"bstr?/std\"],\"wasm32_web_time\":[\"web-time\"]}}",
|
||||
"simple_asn1_0.6.4": "{\"dependencies\":[{\"default_features\":false,\"name\":\"num-bigint\",\"req\":\"^0.4\"},{\"default_features\":false,\"name\":\"num-traits\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0.3\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.4\"},{\"default_features\":false,\"name\":\"thiserror\",\"req\":\"^2\"},{\"default_features\":false,\"features\":[\"formatting\",\"macros\",\"parsing\"],\"name\":\"time\",\"req\":\"^0.3.47\"},{\"default_features\":false,\"features\":[\"formatting\",\"macros\",\"parsing\",\"quickcheck\"],\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3\"}],\"features\":{}}",
|
||||
|
||||
Generated
+4
-96
@@ -3858,11 +3858,11 @@ dependencies = [
|
||||
"codex-utils-path-uri",
|
||||
"codex-utils-pty",
|
||||
"futures",
|
||||
"http 1.4.0",
|
||||
"keyring",
|
||||
"memchr",
|
||||
"oauth2",
|
||||
"pretty_assertions",
|
||||
"reqwest 0.13.4",
|
||||
"rmcp",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3874,6 +3874,7 @@ dependencies = [
|
||||
"tiny_http",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
"urlencoding",
|
||||
"webbrowser",
|
||||
"which 8.0.0",
|
||||
@@ -8487,68 +8488,19 @@ dependencies = [
|
||||
"cesu8",
|
||||
"cfg-if",
|
||||
"combine",
|
||||
"jni-sys 0.3.0",
|
||||
"jni-sys",
|
||||
"log",
|
||||
"thiserror 1.0.69",
|
||||
"walkdir",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.22.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"combine",
|
||||
"jni-macros",
|
||||
"jni-sys 0.4.1",
|
||||
"log",
|
||||
"simd_cesu8",
|
||||
"thiserror 2.0.18",
|
||||
"walkdir",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-macros"
|
||||
version = "0.22.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"simd_cesu8",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
|
||||
dependencies = [
|
||||
"jni-sys-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys-macros"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.34"
|
||||
@@ -10488,7 +10440,6 @@ version = "0.11.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"bytes",
|
||||
"getrandom 0.3.4",
|
||||
"lru-slab",
|
||||
@@ -11177,21 +11128,15 @@ dependencies = [
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-util",
|
||||
"js-sys",
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"rustls-platform-verifier",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tower-http",
|
||||
@@ -11440,33 +11385,6 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
|
||||
dependencies = [
|
||||
"core-foundation 0.10.1",
|
||||
"core-foundation-sys",
|
||||
"jni 0.22.4",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-platform-verifier-android",
|
||||
"rustls-webpki",
|
||||
"security-framework 3.5.1",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier-android"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.13"
|
||||
@@ -12267,16 +12185,6 @@ version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||
|
||||
[[package]]
|
||||
name = "simd_cesu8"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
"simdutf8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.5"
|
||||
@@ -14527,7 +14435,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00f1243ef785213e3a32fa0396093424a3a6ea566f9948497e5a2309261a4c97"
|
||||
dependencies = [
|
||||
"core-foundation 0.10.1",
|
||||
"jni 0.21.1",
|
||||
"jni",
|
||||
"log",
|
||||
"ndk-context",
|
||||
"objc2",
|
||||
|
||||
@@ -409,7 +409,7 @@ use codex_mcp::McpRuntimeContext;
|
||||
use codex_mcp::McpServerStatusSnapshot;
|
||||
use codex_mcp::McpSnapshotDetail;
|
||||
use codex_mcp::collect_mcp_server_status_snapshot_with_detail;
|
||||
use codex_mcp::discover_supported_scopes_with_http_client;
|
||||
use codex_mcp::discover_supported_scopes;
|
||||
use codex_mcp::read_mcp_resource as read_mcp_resource_without_thread;
|
||||
use codex_mcp::resolve_oauth_scopes;
|
||||
use codex_memories_write::clear_memory_roots_contents;
|
||||
@@ -457,7 +457,7 @@ use codex_protocol::protocol::W3cTraceContext;
|
||||
use codex_protocol::protocol::strip_user_message_prefix;
|
||||
use codex_protocol::user_input::MAX_USER_INPUT_TEXT_CHARS;
|
||||
use codex_protocol::user_input::UserInput as CoreInputItem;
|
||||
use codex_rmcp_client::perform_oauth_login_return_url_with_http_client;
|
||||
use codex_rmcp_client::perform_oauth_login_return_url;
|
||||
use codex_rollout::is_persisted_rollout_item;
|
||||
use codex_rollout::state_db::StateDbHandle;
|
||||
use codex_rollout::state_db::reconcile_rollout;
|
||||
|
||||
@@ -172,7 +172,7 @@ impl McpRequestProcessor {
|
||||
})?;
|
||||
|
||||
let discovered_scopes = if scopes.is_none() && server.scopes.is_none() {
|
||||
discover_supported_scopes_with_http_client(
|
||||
discover_supported_scopes(
|
||||
&server.transport,
|
||||
Arc::clone(&http_client),
|
||||
codex_rmcp_client::OAuthDiscoveryTimeout::Requested,
|
||||
@@ -184,7 +184,7 @@ impl McpRequestProcessor {
|
||||
let resolved_scopes =
|
||||
resolve_oauth_scopes(scopes, server.scopes.clone(), discovered_scopes);
|
||||
|
||||
let handle = perform_oauth_login_return_url_with_http_client(
|
||||
let handle = perform_oauth_login_return_url(
|
||||
&name,
|
||||
&url,
|
||||
mcp_config.mcp_oauth_credentials_store_mode,
|
||||
|
||||
@@ -26,7 +26,7 @@ use codex_core_plugins::remote::validate_remote_plugin_id;
|
||||
use codex_core_plugins::remote_bundle::RemotePluginBundleInstallError;
|
||||
use codex_mcp::McpOAuthLoginSupport;
|
||||
use codex_mcp::McpRuntimeContext;
|
||||
use codex_mcp::oauth_login_support_with_http_client;
|
||||
use codex_mcp::oauth_login_support;
|
||||
use codex_mcp::should_retry_without_scopes;
|
||||
use codex_plugin::PluginId;
|
||||
use codex_plugin::PluginTelemetryMetadata;
|
||||
@@ -1888,7 +1888,7 @@ impl PluginRequestProcessor {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let login_support = oauth_login_support_with_http_client(
|
||||
let login_support = oauth_login_support(
|
||||
&server.transport,
|
||||
Arc::clone(&http_client),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
|
||||
@@ -26,8 +26,8 @@ use codex_mcp::McpOAuthLoginSupport;
|
||||
use codex_mcp::McpRuntimeContext;
|
||||
use codex_mcp::ResolvedMcpOAuthScopes;
|
||||
use codex_mcp::compute_auth_statuses;
|
||||
use codex_mcp::discover_supported_scopes_with_http_client;
|
||||
use codex_mcp::oauth_login_support_with_http_client;
|
||||
use codex_mcp::discover_supported_scopes;
|
||||
use codex_mcp::oauth_login_support;
|
||||
use codex_mcp::resolve_oauth_scopes;
|
||||
use codex_mcp::should_retry_without_scopes;
|
||||
use codex_protocol::protocol::McpAuthStatus;
|
||||
@@ -391,7 +391,7 @@ async fn run_add(config_overrides: &CliConfigOverrides, add_args: AddArgs) -> Re
|
||||
// OAuth discovery uses the local route-aware HTTP client.
|
||||
let http_client: Arc<dyn HttpClient> =
|
||||
Arc::new(RouteAwareHttpClient::new(config.http_client_factory()));
|
||||
let login_support = oauth_login_support_with_http_client(
|
||||
let login_support = oauth_login_support(
|
||||
&transport,
|
||||
Arc::clone(&http_client),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
@@ -502,7 +502,7 @@ async fn run_login(config_overrides: &CliConfigOverrides, login_args: LoginArgs)
|
||||
Arc::new(RouteAwareHttpClient::new(config.http_client_factory()));
|
||||
let explicit_scopes = (!scopes.is_empty()).then_some(scopes);
|
||||
let discovered_scopes = if explicit_scopes.is_none() && server.scopes.is_none() {
|
||||
discover_supported_scopes_with_http_client(
|
||||
discover_supported_scopes(
|
||||
&server.transport,
|
||||
Arc::clone(&http_client),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
|
||||
@@ -72,9 +72,7 @@ pub use mcp::McpOAuthScopesSource;
|
||||
pub use mcp::ResolvedMcpOAuthScopes;
|
||||
pub use mcp::compute_auth_statuses;
|
||||
pub use mcp::discover_supported_scopes;
|
||||
pub use mcp::discover_supported_scopes_with_http_client;
|
||||
pub use mcp::oauth_login_support;
|
||||
pub use mcp::oauth_login_support_with_http_client;
|
||||
pub use mcp::resolve_oauth_scopes;
|
||||
pub use mcp::should_retry_without_scopes;
|
||||
|
||||
|
||||
@@ -12,9 +12,8 @@ use codex_login::CodexAuth;
|
||||
use codex_rmcp_client::McpAuthState;
|
||||
use codex_rmcp_client::OAuthDiscoveryTimeout;
|
||||
use codex_rmcp_client::OAuthProviderError;
|
||||
use codex_rmcp_client::determine_streamable_http_auth_status_with_http_client;
|
||||
use codex_rmcp_client::determine_streamable_http_auth_status;
|
||||
use codex_rmcp_client::discover_streamable_http_oauth;
|
||||
use codex_rmcp_client::discover_streamable_http_oauth_with_http_client;
|
||||
use futures::FutureExt;
|
||||
use futures::future::join_all;
|
||||
use tracing::warn;
|
||||
@@ -57,27 +56,7 @@ pub struct McpAuthStatusEntry {
|
||||
pub auth_state: McpAuthState,
|
||||
}
|
||||
|
||||
pub async fn oauth_login_support(transport: &McpServerTransportConfig) -> McpOAuthLoginSupport {
|
||||
let Some(mut config) = oauth_login_candidate(transport) else {
|
||||
return McpOAuthLoginSupport::Unsupported;
|
||||
};
|
||||
match discover_streamable_http_oauth(
|
||||
&config.url,
|
||||
config.http_headers.clone(),
|
||||
config.env_http_headers.clone(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(Some(discovery)) => {
|
||||
config.discovered_scopes = discovery.scopes_supported;
|
||||
McpOAuthLoginSupport::Supported(config)
|
||||
}
|
||||
Ok(None) => McpOAuthLoginSupport::Unsupported,
|
||||
Err(err) => McpOAuthLoginSupport::Unknown(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn oauth_login_support_with_http_client(
|
||||
pub async fn oauth_login_support(
|
||||
transport: &McpServerTransportConfig,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
discovery_timeout: OAuthDiscoveryTimeout,
|
||||
@@ -85,7 +64,7 @@ pub async fn oauth_login_support_with_http_client(
|
||||
let Some(mut config) = oauth_login_candidate(transport) else {
|
||||
return McpOAuthLoginSupport::Unsupported;
|
||||
};
|
||||
match discover_streamable_http_oauth_with_http_client(
|
||||
match discover_streamable_http_oauth(
|
||||
&config.url,
|
||||
config.http_headers.clone(),
|
||||
config.env_http_headers.clone(),
|
||||
@@ -126,19 +105,10 @@ fn oauth_login_candidate(transport: &McpServerTransportConfig) -> Option<McpOAut
|
||||
|
||||
pub async fn discover_supported_scopes(
|
||||
transport: &McpServerTransportConfig,
|
||||
) -> Option<Vec<String>> {
|
||||
match oauth_login_support(transport).await {
|
||||
McpOAuthLoginSupport::Supported(config) => config.discovered_scopes,
|
||||
McpOAuthLoginSupport::Unsupported | McpOAuthLoginSupport::Unknown(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn discover_supported_scopes_with_http_client(
|
||||
transport: &McpServerTransportConfig,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
discovery_timeout: OAuthDiscoveryTimeout,
|
||||
) -> Option<Vec<String>> {
|
||||
match oauth_login_support_with_http_client(transport, http_client, discovery_timeout).await {
|
||||
match oauth_login_support(transport, http_client, discovery_timeout).await {
|
||||
McpOAuthLoginSupport::Supported(config) => config.discovered_scopes,
|
||||
McpOAuthLoginSupport::Unsupported | McpOAuthLoginSupport::Unknown(_) => None,
|
||||
}
|
||||
@@ -266,7 +236,7 @@ async fn compute_auth_status(
|
||||
} else {
|
||||
OAuthDiscoveryTimeout::Requested
|
||||
};
|
||||
determine_streamable_http_auth_status_with_http_client(
|
||||
determine_streamable_http_auth_status(
|
||||
server_name,
|
||||
url,
|
||||
bearer_token_env_var.as_deref(),
|
||||
|
||||
@@ -5,9 +5,7 @@ pub use auth::McpOAuthScopesSource;
|
||||
pub use auth::ResolvedMcpOAuthScopes;
|
||||
pub use auth::compute_auth_statuses;
|
||||
pub use auth::discover_supported_scopes;
|
||||
pub use auth::discover_supported_scopes_with_http_client;
|
||||
pub use auth::oauth_login_support;
|
||||
pub use auth::oauth_login_support_with_http_client;
|
||||
pub use auth::resolve_oauth_scopes;
|
||||
pub use auth::should_retry_without_scopes;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ use codex_mcp::ElicitationReviewerHandle;
|
||||
use codex_mcp::McpOAuthLoginSupport;
|
||||
use codex_mcp::McpPermissionPromptAutoApproveContext;
|
||||
use codex_mcp::mcp_permission_prompt_is_auto_approved;
|
||||
use codex_mcp::oauth_login_support_with_http_client;
|
||||
use codex_mcp::oauth_login_support;
|
||||
use codex_mcp::resolve_oauth_scopes;
|
||||
use codex_mcp::should_retry_without_scopes;
|
||||
|
||||
@@ -148,7 +148,7 @@ pub(crate) async fn maybe_install_mcp_dependencies(
|
||||
} else {
|
||||
OAuthDiscoveryTimeout::Requested
|
||||
};
|
||||
let login_support = oauth_login_support_with_http_client(
|
||||
let login_support = oauth_login_support(
|
||||
&server_config.transport,
|
||||
Arc::clone(&http_client),
|
||||
discovery_timeout,
|
||||
|
||||
@@ -245,7 +245,6 @@ deny = [
|
||||
"codex-otel",
|
||||
"codex-protocol",
|
||||
"codex-responses-api-proxy",
|
||||
"codex-rmcp-client",
|
||||
"codex-tui",
|
||||
# Third-party crates that own their reqwest integration. These are not part of the
|
||||
# first-party migration count above.
|
||||
|
||||
@@ -27,14 +27,10 @@ codex-utils-pty = { workspace = true }
|
||||
codex-utils-home-dir = { workspace = true }
|
||||
bytes = { workspace = true }
|
||||
futures = { workspace = true, default-features = false, features = ["std"] }
|
||||
http = { workspace = true }
|
||||
keyring = { workspace = true, features = ["crypto-rust"] }
|
||||
memchr = { workspace = true }
|
||||
oauth2 = "5"
|
||||
reqwest = { version = "0.13", default-features = false, features = [
|
||||
"json",
|
||||
"stream",
|
||||
"rustls",
|
||||
] }
|
||||
rmcp = { workspace = true, default-features = false, features = [
|
||||
"auth",
|
||||
"base64",
|
||||
@@ -44,7 +40,7 @@ rmcp = { workspace = true, default-features = false, features = [
|
||||
"server",
|
||||
"transport-async-rw",
|
||||
"transport-child-process",
|
||||
"transport-streamable-http-client-reqwest",
|
||||
"transport-streamable-http-client",
|
||||
"transport-streamable-http-server",
|
||||
] }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
@@ -63,11 +59,13 @@ tokio = { workspace = true, features = [
|
||||
"time",
|
||||
] }
|
||||
tracing = { workspace = true, features = ["log"] }
|
||||
url = { workspace = true }
|
||||
urlencoding = { workspace = true }
|
||||
webbrowser = { workspace = true }
|
||||
which = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
codex-http-client = { workspace = true }
|
||||
codex-utils-cargo-bin = { workspace = true }
|
||||
pretty_assertions = { workspace = true }
|
||||
serial_test = { workspace = true }
|
||||
|
||||
@@ -4,14 +4,10 @@ use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use codex_exec_server::HttpClient;
|
||||
use codex_exec_server::RouteAwareHttpClient;
|
||||
use codex_http_client::HttpClientFactory;
|
||||
use codex_http_client::OutboundProxyPolicy;
|
||||
use codex_protocol::protocol::McpAuthStatus;
|
||||
use futures::FutureExt;
|
||||
use reqwest::Client;
|
||||
use reqwest::header::AUTHORIZATION;
|
||||
use reqwest::header::HeaderMap;
|
||||
use http::HeaderMap;
|
||||
use http::header::AUTHORIZATION;
|
||||
use rmcp::transport::AuthorizationManager;
|
||||
use rmcp::transport::auth::AuthError;
|
||||
use tracing::debug;
|
||||
@@ -74,40 +70,10 @@ enum AuthStatusCheck {
|
||||
Discover(HeaderMap),
|
||||
}
|
||||
|
||||
/// Determine the authentication status for a streamable HTTP MCP server.
|
||||
pub async fn determine_streamable_http_auth_status(
|
||||
server_name: &str,
|
||||
url: &str,
|
||||
bearer_token_env_var: Option<&str>,
|
||||
http_headers: Option<HashMap<String, String>>,
|
||||
env_http_headers: Option<HashMap<String, String>>,
|
||||
store_mode: OAuthCredentialsStoreMode,
|
||||
keyring_backend_kind: AuthKeyringBackendKind,
|
||||
) -> Result<McpAuthState> {
|
||||
let default_headers = match auth_status_before_discovery(
|
||||
server_name,
|
||||
url,
|
||||
bearer_token_env_var,
|
||||
http_headers,
|
||||
env_http_headers,
|
||||
store_mode,
|
||||
keyring_backend_kind,
|
||||
)? {
|
||||
AuthStatusCheck::Complete(status) => return Ok(status),
|
||||
AuthStatusCheck::Discover(default_headers) => default_headers,
|
||||
};
|
||||
|
||||
determine_auth_status_from_discovery(
|
||||
server_name,
|
||||
url,
|
||||
discover_streamable_http_oauth_with_headers(url, &default_headers).await,
|
||||
)
|
||||
}
|
||||
|
||||
/// Determine authentication status while routing OAuth discovery through the
|
||||
/// provided HTTP client.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn determine_streamable_http_auth_status_with_http_client(
|
||||
pub async fn determine_streamable_http_auth_status(
|
||||
server_name: &str,
|
||||
url: &str,
|
||||
bearer_token_env_var: Option<&str>,
|
||||
@@ -219,28 +185,10 @@ fn determine_auth_status_from_discovery(
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempt to determine whether a streamable HTTP MCP server advertises OAuth login.
|
||||
pub async fn supports_oauth_login(url: &str) -> Result<bool> {
|
||||
Ok(discover_streamable_http_oauth(
|
||||
url, /*http_headers*/ None, /*env_http_headers*/ None,
|
||||
)
|
||||
.await?
|
||||
.is_some())
|
||||
}
|
||||
|
||||
pub async fn discover_streamable_http_oauth(
|
||||
url: &str,
|
||||
http_headers: Option<HashMap<String, String>>,
|
||||
env_http_headers: Option<HashMap<String, String>>,
|
||||
) -> Result<Option<StreamableHttpOAuthDiscovery>> {
|
||||
let default_headers = build_default_headers(http_headers, env_http_headers)?;
|
||||
discover_streamable_http_oauth_with_headers(url, &default_headers).await
|
||||
}
|
||||
|
||||
pub async fn discover_streamable_http_oauth_with_http_client(
|
||||
url: &str,
|
||||
http_headers: Option<HashMap<String, String>>,
|
||||
env_http_headers: Option<HashMap<String, String>>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
discovery_timeout: OAuthDiscoveryTimeout,
|
||||
) -> Result<Option<StreamableHttpOAuthDiscovery>> {
|
||||
@@ -254,32 +202,6 @@ pub async fn discover_streamable_http_oauth_with_http_client(
|
||||
.await
|
||||
}
|
||||
|
||||
async fn discover_streamable_http_oauth_with_headers(
|
||||
url: &str,
|
||||
default_headers: &HeaderMap,
|
||||
) -> Result<Option<StreamableHttpOAuthDiscovery>> {
|
||||
// Use no_proxy to avoid a bug in the system-configuration crate that
|
||||
// can result in a panic. See #8912.
|
||||
let client = Client::builder()
|
||||
.timeout(DISCOVERY_TIMEOUT)
|
||||
.no_proxy()
|
||||
.redirect(reqwest::redirect::Policy::none())
|
||||
.build()?;
|
||||
let oauth_http_client = Arc::new(
|
||||
OAuthHttpClientAdapter::new(
|
||||
Arc::new(RouteAwareHttpClient::new(HttpClientFactory::new(
|
||||
OutboundProxyPolicy::ReqwestDefault,
|
||||
))),
|
||||
default_headers.clone(),
|
||||
)
|
||||
.with_local_http_client(client),
|
||||
);
|
||||
let mut authorization_manager =
|
||||
AuthorizationManager::new_with_oauth_http_client(url, oauth_http_client).await?;
|
||||
authorization_manager.set_allow_missing_issuer(true);
|
||||
discover_streamable_http_oauth_with_manager(&authorization_manager).await
|
||||
}
|
||||
|
||||
async fn discover_streamable_http_oauth_with_headers_and_http_client(
|
||||
url: &str,
|
||||
default_headers: HeaderMap,
|
||||
@@ -347,6 +269,9 @@ mod tests {
|
||||
use codex_exec_server::HttpRequestParams;
|
||||
use codex_exec_server::HttpRequestResponse;
|
||||
use codex_exec_server::HttpResponseBodyStream;
|
||||
use codex_exec_server::RouteAwareHttpClient;
|
||||
use codex_http_client::HttpClientFactory;
|
||||
use codex_http_client::OutboundProxyPolicy;
|
||||
use futures::future::BoxFuture;
|
||||
use pretty_assertions::assert_eq;
|
||||
use serial_test::serial;
|
||||
@@ -366,6 +291,12 @@ mod tests {
|
||||
handle: JoinHandle<()>,
|
||||
}
|
||||
|
||||
fn test_http_client() -> Arc<dyn HttpClient> {
|
||||
Arc::new(RouteAwareHttpClient::new(HttpClientFactory::new(
|
||||
OutboundProxyPolicy::ReqwestDefault,
|
||||
)))
|
||||
}
|
||||
|
||||
impl Drop for TestServer {
|
||||
fn drop(&mut self) {
|
||||
self.handle.abort();
|
||||
@@ -374,6 +305,7 @@ mod tests {
|
||||
|
||||
#[derive(Default)]
|
||||
struct RecordingHttpClient {
|
||||
headers: Mutex<Option<Vec<(String, String)>>>,
|
||||
timeout_ms: Mutex<Option<Option<u64>>>,
|
||||
}
|
||||
|
||||
@@ -394,6 +326,16 @@ mod tests {
|
||||
params: HttpRequestParams,
|
||||
) -> BoxFuture<'_, Result<(HttpRequestResponse, HttpResponseBodyStream), ExecServerError>>
|
||||
{
|
||||
*self
|
||||
.headers
|
||||
.lock()
|
||||
.expect("header recorder lock should not be poisoned") = Some(
|
||||
params
|
||||
.headers
|
||||
.iter()
|
||||
.map(|header| (header.name.clone(), header.value.clone()))
|
||||
.collect(),
|
||||
);
|
||||
*self
|
||||
.timeout_ms
|
||||
.lock()
|
||||
@@ -482,6 +424,8 @@ mod tests {
|
||||
/*env_http_headers*/ None,
|
||||
OAuthCredentialsStoreMode::Keyring,
|
||||
AuthKeyringBackendKind::default(),
|
||||
test_http_client(),
|
||||
OAuthDiscoveryTimeout::Requested,
|
||||
)
|
||||
.await
|
||||
.expect("status should compute");
|
||||
@@ -504,6 +448,8 @@ mod tests {
|
||||
)])),
|
||||
OAuthCredentialsStoreMode::Keyring,
|
||||
AuthKeyringBackendKind::default(),
|
||||
test_http_client(),
|
||||
OAuthDiscoveryTimeout::Requested,
|
||||
)
|
||||
.await
|
||||
.expect("status should compute");
|
||||
@@ -553,7 +499,11 @@ mod tests {
|
||||
});
|
||||
let url = format!("http://{address}/mcp");
|
||||
let discovery = discover_streamable_http_oauth(
|
||||
&url, /*http_headers*/ None, /*env_http_headers*/ None,
|
||||
&url,
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
test_http_client(),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(
|
||||
@@ -594,6 +544,8 @@ mod tests {
|
||||
"sensitive-key".to_string(),
|
||||
)])),
|
||||
/*env_http_headers*/ None,
|
||||
test_http_client(),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await
|
||||
.expect("discovery should complete without following the redirect");
|
||||
@@ -616,6 +568,8 @@ mod tests {
|
||||
&server.url,
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
test_http_client(),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await
|
||||
.expect("discovery should succeed")
|
||||
@@ -631,7 +585,7 @@ mod tests {
|
||||
async fn routed_oauth_discovery_caps_local_discovery_timeout() {
|
||||
let http_client = Arc::new(RecordingHttpClient::default());
|
||||
|
||||
let discovery = discover_streamable_http_oauth_with_http_client(
|
||||
let discovery = discover_streamable_http_oauth(
|
||||
"http://example.com/mcp",
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
@@ -657,7 +611,7 @@ mod tests {
|
||||
async fn routed_oauth_discovery_preserves_requested_timeout() {
|
||||
let http_client = Arc::new(RecordingHttpClient::default());
|
||||
|
||||
let discovery = discover_streamable_http_oauth_with_http_client(
|
||||
let discovery = discover_streamable_http_oauth(
|
||||
"http://example.com/mcp",
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
@@ -676,6 +630,38 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn routed_oauth_discovery_preserves_configured_headers() {
|
||||
let http_client = Arc::new(RecordingHttpClient::default());
|
||||
|
||||
let discovery = discover_streamable_http_oauth(
|
||||
"http://example.com/mcp",
|
||||
Some(HashMap::from([(
|
||||
"X-Mcp-Discovery".to_string(),
|
||||
"configured-value".to_string(),
|
||||
)])),
|
||||
/*env_http_headers*/ None,
|
||||
http_client.clone(),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(matches!(discovery, Ok(None)));
|
||||
let headers = http_client
|
||||
.headers
|
||||
.lock()
|
||||
.expect("header recorder lock should not be poisoned")
|
||||
.clone()
|
||||
.expect("discovery should issue an HTTP request");
|
||||
assert_eq!(
|
||||
headers
|
||||
.iter()
|
||||
.find(|(name, _)| name.eq_ignore_ascii_case("x-mcp-discovery"))
|
||||
.map(|(_, value)| value.as_str()),
|
||||
Some("configured-value")
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn discover_streamable_http_oauth_follows_protected_resource_metadata() {
|
||||
let authorization_server = spawn_oauth_discovery_server(serde_json::json!({
|
||||
@@ -724,6 +710,8 @@ mod tests {
|
||||
&resource_server.url,
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
test_http_client(),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await
|
||||
.expect("discovery should succeed")
|
||||
@@ -748,6 +736,8 @@ mod tests {
|
||||
&server.url,
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
test_http_client(),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await
|
||||
.expect("discovery should succeed")
|
||||
@@ -764,9 +754,16 @@ mod tests {
|
||||
}))
|
||||
.await;
|
||||
|
||||
let supported = supports_oauth_login(&server.url)
|
||||
.await
|
||||
.expect("support check should succeed");
|
||||
let supported = discover_streamable_http_oauth(
|
||||
&server.url,
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
test_http_client(),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await
|
||||
.expect("support check should succeed")
|
||||
.is_some();
|
||||
|
||||
assert!(supported);
|
||||
}
|
||||
|
||||
@@ -22,12 +22,14 @@ use codex_exec_server::HttpResponseBodyStream;
|
||||
use futures::StreamExt;
|
||||
use futures::stream;
|
||||
use futures::stream::BoxStream;
|
||||
use reqwest::StatusCode;
|
||||
use reqwest::header::ACCEPT;
|
||||
use reqwest::header::AUTHORIZATION;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
use reqwest::header::HeaderMap;
|
||||
use reqwest::header::HeaderName;
|
||||
use http::HeaderMap;
|
||||
use http::HeaderName;
|
||||
use http::HeaderValue;
|
||||
use http::StatusCode;
|
||||
use http::header::ACCEPT;
|
||||
use http::header::AUTHORIZATION;
|
||||
use http::header::CONTENT_TYPE;
|
||||
use http::header::WWW_AUTHENTICATE;
|
||||
use rmcp::model::ClientJsonRpcMessage;
|
||||
use rmcp::model::ClientNotification;
|
||||
use rmcp::model::ConstString;
|
||||
@@ -102,7 +104,7 @@ impl StreamableHttpClient for StreamableHttpClientAdapter {
|
||||
message: ClientJsonRpcMessage,
|
||||
session_id: Option<Arc<str>>,
|
||||
auth_token: Option<String>,
|
||||
custom_headers: HashMap<HeaderName, reqwest::header::HeaderValue>,
|
||||
custom_headers: HashMap<HeaderName, HeaderValue>,
|
||||
) -> std::result::Result<StreamableHttpPostResponse, StreamableHttpError<Self::Error>> {
|
||||
let (mcp_method, mcp_request_id) = client_jsonrpc_message_fields(&message);
|
||||
let has_session_id = session_id.is_some();
|
||||
@@ -187,8 +189,7 @@ impl StreamableHttpClient for StreamableHttpClientAdapter {
|
||||
));
|
||||
}
|
||||
if response.status == StatusCode::UNAUTHORIZED.as_u16()
|
||||
&& let Some(header) =
|
||||
response_header(&response.headers, reqwest::header::WWW_AUTHENTICATE)
|
||||
&& let Some(header) = response_header(&response.headers, WWW_AUTHENTICATE)
|
||||
{
|
||||
return Err(StreamableHttpError::AuthRequired(AuthRequiredError::new(
|
||||
header,
|
||||
@@ -324,7 +325,7 @@ impl StreamableHttpClient for StreamableHttpClientAdapter {
|
||||
uri: Arc<str>,
|
||||
session: Arc<str>,
|
||||
auth_token: Option<String>,
|
||||
custom_headers: HashMap<HeaderName, reqwest::header::HeaderValue>,
|
||||
custom_headers: HashMap<HeaderName, HeaderValue>,
|
||||
) -> std::result::Result<(), StreamableHttpError<Self::Error>> {
|
||||
let mut headers = self.default_headers.clone();
|
||||
headers.extend(custom_headers);
|
||||
@@ -378,7 +379,7 @@ impl StreamableHttpClient for StreamableHttpClientAdapter {
|
||||
session_id: Option<Arc<str>>,
|
||||
last_event_id: Option<String>,
|
||||
auth_token: Option<String>,
|
||||
custom_headers: HashMap<HeaderName, reqwest::header::HeaderValue>,
|
||||
custom_headers: HashMap<HeaderName, HeaderValue>,
|
||||
) -> std::result::Result<
|
||||
BoxStream<'static, std::result::Result<Sse, sse_stream::Error>>,
|
||||
StreamableHttpError<Self::Error>,
|
||||
@@ -535,19 +536,19 @@ fn log_post_message_http_error(
|
||||
has_session_id: bool,
|
||||
has_authorization_header: bool,
|
||||
) {
|
||||
let parsed_url = reqwest::Url::parse(uri).ok();
|
||||
let parsed_url = url::Url::parse(uri).ok();
|
||||
tracing::warn!(
|
||||
endpoint_scheme = parsed_url
|
||||
.as_ref()
|
||||
.map(reqwest::Url::scheme)
|
||||
.map(url::Url::scheme)
|
||||
.unwrap_or("<invalid>"),
|
||||
endpoint_host = parsed_url
|
||||
.as_ref()
|
||||
.and_then(reqwest::Url::host_str)
|
||||
.and_then(url::Url::host_str)
|
||||
.unwrap_or("<invalid>"),
|
||||
endpoint_path = parsed_url
|
||||
.as_ref()
|
||||
.map(reqwest::Url::path)
|
||||
.map(url::Url::path)
|
||||
.unwrap_or("<invalid>"),
|
||||
endpoint_has_query = parsed_url.as_ref().is_some_and(|url| url.query().is_some()),
|
||||
mcp_method = mcp_method.unwrap_or("<none>"),
|
||||
@@ -567,7 +568,7 @@ fn insert_header<Error>(
|
||||
where
|
||||
Error: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
let value = reqwest::header::HeaderValue::from_str(&value)
|
||||
let value = HeaderValue::from_str(&value)
|
||||
.map_err(|error| StreamableHttpError::Client(map_error(error.to_string())))?;
|
||||
headers.insert(name, value);
|
||||
Ok(())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use codex_exec_server::HttpHeader;
|
||||
use reqwest::header::WWW_AUTHENTICATE;
|
||||
use http::header::WWW_AUTHENTICATE;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub(super) struct InsufficientScopeChallenge {
|
||||
|
||||
@@ -22,10 +22,7 @@ pub use auth_status::OAuthDiscoveryTimeout;
|
||||
pub use auth_status::StreamableHttpOAuthDiscovery;
|
||||
pub use auth_status::determine_streamable_http_auth_status;
|
||||
pub use auth_status::determine_streamable_http_auth_status_from_credentials;
|
||||
pub use auth_status::determine_streamable_http_auth_status_with_http_client;
|
||||
pub use auth_status::discover_streamable_http_oauth;
|
||||
pub use auth_status::discover_streamable_http_oauth_with_http_client;
|
||||
pub use auth_status::supports_oauth_login;
|
||||
pub use codex_protocol::protocol::McpAuthStatus;
|
||||
pub use in_process_transport::InProcessTransportFactory;
|
||||
pub use oauth::StoredOAuthTokens;
|
||||
@@ -37,7 +34,6 @@ pub use perform_oauth_login::OAuthProviderError;
|
||||
pub use perform_oauth_login::OauthLoginHandle;
|
||||
pub use perform_oauth_login::perform_oauth_login;
|
||||
pub use perform_oauth_login::perform_oauth_login_return_url;
|
||||
pub use perform_oauth_login::perform_oauth_login_return_url_with_http_client;
|
||||
pub use perform_oauth_login::perform_oauth_login_silent;
|
||||
pub use protocol_mode::McpProtocolMode;
|
||||
pub use rmcp::model::ElicitationAction;
|
||||
|
||||
@@ -6,6 +6,10 @@ use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use codex_config::types::AuthKeyringBackendKind;
|
||||
use codex_config::types::OAuthCredentialsStoreMode;
|
||||
use codex_exec_server::RouteAwareHttpClient;
|
||||
use codex_http_client::HttpClientFactory;
|
||||
use codex_http_client::OutboundProxyPolicy;
|
||||
use http::HeaderMap;
|
||||
use keyring::Error as KeyringError;
|
||||
use oauth2::AccessToken;
|
||||
use oauth2::TokenResponse;
|
||||
@@ -41,6 +45,7 @@ use crate::oauth::load_oauth_tokens_from_file;
|
||||
use crate::oauth::refresh_lock::RefreshCredentialLock;
|
||||
use crate::oauth::save_oauth_tokens_to_file;
|
||||
use crate::oauth::stored_oauth_credentials;
|
||||
use crate::oauth_http_client::OAuthHttpClientAdapter;
|
||||
use crate::startup_error::is_authentication_required_error;
|
||||
|
||||
const REFRESH_LOCK_CONTENTION_EVENT_TARGET: &str =
|
||||
@@ -397,7 +402,14 @@ async fn test_context() -> Result<(TempCodexHome, MockServer, StoredOAuthTokens)
|
||||
async fn authorization_manager_for(
|
||||
tokens: &StoredOAuthTokens,
|
||||
) -> Result<Arc<TokioMutex<AuthorizationManager>>> {
|
||||
let mut state = OAuthState::new(tokens.url.clone(), Some(reqwest::Client::new())).await?;
|
||||
let oauth_http_client = Arc::new(OAuthHttpClientAdapter::new(
|
||||
Arc::new(RouteAwareHttpClient::new(HttpClientFactory::new(
|
||||
OutboundProxyPolicy::ReqwestDefault,
|
||||
))),
|
||||
HeaderMap::new(),
|
||||
));
|
||||
let mut state =
|
||||
OAuthState::new_with_oauth_http_client(tokens.url.clone(), oauth_http_client).await?;
|
||||
state
|
||||
.set_credentials(&tokens.client_id, tokens.token_response.0.clone())
|
||||
.await?;
|
||||
|
||||
@@ -7,11 +7,9 @@ use codex_exec_server::HttpClient;
|
||||
use codex_exec_server::HttpHeader;
|
||||
use codex_exec_server::HttpRedirectPolicy;
|
||||
use codex_exec_server::HttpRequestParams;
|
||||
use futures::StreamExt;
|
||||
use http::HeaderMap;
|
||||
use oauth2::HttpRequest;
|
||||
use oauth2::HttpResponse;
|
||||
use reqwest::Client;
|
||||
use reqwest::header::HeaderMap;
|
||||
use rmcp::transport::auth::OAuthHttpClient;
|
||||
use rmcp::transport::auth::OAuthHttpClientError;
|
||||
use rmcp::transport::auth::OAuthHttpClientFuture;
|
||||
@@ -28,7 +26,6 @@ pub(crate) struct OAuthHttpClientAdapter {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
default_headers: HeaderMap,
|
||||
timeout: OAuthDiscoveryTimeout,
|
||||
local_http_client: Option<Client>,
|
||||
}
|
||||
|
||||
impl OAuthHttpClientAdapter {
|
||||
@@ -37,7 +34,6 @@ impl OAuthHttpClientAdapter {
|
||||
http_client,
|
||||
default_headers,
|
||||
timeout: OAuthDiscoveryTimeout::Requested,
|
||||
local_http_client: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,16 +46,10 @@ impl OAuthHttpClientAdapter {
|
||||
http_client,
|
||||
default_headers,
|
||||
timeout: OAuthDiscoveryTimeout::Capped(max_timeout),
|
||||
local_http_client: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn with_local_http_client(mut self, client: Client) -> Self {
|
||||
self.local_http_client = Some(client);
|
||||
self
|
||||
}
|
||||
|
||||
async fn execute_transport_request(
|
||||
async fn execute_request(
|
||||
&self,
|
||||
request: HttpRequest,
|
||||
redirect_policy: OAuthHttpRedirectPolicy,
|
||||
@@ -74,44 +64,13 @@ impl OAuthHttpClientAdapter {
|
||||
));
|
||||
}
|
||||
};
|
||||
let (mut parts, body) = request.into_parts();
|
||||
let (parts, body) = request.into_parts();
|
||||
let mut headers = self.default_headers.clone();
|
||||
for name in parts.headers.keys() {
|
||||
headers.remove(name);
|
||||
}
|
||||
headers.extend(parts.headers);
|
||||
|
||||
if let Some(client) = &self.local_http_client {
|
||||
parts.headers = headers;
|
||||
let request = HttpRequest::from_parts(parts, body);
|
||||
let request = reqwest::Request::try_from(request)
|
||||
.map_err(|error| OAuthHttpClientError::new(error.to_string()))?;
|
||||
let response = client
|
||||
.execute(request)
|
||||
.await
|
||||
.map_err(|error| OAuthHttpClientError::new(error.to_string()))?;
|
||||
let mut builder = oauth2::http::Response::builder()
|
||||
.status(response.status())
|
||||
.version(response.version());
|
||||
for (name, value) in response.headers() {
|
||||
builder = builder.header(name, value);
|
||||
}
|
||||
let mut body = Vec::new();
|
||||
let mut body_stream = response.bytes_stream();
|
||||
while let Some(chunk) = body_stream.next().await {
|
||||
let chunk = chunk.map_err(|error| OAuthHttpClientError::new(error.to_string()))?;
|
||||
if chunk.len() > MAX_OAUTH_HTTP_RESPONSE_BODY_BYTES - body.len() {
|
||||
return Err(OAuthHttpClientError::new(format!(
|
||||
"OAuth HTTP response body exceeds {MAX_OAUTH_HTTP_RESPONSE_BODY_BYTES} bytes"
|
||||
)));
|
||||
}
|
||||
body.extend_from_slice(&chunk);
|
||||
}
|
||||
return builder
|
||||
.body(body)
|
||||
.map_err(|error| OAuthHttpClientError::new(error.to_string()));
|
||||
}
|
||||
|
||||
let headers = headers
|
||||
.iter()
|
||||
.map(|(name, value)| {
|
||||
@@ -175,10 +134,6 @@ impl OAuthHttpClientAdapter {
|
||||
|
||||
impl OAuthHttpClient for OAuthHttpClientAdapter {
|
||||
fn execute(&self, request: OAuthHttpRequest) -> OAuthHttpClientFuture<'_> {
|
||||
Box::pin(self.execute_transport_request(
|
||||
request.request,
|
||||
request.redirect_policy,
|
||||
request.timeout,
|
||||
))
|
||||
Box::pin(self.execute_request(request.request, request.redirect_policy, request.timeout))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,6 @@ use anyhow::bail;
|
||||
use base64::Engine;
|
||||
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
|
||||
use codex_exec_server::HttpClient;
|
||||
use codex_exec_server::RouteAwareHttpClient;
|
||||
use codex_http_client::HttpClientFactory;
|
||||
use codex_http_client::OutboundProxyPolicy;
|
||||
use reqwest::Url;
|
||||
use rmcp::transport::AuthorizationManager;
|
||||
use rmcp::transport::AuthorizationRequest;
|
||||
use rmcp::transport::AuthorizationSession;
|
||||
@@ -26,6 +22,7 @@ use tiny_http::Response;
|
||||
use tiny_http::Server;
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::time::timeout;
|
||||
use url::Url;
|
||||
use urlencoding::decode;
|
||||
|
||||
use crate::StoredOAuthTokens;
|
||||
@@ -203,41 +200,6 @@ pub async fn perform_oauth_login_return_url(
|
||||
timeout_secs: Option<i64>,
|
||||
callback_port: Option<u16>,
|
||||
callback_url: Option<&str>,
|
||||
) -> Result<OauthLoginHandle> {
|
||||
perform_oauth_login_return_url_with_http_client(
|
||||
server_name,
|
||||
server_url,
|
||||
store_mode,
|
||||
keyring_backend_kind,
|
||||
http_headers,
|
||||
env_http_headers,
|
||||
scopes,
|
||||
oauth_client_id,
|
||||
oauth_resource,
|
||||
timeout_secs,
|
||||
callback_port,
|
||||
callback_url,
|
||||
Arc::new(RouteAwareHttpClient::new(HttpClientFactory::new(
|
||||
OutboundProxyPolicy::ReqwestDefault,
|
||||
))),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn perform_oauth_login_return_url_with_http_client(
|
||||
server_name: &str,
|
||||
server_url: &str,
|
||||
store_mode: OAuthCredentialsStoreMode,
|
||||
keyring_backend_kind: AuthKeyringBackendKind,
|
||||
http_headers: Option<HashMap<String, String>>,
|
||||
env_http_headers: Option<HashMap<String, String>>,
|
||||
scopes: &[String],
|
||||
oauth_client_id: Option<&str>,
|
||||
oauth_resource: Option<&str>,
|
||||
timeout_secs: Option<i64>,
|
||||
callback_port: Option<u16>,
|
||||
callback_url: Option<&str>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
) -> Result<OauthLoginHandle> {
|
||||
let http_context = OAuthHttpContext {
|
||||
@@ -757,11 +719,11 @@ mod tests {
|
||||
use codex_http_client::HttpClientFactory;
|
||||
use codex_http_client::OutboundProxyPolicy;
|
||||
use futures::future::BoxFuture;
|
||||
use http::HeaderMap;
|
||||
use pretty_assertions::assert_eq;
|
||||
use reqwest::Url;
|
||||
use reqwest::header::HeaderMap;
|
||||
use serde_json::json;
|
||||
use tokio::net::TcpListener;
|
||||
use url::Url;
|
||||
|
||||
use super::CallbackOutcome;
|
||||
use super::OAuthHttpClientAdapter;
|
||||
|
||||
@@ -19,9 +19,9 @@ use codex_exec_server::HttpClient;
|
||||
use codex_keyring_store::DefaultKeyringStore;
|
||||
use futures::FutureExt;
|
||||
use futures::future::BoxFuture;
|
||||
use http::HeaderMap;
|
||||
use http::header::AUTHORIZATION;
|
||||
use oauth2::TokenResponse;
|
||||
use reqwest::header::AUTHORIZATION;
|
||||
use reqwest::header::HeaderMap;
|
||||
use rmcp::model::CallToolRequestParams;
|
||||
use rmcp::model::CallToolResult;
|
||||
use rmcp::model::ClientNotification;
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::time::Instant;
|
||||
use anyhow::Result;
|
||||
use anyhow::anyhow;
|
||||
use codex_exec_server::ExecServerError;
|
||||
use reqwest::StatusCode;
|
||||
use http::StatusCode;
|
||||
use rmcp::service::RoleClient;
|
||||
use rmcp::service::RunningService;
|
||||
use rmcp::transport::streamable_http_client::StreamableHttpError;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use anyhow::Result;
|
||||
use anyhow::anyhow;
|
||||
use codex_config::types::McpServerEnvVar;
|
||||
use reqwest::header::HeaderMap;
|
||||
use reqwest::header::HeaderName;
|
||||
use reqwest::header::HeaderValue;
|
||||
use reqwest::header::USER_AGENT;
|
||||
use http::HeaderMap;
|
||||
use http::HeaderName;
|
||||
use http::HeaderValue;
|
||||
use http::header::USER_AGENT;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
|
||||
@@ -7,7 +7,6 @@ use codex_http_client::OutboundProxyPolicy;
|
||||
use codex_rmcp_client::OAuthDiscoveryTimeout;
|
||||
use codex_rmcp_client::StreamableHttpOAuthDiscovery;
|
||||
use codex_rmcp_client::discover_streamable_http_oauth;
|
||||
use codex_rmcp_client::discover_streamable_http_oauth_with_http_client;
|
||||
use pretty_assertions::assert_eq;
|
||||
use rmcp::transport::auth::AuthError;
|
||||
use serde_json::json;
|
||||
@@ -105,9 +104,13 @@ async fn discover_legacy_oauth_without_starting_an_mcp_session(
|
||||
&resource_url,
|
||||
resource_headers(),
|
||||
/*env_http_headers*/ None,
|
||||
Arc::new(RouteAwareHttpClient::new(HttpClientFactory::new(
|
||||
OutboundProxyPolicy::ReqwestDefault,
|
||||
))),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await;
|
||||
let routed_discovery = discover_streamable_http_oauth_with_http_client(
|
||||
let routed_discovery = discover_streamable_http_oauth(
|
||||
&resource_url,
|
||||
resource_headers(),
|
||||
/*env_http_headers*/ None,
|
||||
@@ -186,7 +189,7 @@ async fn oauth_discovery_does_not_invent_support_for_an_unauthenticated_legacy_s
|
||||
let resource_server = MockServer::start().await;
|
||||
|
||||
let server_url = format!("{}/mcp", resource_server.uri());
|
||||
let executor_discovery = discover_streamable_http_oauth_with_http_client(
|
||||
let executor_discovery = discover_streamable_http_oauth(
|
||||
&server_url,
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
@@ -200,6 +203,10 @@ async fn oauth_discovery_does_not_invent_support_for_an_unauthenticated_legacy_s
|
||||
&server_url,
|
||||
/*http_headers*/ None,
|
||||
/*env_http_headers*/ None,
|
||||
Arc::new(RouteAwareHttpClient::new(HttpClientFactory::new(
|
||||
OutboundProxyPolicy::ReqwestDefault,
|
||||
))),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ use codex_config::types::OAuthCredentialsStoreMode;
|
||||
use codex_exec_server::Environment;
|
||||
use codex_rmcp_client::McpAuthState;
|
||||
use codex_rmcp_client::McpLoginRequirement;
|
||||
use codex_rmcp_client::OAuthDiscoveryTimeout;
|
||||
use codex_rmcp_client::RmcpClient;
|
||||
use codex_rmcp_client::StoredOAuthTokens;
|
||||
use codex_rmcp_client::WrappedOAuthTokenResponse;
|
||||
@@ -294,6 +295,8 @@ async fn auth_status(server_url: &str) -> anyhow::Result<McpAuthState> {
|
||||
/*env_http_headers*/ None,
|
||||
OAuthCredentialsStoreMode::File,
|
||||
AuthKeyringBackendKind::default(),
|
||||
Environment::default_for_tests().get_http_client(),
|
||||
OAuthDiscoveryTimeout::LOCAL,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -177,13 +177,17 @@ pub(crate) async fn call_echo_tool(
|
||||
.await
|
||||
}
|
||||
|
||||
fn control_client() -> anyhow::Result<codex_http_client::HttpClient> {
|
||||
Ok(codex_http_client::HttpClientBuilder::new().build_direct()?)
|
||||
}
|
||||
|
||||
pub(crate) async fn arm_session_post_failure(
|
||||
base_url: &str,
|
||||
status: u16,
|
||||
remaining: usize,
|
||||
www_authenticate_headers: &[&str],
|
||||
) -> anyhow::Result<()> {
|
||||
let response = reqwest::Client::new()
|
||||
let response = control_client()?
|
||||
.post(format!("{base_url}{SESSION_POST_FAILURE_CONTROL_PATH}"))
|
||||
.json(&json!({
|
||||
"status": status,
|
||||
@@ -193,7 +197,7 @@ pub(crate) async fn arm_session_post_failure(
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert_eq!(response.status(), reqwest::StatusCode::NO_CONTENT);
|
||||
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -202,7 +206,7 @@ pub(crate) async fn arm_session_post_json_rpc_failure(
|
||||
status: u16,
|
||||
remaining: usize,
|
||||
) -> anyhow::Result<()> {
|
||||
let response = reqwest::Client::new()
|
||||
let response = control_client()?
|
||||
.post(format!("{base_url}{SESSION_POST_FAILURE_CONTROL_PATH}"))
|
||||
.json(&json!({
|
||||
"status": status,
|
||||
@@ -220,7 +224,7 @@ pub(crate) async fn arm_session_post_json_rpc_failure(
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert_eq!(response.status(), reqwest::StatusCode::NO_CONTENT);
|
||||
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -229,7 +233,7 @@ pub(crate) async fn arm_initialized_notification_post_json_rpc_failure(
|
||||
status: u16,
|
||||
remaining: usize,
|
||||
) -> anyhow::Result<()> {
|
||||
let response = reqwest::Client::new()
|
||||
let response = control_client()?
|
||||
.post(format!(
|
||||
"{base_url}{INITIALIZED_NOTIFICATION_POST_FAILURE_CONTROL_PATH}"
|
||||
))
|
||||
@@ -249,7 +253,7 @@ pub(crate) async fn arm_initialized_notification_post_json_rpc_failure(
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert_eq!(response.status(), reqwest::StatusCode::NO_CONTENT);
|
||||
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -258,7 +262,7 @@ pub(crate) async fn arm_initialize_post_failure(
|
||||
status: u16,
|
||||
remaining: usize,
|
||||
) -> anyhow::Result<()> {
|
||||
let response = reqwest::Client::new()
|
||||
let response = control_client()?
|
||||
.post(format!("{base_url}{INITIALIZE_POST_FAILURE_CONTROL_PATH}"))
|
||||
.json(&json!({
|
||||
"status": status,
|
||||
@@ -267,7 +271,7 @@ pub(crate) async fn arm_initialize_post_failure(
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert_eq!(response.status(), reqwest::StatusCode::NO_CONTENT);
|
||||
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -276,7 +280,7 @@ pub(crate) async fn arm_initialize_post_json_rpc_failure(
|
||||
status: u16,
|
||||
remaining: usize,
|
||||
) -> anyhow::Result<()> {
|
||||
let response = reqwest::Client::new()
|
||||
let response = control_client()?
|
||||
.post(format!("{base_url}{INITIALIZE_POST_FAILURE_CONTROL_PATH}"))
|
||||
.json(&json!({
|
||||
"status": status,
|
||||
@@ -294,7 +298,7 @@ pub(crate) async fn arm_initialize_post_json_rpc_failure(
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
assert_eq!(response.status(), reqwest::StatusCode::NO_CONTENT);
|
||||
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user