Skip to content

URI::FTP#normalize returns incorrect (?) value if original path is empty #185

@maxfelsher

Description

@maxfelsher

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:

uri/lib/uri/generic.rb

Lines 1341 to 1343 in 52077e9

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:

uri/lib/uri/ftp.rb

Lines 245 to 247 in 52077e9

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions