From 99bd0775c33030f7ce146cf146ae263c431556e3 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Mon, 27 Jan 2025 18:00:40 +0100 Subject: [PATCH 1/3] refactor(ureq): update to ureq v3 --- Cargo.toml | 4 +- examples/custom_client.rs | 5 ++- src/client_ureq.rs | 80 ++++++++++++++++++++------------------- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8bd12e1..4c4f5d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -113,7 +113,9 @@ features = ["fs"] optional = true [dependencies.ureq] -version = "2" +version = "3.0.0" +default-features = false +features = ["rustls", "json"] optional = true [dev-dependencies] diff --git a/examples/custom_client.rs b/examples/custom_client.rs index 009e91a..62c1eb7 100644 --- a/examples/custom_client.rs +++ b/examples/custom_client.rs @@ -24,9 +24,10 @@ fn main() { } fn custom_client() -> Api { - let request_agent = frankenstein::ureq::builder() - .timeout(Duration::from_secs(100)) + let config = frankenstein::ureq::Agent::config_builder() + .timeout_global(Some(Duration::from_secs(100))) .build(); + let request_agent = frankenstein::ureq::Agent::new_with_config(config); let api_url = format!("{BASE_API_URL}{TOKEN}"); Api::builder() diff --git a/src/client_ureq.rs b/src/client_ureq.rs index 037635d..07b7d5c 100644 --- a/src/client_ureq.rs +++ b/src/client_ureq.rs @@ -4,7 +4,6 @@ use std::time::Duration; use bon::Builder; use multipart::client::lazy::Multipart; use serde_json::Value; -use ureq::Response; use crate::trait_sync::TelegramApi; use crate::Error; @@ -16,10 +15,19 @@ pub struct Api { #[builder(into)] pub api_url: String, - #[builder(default = ureq::builder().timeout(Duration::from_secs(500)).build())] + #[builder(default = default_agent())] pub request_agent: ureq::Agent, } +fn default_agent() -> ureq::Agent { + ureq::Agent::new_with_config( + ureq::config::Config::builder() + .http_status_as_error(false) + .timeout_global(Some(Duration::from_secs(500))) + .build(), + ) +} + impl Api { /// Create a new `Api`. You can use [`Api::new_url`] or [`Api::builder`] for more options. pub fn new(api_key: &str) -> Self { @@ -30,33 +38,19 @@ impl Api { pub fn new_url>(api_url: S) -> Self { Self::builder().api_url(api_url).build() } - - pub fn decode_response(response: Response) -> Result - where - Output: serde::de::DeserializeOwned, - { - match response.into_string() { - Ok(message) => crate::json::decode(&message), - Err(error) => Err(Error::Decode(format!("{error:?}"))), - } - } } impl From for Error { fn from(error: ureq::Error) -> Self { match error { - ureq::Error::Status(code, response) => match response.into_string() { - Ok(message) => match serde_json::from_str(&message) { - Ok(json_result) => Self::Api(json_result), - Err(_) => Self::Http { code, message }, - }, - Err(_) => Self::Http { - code, - message: "Failed to decode response".to_string(), - }, + // Disabled for the `default_agent` + ureq::Error::StatusCode(code) => Self::Http { + code, + message: String::new(), }, - ureq::Error::Transport(transport_error) => Self::Http { - message: format!("{transport_error:?}"), + ureq::Error::Json(error) => Self::Decode(format!("{error}")), + _ => Self::Http { + message: format!("{error}"), code: 500, }, } @@ -72,18 +66,19 @@ impl TelegramApi for Api { Output: serde::de::DeserializeOwned, { let url = format!("{}/{method}", self.api_url); - let prepared_request = self - .request_agent - .post(&url) - .set("Content-Type", "application/json"); + let request = self.request_agent.post(&url); let response = match params { - None => prepared_request.call()?, - Some(data) => { - let json = crate::json::encode(&data)?; - prepared_request.send_string(&json)? - } + None => request.send_empty()?, + Some(data) => request.send_json(&data)?, }; - Self::decode_response(response) + let success = response.status().is_success(); + let body = response.into_body().read_to_string()?; + if success { + crate::json::decode(&body) + } else { + let api_error = crate::json::decode(&body)?; + Err(Error::Api(api_error)) + } } fn request_with_form_data( @@ -128,16 +123,23 @@ impl TelegramApi for Api { } let url = format!("{}/{method}", self.api_url); - let form_data = form.prepare().unwrap(); + let mut form_data = form.prepare().unwrap(); let response = self .request_agent .post(&url) - .set( - "Content-Type", - &format!("multipart/form-data; boundary={}", form_data.boundary()), + .header( + ureq::http::header::CONTENT_TYPE, + format!("multipart/form-data; boundary={}", form_data.boundary()), ) - .send(form_data)?; - Self::decode_response(response) + .send(ureq::SendBody::from_reader(&mut form_data))?; + let success = response.status().is_success(); + let body = response.into_body().read_to_string()?; + if success { + crate::json::decode(&body) + } else { + let api_error = crate::json::decode(&body)?; + Err(Error::Api(api_error)) + } } } From b1ff022f7ad3ac3238712127f2e5ee85de0c412f Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Thu, 30 Jan 2025 18:52:36 +0100 Subject: [PATCH 2/3] build: update Cargo.lock for ureq=3 --- Cargo.lock | 98 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d7f8f9..fe7c232 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,20 +221,40 @@ dependencies = [ ] [[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "cookie" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] [[package]] -name = "crc32fast" -version = "1.4.2" +name = "cookie_store" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" dependencies = [ - "cfg-if", + "cookie", + "document-features", + "idna", + "indexmap 2.7.1", + "log", + "serde", + "serde_derive", + "serde_json", + "time", + "url", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -328,6 +348,15 @@ dependencies = [ "syn", ] +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + [[package]] name = "encoding_rs" version = "0.8.35" @@ -374,16 +403,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "flate2" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -961,6 +980,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + [[package]] name = "lock_api" version = "0.4.12" @@ -1958,20 +1983,37 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +checksum = "217751151c53226090391713e533d9a5e904ba2570dabaaace29032687589c3e" dependencies = [ "base64", - "flate2", + "cc", + "cookie_store", "log", - "once_cell", + "percent-encoding", "rustls", + "rustls-pemfile", "rustls-pki-types", - "url", + "serde", + "serde_json", + "ureq-proto", + "utf-8", "webpki-roots", ] +[[package]] +name = "ureq-proto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c51fe73e1d8c4e06bb2698286f7e7453c6fc90528d6d2e7fc36bb4e87fe09b1" +dependencies = [ + "base64", + "http 1.2.0", + "httparse", + "log", +] + [[package]] name = "url" version = "2.5.4" @@ -1983,6 +2025,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf16_iter" version = "1.0.5" @@ -2001,6 +2049,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "waker-fn" version = "1.2.0" From ca89a3c9dd1ee9ca9264d090f01d767b29406f65 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Fri, 31 Jan 2025 13:16:43 +0100 Subject: [PATCH 3/3] fix(ureq): handle json correctly --- Cargo.lock | 53 --------------------------------------- Cargo.toml | 2 +- examples/custom_client.rs | 1 + src/client_ureq.rs | 7 +++++- 4 files changed, 8 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe7c232..1750697 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,35 +220,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "cookie" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "cookie_store" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" -dependencies = [ - "cookie", - "document-features", - "idna", - "indexmap 2.7.1", - "log", - "serde", - "serde_derive", - "serde_json", - "time", - "url", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -348,15 +319,6 @@ dependencies = [ "syn", ] -[[package]] -name = "document-features" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" -dependencies = [ - "litrs", -] - [[package]] name = "encoding_rs" version = "0.8.35" @@ -980,12 +942,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" -[[package]] -name = "litrs" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" - [[package]] name = "lock_api" version = "0.4.12" @@ -1989,14 +1945,11 @@ checksum = "217751151c53226090391713e533d9a5e904ba2570dabaaace29032687589c3e" dependencies = [ "base64", "cc", - "cookie_store", "log", "percent-encoding", "rustls", "rustls-pemfile", "rustls-pki-types", - "serde", - "serde_json", "ureq-proto", "utf-8", "webpki-roots", @@ -2049,12 +2002,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "waker-fn" version = "1.2.0" diff --git a/Cargo.toml b/Cargo.toml index 116bfc0..45ed2e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -116,7 +116,7 @@ optional = true [dependencies.ureq] version = "3.0.0" default-features = false -features = ["rustls", "json"] +features = ["rustls"] optional = true [dev-dependencies] diff --git a/examples/custom_client.rs b/examples/custom_client.rs index 62c1eb7..0a97e10 100644 --- a/examples/custom_client.rs +++ b/examples/custom_client.rs @@ -25,6 +25,7 @@ fn main() { fn custom_client() -> Api { let config = frankenstein::ureq::Agent::config_builder() + .http_status_as_error(false) .timeout_global(Some(Duration::from_secs(100))) .build(); let request_agent = frankenstein::ureq::Agent::new_with_config(config); diff --git a/src/client_ureq.rs b/src/client_ureq.rs index 6d58716..37ef6d6 100644 --- a/src/client_ureq.rs +++ b/src/client_ureq.rs @@ -70,7 +70,12 @@ impl TelegramApi for Api { None => request.send_empty()?, Some(data) => { let json = crate::json::encode(&data)?; - request.send(&json)? + request + .header( + ureq::http::header::CONTENT_TYPE, + ureq::http::HeaderValue::from_static("application/json; charset=utf-8"), + ) + .send(&json)? } }; Self::decode_response(response)