From 2b95c181b868e0637740a318e7bb464618686432 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Fri, 22 Nov 2019 13:45:37 -0600 Subject: [PATCH] fix: improved percent encoding of paths --- src/Tiny_httpd_util.ml | 3 ++- src/Tiny_httpd_util.mli | 3 ++- src/bin/http_of_dir.ml | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Tiny_httpd_util.ml b/src/Tiny_httpd_util.ml index 80efcecb..6ea4a197 100644 --- a/src/Tiny_httpd_util.ml +++ b/src/Tiny_httpd_util.ml @@ -1,7 +1,8 @@ -let percent_encode s = +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" diff --git a/src/Tiny_httpd_util.mli b/src/Tiny_httpd_util.mli index ab54263f..16b50f45 100644 --- a/src/Tiny_httpd_util.mli +++ b/src/Tiny_httpd_util.mli @@ -3,9 +3,10 @@ @since NEXT_RELEASE *) -val percent_encode : string -> string +val percent_encode : ?skip:(char -> bool) -> string -> string (** Encode the string into a valid path following https://tools.ietf.org/html/rfc3986#section-2.1 + @param skip if provided, allows to preserve some characters, e.g. '/' in a path. *) val percent_decode : string -> string option diff --git a/src/bin/http_of_dir.ml b/src/bin/http_of_dir.ml index 475008a4..07e03135 100644 --- a/src/bin/http_of_dir.ml +++ b/src/bin/http_of_dir.ml @@ -39,10 +39,14 @@ let human_size (x:int) : string = let header_html = "Content-Type", "text/html" let (//) = Filename.concat +let encode_path s = + U.percent_encode ~skip:(fun c -> c='/') s + let html_list_dir ~top ~parent d : string = let entries = Sys.readdir @@ (top // d) in Array.sort compare entries; let body = Buffer.create 256 in + (* TODO: breadcrumbs for the path, each element a link to the given ancestor dir *) Printf.bprintf body {| http_of_dir %S

Index of %S

@@ -65,7 +69,7 @@ let html_list_dir ~top ~parent d : string = with _ -> "" in Printf.bprintf body "
  • %s %s%s
  • \n" - (U.percent_encode (d // f)) f (if Sys.is_directory fpath then "[dir]" else "") size + (encode_path (d // f)) f (if Sys.is_directory fpath then "[dir]" else "") size ); ) )