(
state: &State<Proxy>,
cert: Option<Certificate<'_>>,
store: &str,
data: Data<'_>,
)
| 107 | /// Handle sync request (msgpack + gzip encoded) |
| 108 | #[post("/wavekv/sync/<store>", data = "<data>")] |
| 109 | pub async fn sync_store( |
| 110 | state: &State<Proxy>, |
| 111 | cert: Option<Certificate<'_>>, |
| 112 | store: &str, |
| 113 | data: Data<'_>, |
| 114 | ) -> Result<(ContentType, Vec<u8>), Status> { |
| 115 | verify_gateway_peer(state, cert)?; |
| 116 | |
| 117 | let Some(ref wavekv_sync) = state.wavekv_sync else { |
| 118 | return Err(Status::ServiceUnavailable); |
| 119 | }; |
| 120 | |
| 121 | // Read and decode request |
| 122 | let bytes = data |
| 123 | .open(16.mebibytes()) |
| 124 | .into_bytes() |
| 125 | .await |
| 126 | .map_err(|_| Status::BadRequest)?; |
| 127 | let msg = decode_sync_message(&bytes)?; |
| 128 | |
| 129 | // Reject sync from node_id == 0 |
| 130 | if msg.sender_id == 0 { |
| 131 | warn!("rejected sync from invalid node_id 0"); |
| 132 | return Err(Status::BadRequest); |
| 133 | } |
| 134 | |
| 135 | // Handle sync based on store type |
| 136 | let response = match store { |
| 137 | "persistent" => wavekv_sync.handle_persistent_sync(msg), |
| 138 | "ephemeral" => wavekv_sync.handle_ephemeral_sync(msg), |
| 139 | _ => return Err(Status::NotFound), |
| 140 | } |
| 141 | .map_err(|e| { |
| 142 | tracing::error!("{store} sync failed: {e}"); |
| 143 | Status::InternalServerError |
| 144 | })?; |
| 145 | |
| 146 | // Encode response |
| 147 | let encoded = encode_sync_response(&response)?; |
| 148 | |
| 149 | Ok((ContentType::new("application", "x-msgpack-gz"), encoded)) |
| 150 | } |
nothing calls this directly
no test coverage detected