Mahmoud Khaled
Mahmoud Khaled

Reputation: 6276

How can I parse a FTP URL with the username or password having special characters?

I am trying to parse a FTP URL that has some special characters like @ in the username and password:

username:p@[email protected]/mypath

When I try:

URI.parse(url)

I get:

URI::InvalidURIError: the scheme ftp does not accept registry part: username:p@[email protected] (or bad hostname?)

Then, I tried to encode the url:

url = URI.encode(url, '@')

But also got another error:

URI::InvalidURIError: the scheme ftp does not accept registry part: username:p%40sswrd%40ftp.myhost.com (or bad hostname?)

Finally, I tried another solution:

URI::FTP.build(:userinfo => 'username:p@sswrd', :host=>'ftp.myhost.com', :path => '/mypath')

But I also got an error:

URI::InvalidComponentError: bad component(expected user component): p@ssword

I am using ruby 1.8.7.

Upvotes: 5

Views: 2202

Answers (4)

Avael Kross
Avael Kross

Reputation: 428

I was able to parse an ftp url and open it like this:

ftp_regex = /\/\/(.*)?\:(.*)?@([^\/]*)?\/(.*)/
user, password, host, path = ftp_file_url.match(ftp_regex).captures

ftp = Net::FTP.new
ftp.connect(host, 21)
ftp.login(user, password)
ftp.passive = true
file = ftp.getbinaryfile(path, nil)

Upvotes: 0

user1137277
user1137277

Reputation: 233

I needed to set passive mode as I was receiving the following error:

425 Could not open data connection to port XXXXX: Connection timed out

I did this like so:

require 'net/ftp'
ftp = Net::FTP.new
ftp.passive = true
ftp.connect("ftp.myhost.com",21)
ftp.login("username","p@sswd")
ftp.getbinaryfile("/mypath"){|data| puts data}
ftp.close

Upvotes: 0

Mahmoud Khaled
Mahmoud Khaled

Reputation: 6276

require 'net/ftp'
ftp=Net::FTP.new
ftp.connect("ftp.myhost.com",21)
ftp.login("username","p@sswd")
ftp.getbinaryfile("/mypath"){|data| puts data}
ftp.close

Upvotes: 1

josephrider
josephrider

Reputation: 943

If your ftp server supports unicode:

URI::FTP.build(:userinfo => 'username:p%00%40sswrd', :host=>'ftp.myhost.com', :path => '/mypath')

should work. As indicated by this discussion.

But just realized you tried encoding and it failed. Sorry.

Upvotes: 0

Related Questions