mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
feat(unstable): support in memory certificate data for Deno.createHttpClient (#8739)
This commit is contained in:
parent
4ab1aa8877
commit
afbd19ed9b
3 changed files with 57 additions and 4 deletions
4
cli/dts/lib.deno.unstable.d.ts
vendored
4
cli/dts/lib.deno.unstable.d.ts
vendored
|
@ -1266,6 +1266,10 @@ declare namespace Deno {
|
||||||
* Requires `allow-read` permission.
|
* Requires `allow-read` permission.
|
||||||
*/
|
*/
|
||||||
caFile?: string;
|
caFile?: string;
|
||||||
|
|
||||||
|
/** A certificate authority to use when validating TLS certificates. Certificate data must be PEM encoded.
|
||||||
|
*/
|
||||||
|
caData?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** **UNSTABLE**: New API, yet to be vetted.
|
/** **UNSTABLE**: New API, yet to be vetted.
|
||||||
|
|
|
@ -959,7 +959,7 @@ unitTest(function fetchResponseEmptyConstructor(): void {
|
||||||
|
|
||||||
unitTest(
|
unitTest(
|
||||||
{ perms: { net: true, read: true } },
|
{ perms: { net: true, read: true } },
|
||||||
async function fetchCustomHttpClientSuccess(): Promise<
|
async function fetchCustomHttpClientFileCertificateSuccess(): Promise<
|
||||||
void
|
void
|
||||||
> {
|
> {
|
||||||
const client = Deno.createHttpClient(
|
const client = Deno.createHttpClient(
|
||||||
|
@ -974,3 +974,42 @@ unitTest(
|
||||||
client.close();
|
client.close();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
unitTest(
|
||||||
|
{ perms: { net: true } },
|
||||||
|
async function fetchCustomHttpClientParamCertificateSuccess(): Promise<
|
||||||
|
void
|
||||||
|
> {
|
||||||
|
const client = Deno.createHttpClient(
|
||||||
|
{
|
||||||
|
caData: `-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDIzCCAgugAwIBAgIJAMKPPW4tsOymMA0GCSqGSIb3DQEBCwUAMCcxCzAJBgNV
|
||||||
|
BAYTAlVTMRgwFgYDVQQDDA9FeGFtcGxlLVJvb3QtQ0EwIBcNMTkxMDIxMTYyODIy
|
||||||
|
WhgPMjExODA5MjcxNjI4MjJaMCcxCzAJBgNVBAYTAlVTMRgwFgYDVQQDDA9FeGFt
|
||||||
|
cGxlLVJvb3QtQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMH/IO
|
||||||
|
2qtHfyBKwANNPB4K0q5JVSg8XxZdRpTTlz0CwU0oRO3uHrI52raCCfVeiQutyZop
|
||||||
|
eFZTDWeXGudGAFA2B5m3orWt0s+touPi8MzjsG2TQ+WSI66QgbXTNDitDDBtTVcV
|
||||||
|
5G3Ic+3SppQAYiHSekLISnYWgXLl+k5CnEfTowg6cjqjVr0KjL03cTN3H7b+6+0S
|
||||||
|
ws4rYbW1j4ExR7K6BFNH6572yq5qR20E6GqlY+EcOZpw4CbCk9lS8/CWuXze/vMs
|
||||||
|
OfDcc6K+B625d27wyEGZHedBomT2vAD7sBjvO8hn/DP1Qb46a8uCHR6NSfnJ7bXO
|
||||||
|
G1igaIbgY1zXirNdAgMBAAGjUDBOMB0GA1UdDgQWBBTzut+pwwDfqmMYcI9KNWRD
|
||||||
|
hxcIpTAfBgNVHSMEGDAWgBTzut+pwwDfqmMYcI9KNWRDhxcIpTAMBgNVHRMEBTAD
|
||||||
|
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB9AqSbZ+hEglAgSHxAMCqRFdhVu7MvaQM0
|
||||||
|
P090mhGlOCt3yB7kdGfsIrUW6nQcTz7PPQFRaJMrFHPvFvPootkBUpTYR4hTkdce
|
||||||
|
H6RCRu2Jxl4Y9bY/uezd9YhGCYfUtfjA6/TH9FcuZfttmOOlxOt01XfNvVMIR6RM
|
||||||
|
z/AYhd+DeOXjr35F/VHeVpnk+55L0PYJsm1CdEbOs5Hy1ecR7ACuDkXnbM4fpz9I
|
||||||
|
kyIWJwk2zJReKcJMgi1aIinDM9ao/dca1G99PHOw8dnr4oyoTiv8ao6PWiSRHHMi
|
||||||
|
MNf4EgWfK+tZMnuqfpfO9740KzfcVoMNo4QJD4yn5YxroUOO/Azi
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const response = await fetch(
|
||||||
|
"https://localhost:5545/cli/tests/fixture.json",
|
||||||
|
{ client },
|
||||||
|
);
|
||||||
|
const json = await response.json();
|
||||||
|
assertEquals(json.name, "deno");
|
||||||
|
client.close();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
@ -260,6 +260,7 @@ where
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
struct CreateHttpClientOptions {
|
struct CreateHttpClientOptions {
|
||||||
ca_file: Option<String>,
|
ca_file: Option<String>,
|
||||||
|
ca_data: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let args: CreateHttpClientOptions = serde_json::from_value(args)?;
|
let args: CreateHttpClientOptions = serde_json::from_value(args)?;
|
||||||
|
@ -269,7 +270,9 @@ where
|
||||||
permissions.check_read(&PathBuf::from(ca_file))?;
|
permissions.check_read(&PathBuf::from(ca_file))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = create_http_client(args.ca_file.as_deref()).unwrap();
|
let client =
|
||||||
|
create_http_client(args.ca_file.as_deref(), args.ca_data.as_deref())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let rid = state.resource_table.add(HttpClientResource::new(client));
|
let rid = state.resource_table.add(HttpClientResource::new(client));
|
||||||
Ok(json!(rid))
|
Ok(json!(rid))
|
||||||
|
@ -277,9 +280,16 @@ where
|
||||||
|
|
||||||
/// Create new instance of async reqwest::Client. This client supports
|
/// Create new instance of async reqwest::Client. This client supports
|
||||||
/// proxies and doesn't follow redirects.
|
/// proxies and doesn't follow redirects.
|
||||||
fn create_http_client(ca_file: Option<&str>) -> Result<Client, AnyError> {
|
fn create_http_client(
|
||||||
|
ca_file: Option<&str>,
|
||||||
|
ca_data: Option<&str>,
|
||||||
|
) -> Result<Client, AnyError> {
|
||||||
let mut builder = Client::builder().redirect(Policy::none()).use_rustls_tls();
|
let mut builder = Client::builder().redirect(Policy::none()).use_rustls_tls();
|
||||||
if let Some(ca_file) = ca_file {
|
if let Some(ca_data) = ca_data {
|
||||||
|
let ca_data_vec = ca_data.as_bytes().to_vec();
|
||||||
|
let cert = reqwest::Certificate::from_pem(&ca_data_vec)?;
|
||||||
|
builder = builder.add_root_certificate(cert);
|
||||||
|
} else if let Some(ca_file) = ca_file {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
File::open(ca_file)?.read_to_end(&mut buf)?;
|
File::open(ca_file)?.read_to_end(&mut buf)?;
|
||||||
let cert = reqwest::Certificate::from_pem(&buf)?;
|
let cert = reqwest::Certificate::from_pem(&buf)?;
|
||||||
|
|
Loading…
Reference in a new issue