Add support for https uri in extensions.wasm.v3.VmConfig
#29,824 opened on Sep 26, 2023
Repository metrics
- Stars
- (27,997 stars)
- PR merge metrics
- (Avg merge 8d) (378 merged PRs in 30d)
Description
Title: Add support to fetch wasm binary from https base clusters
Description: Currently, using https urls to fetch wasm binaries, does not support https, as it will always set the wrong :scheme:http header, despite configuring an https url.
Bootstrapping wasm service:
bootstrap_extensions:
- name: envoy.bootstrap.wasm
typed_config:
"@type": type.googleapis.com/envoy.extensions.wasm.v3.WasmService
singleton: true
config:
name: wasm-plugin
root_id: wasm_root_id
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
remote:
http_uri:
uri: "https://github.com/XXX/YYY/releases/download/ZZZ/envoy-wasm-plugin.wasm"
timeout: 600s
cluster: "github-com"
sha256: "aab45ba4aab5c313b5206fa57b3843cd6a09c633eddef08371a83699c312aaf2"
Creating static cluster:
- name: "github-com"
connect_timeout: "60s"
type: STRICT_DNS
load_assignment:
cluster_name: "github-com"
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: github.com
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: github.com
This results in the following error traces:
2023-09-26T19:30:48.587732Z debug envoy config external/envoy/source/common/config/remote_data_fetcher.cc:35 fetch remote data from [uri = https://github.com/XXX/YYY/releases/download/ZZZ/envoy-wasm-plugin.wasm]: start thread=27
2023-09-26T19:30:48.587780Z debug envoy router external/envoy/source/common/router/router.cc:478 [C0][S17801876496647140807] cluster 'github-com' match for URL '/XXX/YYY/releases/download/ZZZ/envoy-wasm-plugin.wasm' thread=27
2023-09-26T19:30:48.587866Z debug envoy router external/envoy/source/common/router/router.cc:686 [C0][S17801876496647140807] router decoding headers:
':path', '/XXX/YYY/releases/download/ZZZ/envoy-wasm-plugin.wasm'
':authority', 'github.com'
':method', 'GET'
':scheme', 'http'
'x-envoy-internal', 'true'
'x-forwarded-for', '10.244.0.17'
'x-envoy-expected-rq-timeout-ms', '600000'
thread=27
...
2023-09-26T19:30:48.588508Z debug envoy router external/envoy/source/common/router/router.cc:1278 [C0][S17801876496647140807] upstream reset: reset reason: connection failure, transport failure reason: immediate connect error: Network is unreachable thread=27
2023-09-26T19:30:48.588576Z debug envoy http external/envoy/source/common/http/async_client_impl.cc:123 async http request response headers (end_stream=false):
':status', '503'
'content-length', '166'
'content-type', 'text/plain'
thread=27
As one can see, the headers are not taking into account the fact that my uri is of scheme https.
Source code:
Digging into the code, I can see the following.
void RemoteDataFetcher::fetch() {
Http::RequestMessagePtr message = Http::Utility::prepareHeaders(uri_);
message->headers().setReferenceMethod(Http::Headers::get().MethodValues.Get);
ENVOY_LOG(debug, "fetch remote data from [uri = {}]: start", uri_.uri());
const auto thread_local_cluster = cm_.getThreadLocalCluster(uri_.cluster());
if (thread_local_cluster != nullptr) {
request_ = thread_local_cluster->httpAsyncClient().send(
std::move(message), *this,
Http::AsyncClient::RequestOptions().setTimeout(
std::chrono::milliseconds(DurationUtil::durationToMilliseconds(uri_.timeout()))));
} else {
ENVOY_LOG(debug, "fetch remote data [uri = {}]: no cluster {}", uri_.uri(), uri_.cluster());
callback_.onFailure(FailureReason::Network);
}
}
RequestMessagePtr Utility::prepareHeaders(const envoy::config::core::v3::HttpUri& http_uri) {
absl::string_view host, path;
extractHostPathFromUri(http_uri.uri(), host, path);
RequestMessagePtr message(new RequestMessageImpl());
message->headers().setPath(path);
message->headers().setHost(host);
return message;
}
As you can see, they just do not take into account the scheme at all.
Also, there is no logic to deal with retries, or with 302 HTTP redirect (eg http > https) from the upstream web server containing the wasm binary.