mirror of
https://github.com/c-cube/tiny_httpd.git
synced 2025-12-06 11:15:35 -05:00
feat multipart: add helper to parse boundary
This commit is contained in:
parent
3f37161649
commit
a5a06f0159
3 changed files with 31 additions and 55 deletions
|
|
@ -204,6 +204,30 @@ and parse_headers_rec (self : st) acc : Headers.t =
|
|||
)
|
||||
)
|
||||
|
||||
let parse_content_type (hs : Tiny_httpd.Headers.t) : _ option =
|
||||
match Tiny_httpd.Headers.get "content-type" hs with
|
||||
| None -> None
|
||||
| Some s ->
|
||||
(match String.split_on_char ';' s with
|
||||
| "multipart/form-data" :: tl ->
|
||||
let boundary = ref None in
|
||||
List.iter
|
||||
(fun s ->
|
||||
match Utils_.split1_on ~c:'=' @@ String.trim s with
|
||||
| Some ("boundary", "") -> ()
|
||||
| Some ("boundary", s) ->
|
||||
let s =
|
||||
if s.[0] = '"' && s.[String.length s - 1] = '"' then
|
||||
String.sub s 1 (String.length s - 2)
|
||||
else
|
||||
s
|
||||
in
|
||||
boundary := Some (`boundary s)
|
||||
| _ -> ())
|
||||
tl;
|
||||
!boundary
|
||||
| _ -> None)
|
||||
|
||||
module Private_ = struct
|
||||
type nonrec chunk = chunk = Delim | Eof | Read of int
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ type st
|
|||
val create :
|
||||
?buf_size:int -> ?out_buf_size:int -> boundary:string -> #Iostream.In.t -> st
|
||||
|
||||
val parse_content_type : Tiny_httpd.Headers.t -> [ `boundary of string ] option
|
||||
(** Parse headers for [content-type: multipart/form-data; boundary=…] *)
|
||||
|
||||
type slice = Iostream.Slice.t
|
||||
type event = Part of Tiny_httpd.Headers.t | Read of slice | End_of_input
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
(* module StringMap = Map.Make (String) *)
|
||||
|
||||
let string_eq ~a ~a_start ~b ~len : bool =
|
||||
assert (len <= String.length b);
|
||||
if String.length a >= a_start + len then (
|
||||
|
|
@ -14,56 +12,7 @@ let string_eq ~a ~a_start ~b ~len : bool =
|
|||
) else
|
||||
false
|
||||
|
||||
let ends_with ~suffix ~suffix_length s =
|
||||
let s_length = String.length s in
|
||||
s_length >= suffix_length
|
||||
&& string_eq ~a:s ~a_start:(s_length - suffix_length) ~b:suffix
|
||||
~len:suffix_length
|
||||
|
||||
let rec first_matching p = function
|
||||
| [] -> None
|
||||
| x :: xs ->
|
||||
(match p x with
|
||||
| Some y -> Some y
|
||||
| None -> first_matching p xs)
|
||||
|
||||
let[@inline] option_map f = function
|
||||
| None -> None
|
||||
| Some x -> Some (f x)
|
||||
|
||||
let find_common_idx a b =
|
||||
let rec go i =
|
||||
if i <= 0 then
|
||||
None
|
||||
else if ends_with ~suffix:b ~suffix_length:i a then
|
||||
Some (String.length a - i)
|
||||
else
|
||||
go (i - 1)
|
||||
in
|
||||
go (String.length b)
|
||||
|
||||
(*
|
||||
let[@inline] word = function
|
||||
| "" -> []
|
||||
| w -> [ Some w ]
|
||||
|
||||
let split_on_string ~pattern s =
|
||||
let pattern_length = String.length pattern in
|
||||
let rec go start acc =
|
||||
match Stringext.find_from ~start s ~pattern with
|
||||
| Some match_start ->
|
||||
let before = String.sub s start (match_start - start) in
|
||||
let new_acc = (None :: word before) @ acc in
|
||||
let new_start = match_start + pattern_length in
|
||||
go new_start new_acc
|
||||
| None -> word (Stringext.string_after s start) @ acc
|
||||
in
|
||||
List.rev (go 0 [])
|
||||
|
||||
let split_and_process_string ~boundary s =
|
||||
let f = function
|
||||
| None -> `Delim
|
||||
| Some w -> `Word w
|
||||
in
|
||||
List.map f @@ split_on_string ~pattern:boundary s
|
||||
*)
|
||||
let split1_on ~c s =
|
||||
match String.index s c with
|
||||
| exception Not_found -> None
|
||||
| i -> Some (String.sub s 0 i, String.sub s (i + 1) (String.length s - i - 1))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue