path->url: ensure directory paths have a trailing slash
If a path to a directory is converted to an URL it loses its trailing path separator. This can lead to a bug if the URL is used as a base URL to build other URLs (e.g. combine-url/relative).
This commit is contained in:
parent
36bfae9497
commit
d8ff661118
|
@ -558,47 +558,53 @@
|
||||||
";"))
|
";"))
|
||||||
|
|
||||||
(define (path->url path)
|
(define (path->url path)
|
||||||
(let ([url-path
|
(let* ([spath (simplify-path path #f)]
|
||||||
(let loop ([path (simplify-path path #f)][accum null])
|
[dir? (let-values ([(b n dir?) (split-path spath)]) dir?)]
|
||||||
(let-values ([(base name dir?) (split-path path)])
|
;; If original path is a directory the resulting URL
|
||||||
(cond
|
;; should have a trailing forward slash
|
||||||
[(not base)
|
[url-tail (if dir? (list (make-path/param "" null)) null)]
|
||||||
(append (map
|
[url-path
|
||||||
(lambda (s)
|
(let loop ([path spath][accum null])
|
||||||
(make-path/param s null))
|
(let-values ([(base name dir?) (split-path path)])
|
||||||
(if (eq? (path-convention-type path) 'windows)
|
(cond
|
||||||
;; For Windows, massage the root:
|
[(not base)
|
||||||
(let ([s (regexp-replace
|
(append (map
|
||||||
#rx"[/\\\\]$"
|
(lambda (s)
|
||||||
(bytes->string/utf-8 (path->bytes name))
|
(make-path/param s null))
|
||||||
"")])
|
(if (eq? (path-convention-type path) 'windows)
|
||||||
(cond
|
;; For Windows, massage the root:
|
||||||
[(regexp-match? #rx"^\\\\\\\\[?]\\\\[a-zA-Z]:" s)
|
(let ([s (regexp-replace
|
||||||
;; \\?\<drive>: path:
|
#rx"[/\\\\]$"
|
||||||
(regexp-split #rx"[/\\]+" (substring s 4))]
|
(bytes->string/utf-8 (path->bytes name))
|
||||||
[(regexp-match? #rx"^\\\\\\\\[?]\\\\UNC" s)
|
"")])
|
||||||
;; \\?\ UNC path:
|
(cond
|
||||||
(regexp-split #rx"[/\\]+" (substring s 7))]
|
[(regexp-match? #rx"^\\\\\\\\[?]\\\\[a-zA-Z]:" s)
|
||||||
[(regexp-match? #rx"^[/\\]" s)
|
;; \\?\<drive>: path:
|
||||||
;; UNC path:
|
(regexp-split #rx"[/\\]+" (substring s 4))]
|
||||||
(regexp-split #rx"[/\\]+" s)]
|
[(regexp-match? #rx"^\\\\\\\\[?]\\\\UNC" s)
|
||||||
[else
|
;; \\?\ UNC path:
|
||||||
(list s)]))
|
(regexp-split #rx"[/\\]+" (substring s 7))]
|
||||||
;; On other platforms, we drop the root:
|
[(regexp-match? #rx"^[/\\]" s)
|
||||||
null))
|
;; UNC path:
|
||||||
accum)]
|
(regexp-split #rx"[/\\]+" s)]
|
||||||
[else
|
[else
|
||||||
(let ([accum (cons (make-path/param
|
(list s)]))
|
||||||
(if (symbol? name)
|
;; On other platforms, we drop the root:
|
||||||
name
|
null))
|
||||||
(bytes->string/utf-8
|
accum)]
|
||||||
(path-element->bytes name)))
|
[else
|
||||||
null)
|
(let ([accum (cons (make-path/param
|
||||||
accum)])
|
(if (symbol? name)
|
||||||
(if (eq? base 'relative)
|
name
|
||||||
accum
|
(bytes->string/utf-8
|
||||||
(loop base accum)))])))])
|
(path-element->bytes name)))
|
||||||
(make-url "file" #f "" #f (absolute-path? path) url-path '() #f)))
|
null)
|
||||||
|
accum)])
|
||||||
|
(if (eq? base 'relative)
|
||||||
|
accum
|
||||||
|
(loop base accum)))])))])
|
||||||
|
(make-url "file" #f "" #f (absolute-path? path) (append url-path url-tail) '() #f)))
|
||||||
|
|
||||||
|
|
||||||
(define (url->path url [kind (system-path-convention-type)])
|
(define (url->path url [kind (system-path-convention-type)])
|
||||||
(file://->path url kind))
|
(file://->path url kind))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user