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.
102 lines
2.7 KiB
Rust
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),
|
|
}
|
|
}
|