diff --git a/desktop/src/main.rs b/desktop/src/main.rs index 9548957..ef11375 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -21,6 +21,7 @@ struct App { share_url: String, upload_rx: Option>, uploading: bool, + skip_ssl: bool, } impl App { @@ -31,16 +32,19 @@ impl App { share_url: String::new(), upload_rx: None, uploading: false, + skip_ssl: false, } } - fn start_upload(&mut self, filepath: std::path::PathBuf, api_url: String) { + fn start_upload(&mut self, filepath: std::path::PathBuf) { let (tx, rx) = mpsc::channel(); self.upload_rx = Some(rx); self.uploading = true; + let api_url = self.api_url.clone(); + let skip_ssl = self.skip_ssl; std::thread::spawn(move || { - let result = do_upload(&api_url, &filepath); + let result = do_upload(&api_url, &filepath, skip_ssl); let _ = tx.send(result); }); } @@ -65,7 +69,7 @@ impl App { } } -fn do_upload(api_url: &str, filepath: &std::path::Path) -> UploadResult { +fn do_upload(api_url: &str, filepath: &std::path::Path, skip_ssl: bool) -> UploadResult { let filename = filepath .file_name() .map(|n| n.to_string_lossy().to_string()) @@ -81,18 +85,33 @@ fn do_upload(api_url: &str, filepath: &std::path::Path) -> UploadResult { .part("file", part) .text("expiry", "24h"); - let client = match reqwest::blocking::Client::builder() - .user_agent("TempFileTransfer-Desktop/0.1") - .timeout(std::time::Duration::from_secs(300)) - .build() - { + let mut builder = reqwest::blocking::Client::builder() + .user_agent("TempFileTransfer-Desktop/0.2") + .timeout(std::time::Duration::from_secs(300)); + + if skip_ssl { + builder = builder.danger_accept_invalid_certs(true); + } + + let client = match builder.build() { Ok(c) => c, Err(e) => return UploadResult::Err(format!("创建客户端失败: {}", e)), }; let resp = match client.post(api_url).multipart(form).send() { Ok(r) => r, - Err(e) => return UploadResult::Err(format!("网络请求失败: {}", e)), + Err(e) => { + let detail = if e.is_connect() { + format!("连接失败(无法连接到服务器): {}", e) + } else if e.is_timeout() { + format!("连接超时: {}", e) + } else if e.is_body() { + format!("SSL/数据传输出错(请尝试勾选「跳过SSL验证」): {}", e) + } else { + format!("{}", e) + }; + return UploadResult::Err(detail); + } }; let status = resp.status(); @@ -138,6 +157,11 @@ impl eframe::App for App { ); }); + ui.add_space(4.0); + ui.horizontal(|ui| { + ui.checkbox(&mut self.skip_ssl, "跳过 SSL 证书验证(仅当连接失败时尝试)"); + }); + ui.add_space(8.0); let drop_frame = egui::Frame::dark_canvas(ui.style()) @@ -180,7 +204,7 @@ impl eframe::App for App { if !self.uploading { for f in files { if let Some(ref path) = f.path { - self.start_upload(path.to_owned(), self.api_url.clone()); + self.start_upload(path.to_owned()); break; } } @@ -191,10 +215,14 @@ impl eframe::App for App { ui.horizontal(|ui| { ui.label("状态:"); - ui.label( - egui::RichText::new(&self.status) - .color(egui::Color32::from_rgb(100, 180, 100)), - ); + let color = if self.status.starts_with("上传失败") { + egui::Color32::from_rgb(220, 80, 80) + } else if self.status.starts_with("上传成功") { + egui::Color32::from_rgb(80, 200, 80) + } else { + egui::Color32::from_rgb(100, 180, 100) + }; + ui.label(egui::RichText::new(&self.status).color(color)); }); ui.add_space(8.0); @@ -253,7 +281,7 @@ fn load_chinese_font(ctx: &egui::Context) { fn main() { let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default() - .with_inner_size([560.0, 480.0]) + .with_inner_size([560.0, 500.0]) .with_resizable(false) .with_title("临时文件传输"), ..Default::default()