11//! Defines Rojo's HTTP API, all under /api. These endpoints generally return
22//! JSON.
33
4- use std:: {
5- collections:: { HashMap , HashSet } ,
6- fs,
7- path:: PathBuf ,
8- str:: FromStr ,
9- sync:: Arc ,
10- } ;
4+ use std:: { collections:: HashMap , fs, path:: PathBuf , str:: FromStr , sync:: Arc } ;
115
126use futures:: { sink:: SinkExt , stream:: StreamExt } ;
137use hyper:: { body, Body , Method , Request , Response , StatusCode } ;
@@ -30,7 +24,10 @@ use crate::{
3024 } ,
3125 util:: { json, json_ok} ,
3226 } ,
33- web_api:: { BufferEncode , InstanceUpdate , RefPatchResponse , SerializeResponse } ,
27+ web_api:: {
28+ BufferEncode , InstanceUpdate , RefPatchRequest , RefPatchResponse , SerializeRequest ,
29+ SerializeResponse ,
30+ } ,
3431} ;
3532
3633pub async fn call ( serve_session : Arc < ServeSession > , mut request : Request < Body > ) -> Response < Body > {
@@ -53,12 +50,8 @@ pub async fn call(serve_session: Arc<ServeSession>, mut request: Request<Body>)
5350 )
5451 }
5552 }
56- ( & Method :: GET , path) if path. starts_with ( "/api/serialize/" ) => {
57- service. handle_api_serialize ( request) . await
58- }
59- ( & Method :: GET , path) if path. starts_with ( "/api/ref-patch/" ) => {
60- service. handle_api_ref_patch ( request) . await
61- }
53+ ( & Method :: POST , "/api/serialize" ) => service. handle_api_serialize ( request) . await ,
54+ ( & Method :: POST , "/api/ref-patch" ) => service. handle_api_ref_patch ( request) . await ,
6255
6356 ( & Method :: POST , path) if path. starts_with ( "/api/open/" ) => {
6457 service. handle_api_open ( request) . await
@@ -229,22 +222,30 @@ impl ApiService {
229222 /// that correspond to the requested Instances. These values have their
230223 /// `Value` property set to point to the requested Instance.
231224 async fn handle_api_serialize ( & self , request : Request < Body > ) -> Response < Body > {
232- let argument = & request . uri ( ) . path ( ) [ "/api/serialize/" . len ( ) .. ] ;
233- let requested_ids : Result < Vec < Ref > , _ > = argument . split ( ',' ) . map ( Ref :: from_str ) . collect ( ) ;
225+ let session_id = self . serve_session . session_id ( ) ;
226+ let body = body :: to_bytes ( request . into_body ( ) ) . await . unwrap ( ) ;
234227
235- let requested_ids = match requested_ids {
236- Ok ( ids ) => ids ,
237- Err ( _ ) => {
228+ let request : SerializeRequest = match json :: from_slice ( & body ) {
229+ Ok ( request ) => request ,
230+ Err ( err ) => {
238231 return json (
239- ErrorResponse :: bad_request ( "Malformed ID list" ) ,
232+ ErrorResponse :: bad_request ( format ! ( "Invalid body: {}" , err ) ) ,
240233 StatusCode :: BAD_REQUEST ,
241234 ) ;
242235 }
243236 } ;
237+
238+ if request. session_id != session_id {
239+ return json (
240+ ErrorResponse :: bad_request ( "Wrong session ID" ) ,
241+ StatusCode :: BAD_REQUEST ,
242+ ) ;
243+ }
244+
244245 let mut response_dom = WeakDom :: new ( InstanceBuilder :: new ( "Folder" ) ) ;
245246
246247 let tree = self . serve_session . tree ( ) ;
247- for id in & requested_ids {
248+ for id in & request . ids {
248249 if let Some ( instance) = tree. get_instance ( * id) {
249250 let clone = response_dom. insert (
250251 Ref :: none ( ) ,
@@ -290,20 +291,26 @@ impl ApiService {
290291 /// and referent properties need to be updated after the serialize
291292 /// endpoint is used.
292293 async fn handle_api_ref_patch ( self , request : Request < Body > ) -> Response < Body > {
293- let argument = & request. uri ( ) . path ( ) [ "/api/ref-patch/" . len ( ) ..] ;
294- let requested_ids: Result < HashSet < Ref > , _ > =
295- argument. split ( ',' ) . map ( Ref :: from_str) . collect ( ) ;
294+ let session_id = self . serve_session . session_id ( ) ;
295+ let body = body:: to_bytes ( request. into_body ( ) ) . await . unwrap ( ) ;
296296
297- let requested_ids = match requested_ids {
298- Ok ( ids ) => ids ,
299- Err ( _ ) => {
297+ let request : RefPatchRequest = match json :: from_slice ( & body ) {
298+ Ok ( request ) => request ,
299+ Err ( err ) => {
300300 return json (
301- ErrorResponse :: bad_request ( "Malformed ID list" ) ,
301+ ErrorResponse :: bad_request ( format ! ( "Invalid body: {}" , err ) ) ,
302302 StatusCode :: BAD_REQUEST ,
303303 ) ;
304304 }
305305 } ;
306306
307+ if request. session_id != session_id {
308+ return json (
309+ ErrorResponse :: bad_request ( "Wrong session ID" ) ,
310+ StatusCode :: BAD_REQUEST ,
311+ ) ;
312+ }
313+
307314 let mut instance_updates: HashMap < Ref , InstanceUpdate > = HashMap :: new ( ) ;
308315
309316 let tree = self . serve_session . tree ( ) ;
@@ -312,7 +319,7 @@ impl ApiService {
312319 let Variant :: Ref ( prop_value) = prop_value else {
313320 continue ;
314321 } ;
315- if let Some ( target_id) = requested_ids . get ( prop_value) {
322+ if let Some ( target_id) = request . ids . get ( prop_value) {
316323 let instance_id = instance. id ( ) ;
317324 let update =
318325 instance_updates
0 commit comments