I don't know how common this case is, but I did run into it accidentally while testing some code.
u = URI("ftp://ftp.example.com") # Note that there's no slash at the end
u.normalize.to_s # => "ftp://ftp.example.com/%2F"
I would expect the result to be "ftp://ftp.example.com/" or possibly the same as the original string, "ftp://ftp.example.com". As best as I can tell from RFC 1738, Section 3.2, "ftp://ftp.example.com" and "ftp://ftp.example.com/" are equivalent and refer to whatever the "default" directory is for FTP access, while "ftp://ftp.example.com/%2F" refers to the root directory.
This seems to be caused by a combination of two things. First, this code in URI::Generic#normalize!calls set_path('/') if the path is empty:
|
if path&.empty? |
|
set_path('/') |
|
end |
Second, URI::FTP overrides #set_path so that a leading slash in the argument is percent-encoded and appended to an unencoded slash:
|
def set_path(v) |
|
super("/" + v.sub(/^\//, "%2F")) |
|
end |
I didn't see any tests for normalizing FTP URIs, so I'm not sure if this behavior is intended.