(
&self,
url: &str,
headers: Vec<(&str, &str)>,
body: &serde_json::Value,
cancel_token: CancellationToken,
)
| 120 | #[async_trait] |
| 121 | impl HttpClient for ReqwestHttpClient { |
| 122 | async fn post( |
| 123 | &self, |
| 124 | url: &str, |
| 125 | headers: Vec<(&str, &str)>, |
| 126 | body: &serde_json::Value, |
| 127 | cancel_token: CancellationToken, |
| 128 | ) -> Result<HttpResponse> { |
| 129 | let start = std::time::Instant::now(); |
| 130 | let request_body = serde_json::to_string(body).unwrap_or_default(); |
| 131 | let request_bytes = request_body.len() as u64; |
| 132 | |
| 133 | tracing::debug!( |
| 134 | "HTTP POST to {}: {}", |
| 135 | url, |
| 136 | serde_json::to_string_pretty(body)? |
| 137 | ); |
| 138 | |
| 139 | let mut request = self.client.post(url); |
| 140 | for (key, value) in headers { |
| 141 | request = request.header(key, value); |
| 142 | } |
| 143 | request = request.json(body); |
| 144 | |
| 145 | let response = tokio::select! { |
| 146 | _ = cancel_token.cancelled() => { |
| 147 | anyhow::bail!("HTTP request cancelled"); |
| 148 | } |
| 149 | result = request.send() => { |
| 150 | result.context(format!("Failed to send request to {}", url))? |
| 151 | } |
| 152 | }; |
| 153 | |
| 154 | let status = response.status().as_u16(); |
| 155 | let response_body = response.text().await?; |
| 156 | let response_bytes = response_body.len() as u64; |
| 157 | let duration_ms = start.elapsed().as_secs_f64() * 1000.0; |
| 158 | |
| 159 | maybe_record_metrics(HttpMetricsRecord { |
| 160 | url: url.to_string(), |
| 161 | method: "POST".to_string(), |
| 162 | status, |
| 163 | duration_ms, |
| 164 | request_bytes, |
| 165 | response_bytes, |
| 166 | streaming: false, |
| 167 | }); |
| 168 | |
| 169 | Ok(HttpResponse { |
| 170 | status, |
| 171 | body: response_body, |
| 172 | }) |
| 173 | } |
| 174 | |
| 175 | async fn post_streaming( |
| 176 | &self, |
no test coverage detected