Send a POST request with msgpack + gzip encoded body and receive msgpack + gzip response
(
&self,
url: &str,
body: &T,
)
| 230 | |
| 231 | /// Send a POST request with msgpack + gzip encoded body and receive msgpack + gzip response |
| 232 | pub async fn post_compressed_msg<T: Serialize, R: DeserializeOwned>( |
| 233 | &self, |
| 234 | url: &str, |
| 235 | body: &T, |
| 236 | ) -> Result<R> { |
| 237 | let encoded = encode(body).context("failed to encode request body")?; |
| 238 | |
| 239 | // Compress with gzip |
| 240 | let mut encoder = GzEncoder::new(Vec::new(), Compression::fast()); |
| 241 | encoder |
| 242 | .write_all(&encoded) |
| 243 | .context("failed to compress request")?; |
| 244 | let compressed = encoder.finish().context("failed to finish compression")?; |
| 245 | |
| 246 | let request = hyper::Request::builder() |
| 247 | .method(hyper::Method::POST) |
| 248 | .uri(url) |
| 249 | .header("content-type", "application/x-msgpack-gz") |
| 250 | .body(Full::new(Bytes::from(compressed))) |
| 251 | .context("failed to build request")?; |
| 252 | |
| 253 | let response = self |
| 254 | .client |
| 255 | .request(request) |
| 256 | .await |
| 257 | .with_context(|| format!("failed to send request to {url}"))?; |
| 258 | |
| 259 | if !response.status().is_success() { |
| 260 | anyhow::bail!("request failed: {}", response.status()); |
| 261 | } |
| 262 | |
| 263 | let body = response |
| 264 | .into_body() |
| 265 | .collect() |
| 266 | .await |
| 267 | .context("failed to read response body")? |
| 268 | .to_bytes(); |
| 269 | |
| 270 | // Decompress |
| 271 | let mut decoder = GzDecoder::new(body.as_ref()); |
| 272 | let mut decompressed = Vec::new(); |
| 273 | decoder |
| 274 | .read_to_end(&mut decompressed) |
| 275 | .context("failed to decompress response")?; |
| 276 | |
| 277 | decode(&decompressed).context("failed to decode response") |
| 278 | } |
| 279 | } |
| 280 | |
| 281 | // ============================================================================ |