Skip to content

Commit

Permalink
refactor(core): remove attohttpc client, closes #6415 (#6468)
Browse files Browse the repository at this point in the history
* refactor(core): remove attohttpc client, closes #6415

* lint [skip ci]
  • Loading branch information
lucasfernog authored Mar 17, 2023
1 parent 1798c59 commit dddaa94
Show file tree
Hide file tree
Showing 11 changed files with 41 additions and 288 deletions.
5 changes: 5 additions & 0 deletions .changes/remove-attohttpc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": major
---

Removed the attohttpc client. The `reqwest-*` Cargo features were also removed.
9 changes: 2 additions & 7 deletions core/tauri-runtime/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ fn get_menu_ids(map: &mut HashMap<MenuHash, MenuId>, menu: &Menu) {

/// Describes the appearance of the mouse cursor.
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CursorIcon {
/// The platform-dependent default cursor.
#[default]
Default,
/// A simple crosshair.
Crosshair,
Expand Down Expand Up @@ -203,12 +204,6 @@ impl<'de> Deserialize<'de> for CursorIcon {
}
}

impl Default for CursorIcon {
fn default() -> Self {
CursorIcon::Default
}
}

#[cfg(target_os = "android")]
pub struct CreationContext<'a> {
pub env: jni::JNIEnv<'a>,
Expand Down
17 changes: 5 additions & 12 deletions core/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ targets = [
"x86_64-apple-darwin"
]

[package.metadata.cargo-udeps.ignore]
normal = [ "attohttpc", "reqwest" ]

[dependencies]
serde_json = { version = "1.0", features = [ "raw_value" ] }
serde = { version = "1.0", features = [ "derive" ] }
Expand Down Expand Up @@ -68,9 +65,8 @@ dirs-next = "2.0"
percent-encoding = "2.2"
base64 = { version = "0.21", optional = true }
clap = { version = "3", optional = true }
reqwest = { version = "0.11", default-features = false, features = [ "json", "stream" ], optional = true }
bytes = { version = "1", features = [ "serde" ], optional = true }
attohttpc = { version = "0.24", default-features = false, features = [ "compress", "json", "form" ] }
reqwest = { version = "0.11", default-features = false, features = [ "json", "stream" ] }
bytes = { version = "1", features = [ "serde" ] }
open = { version = "3.0", optional = true }
shared_child = { version = "1.0", optional = true }
os_pipe = { version = "1.0", optional = true }
Expand Down Expand Up @@ -157,14 +153,11 @@ updater = [
"fs-extract-api"
]
http-api = [ ]
http-multipart = [ "attohttpc/multipart-form", "reqwest/multipart" ]
http-multipart = [ "reqwest/multipart" ]
shell-open-api = [ "open", "regex", "tauri-macros/shell-scope" ]
fs-extract-api = [ "zip" ]
reqwest-client = [ "reqwest", "bytes" ]
reqwest-default-tls = [ "reqwest-client", "reqwest/default-tls" ]
default-tls = [ "attohttpc/tls-native" ]
reqwest-native-tls-vendored = [ "reqwest-client", "reqwest/native-tls-vendored" ]
native-tls-vendored = [ "attohttpc/tls-vendored" ]
default-tls = [ "reqwest/default-tls" ]
native-tls-vendored = [ "reqwest/native-tls-vendored" ]
process-command-api = [ "shared_child", "os_pipe" ]
global-shortcut = [
"tauri-runtime/global-shortcut",
Expand Down
8 changes: 0 additions & 8 deletions core/tauri/src/api/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,12 @@ pub enum Error {
#[error("user cancelled the dialog")]
DialogCancelled,
/// The network error.
#[cfg(all(feature = "http-api", not(feature = "reqwest-client")))]
#[error("Network Error: {0}")]
Network(#[from] attohttpc::Error),
/// The network error.
#[cfg(feature = "reqwest-client")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "reqwest-client")))]
#[error("Network Error: {0}")]
Network(#[from] reqwest::Error),
/// HTTP method error.
#[error(transparent)]
HttpMethod(#[from] http::method::InvalidMethod),
/// Invalid HTTP header value.
#[cfg(feature = "reqwest-client")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "reqwest-client")))]
#[error(transparent)]
HttpHeaderValue(#[from] http::header::InvalidHeaderValue),
/// Invalid HTTP header value.
Expand Down
175 changes: 0 additions & 175 deletions core/tauri/src/api/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,8 @@ use url::Url;

use std::{collections::HashMap, path::PathBuf, time::Duration};

#[cfg(feature = "reqwest-client")]
pub use reqwest::header;

#[cfg(not(feature = "reqwest-client"))]
pub use attohttpc::header;

use header::{HeaderName, HeaderValue};

#[derive(Deserialize)]
Expand Down Expand Up @@ -73,13 +69,6 @@ impl ClientBuilder {
}

/// Builds the Client.
#[cfg(not(feature = "reqwest-client"))]
pub fn build(self) -> crate::api::Result<Client> {
Ok(Client(self))
}

/// Builds the Client.
#[cfg(feature = "reqwest-client")]
pub fn build(self) -> crate::api::Result<Client> {
let mut client_builder = reqwest::Client::builder();

Expand All @@ -101,146 +90,9 @@ impl ClientBuilder {
}

/// The HTTP client based on [`reqwest`].
#[cfg(feature = "reqwest-client")]
#[derive(Debug, Clone)]
pub struct Client(reqwest::Client);

/// The HTTP client.
#[cfg(not(feature = "reqwest-client"))]
#[derive(Debug, Clone)]
pub struct Client(ClientBuilder);

#[cfg(not(feature = "reqwest-client"))]
impl Client {
/// Executes an HTTP request.
///
/// # Examples
///
/// ```rust,no_run
/// use tauri::api::http::{ClientBuilder, HttpRequestBuilder, ResponseType};
/// async fn run_request() {
/// let client = ClientBuilder::new().build().unwrap();
/// let response = client.send(
/// HttpRequestBuilder::new("GET", "https://www.rust-lang.org")
/// .unwrap()
/// .response_type(ResponseType::Binary)
/// ).await;
/// if let Ok(response) = response {
/// let bytes = response.bytes();
/// }
/// }
/// ```
pub async fn send(&self, request: HttpRequestBuilder) -> crate::api::Result<Response> {
let method = Method::from_bytes(request.method.to_uppercase().as_bytes())?;

let mut request_builder = attohttpc::RequestBuilder::try_new(method, &request.url)?;

if let Some(query) = request.query {
request_builder = request_builder.params(&query);
}

if let Some(headers) = &request.headers {
for (name, value) in headers.0.iter() {
request_builder = request_builder.header(name, value);
}
}

if let Some(max_redirections) = self.0.max_redirections {
if max_redirections == 0 {
request_builder = request_builder.follow_redirects(false);
} else {
request_builder = request_builder.max_redirections(max_redirections as u32);
}
}

if let Some(timeout) = request.timeout {
request_builder = request_builder.timeout(timeout);
}

let response = if let Some(body) = request.body {
match body {
Body::Bytes(data) => request_builder.body(attohttpc::body::Bytes(data)).send()?,
Body::Text(text) => request_builder.body(attohttpc::body::Bytes(text)).send()?,
Body::Json(json) => request_builder.json(&json)?.send()?,
Body::Form(form_body) => {
#[allow(unused_variables)]
fn send_form(
request_builder: attohttpc::RequestBuilder,
headers: &Option<HeaderMap>,
form_body: FormBody,
) -> crate::api::Result<attohttpc::Response> {
#[cfg(feature = "http-multipart")]
if matches!(
headers
.as_ref()
.and_then(|h| h.0.get("content-type"))
.map(|v| v.as_bytes()),
Some(b"multipart/form-data")
) {
let mut multipart = attohttpc::MultipartBuilder::new();
let mut byte_cache: HashMap<String, Vec<u8>> = Default::default();

for (name, part) in &form_body.0 {
if let FormPart::File { file, .. } = part {
byte_cache.insert(name.to_string(), file.clone().try_into()?);
}
}
for (name, part) in &form_body.0 {
multipart = match part {
FormPart::File {
file,
mime,
file_name,
} => {
// safe to unwrap: always set by previous loop
let mut file =
attohttpc::MultipartFile::new(name, byte_cache.get(name).unwrap());
if let Some(mime) = mime {
file = file.with_type(mime)?;
}
if let Some(file_name) = file_name {
file = file.with_filename(file_name);
}
multipart.with_file(file)
}
FormPart::Text(value) => multipart.with_text(name, value),
};
}
return request_builder
.body(multipart.build()?)
.send()
.map_err(Into::into);
}

let mut form = Vec::new();
for (name, part) in form_body.0 {
match part {
FormPart::File { file, .. } => {
let bytes: Vec<u8> = file.try_into()?;
form.push((name, serde_json::to_string(&bytes)?))
}
FormPart::Text(value) => form.push((name, value)),
}
}
request_builder.form(&form)?.send().map_err(Into::into)
}

send_form(request_builder, &request.headers, form_body)?
}
}
} else {
request_builder.send()?
};

Ok(Response(
request.response_type.unwrap_or(ResponseType::Json),
response,
request.url,
))
}
}

#[cfg(feature = "reqwest-client")]
impl Client {
/// Executes an HTTP request
///
Expand Down Expand Up @@ -557,13 +409,8 @@ impl HttpRequestBuilder {
}

/// The HTTP response.
#[cfg(feature = "reqwest-client")]
#[derive(Debug)]
pub struct Response(ResponseType, reqwest::Response);
/// The HTTP response.
#[cfg(not(feature = "reqwest-client"))]
#[derive(Debug)]
pub struct Response(ResponseType, attohttpc::Response, Url);

impl Response {
/// Get the [`StatusCode`] of this Response.
Expand All @@ -579,20 +426,10 @@ impl Response {
/// Reads the response as raw bytes.
pub async fn bytes(self) -> crate::api::Result<RawResponse> {
let status = self.status().as_u16();
#[cfg(feature = "reqwest-client")]
let data = self.1.bytes().await?.to_vec();
#[cfg(not(feature = "reqwest-client"))]
let data = self.1.bytes()?;
Ok(RawResponse { status, data })
}

#[cfg(not(feature = "reqwest-client"))]
#[allow(dead_code)]
pub(crate) fn reader(self) -> attohttpc::ResponseReader {
let (_, _, reader) = self.1.split();
reader
}

// Convert the response into a Stream of [`bytes::Bytes`] from the body.
//
// # Examples
Expand All @@ -612,7 +449,6 @@ impl Response {
// # Ok(())
// # }
// ```
#[cfg(feature = "reqwest-client")]
#[allow(dead_code)]
pub(crate) fn bytes_stream(
self,
Expand All @@ -625,10 +461,7 @@ impl Response {
///
/// Note that the body is serialized to a [`Value`].
pub async fn read(self) -> crate::api::Result<ResponseData> {
#[cfg(feature = "reqwest-client")]
let url = self.1.url().clone();
#[cfg(not(feature = "reqwest-client"))]
let url = self.2;

let mut headers = HashMap::new();
let mut raw_headers = HashMap::new();
Expand All @@ -650,20 +483,12 @@ impl Response {
}
let status = self.1.status().as_u16();

#[cfg(feature = "reqwest-client")]
let data = match self.0 {
ResponseType::Json => self.1.json().await?,
ResponseType::Text => Value::String(self.1.text().await?),
ResponseType::Binary => serde_json::to_value(&self.1.bytes().await?)?,
};

#[cfg(not(feature = "reqwest-client"))]
let data = match self.0 {
ResponseType::Json => self.1.json()?,
ResponseType::Text => Value::String(self.1.text()?),
ResponseType::Binary => serde_json::to_value(self.1.bytes()?)?,
};

Ok(ResponseData {
url,
status,
Expand Down
7 changes: 2 additions & 5 deletions core/tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@
//! - **shell-open-api**: Enables the [`api::shell`] module.
//! - **http-api**: Enables the [`api::http`] module.
//! - **http-multipart**: Adds support to `multipart/form-data` requests.
//! - **reqwest-client**: Uses `reqwest` as HTTP client on the `http` APIs. Improves performance, but increases the bundle size.
//! - **default-tls**: Provides TLS support to connect over HTTPS (applies to the default HTTP client).
//! - **reqwest-default-tls**: Provides TLS support to connect over HTTPS (applies to the `reqwest` HTTP client).
//! - **native-tls-vendored**: Compile and statically link to a vendored copy of OpenSSL (applies to the default HTTP client).
//! - **reqwest-native-tls-vendored**: Compile and statically link to a vendored copy of OpenSSL (applies to the `reqwest` HTTP client).
//! - **default-tls**: Provides TLS support to connect over HTTPS.
//! - **native-tls-vendored**: Compile and statically link to a vendored copy of OpenSSL.
//! - **process-command-api**: Enables the [`api::process::Command`] APIs.
//! - **global-shortcut**: Enables the global shortcut APIs.
//! - **clipboard**: Enables the clipboard APIs.
Expand Down
Loading

0 comments on commit dddaa94

Please sign in to comment.