refactor: improve code of percent encode/decode

This commit is contained in:
Simon Cruanes 2019-11-26 19:10:08 -06:00
parent 6852912fbb
commit 9eae697ded

View file

@ -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)