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

Method upload_change_streamed

atomic-remote/src/http/upload.rs:406–468  ·  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

404 /// Returns an error if the file can't be opened, the upload fails, or
405 /// the server rejects the change.
406 pub async fn upload_change_streamed(
407 &self,
408 hash: &str,
409 view: &str,
410 path: &std::path::Path,
411 ) -> RemoteResult<()> {
412 let url = format!("{}?insert={}&view={}", self.base_url, hash, view);
413 debug!("POST insert (streamed): {} from {:?}", url, path);
414
415 let file = tokio::fs::File::open(path).await.map_err(|e| {
416 RemoteError::other(format!("Failed to open change file {:?}: {}", path, e))
417 })?;
418
419 let file_size = file
420 .metadata()
421 .await
422 .map_err(|e| {
423 RemoteError::other(format!("Failed to read metadata for {:?}: {}", path, e))
424 })?
425 .len();
426
427 info!("Streaming upload of change {} ({} bytes)", hash, file_size);
428
429 let stream = ReaderStream::new(file);
430 let body = reqwest::Body::wrap_stream(stream);
431
432 let response = self
433 .client
434 .post(&url)
435 .header(CONTENT_TYPE, "application/octet-stream")
436 .header(CONTENT_LENGTH, file_size)
437 .body(body)
438 .send()
439 .await
440 .map_err(|e| RemoteError::connection_failed(&url, e))?;
441
442 crate::check_min_version_header(response.headers());
443 let status = response.status();
444
445 match status {
446 StatusCode::OK => {
447 debug!("Successfully streamed change {} from file", hash);
448 Ok(())
449 }
450 StatusCode::NOT_FOUND => Err(RemoteError::repo_not_found(&url)),
451 StatusCode::UNAUTHORIZED | StatusCode::FORBIDDEN => {
452 let msg = response.text().await.unwrap_or_default();
453 Err(RemoteError::auth_failed(&url, msg))
454 }
455 StatusCode::BAD_REQUEST | StatusCode::INTERNAL_SERVER_ERROR => {
456 let msg = response.text().await.unwrap_or_default();
457 if msg.contains("missing") && msg.contains("dependenc") {
458 Err(RemoteError::missing_deps(vec![]))
459 } else {
460 Err(RemoteError::http(status.as_u16(), msg))
461 }
462 }
463 _ => {

Callers 1

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