orinium_browser/platform/network/
mod.rs

1//! Network processing module, providing HTTP communication, cache, and cookie management.
2
3pub mod cache;
4pub mod config;
5pub mod cookie_store;
6mod core;
7pub mod error;
8pub mod sender_pool;
9
10// 外部公開用
11pub use cache::Cache;
12pub use config::NetworkConfig;
13pub use cookie_store::CookieStore;
14pub use core::Response;
15pub use error::NetworkError;
16pub use hyper::http::{Request, StatusCode};
17pub use sender_pool::HostKey;
18pub use sender_pool::{HttpSender, SenderPool};
19
20use core::AsyncNetworkCore;
21
22use std::sync::mpsc::{self, Receiver, Sender};
23use std::thread;
24
25pub enum NetworkCommand {
26    Fetch { url: String, msg_id: usize },
27    SetConfig(NetworkConfig),
28}
29
30pub struct NetworkMessage {
31    pub msg_id: usize,
32    pub response: Result<Response, NetworkError>,
33}
34
35pub struct NetworkCore {
36    cmd_tx: Sender<NetworkCommand>,
37    msg_rx: Receiver<NetworkMessage>, // UI スレッド用
38}
39
40impl Default for NetworkCore {
41    fn default() -> Self {
42        Self::new()
43    }
44}
45
46impl NetworkCore {
47    pub fn new() -> Self {
48        let (cmd_tx, cmd_rx) = mpsc::channel();
49        let (msg_tx, msg_rx) = mpsc::channel();
50
51        thread::spawn(move || spawn_network_thread(cmd_rx, msg_tx));
52
53        Self { cmd_tx, msg_rx }
54    }
55
56    pub fn set_network_config(&self, cfg: NetworkConfig) {
57        let _ = self.cmd_tx.send(NetworkCommand::SetConfig(cfg));
58    }
59
60    /// 非同期送信のみ。結果は try_receive で取得
61    pub fn fetch_async(&self, url: String, msg_id: usize) {
62        let _ = self.cmd_tx.send(NetworkCommand::Fetch { url, msg_id });
63    }
64
65    /// UIスレッドから呼ぶ: 完了しているメッセージを取り込む
66    pub fn try_receive(&self) -> Vec<NetworkMessage> {
67        let mut msgs = Vec::new();
68        while let Ok(msg) = self.msg_rx.try_recv() {
69            log::info!("NetworkCore: received message for msg_id={}", msg.msg_id);
70            msgs.push(msg);
71        }
72        msgs
73    }
74
75    pub fn fetch_blocking(&self, url: &str) -> Result<Response, NetworkError> {
76        self.fetch_async(url.to_string(), 0);
77        loop {
78            if let Some(v) = self.try_receive().into_iter().next() {
79                return v.response;
80            }
81            std::thread::yield_now();
82        }
83    }
84}
85
86/// ネットワークスレッド
87fn spawn_network_thread(rx: Receiver<NetworkCommand>, tx: Sender<NetworkMessage>) {
88    let mut core = AsyncNetworkCore::new();
89
90    for cmd in rx {
91        match cmd {
92            NetworkCommand::SetConfig(cfg) => core.set_network_config(cfg),
93            NetworkCommand::Fetch { url, msg_id } => {
94                let res = core.fetch_blocking(&url);
95                log::info!("NetworkCore: fetched URL for msg_id={}", msg_id);
96                let _ = tx.send(NetworkMessage {
97                    msg_id,
98                    response: res,
99                });
100            }
101        }
102    }
103}