diff options
Diffstat (limited to 'rs/server')
| -rw-r--r-- | rs/server/src/main.rs | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/rs/server/src/main.rs b/rs/server/src/main.rs index aebeb88..0266f61 100644 --- a/rs/server/src/main.rs +++ b/rs/server/src/main.rs | |||
| @@ -299,7 +299,7 @@ struct BatchResponseObjectAction { | |||
| 299 | expires_at: DateTime<Utc>, | 299 | expires_at: DateTime<Utc>, |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | #[derive(Debug, Serialize, Clone)] | 302 | #[derive(Default, Debug, Serialize, Clone)] |
| 303 | struct BatchResponseObjectActions { | 303 | struct BatchResponseObjectActions { |
| 304 | #[serde(skip_serializing_if = "Option::is_none")] | 304 | #[serde(skip_serializing_if = "Option::is_none")] |
| 305 | upload: Option<BatchResponseObjectAction>, | 305 | upload: Option<BatchResponseObjectAction>, |
| @@ -315,6 +315,7 @@ struct BatchResponseObject { | |||
| 315 | size: i64, | 315 | size: i64, |
| 316 | #[serde(skip_serializing_if = "Option::is_none")] | 316 | #[serde(skip_serializing_if = "Option::is_none")] |
| 317 | authenticated: Option<bool>, | 317 | authenticated: Option<bool>, |
| 318 | actions: BatchResponseObjectActions, | ||
| 318 | } | 319 | } |
| 319 | 320 | ||
| 320 | #[derive(Debug, Serialize, Clone)] | 321 | #[derive(Debug, Serialize, Clone)] |
| @@ -342,7 +343,7 @@ fn validate_size(expected: i64, obj: &HeadObjectOutput) -> bool { | |||
| 342 | true | 343 | true |
| 343 | } | 344 | } |
| 344 | 345 | ||
| 345 | async fn handle_download_object(state: &AppState, repo: &str, obj: &BatchRequestObject) { | 346 | async fn handle_download_object(state: &AppState, repo: &str, obj: &BatchRequestObject, trusted: bool) -> BatchResponseObject { |
| 346 | let (oid0, oid1) = (HexByte(obj.oid[0]), HexByte(obj.oid[1])); | 347 | let (oid0, oid1) = (HexByte(obj.oid[0]), HexByte(obj.oid[1])); |
| 347 | let full_path = format!("{repo}/lfs/objects/{}/{}/{}", oid0, oid1, obj.oid); | 348 | let full_path = format!("{repo}/lfs/objects/{}/{}/{}", oid0, oid1, obj.oid); |
| 348 | 349 | ||
| @@ -354,16 +355,36 @@ async fn handle_download_object(state: &AppState, repo: &str, obj: &BatchRequest | |||
| 354 | .checksum_mode(aws_sdk_s3::types::ChecksumMode::Enabled) | 355 | .checksum_mode(aws_sdk_s3::types::ChecksumMode::Enabled) |
| 355 | .send() | 356 | .send() |
| 356 | .await | 357 | .await |
| 357 | .unwrap(); | 358 | .unwrap(); // TODO: don't unwrap() |
| 358 | // Scaleway actually doesn't provide SHA256 suport, but maybe in the future :) | 359 | // Scaleway actually doesn't provide SHA256 suport, but maybe in the future :) |
| 359 | if !validate_checksum(obj.oid, &result) { | 360 | if !validate_checksum(obj.oid, &result) { |
| 360 | unreachable!(); | 361 | todo!(); |
| 361 | } | 362 | } |
| 362 | if !validate_size(obj.size, &result) { | 363 | if !validate_size(obj.size, &result) { |
| 363 | unreachable!(); | 364 | todo!(); |
| 364 | } | 365 | } |
| 365 | 366 | ||
| 366 | let expires_at = Utc::now() + Duration::seconds(5 * 60); | 367 | let expires_in = std::time::Duration::from_secs(5 * 60); |
| 368 | let expires_at = Utc::now() + expires_in; | ||
| 369 | |||
| 370 | if trusted { | ||
| 371 | let config = aws_sdk_s3::presigning::PresigningConfig::expires_in(expires_in).unwrap(); | ||
| 372 | let presigned = state.s3_client.get_object().presigned(config).await.unwrap(); | ||
| 373 | return BatchResponseObject{ | ||
| 374 | oid: obj.oid, | ||
| 375 | size: obj.size, | ||
| 376 | authenticated: Some(true), | ||
| 377 | actions: BatchResponseObjectActions { | ||
| 378 | download: Some(BatchResponseObjectAction{ | ||
| 379 | header: presigned.headers().map(|(k, v)| (k.to_owned(), v.to_owned())).collect(), | ||
| 380 | expires_at, | ||
| 381 | href: presigned.uri().to_string(), | ||
| 382 | }), | ||
| 383 | ..Default::default() | ||
| 384 | } | ||
| 385 | }; | ||
| 386 | } | ||
| 387 | todo!(); | ||
| 367 | } | 388 | } |
| 368 | 389 | ||
| 369 | struct AuthorizationConfig { | 390 | struct AuthorizationConfig { |
| @@ -496,7 +517,7 @@ async fn batch( | |||
| 496 | let Some(public) = is_repo_public(&repo) else { | 517 | let Some(public) = is_repo_public(&repo) else { |
| 497 | return REPO_NOT_FOUND.into_response(); | 518 | return REPO_NOT_FOUND.into_response(); |
| 498 | }; | 519 | }; |
| 499 | let authn = match authorize( | 520 | let Trusted(trusted) = match authorize( |
| 500 | &state.authz_conf, | 521 | &state.authz_conf, |
| 501 | &headers, | 522 | &headers, |
| 502 | &repo, | 523 | &repo, |
| @@ -528,7 +549,7 @@ async fn batch( | |||
| 528 | 549 | ||
| 529 | let resp: BatchResponse; | 550 | let resp: BatchResponse; |
| 530 | for obj in payload.objects { | 551 | for obj in payload.objects { |
| 531 | handle_download_object(&state, &repo, &obj).await; | 552 | handle_download_object(&state, &repo, &obj, trusted).await; |
| 532 | // match payload.operation { | 553 | // match payload.operation { |
| 533 | // Operation::Download => resp.objects.push(handle_download_object(repo, obj));, | 554 | // Operation::Download => resp.objects.push(handle_download_object(repo, obj));, |
| 534 | // Operation::Upload => resp.objects.push(handle_upload_object(repo, obj)), | 555 | // Operation::Upload => resp.objects.push(handle_upload_object(repo, obj)), |