@@ -92,7 +92,8 @@ let rec resolve :
9292 (resolved_directory , lookup_error ) result Lwt. t =
9393 fun prefix dir args path ->
9494 match path, dir with
95- | [] , dir -> Lwt. return_ok (Dir (dir, args))
95+ | [] , dir ->
96+ Lwt. return_ok (Dir (dir, args))
9697 | _name :: _path , { subdirs = None , None ; _ } -> Lwt. return_error `Not_found
9798 | name :: path , { subdirs = Some static , None ; _ } ->
9899 begin match StringMap. find_opt name static with
@@ -114,28 +115,33 @@ let rec resolve :
114115 | Error msg -> Lwt. return_error @@
115116 `Cannot_parse (arg.Arg. description, msg, name :: prefix)
116117
117- let io_to_answer : type a. code:int -> a io -> a -> string Answer.t = fun ~code io body ->
118+ (* Note : headers are merged with predefined headers *)
119+ let io_to_answer : type a. code:int -> headers:(string * string) list -> a io -> a -> string Answer.t =
120+ fun ~code ~headers io body ->
118121 match io with
119- | Empty -> {Answer. code; body= " " ; headers= [] }
122+ | Empty -> {Answer. code; body= " " ; headers}
120123 | Raw l ->
121124 let content_type = match l with
122125 | [] -> " application/octet-stream"
123126 | h :: _ -> Mime. to_string h in
124- {Answer. code; body; headers= [ " content-type" , content_type] }
127+ {Answer. code; body; headers= ( " content-type" , content_type)::headers }
125128 | Json enc ->
126129 {Answer. code; body = EzEncoding. construct enc body;
127- headers= [ " content-type" , " application/json" ] }
130+ headers= ( " content-type" , " application/json" )::headers }
128131
129132let ser_handler :
130- type i o e . ?content_type :string -> ('a -> i -> (o , e ) result Answer. t Lwt. t ) -> 'a ->
133+ type i o e . ?content_type :string -> access_control :(string * string ) list
134+ -> ('a -> i -> (o , e ) result Answer. t Lwt. t ) -> 'a ->
131135 i io -> o io -> e Json_encoding. encoding ->
132136 string -> (string Answer. t , handler_error ) result Lwt. t =
133- fun ?content_type handler args input output errors ->
134- let handle_result {Answer. code; body; _} = match body with
135- | Ok o -> io_to_answer ~code output o
137+ fun ?content_type ~access_control handler args input output errors ->
138+ let handle_result {Answer. code; body; headers} =
139+ match body with
140+ | Ok o -> io_to_answer ~code ~headers: (headers @ access_control) output o
136141 | Error e ->
137142 {Answer. code; body = EzEncoding. construct errors e;
138- headers= [" content-type" , " application/json" ]} in
143+ headers= (" content-type" , " application/json" )::access_control }
144+ in
139145 match input with
140146 | Empty -> (fun _ ->
141147 Lwt. catch
@@ -185,11 +191,15 @@ let lookup ?meth ?content_type dir r path : (lookup_ok, lookup_error) result Lwt
185191 begin match MethMap. bindings dir.services with
186192 | [] -> Lwt. return_error `Not_found
187193 | l ->
194+ (* Todo : combine access control headers correctly. *)
195+ let access_control = List. fold_left (fun acc (_ ,rs ) -> match rs with
196+ | Http {service; _} when acc = [] -> Service. access_control service
197+ | _ -> acc) [] l in
188198 let meths = Meth. headers @@ List. map fst l in
189199 let sec_set = List. fold_left (fun acc (_ , rs ) -> match rs with
190200 | Http {service; _} -> Security.StringSet. union acc (Security. headers (Service. security service))
191201 | Websocket _ -> acc) Security.StringSet. empty l in
192- Lwt. return_ok @@ `options (meths @ (Security. header sec_set))
202+ Lwt. return_ok @@ `options (access_control @ meths @ (Security. header sec_set))
193203 end
194204 | Some `HEAD -> Lwt. return_ok `head
195205 | Some (#Meth. t as m ) ->
@@ -198,7 +208,8 @@ let lookup ?meth ?content_type dir r path : (lookup_ok, lookup_error) result Lwt
198208 let input = Service. input service in
199209 let output = Service. output service in
200210 let errors = Service. errors_encoding service in
201- let h = ser_handler ?content_type handler args input output errors in
211+ let access_control = Service. access_control service in
212+ let h = ser_handler ?content_type ~access_control handler args input output errors in
202213 Lwt. return_ok @@ `http h
203214 | `GET , Some (Websocket {service; react; bg; onclose; step} ) ->
204215 let input = Service. input service in
0 commit comments