} [
1 cut* swap first2 '[ _ _ url-append-path ] unit-test
] each
+
+! RFC 3986 6.2.2. Syntax Normalization
+{ URL" example://a/b/c/%7Bfoo%7D" } [
+ URL" eXAMPLE://a/./b/../b/%63/%7bfoo%7d"
+] unit-test
+
+! RFC 3986 6.2.3. Scheme-Based Normalization
+{ t } [
+ {
+ "http://example.com"
+ "http://example.com/"
+ "http://example.com:/"
+ "http://example.com:80/"
+ } [ >url present "http://example.com/" = ] all?
+] unit-test
+
<PRIVATE
+: remove-dot-segments ( path -- path' )
+ [ "//" split1 ] [ "/" glue ] while*
+ [ "/./" split1 ] [ "/" glue ] while*
+ [ "/../" split1 ] [ [ "/" split1-last drop ] dip "/" glue ] while*
+ "/.." ?tail [ "/" split1-last drop "/" append ] when
+ "../" ?head [ "/" prepend ] when
+ "./" ?head [ "/" prepend ] when
+ "/." ?tail [ "/" append ] when
+ [ "/" ] when-empty ;
+
: parse-path ( string -- path )
- "/" split [ url-decode "/" "%2F" replace ] map "/" join ;
+ "/" split [ url-decode "/" "%2F" replace ] map "/" join
+ remove-dot-segments ;
EBNF: parse-url [=[
} cleave
] "" make ;
-: remove-dot-segments ( path -- path' )
- [ "//" split1 ] [ "/" glue ] while*
- [ "/./" split1 ] [ "/" glue ] while*
- [ "/../" split1 ] [ [ "/" split1-last drop ] dip "/" glue ] while*
- "/.." ?tail [ "/" split1-last drop "/" append ] when
- "../" ?head [ "/" prepend ] when
- "./" ?head [ "/" prepend ] when
- "/." ?tail [ "/" append ] when
- [ "/" ] when-empty ;
-
PRIVATE>
: url-append-path ( path1 path2 -- path )