package tiny_httpd

  1. Overview
  2. Docs

Source file Tiny_httpd_util.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
let percent_encode ?(skip=fun _->false) s =
  let buf = Buffer.create (String.length s) in
  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"
      | c -> Buffer.add_char buf c)
    s;
  Buffer.contents buf

let percent_decode (s:string) : _ option =
  let buf = Buffer.create (String.length s) in
  let i = ref 0 in
  try
    while !i < String.length s do
      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
          end;
          i := !i + 3;
        ) else (
          raise Exit (* truncated *)
        )
      | c -> Buffer.add_char buf c; incr i
    done;
    Some (Buffer.contents buf)
  with Exit -> None

OCaml

Innovation. Community. Security.