Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
static.ml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83(* * Copyright (c) 2012-2017 Anil Madhavapeddy <anil@recoil.org> * Copyright (c) 2013-2015 Thomas Gazagnaire <thomas@gazazagnaire.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * cohttp v6.2.1 *) module Key = Mirage_kv.Key module Connection = Cohttp.Connection [@@warning "-3"] module HTTP (FS : Mirage_kv.RO) (S : Cohttp_lwt.S.Server) = struct open Lwt.Infix open Astring let failf fmt = Fmt.failwith fmt let read_fs t name = FS.get t (Key.v name) >>= function | Error e -> failf "read %a" FS.pp_error e | Ok buf -> Lwt.return buf let exists t name = FS.exists t (Key.v name) >|= function | Ok (Some `Value) -> true | Ok (Some _ | None) -> false | Error e -> Fmt.failwith "exists %a" FS.pp_error e let dispatcher request_fn = let rec fn fs uri = match Uri.path uri with | ("" | "/") as path -> Logs.info (fun f -> f "request for '%s'" path); fn fs (Uri.with_path uri "index.html") | path when String.is_suffix ~affix:"/" path -> Logs.info (fun f -> f "request for '%s'" path); fn fs (Uri.with_path uri "index.html") | path -> Logs.info (fun f -> f "request for '%s'" path); Lwt.catch (fun () -> read_fs fs path >>= fun body -> let mime_type = Magic_mime.lookup path in let headers = Cohttp.Header.init_with "content-type" mime_type in let headers = match request_fn with | None -> headers | Some fn -> fn uri headers in S.respond_string ~status:`OK ~body ~headers ()) (fun _exn -> let with_index = Fmt.str "%s/index.html" path in exists fs with_index >>= function | true -> fn fs (Uri.with_path uri with_index) | false -> S.respond_not_found ()) in fn let start ~http_port ?request_fn fs http = let callback (_, cid) request _body = let uri = Cohttp.Request.uri request in let cid = Connection.to_string cid in Logs.info (fun f -> f "[%s] serving %s" cid (Uri.to_string uri)); dispatcher request_fn fs uri in let conn_closed (_, cid) = let cid = Connection.to_string cid in Logs.info (fun f -> f "[%s] closing" cid) in Logs.info (fun f -> f "listening on %d/TCP" http_port); http (`TCP http_port) (S.make ~conn_closed ~callback ()) end