@@ -105,6 +105,7 @@ let rec resolve :
105105 | Error msg -> Lwt. return_error @@
106106 `Cannot_parse (arg.Arg. description, msg, name :: prefix)
107107
108+ (* Note : headers are merged with predefined headers *)
108109let io_to_answer : type a. code:int -> headers:(string * string) list -> a io -> a -> string Answer.t =
109110fun ~code ~headers io body ->
110111 match io with
@@ -119,15 +120,18 @@ fun ~code ~headers io body ->
119120 headers= (" content-type" , " application/json" )::headers}
120121
121122let ser_handler :
122- type i o e . ?content_type :string -> ('a -> i -> (o , e ) result Answer. t Lwt. t ) -> 'a ->
123+ type i o e . ?content_type :string -> access_control :(string * string ) list
124+ -> ('a -> i -> (o , e ) result Answer. t Lwt. t ) -> 'a ->
123125 i io -> o io -> e Json_encoding. encoding ->
124126 string -> (string Answer. t , handler_error ) result Lwt. t =
125- fun ?content_type handler args input output errors ->
126- let handle_result {Answer. code; body; headers} = match body with
127- | Ok o -> io_to_answer ~code ~headers output o
127+ fun ?content_type ~access_control handler args input output errors ->
128+ let handle_result {Answer. code; body; headers} =
129+ match body with
130+ | Ok o -> io_to_answer ~code ~headers: (headers @ access_control) output o
128131 | Error e ->
129132 {Answer. code; body = EzEncoding. construct errors e;
130- headers= [" content-type" , " application/json" ]} in
133+ headers= (" content-type" , " application/json" )::access_control }
134+ in
131135 match input with
132136 | Empty -> (fun _ ->
133137 Lwt. catch
@@ -177,11 +181,15 @@ let lookup ?meth ?content_type dir r path : (lookup_ok, lookup_error) result Lwt
177181 begin match MethMap. bindings dir.services with
178182 | [] -> Lwt. return_error `Not_found
179183 | l ->
184+ (* Todo : combine access control headers correctly. *)
185+ let access_control = List. fold_left (fun acc (_ ,rs ) -> match rs with
186+ | Http {service; _} when acc = [] -> Service. access_control service
187+ | _ -> acc) [] l in
180188 let meths = Meth. headers @@ List. map fst l in
181189 let sec_set = List. fold_left (fun acc (_ , rs ) -> match rs with
182190 | Http {service; _} -> Security.StringSet. union acc (Security. headers (Service. security service))
183191 | Websocket _ -> acc) Security.StringSet. empty l in
184- Lwt. return_ok @@ `options (meths @ (Security. header sec_set))
192+ Lwt. return_ok @@ `options (access_control @ meths @ (Security. header sec_set))
185193 end
186194 | Some `HEAD -> Lwt. return_ok `head
187195 | Some (#Meth. t as m ) ->
@@ -190,7 +198,8 @@ let lookup ?meth ?content_type dir r path : (lookup_ok, lookup_error) result Lwt
190198 let input = Service. input service in
191199 let output = Service. output service in
192200 let errors = Service. errors_encoding service in
193- let h = ser_handler ?content_type handler args input output errors in
201+ let access_control = Service. access_control service in
202+ let h = ser_handler ?content_type ~access_control handler args input output errors in
194203 Lwt. return_ok @@ `http h
195204 | `GET , Some (Websocket {service; react; bg; onclose; step} ) ->
196205 let input = Service. input service in
0 commit comments