open Lwt
open Cohttp
open Cohttp_lwt_unix
open Omd
let root = "~/server"
let read_file file_name =
let input = open_in file_name in
let content = ref "" in
try
while true do
let line =input_line input ^ "\n" in
content := (!content) ^ line;
done;
!content
with End_of_file ->
close_in input ;
!content
let is_end_with path suf =
let len_p = String.length path in
let len_s = String.length suf in
if len_p < len_s
then false
else
(String.sub path (len_p - len_s) len_s) = suf
let is_md_file path = is_end_with path ".md"
let is_html_file path = is_end_with path ".html"
let html_to_md_name root_path =
let len = String.length root_path in
if is_html_file root_path
then (String.sub root_path 0 (len - 5) ) ^ ".md"
else
root_path
let md_to_html md_file_name =
let md_content = read_file md_file_name in
let my_temp_head = read_file (root ^ "/md_head.html") in
let my_temp_tail = read_file (root ^ "/md_tail.html") in
let omd_md = Omd.of_string md_content in
let omd_html = Omd.to_html omd_md in
my_temp_head ^ omd_html ^ my_temp_tail
let file_cache = Hashtbl.create 100
let file_mtime file_name =
let file_desc = Unix.openfile file_name [O_RDONLY] 7 in
let file_state = Unix.fstat file_desc in
Unix.close file_desc ;
string_of_float file_state.st_mtime
let check_file path =
let root_path = root ^ "/root" ^ path in
try
let file_desc = Unix.openfile root_path [O_RDONLY] 4 in
Unix.close file_desc ;
root_path
with Unix.Unix_error (_, _ ,_) ->
html_to_md_name root_path ;;
let chong_res path =
let root_path = check_file path in
let cache_key = root_path ^ file_mtime root_path in
try
Printf.printf "%s" root_path;
Hashtbl.find file_cache cache_key
with Not_found ->
if is_md_file root_path then
let html_of_md = md_to_html root_path in
Hashtbl.add file_cache cache_key html_of_md;
html_of_md
else
let file_content = read_file root_path in
Hashtbl.add file_cache cache_key file_content;
file_content
let server =
let callback _conn req body =
let uri = req |> Request.uri |> Uri.to_string in
let path = req |> Request.uri |> Uri.path in
let meth = req |> Request.meth |> Code.string_of_method in
let headers = req |> Request.headers |> Header.to_string in
body |> Cohttp_lwt.Body.to_string >|=
(fun body ->
(Printf.sprintf "Uri: %s\nMethod: %s\nHeaders\nHeaders: %s\nBody: %s"
uri meth headers body))
>>= (fun body -> Server.respond_string ~status:`OK
~body:(chong_res path) ())
in
Server.create
~mode:(`TCP (`Port 8000))
(Server.make ~callback ())
let () = ignore (Lwt_main.run server)