Rework api to take and return binary directly without hex serialization
Some checks failed
CI / rust (push) Failing after 30s

This commit is contained in:
NicolasCantu 2025-09-04 12:55:55 +02:00
parent f1021295f7
commit 44472bef1e
2 changed files with 20 additions and 18 deletions

View File

@ -163,22 +163,23 @@ pub async fn handle_health(_req: Request<StorageService>) -> tide::Result<Respon
} }
pub async fn handle_store(mut req: Request<StorageService>, no_ttl_permanent: bool) -> tide::Result<Response> { pub async fn handle_store(mut req: Request<StorageService>, no_ttl_permanent: bool) -> tide::Result<Response> {
let data: StoreRequest = match req.body_json().await { // Extract key from URL parameter
Ok(data) => data, let key: String = req.param("key")?.to_string();
Err(e) => {
return Ok(Response::builder(StatusCode::BadRequest)
.body(format!("Invalid request: {}", e))
.build());
}
};
if data.key.len() != 64 || !data.key.chars().all(|c| c.is_ascii_hexdigit()) { // Validate key format
if key.len() != 64 || !key.chars().all(|c| c.is_ascii_hexdigit()) {
return Ok(Response::builder(StatusCode::BadRequest) return Ok(Response::builder(StatusCode::BadRequest)
.body("Invalid key: must be a 32 bytes hex string.".to_string()) .body("Invalid key: must be a 32 bytes hex string.".to_string())
.build()); .build());
} }
let live_for: Option<Duration> = if let Some(ttl) = data.ttl { // Get TTL from query parameter (optional)
let ttl: Option<u64> = req.url().query_pairs()
.find(|(key, _)| key == "ttl")
.and_then(|(_, value)| value.parse().ok());
log::info!("ttl: {:?}", ttl);
let live_for: Option<Duration> = if let Some(ttl) = ttl {
if ttl < 60 { if ttl < 60 {
return Ok(Response::builder(StatusCode::BadRequest) return Ok(Response::builder(StatusCode::BadRequest)
.body(format!("Invalid ttl: must be at least {} seconds.", 60)) .body(format!("Invalid ttl: must be at least {} seconds.", 60))
@ -204,11 +205,12 @@ pub async fn handle_store(mut req: Request<StorageService>, no_ttl_permanent: bo
None => None, None => None,
}; };
let value_bytes = match hex::decode(&data.value) { // Read binary data directly from request body
Ok(value) => value, let value_bytes = match req.body_bytes().await {
Ok(bytes) => bytes,
Err(e) => { Err(e) => {
return Ok(Response::builder(StatusCode::BadRequest) return Ok(Response::builder(StatusCode::BadRequest)
.body(format!("Invalid request: {}", e)) .body(format!("Failed to read request body: {}", e))
.build()); .build());
} }
}; };
@ -216,7 +218,7 @@ pub async fn handle_store(mut req: Request<StorageService>, no_ttl_permanent: bo
log::info!("received {} bytes", value_bytes.len()); log::info!("received {} bytes", value_bytes.len());
let svc = req.state(); let svc = req.state();
match svc.store_data(&data.key, &value_bytes, expires_at).await { match svc.store_data(&key, &value_bytes, expires_at).await {
Ok(()) => Ok(Response::builder(StatusCode::Ok) Ok(()) => Ok(Response::builder(StatusCode::Ok)
.body(serde_json::to_value(&ApiResponse { .body(serde_json::to_value(&ApiResponse {
message: "Data stored successfully.".to_string(), message: "Data stored successfully.".to_string(),
@ -242,9 +244,9 @@ pub async fn handle_retrieve(req: Request<StorageService>) -> tide::Result<Respo
let svc = req.state(); let svc = req.state();
match svc.retrieve_data(&key).await { match svc.retrieve_data(&key).await {
Ok(value) => { Ok(value) => {
let encoded_value = hex::encode(value);
Ok(Response::builder(StatusCode::Ok) Ok(Response::builder(StatusCode::Ok)
.body(serde_json::to_value(&RetrieveResponse { key, value: encoded_value })?) .header("Content-Type", "application/octet-stream")
.body(value)
.build()) .build())
} }
Err(e) => Ok(Response::builder(StatusCode::NotFound).body(e).build()), Err(e) => Ok(Response::builder(StatusCode::NotFound).body(e).build()),
@ -255,7 +257,7 @@ pub fn create_app(no_ttl_permanent: bool, storage_dir: impl Into<String>) -> tid
let svc = StorageService::new(storage_dir); let svc = StorageService::new(storage_dir);
let mut app = tide::with_state(svc); let mut app = tide::with_state(svc);
app.at("/health").get(handle_health); app.at("/health").get(handle_health);
app.at("/store").post(move |req| handle_store(req, no_ttl_permanent)); app.at("/store/:key").post(move |req| handle_store(req, no_ttl_permanent));
app.at("/retrieve/:key").get(handle_retrieve); app.at("/retrieve/:key").get(handle_retrieve);
app app
} }

View File

@ -5,7 +5,7 @@ use sdk_storage::{StorageService, create_app};
use tide::log; use tide::log;
const STORAGE_DIR: &str = "./storage"; const STORAGE_DIR: &str = "./storage";
const PORT: u16 = 8081; const PORT: u16 = 8080;
const DEFAULT_TTL: u64 = 86400; const DEFAULT_TTL: u64 = 86400;