diff --git a/Cargo.lock b/Cargo.lock index 8a1f8c161c..c5c7262cbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3579,6 +3579,7 @@ dependencies = [ "fs", "futures 0.3.28", "gpui", + "isahc", "language", "log", "lsp", diff --git a/crates/extension/Cargo.toml b/crates/extension/Cargo.toml index df02174e1e..7d6713729a 100644 --- a/crates/extension/Cargo.toml +++ b/crates/extension/Cargo.toml @@ -23,6 +23,7 @@ collections.workspace = true fs.workspace = true futures.workspace = true gpui.workspace = true +isahc.workspace = true language.workspace = true log.workspace = true lsp.workspace = true diff --git a/crates/extension/src/extension_store.rs b/crates/extension/src/extension_store.rs index 4a087b8402..dcac1d1825 100644 --- a/crates/extension/src/extension_store.rs +++ b/crates/extension/src/extension_store.rs @@ -606,7 +606,23 @@ impl ExtensionStore { ) .await?; - let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut())); + let content_length = response + .headers() + .get(isahc::http::header::CONTENT_LENGTH) + .and_then(|value| value.to_str().ok()?.parse::().ok()); + + let mut body = BufReader::new(response.body_mut()); + let mut tgz_bytes = Vec::new(); + body.read_to_end(&mut tgz_bytes).await?; + + if let Some(content_length) = content_length { + let actual_len = tgz_bytes.len(); + if content_length != actual_len { + bail!("downloaded extension size {actual_len} does not match content length {content_length}"); + } + } + let decompressed_bytes = GzipDecoder::new(BufReader::new(tgz_bytes.as_slice())); + // let decompressed_bytes = GzipDecoder::new(BufReader::new(tgz_bytes)); let archive = Archive::new(decompressed_bytes); archive.unpack(extension_dir).await?; this.update(&mut cx, |this, cx| {