diff --git a/crates/extension/src/wasm_host/wit/since_v0_1_0.rs b/crates/extension/src/wasm_host/wit/since_v0_1_0.rs index 53024bb4c1..694e2f227d 100644 --- a/crates/extension/src/wasm_host/wit/since_v0_1_0.rs +++ b/crates/extension/src/wasm_host/wit/since_v0_1_0.rs @@ -136,7 +136,7 @@ impl http_client::Host for WasmState { ) -> wasmtime::Result> { maybe!(async { let url = &request.url; - let request = convert_request(&request, true)?; + let request = convert_request(&request)?; let mut response = self.host.http_client.send(request).await?; if response.status().is_client_error() || response.status().is_server_error() { @@ -152,7 +152,7 @@ impl http_client::Host for WasmState { &mut self, request: http_client::HttpRequest, ) -> wasmtime::Result, String>> { - let request = convert_request(&request, true)?; + let request = convert_request(&request)?; let response = self.host.http_client.send(request); maybe!(async { let response = response.await?; @@ -208,15 +208,14 @@ impl From for ::http_client::Method { fn convert_request( extension_request: &http_client::HttpRequest, - follow_redirects: bool, ) -> Result<::http_client::Request, anyhow::Error> { let mut request = ::http_client::Request::builder() .method(::http_client::Method::from(extension_request.method)) .uri(&extension_request.url) - .redirect_policy(if follow_redirects { - RedirectPolicy::Follow - } else { - RedirectPolicy::None + .redirect_policy(match extension_request.redirect_policy { + http_client::RedirectPolicy::NoFollow => RedirectPolicy::None, + http_client::RedirectPolicy::FollowLimit(limit) => RedirectPolicy::Limit(limit), + http_client::RedirectPolicy::FollowAll => RedirectPolicy::Follow, }); for (key, value) in &extension_request.headers { request = request.header(key, value); diff --git a/crates/extension_api/src/extension_api.rs b/crates/extension_api/src/extension_api.rs index 09a24486ac..4bc5889122 100644 --- a/crates/extension_api/src/extension_api.rs +++ b/crates/extension_api/src/extension_api.rs @@ -21,6 +21,7 @@ pub use wit::{ }, zed::extension::http_client::{ fetch, fetch_stream, HttpMethod, HttpRequest, HttpResponse, HttpResponseStream, + RedirectPolicy, }, zed::extension::nodejs::{ node_binary_path, npm_install_package, npm_package_installed_version, diff --git a/crates/extension_api/wit/since_v0.1.0/http-client.wit b/crates/extension_api/wit/since_v0.1.0/http-client.wit index a2a847c72d..bb0206c17a 100644 --- a/crates/extension_api/wit/since_v0.1.0/http-client.wit +++ b/crates/extension_api/wit/since_v0.1.0/http-client.wit @@ -5,23 +5,44 @@ interface http-client { method: http-method, /// The URL to which the request should be made. url: string, - /// Headers for the request. + /// The headers for the request. headers: list>, /// The request body. body: option>, + /// The policy to use for redirects. + redirect-policy: redirect-policy, } /// HTTP methods. enum http-method { + /// `GET` get, - post, - put, - delete, + /// `HEAD` head, + /// `POST` + post, + /// `PUT` + put, + /// `DELETE` + delete, + /// `OPTIONS` options, + /// `PATCH` patch, } + /// The policy for dealing with redirects received from the server. + variant redirect-policy { + /// Redirects from the server will not be followed. + /// + /// This is the default behavior. + no-follow, + /// Redirects from the server will be followed up to the specified limit. + follow-limit(u32), + /// All redirects from the server will be followed. + follow-all, + } + /// An HTTP response. record http-response { /// The response headers. @@ -36,7 +57,8 @@ interface http-client { /// An HTTP response stream. resource http-response-stream { /// Retrieves the next chunk of data from the response stream. - /// Returns None if the stream has ended. + /// + /// Returns `Ok(None)` if the stream has ended. next-chunk: func() -> result>, string>; } diff --git a/extensions/gleam/src/gleam.rs b/extensions/gleam/src/gleam.rs index a95231e15d..975ce4e8e1 100644 --- a/extensions/gleam/src/gleam.rs +++ b/extensions/gleam/src/gleam.rs @@ -4,7 +4,8 @@ use std::{fs, io}; use zed::lsp::CompletionKind; use zed::{ CodeLabel, CodeLabelSpan, HttpMethod, HttpRequest, KeyValueStore, LanguageServerId, - SlashCommand, SlashCommandArgumentCompletion, SlashCommandOutput, SlashCommandOutputSection, + RedirectPolicy, SlashCommand, SlashCommandArgumentCompletion, SlashCommandOutput, + SlashCommandOutputSection, }; use zed_extension_api::{self as zed, Result}; @@ -208,6 +209,7 @@ impl zed::Extension for GleamExtension { "Zed (Gleam Extension)".to_string(), )], body: None, + redirect_policy: RedirectPolicy::FollowAll, })?; let (markdown, _modules) = diff --git a/extensions/gleam/src/hexdocs.rs b/extensions/gleam/src/hexdocs.rs index 07be1424da..8310899f03 100644 --- a/extensions/gleam/src/hexdocs.rs +++ b/extensions/gleam/src/hexdocs.rs @@ -10,7 +10,9 @@ use html_to_markdown::{ convert_html_to_markdown, HandleTag, HandlerOutcome, HtmlElement, MarkdownWriter, StartTagOutcome, TagHandler, }; -use zed_extension_api::{self as zed, HttpMethod, HttpRequest, KeyValueStore, Result}; +use zed_extension_api::{ + self as zed, HttpMethod, HttpRequest, KeyValueStore, RedirectPolicy, Result, +}; pub fn index(package: String, database: &KeyValueStore) -> Result<()> { let headers = vec![( @@ -23,6 +25,7 @@ pub fn index(package: String, database: &KeyValueStore) -> Result<()> { url: format!("https://hexdocs.pm/{package}"), headers: headers.clone(), body: None, + redirect_policy: RedirectPolicy::FollowAll, })?; let (package_root_markdown, modules) = @@ -36,6 +39,7 @@ pub fn index(package: String, database: &KeyValueStore) -> Result<()> { url: format!("https://hexdocs.pm/{package}/{module}.html"), headers: headers.clone(), body: None, + redirect_policy: RedirectPolicy::FollowAll, })?; let (markdown, _modules) =