response.ml (1725B)
1 type status = 2 | Input 3 | Sensitive_input 4 | Success 5 | Redirect_temporary 6 | Redirect_permanent 7 | Temporary_failure 8 | Server_unavailable 9 | CGI_error 10 | Proxy_error 11 | Slow_down 12 | Permanent_failure 13 | Not_found 14 | Gone 15 | Proxy_request_refused 16 | Bad_request 17 | Client_certificate_required 18 | Certificate_not_autorised 19 | Certificate_not_valid 20 21 type mime = string 22 type head = status * string 23 type body = status * mime * in_channel 24 25 type response = 26 | Head of head 27 | Body of body 28 29 let int_of_status = function 30 | Input -> 10 31 | Sensitive_input -> 11 32 | Success -> 20 33 | Redirect_temporary -> 30 34 | Redirect_permanent -> 31 35 | Temporary_failure -> 40 36 | Server_unavailable -> 41 37 | CGI_error -> 42 38 | Proxy_error -> 43 39 | Slow_down -> 44 40 | Permanent_failure -> 50 41 | Not_found -> 51 42 | Gone -> 52 43 | Proxy_request_refused -> 53 44 | Bad_request -> 59 45 | Client_certificate_required -> 60 46 | Certificate_not_autorised -> 61 47 | Certificate_not_valid -> 62 48 49 let handle uri = 50 (fun path -> 51 match Unix.(in_channel_of_descr @@ openfile path [ O_RDONLY; O_NONBLOCK ] 0) with 52 | exception _ -> Head (Not_found, "Page Not Found.") 53 | input_chan -> Body (Success, "text/gemini", input_chan)) 54 @@ Filename.concat "." 55 @@ Text.concat "/" 56 @@ List.filter (( <> ) "..") 57 @@ Text.split ~sep:"/" 58 @@ (function 59 | "" -> "index.gmi" 60 | p when Text.ends_with p "/" -> Filename.(concat p "index.gmi") 61 | p -> p) 62 @@ Uri.(pct_decode @@ path uri)