/server/dispatch.ml

http://github.com/hhughes/ocaml-frui · OCaml · 111 lines · 71 code · 14 blank · 26 comment · 0 complexity · 63b371cf6773307b85901723a984d4b4 MD5 · raw file

  1. (*pp camlp4o -I `ocamlfind query lwt.syntax` lwt-syntax-options.cma lwt-syntax.cma *)
  2. (*
  3. * Copyright (c) 2009 Anil Madhavapeddy <anil@recoil.org>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. *)
  17. open Printf
  18. open Cohttp
  19. open Cohttpserver
  20. open Lwt
  21. open Events
  22. module Resp = struct
  23. (* respond with an error *)
  24. (* HACK *)
  25. let root = "/home/henry/proj/ocaml-frui"
  26. let not_found req err =
  27. let status = `Not_found in
  28. let headers = [ "Cache-control", "no-cache" ] in
  29. let resp = sprintf "<html><body><h1>Error</h1><p>%s</p></body></html>" err in
  30. let body = [`String resp] in
  31. Http_response.init ~body ~headers ~status ()
  32. (* internal error *)
  33. let internal_error err =
  34. let status = `Internal_server_error in
  35. let headers = [ "Cache-control", "no-cache" ] in
  36. let resp = sprintf "<html><body><h1>Internal Server Error</h1><p>%s</p></body></html>" err in
  37. let body = [`String resp] in
  38. Http_response.init ~body ~headers ~status ()
  39. (* dynamic response *)
  40. let dyn req body =
  41. let status = `OK in
  42. let headers = [] in
  43. Http_response.init ~body ~headers ~status ()
  44. let get_file file req =
  45. let size = (Unix.stat file).Unix.st_size in
  46. let fd = Unix.openfile file [Unix.O_RDONLY] 0o444 in
  47. let ic = Lwt_io.of_unix_fd ~close:(fun () -> Unix.close fd; Lwt.return ()) ~mode:Lwt_io.input fd in
  48. let t,u = Lwt.wait () in
  49. let body = [`Inchan (Int64.of_int size, ic, u)] in
  50. return (dyn req body)
  51. let events = get_file "/home/henry/proj/ocaml-frui/src/visualiser/dummy.json"
  52. let pop file = get_file (sprintf "/home/henry/proj/datasources/worldbank/pop/%s" file)
  53. let gdp file = get_file (sprintf "/home/henry/proj/datasources/worldbank/gdp/%s" file)
  54. let life file = get_file (sprintf "/home/henry/proj/datasources/worldbank/life/%s" file)
  55. let tests file = get_file (sprintf "/home/henry/proj/ocaml-frui/tests/%s" file)
  56. let elec = get_file "/home/henry/proj/datasources/elec/primary-cs1-riser/G-lighting/S-m22-2011-01.json"
  57. let elec2 = get_file "/home/henry/proj/datasources/elec/primary-cs1-riser/F-lighting/S-m23-2011-01.json"
  58. let elec3 = get_file "/home/henry/proj/datasources/elec/primary-cs1-riser/S-lighting/S-m25-2011-01.json"
  59. let next_msg req =
  60. let body = [`String (Thread_state.get_events ())] in
  61. return (dyn req body)
  62. let reset req =
  63. let body = [`String ""] in
  64. Thread_state.reset ();
  65. return (dyn req body)
  66. (* index page *)
  67. let index req =
  68. let body = [`String "HELLO WORLD"] in
  69. return (dyn req body)
  70. (* dispatch non-file URLs *)
  71. let dispatch req = function
  72. | [], _
  73. (* | "" :: "index.html" :: [], _->
  74. index req *)
  75. | "" :: "events" :: [], _ -> events req
  76. | "" :: "pop" :: file :: [], _ -> pop file req
  77. | "" :: "gdp" :: file :: [], _ -> gdp file req
  78. | "" :: "life" :: file :: [], _ -> life file req
  79. | "" :: "tests" :: file :: [], _ -> tests file req
  80. | "" :: "elec" :: [], _ -> elec req
  81. | "" :: "elec2" :: [], _ -> elec2 req
  82. | "" :: "elec3" :: [], _ -> elec3 req
  83. | "" :: "next_msg" :: [], _ -> next_msg req
  84. | "" :: "reset" :: [], _ -> reset req
  85. | _, path -> try get_file (root ^ path) req
  86. with _ -> return (not_found req "dispatch")
  87. end
  88. (* main callback function *)
  89. let t con_id req =
  90. let path = Http_request.path req in
  91. printf "%s %s [%s]\n%!" (Http_common.string_of_method (Http_request.meth req)) path
  92. (String.concat "," (List.map (fun (h,v) -> sprintf "%s=%s" h v)
  93. (Http_request.params_get req)));
  94. (* normalize path to strip out ../. and such *)
  95. let path_elem = Neturl.norm_path (Pcre.split ~pat:"/" path) in
  96. lwt resp = Resp.dispatch req (path_elem, path) in
  97. Http_daemon.respond_with resp