Skip to content

Commit a58828f

Browse files
authored
Fix multibyte request failed (#24)
* fix multibyte request failed * remove unused variable * add test
1 parent 9829954 commit a58828f

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

src/utils/encode.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
pub fn encode(input: &str) -> String {
2+
let mut encoded = String::new();
3+
4+
for byte in input.bytes() {
5+
match byte {
6+
b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
7+
encoded.push(byte as char);
8+
}
9+
// 他の文字は %XX の形式でエンコード
10+
_ => encoded.push_str(&format!("%{:02X}", byte)),
11+
}
12+
}
13+
14+
encoded
15+
}
16+
17+
#[cfg(test)]
18+
mod tests {
19+
use super::*;
20+
21+
#[test]
22+
fn test_encode() {
23+
assert_eq!(encode("abc"), "abc");
24+
assert_eq!(encode("あいう"), "%E3%81%82%E3%81%84%E3%81%86");
25+
assert_eq!(encode("a b c"), "a%20b%20c");
26+
assert_eq!(encode("a+b+c"), "a%2Bb%2Bc");
27+
assert_eq!(encode("a=b=c"), "a%3Db%3Dc");
28+
assert_eq!(encode("a:b:c"), "a%3Ab%3Ac");
29+
assert_eq!(encode("a~b~c"), "a~b~c");
30+
assert_eq!(encode("a!b!c"), "a%21b%21c");
31+
assert_eq!(encode("a*b*c"), "a%2Ab%2Ac");
32+
assert_eq!(encode("a'b'c"), "a%27b%27c");
33+
assert_eq!(encode("a(c)c"), "a%28c%29c");
34+
assert_eq!(encode("a)c)c"), "a%29c%29c");
35+
assert_eq!(encode("a;c;c"), "a%3Bc%3Bc");
36+
assert_eq!(encode("a:c:c"), "a%3Ac%3Ac");
37+
assert_eq!(encode("a,d,c"), "a%2Cd%2Cc");
38+
assert_eq!(encode("a/d/c"), "a%2Fd%2Fc");
39+
assert_eq!(encode("a\\d\\c"), "a%5Cd%5Cc");
40+
assert_eq!(encode("a?d?c"), "a%3Fd%3Fc");
41+
assert_eq!(encode("a#d#c"), "a%23d%23c");
42+
assert_eq!(encode("a&d&c"), "a%26d%26c");
43+
assert_eq!(encode("a=d=c"), "a%3Dd%3Dc");
44+
assert_eq!(encode("a@d@c"), "a%40d%40c");
45+
assert_eq!(encode("a$d$c"), "a%24d%24c");
46+
assert_eq!(encode("a`d`c"), "a%60d%60c");
47+
}
48+
}

src/utils/google_search.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use serde::Deserialize;
22
use std::env;
33
use tracing::error;
44

5-
use crate::http::client::{HttpClient, StatusCode};
5+
use crate::{
6+
http::client::{HttpClient, StatusCode},
7+
utils::encode::encode,
8+
};
69

710
#[derive(Deserialize, Debug)]
811
pub struct GoogleItem {
@@ -48,20 +51,26 @@ pub async fn google_search(
4851
};
4952

5053
let url = format!(
51-
"https://www.googleapis.com/customsearch/v1?cx={search_engine_id}&key={api_key}&hl=ja{search_type}&q={q}{site}");
54+
"https://www.googleapis.com/customsearch/v1?cx={search_engine_id}&key={api_key}&hl=ja{search_type}&q={}{site}", encode(q));
5255

5356
let client = HttpClient::new();
5457
let result = match client.get(&url).await {
5558
Ok(result) => match result.status_code {
5659
StatusCode::OK => result,
60+
StatusCode::BadRequest => return Err("リクエストが不正です。".to_string()),
5761
StatusCode::Unauthorized => return Err("認証に失敗しました。".to_string()),
5862
StatusCode::Forbidden => return Err("アクセス権限がありません。".to_string()),
5963
StatusCode::NotFound => return Err("リソースが見つかりませんでした。".to_string()),
6064
StatusCode::TooManyRequests => return Err(
6165
"Google Search API へのリクエスト超過です。しばらくしてからやり直してください。"
6266
.to_string(),
6367
),
64-
_ => return Err("予期しないエラーが発生しました。".to_string()),
68+
status => {
69+
return Err(
70+
format!("予期しないエラーが発生しました。status: {}", status as u16)
71+
.to_string(),
72+
);
73+
}
6574
},
6675
Err(_) => return Err("Google 検索でエラーが発生しました。".to_string()),
6776
};

src/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod encode;
12
pub mod fetch_atproto;
23
pub mod fetch_chatgpt;
34
pub mod fetch_rss_feed;

0 commit comments

Comments
 (0)