1use std::time::Duration;
4
5pub use self::download::{download_file, download_file_stream, Download};
6
7pub(crate) use self::{
8 request::{request_json, request_multipart},
9 telegram_response::TelegramResponse,
10};
11
12mod download;
13mod request;
14mod telegram_response;
15
16pub const TELEGRAM_API_URL: &str = "https://api.telegram.org";
18
19#[must_use]
38pub fn client_from_env() -> reqwest::Client {
39 use reqwest::Proxy;
40
41 const TELOXIDE_PROXY: &str = "TELOXIDE_PROXY";
42
43 let builder = default_reqwest_settings();
44
45 match std::env::var(TELOXIDE_PROXY).ok() {
46 Some(proxy) => builder.proxy(Proxy::all(proxy).expect("reqwest::Proxy creation failed")),
47 None => builder,
48 }
49 .build()
50 .expect("creating reqwest::Client")
51}
52
53pub fn default_reqwest_settings() -> reqwest::ClientBuilder {
73 reqwest::Client::builder()
74 .connect_timeout(Duration::from_secs(5))
75 .timeout(Duration::from_secs(17))
76 .tcp_nodelay(true)
77}
78
79fn method_url(base: reqwest::Url, token: &str, method_name: &str) -> reqwest::Url {
83 let mut url = base;
84 {
85 let mut segments = url.path_segments_mut().expect("base URL cannot be a cannot-be-a-base");
86 segments.push(&format!("bot{token}"));
87 segments.push(method_name);
88 }
89 url
90}
91
92fn file_url(base: reqwest::Url, token: &str, file_path: &str) -> reqwest::Url {
96 let mut url = base;
97 {
98 let mut segments = url.path_segments_mut().expect("base URL cannot be a cannot-be-a-base");
99 segments.push("file");
100 segments.push(&format!("bot{token}"));
101 segments.push(file_path);
102 }
103 url
104}
105
106#[cfg(test)]
107mod tests {
108 use crate::net::*;
109
110 #[test]
111 fn method_url_test() {
112 let url = method_url(
113 reqwest::Url::parse(TELEGRAM_API_URL).unwrap(),
114 "535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao",
115 "methodName",
116 );
117
118 assert_eq!(
119 url.as_str(),
120 "https://api.telegram.org/bot535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao/methodName"
121 );
122 }
123
124 #[test]
125 fn method_url_with_custom_url_test() {
126 let url = method_url(
127 reqwest::Url::parse("https://example.com/telegram").unwrap(),
128 "535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao",
129 "methodName",
130 );
131
132 assert_eq!(
133 url.as_str(),
134 "https://example.com/telegram/bot535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao/methodName"
135 );
136 }
137
138 #[test]
139 fn file_url_test() {
140 let url = file_url(
141 reqwest::Url::parse(TELEGRAM_API_URL).unwrap(),
142 "535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao",
143 "AgADAgADyqoxG2g8aEsu_KjjVsGF4-zetw8ABAEAAwIAA20AA_8QAwABFgQ",
144 );
145
146 assert_eq!(
147 url.as_str(),
148 "https://api.telegram.org/file/bot535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao/AgADAgADyqoxG2g8aEsu_KjjVsGF4-zetw8ABAEAAwIAA20AA_8QAwABFgQ"
149 );
150 }
151
152 #[test]
153 fn file_url_with_custom_url_test() {
154 let url = file_url(
155 reqwest::Url::parse("https://example.com/telegram").unwrap(),
156 "535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao",
157 "AgADAgADyqoxG2g8aEsu_KjjVsGF4-zetw8ABAEAAwIAA20AA_8QAwABFgQ",
158 );
159
160 assert_eq!(
161 url.as_str(),
162 "https://example.com/telegram/file/bot535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao/AgADAgADyqoxG2g8aEsu_KjjVsGF4-zetw8ABAEAAwIAA20AA_8QAwABFgQ"
163 );
164 }
165}