diff --git a/src/Tiny_httpd_util.ml b/src/Tiny_httpd_util.ml index 6dd12717..6aac8a02 100644 --- a/src/Tiny_httpd_util.ml +++ b/src/Tiny_httpd_util.ml @@ -3,31 +3,16 @@ let percent_encode ?(skip=fun _->false) s = String.iter (function | c when skip c -> Buffer.add_char buf c - | ' ' -> Buffer.add_string buf "%20" - | '!' -> Buffer.add_string buf "%21" - | '"' -> Buffer.add_string buf "%22" - | '#' -> Buffer.add_string buf "%23" - | '$' -> Buffer.add_string buf "%24" - | '%' -> Buffer.add_string buf "%25" - | '&' -> Buffer.add_string buf "%26" - | '\'' -> Buffer.add_string buf "%27" - | '(' -> Buffer.add_string buf "%28" - | ')' -> Buffer.add_string buf "%29" - | '*' -> Buffer.add_string buf "%2A" - | '+' -> Buffer.add_string buf "%2B" - | ',' -> Buffer.add_string buf "%2C" - | '/' -> Buffer.add_string buf "%2F" - | ':' -> Buffer.add_string buf "%3A" - | ';' -> Buffer.add_string buf "%3B" - | '=' -> Buffer.add_string buf "%3D" - | '?' -> Buffer.add_string buf "%3F" - | '@' -> Buffer.add_string buf "%40" - | '[' -> Buffer.add_string buf "%5B" - | ']' -> Buffer.add_string buf "%5D" + | (' ' | '!' | '"' | '#' | '$' | '%' | '&' | '\'' | '(' | ')' | '*' | '+' + | ',' | '/' | ':' | ';' | '=' | '?' | '@' | '[' | ']' | '~') + as c -> + Printf.bprintf buf "%%%x" (Char.code c) | c -> Buffer.add_char buf c) s; Buffer.contents buf +let hex_int (s:string) : int = Scanf.sscanf s "%x" (fun x->x) + let percent_decode (s:string) : _ option = let buf = Buffer.create (String.length s) in let i = ref 0 in @@ -36,34 +21,15 @@ let percent_decode (s:string) : _ option = match String.get s !i with | '%' -> if !i+2 < String.length s then ( - begin match String.sub s (!i+1) 2 with - | "20" -> Buffer.add_char buf ' ' - | "21" -> Buffer.add_char buf '!' - | "22" -> Buffer.add_char buf '"' - | "23" -> Buffer.add_char buf '#' - | "24" -> Buffer.add_char buf '$' - | "25" -> Buffer.add_char buf '%' - | "26" -> Buffer.add_char buf '&' - | "27" -> Buffer.add_char buf '\'' - | "28" -> Buffer.add_char buf '(' - | "29" -> Buffer.add_char buf ')' - | "2A" -> Buffer.add_char buf '*' - | "2B" -> Buffer.add_char buf '+' - | "2C" -> Buffer.add_char buf ',' - | "2F" -> Buffer.add_char buf '/' - | "3A" -> Buffer.add_char buf ':' - | "3B" -> Buffer.add_char buf ';' - | "3D" -> Buffer.add_char buf '=' - | "3F" -> Buffer.add_char buf '?' - | "40" -> Buffer.add_char buf '@' - | "5B" -> Buffer.add_char buf '[' - | "5D" -> Buffer.add_char buf ']' - | _ -> raise Exit + begin match hex_int @@ String.sub s (!i+1) 2 with + | n -> Buffer.add_char buf (Char.chr n) + | exception _ -> raise Exit end; i := !i + 3; ) else ( raise Exit (* truncated *) ) + | '+' -> Buffer.add_char buf ' '; incr i (* for query strings *) | c -> Buffer.add_char buf c; incr i done; Some (Buffer.contents buf)