Files
quicproquo/crates/quicprochat-server/src/v2_handlers/blob.rs
Christian Nennemann a710037dde chore: rename quicproquo → quicprochat in Rust workspace
Rename all crate directories, package names, binary names, proto
package/module paths, ALPN strings, env var prefixes, config filenames,
mDNS service names, and plugin ABI symbols from quicproquo/qpq to
quicprochat/qpc.
2026-03-21 19:14:06 +01:00

102 lines
2.7 KiB
Rust

//! Blob handlers — chunked file upload/download.
use std::sync::Arc;
use bytes::Bytes;
use prost::Message;
use quicprochat_proto::qpc::v1;
use quicprochat_rpc::method::{HandlerResult, RequestContext};
use crate::domain::blobs::BlobService;
use crate::domain::types::{CallerAuth, DownloadBlobReq, UploadBlobReq};
use super::{domain_err, require_auth, ServerState};
fn caller_auth(identity_key: Vec<u8>) -> CallerAuth {
CallerAuth {
identity_key,
token: Vec::new(),
device_id: None,
}
}
pub async fn handle_upload_blob(state: Arc<ServerState>, ctx: RequestContext) -> HandlerResult {
let identity_key = match require_auth(&state, &ctx) {
Ok(ik) => ik,
Err(e) => return e,
};
let req = match v1::UploadBlobRequest::decode(ctx.payload) {
Ok(r) => r,
Err(e) => {
return HandlerResult::err(
quicprochat_rpc::error::RpcStatus::BadRequest,
&format!("decode: {e}"),
)
}
};
let svc = BlobService {
data_dir: state.data_dir.clone(),
};
let auth = caller_auth(identity_key);
let domain_req = UploadBlobReq {
blob_hash: req.blob_hash,
chunk: req.chunk,
offset: req.offset,
total_size: req.total_size,
mime_type: req.mime_type,
};
match svc.upload_blob(domain_req, &auth) {
Ok(resp) => {
let proto = v1::UploadBlobResponse {
blob_id: resp.blob_id,
};
HandlerResult::ok(Bytes::from(proto.encode_to_vec()))
}
Err(e) => domain_err(e),
}
}
pub async fn handle_download_blob(state: Arc<ServerState>, ctx: RequestContext) -> HandlerResult {
let identity_key = match require_auth(&state, &ctx) {
Ok(ik) => ik,
Err(e) => return e,
};
let req = match v1::DownloadBlobRequest::decode(ctx.payload) {
Ok(r) => r,
Err(e) => {
return HandlerResult::err(
quicprochat_rpc::error::RpcStatus::BadRequest,
&format!("decode: {e}"),
)
}
};
let svc = BlobService {
data_dir: state.data_dir.clone(),
};
let auth = caller_auth(identity_key);
let domain_req = DownloadBlobReq {
blob_id: req.blob_id,
offset: req.offset,
length: req.length,
};
match svc.download_blob(domain_req, &auth) {
Ok(resp) => {
let proto = v1::DownloadBlobResponse {
chunk: resp.chunk,
total_size: resp.total_size,
mime_type: resp.mime_type,
};
HandlerResult::ok(Bytes::from(proto.encode_to_vec()))
}
Err(e) => domain_err(e),
}
}