MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / upload_change_streamed

Method upload_change_streamed

atomic-remote/src/http/upload.rs:303–365  ·  view source on GitHub ↗

Upload a change file by streaming from disk. Uses reqwest's streaming body support to avoid loading the entire file into memory. The `Content-Length` header is set from file metadata so the server can validate the upload without buffering. # Arguments `hash` - The base32-encoded hash of the change. `view` - The target view name. `path` - Path to the `.change` file on disk. # Errors Returns a

(
        &self,
        hash: &str,
        view: &str,
        path: &std::path::Path,
    )

Source from the content-addressed store, hash-verified

301 /// Returns an error if the file can't be opened, the upload fails, or
302 /// the server rejects the change.
303 pub async fn upload_change_streamed(
304 &self,
305 hash: &str,
306 view: &str,
307 path: &std::path::Path,
308 ) -> RemoteResult<()> {
309 let url = format!("{}?insert={}&view={}", self.base_url, hash, view);
310 debug!("POST insert (streamed): {} from {:?}", url, path);
311
312 let file = tokio::fs::File::open(path).await.map_err(|e| {
313 RemoteError::other(format!("Failed to open change file {:?}: {}", path, e))
314 })?;
315
316 let file_size = file
317 .metadata()
318 .await
319 .map_err(|e| {
320 RemoteError::other(format!("Failed to read metadata for {:?}: {}", path, e))
321 })?
322 .len();
323
324 info!("Streaming upload of change {} ({} bytes)", hash, file_size);
325
326 let stream = ReaderStream::new(file);
327 let body = reqwest::Body::wrap_stream(stream);
328
329 let response = self
330 .client
331 .post(&url)
332 .header(CONTENT_TYPE, "application/octet-stream")
333 .header(CONTENT_LENGTH, file_size)
334 .body(body)
335 .send()
336 .await
337 .map_err(|e| RemoteError::connection_failed(&url, e))?;
338
339 crate::check_min_version_header(response.headers());
340 let status = response.status();
341
342 match status {
343 StatusCode::OK => {
344 debug!("Successfully streamed change {} from file", hash);
345 Ok(())
346 }
347 StatusCode::NOT_FOUND => Err(RemoteError::repo_not_found(&url)),
348 StatusCode::UNAUTHORIZED | StatusCode::FORBIDDEN => {
349 let msg = response.text().await.unwrap_or_default();
350 Err(RemoteError::auth_failed(&url, msg))
351 }
352 StatusCode::BAD_REQUEST | StatusCode::INTERNAL_SERVER_ERROR => {
353 let msg = response.text().await.unwrap_or_default();
354 if msg.contains("missing") && msg.contains("dependenc") {
355 Err(RemoteError::missing_deps(vec![]))
356 } else {
357 Err(RemoteError::http(status.as_u16(), msg))
358 }
359 }
360 _ => {

Callers 2

upload_change_smartFunction · 0.80
upload_change_fileMethod · 0.80

Calls 8

check_min_version_headerFunction · 0.85
postMethod · 0.80
textMethod · 0.80
lenMethod · 0.45
metadataMethod · 0.45
headerMethod · 0.45
statusMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected