Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32177692
D13503.1765069878.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D13503.1765069878.diff
View Options
diff --git a/Cargo.lock b/Cargo.lock
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1419,6 +1419,7 @@
"aws-config",
"aws-sdk-dynamodb",
"aws-sdk-s3",
+ "base64 0.21.7",
"chrono",
"clap",
"comm-lib",
diff --git a/services/blob/Cargo.toml b/services/blob/Cargo.toml
--- a/services/blob/Cargo.toml
+++ b/services/blob/Cargo.toml
@@ -14,6 +14,7 @@
aws-config = { workspace = true }
aws-sdk-dynamodb = { workspace = true }
aws-sdk-s3 = { workspace = true }
+base64 = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true, features = ["derive", "env"] }
comm-lib = { path = "../../shared/comm-lib", features = [
diff --git a/services/blob/src/http/handlers/blob.rs b/services/blob/src/http/handlers/blob.rs
--- a/services/blob/src/http/handlers/blob.rs
+++ b/services/blob/src/http/handlers/blob.rs
@@ -5,15 +5,17 @@
use crate::validate_identifier;
use actix_web::error::{ErrorBadRequest, ErrorRangeNotSatisfiable};
+use actix_web::web::Bytes;
use actix_web::{
http::header::{ByteRangeSpec, Range},
web, HttpResponse,
};
use async_stream::try_stream;
+use base64::Engine;
use comm_lib::http::multipart;
use serde::{Deserialize, Serialize};
use tokio_stream::StreamExt;
-use tracing::{info, instrument, trace, warn};
+use tracing::{debug, info, instrument, trace, warn};
use tracing_futures::Instrument;
/// Returns a tuple of first and last byte number (inclusive) represented by given range header.
@@ -162,21 +164,43 @@
return Err(ErrorBadRequest("Bad request"));
}
validate_identifier!(blob_hash);
-
tracing::Span::current().record("blob_hash", &blob_hash);
trace!("Receiving blob data");
let stream = try_stream! {
while let Some(mut field) = payload.try_next().await? {
let field_name = field.name();
+
+ if field_name == "base64_data" {
+ trace!("Got base64_data");
+
+ let mut buf = Vec::new();
+ while let Some(chunk) = field.try_next().await? {
+ buf.extend_from_slice(&chunk);
+ }
+
+ let base64_string = String::from_utf8(buf)
+ .map_err(|err| actix_web::error::ParseError::Utf8(err.utf8_error()))?;
+
+ let data = base64::engine::general_purpose::STANDARD
+ .decode(&base64_string)
+ .map_err(|err| {
+ debug!("Invalid base64 payload: {err:?}");
+ ErrorBadRequest("Invalid base64")
+ })?;
+ yield Bytes::from(data);
+ return;
+ }
+
if field_name != "blob_data" {
warn!(
field_name,
- "Malfolmed request: 'blob_data' multipart field expected."
+ "Malformed request: 'blob_data' or 'base64_data' multipart field expected."
);
Err(ErrorBadRequest("Bad request"))?;
}
+ trace!("Got blob_data. Streaming...");
while let Some(chunk) = field.try_next().await? {
yield chunk;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 7, 1:11 AM (6 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5840738
Default Alt Text
D13503.1765069878.diff (2 KB)
Attached To
Mode
D13503: [blob] Support uploading base64-encoded blobs
Attached
Detach File
Event Timeline
Log In to Comment