| 80 | } |
| 81 | |
| 82 | fn fire_http( |
| 83 | method: &str, |
| 84 | id: &str, |
| 85 | url: &str, |
| 86 | f: impl FnOnce(&mut HttpConfig) -> &mut HttpConfig, |
| 87 | ) { |
| 88 | let key = hash_id(id); |
| 89 | let mut mgr = NET_MANAGER.lock().unwrap(); |
| 90 | |
| 91 | // Idempotent: don't re-fire if a request with this ID already exists |
| 92 | if mgr.http_requests.contains_key(&key) { |
| 93 | return; |
| 94 | } |
| 95 | |
| 96 | let mut config = HttpConfig::new(); |
| 97 | f(&mut config); |
| 98 | |
| 99 | #[cfg(not(target_arch = "wasm32"))] |
| 100 | { |
| 101 | use http::PendingHttp; |
| 102 | |
| 103 | let method = method.to_owned(); |
| 104 | let url = url.to_owned(); |
| 105 | let (tx, rx) = std::sync::mpsc::channel(); |
| 106 | |
| 107 | std::thread::spawn(move || { |
| 108 | let result: Result<Response, String> = (|| { |
| 109 | let agent = ureq::Agent::new_with_defaults(); |
| 110 | |
| 111 | macro_rules! apply_headers { |
| 112 | ($req:expr, $headers:expr) => {{ |
| 113 | let mut r = $req; |
| 114 | for (key, value) in $headers { |
| 115 | r = r.header(key.as_str(), value.as_str()); |
| 116 | } |
| 117 | r |
| 118 | }}; |
| 119 | } |
| 120 | |
| 121 | let send_result = match method.as_str() { |
| 122 | "GET" => { |
| 123 | let req = apply_headers!(agent.get(&url), &config.headers); |
| 124 | req.call() |
| 125 | } |
| 126 | "DELETE" => { |
| 127 | let req = apply_headers!(agent.delete(&url), &config.headers); |
| 128 | req.call() |
| 129 | } |
| 130 | "POST" => { |
| 131 | let req = apply_headers!(agent.post(&url), &config.headers); |
| 132 | if let Some(body) = &config.body { |
| 133 | req.content_type("application/octet-stream").send(body) |
| 134 | } else { |
| 135 | req.send_empty() |
| 136 | } |
| 137 | } |
| 138 | "PUT" => { |
| 139 | let req = apply_headers!(agent.put(&url), &config.headers); |