ftp: cosmetic fixes

Use single quotes for strings.
Use string interpolation instead of concatenation.
Don't print messages in non-debug mode.
Fix typos in error messages.
Add space after comma, add spaces between operators.
extract code to separate functions
pull/3250/head
Alexey 2019-12-28 10:53:28 +03:00 committed by Alexander Medvednikov
parent c09ce9cb42
commit f40f023487
1 changed files with 68 additions and 39 deletions

View File

@ -5,7 +5,7 @@
Methods: Methods:
ftp.connect(host) ftp.connect(host)
ftp.login(user,passw) ftp.login(user, passw)
pwd := ftp.pwd() pwd := ftp.pwd()
ftp.cd(folder) ftp.cd(folder)
dtp := ftp.pasv() dtp := ftp.pasv()
@ -44,10 +44,10 @@ mut:
fn (dtp DTP) read() []byte { fn (dtp DTP) read() []byte {
mut data := []byte mut data := []byte
for { for {
buf,len := dtp.sock.recv(1024) buf, len := dtp.sock.recv(1024)
if len == 0 { break } if len == 0 { break }
for i:=0;i<len;i++ { for i := 0; i < len; i++ {
data << buf[i] data << buf[i]
} }
} }
@ -75,20 +75,20 @@ fn (ftp FTP) write(data string) ?int {
$if debug { $if debug {
println('FTP.v >>> $data') println('FTP.v >>> $data')
} }
n := ftp.sock.send_string(data + '\n') or { n := ftp.sock.send_string('$data\n') or {
return error('cannot send data') return error('Cannot send data')
} }
return n return n
} }
fn (ftp FTP) read() (int,string) { fn (ftp FTP) read() (int, string) {
mut data := ftp.sock.read_line() mut data := ftp.sock.read_line()
$if debug { $if debug {
println('FTP.v <<< $data') println('FTP.v <<< $data')
} }
if data.len < 5 { if data.len < 5 {
return 0,'' return 0, ''
} }
code := data[0..3].int() code := data[0..3].int()
@ -101,7 +101,7 @@ fn (ftp FTP) read() (int,string) {
} }
} }
return code,data return code, data
} }
pub fn (ftp mut FTP) connect(ip string) bool { pub fn (ftp mut FTP) connect(ip string) bool {
@ -110,7 +110,7 @@ pub fn (ftp mut FTP) connect(ip string) bool {
} }
ftp.sock = sock ftp.sock = sock
code,_ := ftp.read() code, _ := ftp.read()
if code == Connected { if code == Connected {
return true return true
} }
@ -119,16 +119,17 @@ pub fn (ftp mut FTP) connect(ip string) bool {
} }
pub fn (ftp FTP) login(user, passwd string) bool { pub fn (ftp FTP) login(user, passwd string) bool {
ftp.write('USER $user') or {
ftp.write('USER '+user) or { $if debug {
println('ERROR sending user') println('ERROR sending user')
}
return false return false
} }
mut data := '' mut data := ''
mut code := 0 mut code := 0
code,data = ftp.read() code, data = ftp.read()
if code == LoggedIn { if code == LoggedIn {
return true return true
} }
@ -137,12 +138,14 @@ pub fn (ftp FTP) login(user, passwd string) bool {
return false return false
} }
ftp.write('PASS '+passwd) or { ftp.write('PASS $passwd') or {
$if debug {
println('ERROR sending password') println('ERROR sending password')
}
return false return false
} }
code,data = ftp.read() code, data = ftp.read()
if code == LoggedIn { if code == LoggedIn {
return true return true
@ -161,7 +164,7 @@ pub fn (ftp FTP) pwd() string {
ftp.write('PWD') or { ftp.write('PWD') or {
return '' return ''
} }
_,data := ftp.read() _, data := ftp.read()
spl := data.split('"') spl := data.split('"')
if spl.len >= 2 { if spl.len >= 2 {
return spl[1] return spl[1]
@ -174,35 +177,34 @@ pub fn (ftp FTP) cd(dir string) {
mut code, mut data := ftp.read() mut code, mut data := ftp.read()
match code { match code {
Denied { Denied {
println("CD $dir denied!") $if debug {
println('CD $dir denied!')
}
} }
Complete { Complete {
code,data = ftp.read() code, data = ftp.read()
} }
else {} else {}
} }
println('cd $data') $if debug {
println('CD $data')
}
} }
fn new_dtp(msg string) ?DTP { fn new_dtp(msg string) ?DTP {
// it receives a control message 227 like: if !is_dtp_message_valid(msg) {
// '227 Entering Passive Mode (209,132,183,61,48,218)' return error('Bad message')
if !msg.contains('(') || !msg.contains(')') || !msg.contains(',') {
return error('bad message')
} }
t := msg.split('(')[1].split(')')[0].split(',') ip, port := get_host_ip_from_dtp_message(msg)
ip := t[0]+'.'+t[1]+'.'+t[2]+'.'+t[3]
port := t[4].int()*256+t[5].int()
sock := net.dial(ip, port) or { sock := net.dial(ip, port) or {
return error('Cant connect to the data channel') return error('Cannot connect to the data channel')
} }
dtp := DTP { dtp := DTP {
sock : sock sock: sock
ip: ip ip: ip
port: port port: port
} }
@ -211,8 +213,10 @@ fn new_dtp(msg string) ?DTP {
fn (ftp FTP) pasv() ?DTP { fn (ftp FTP) pasv() ?DTP {
ftp.write('PASV') or {} ftp.write('PASV') or {}
code,data := ftp.read() code, data := ftp.read()
println("pass: $data") $if debug {
println('pass: $data')
}
if code != PassiveMode { if code != PassiveMode {
return error('pasive mode not allowed') return error('pasive mode not allowed')
@ -229,16 +233,16 @@ pub fn (ftp FTP) dir() ?[]string {
} }
ftp.write('LIST') or {} ftp.write('LIST') or {}
code,_ := ftp.read() code, _ := ftp.read()
if code == Denied { if code == Denied {
return error('list denied') return error('LIST denied')
} }
if code != OpenDataConnection { if code != OpenDataConnection {
return error('data channel empty') return error('data channel empty')
} }
list_dir := dtp.read() list_dir := dtp.read()
result,_ := ftp.read() result, _ := ftp.read()
if result != CloseDataConnection { if result != CloseDataConnection {
println('LIST not ok') println('LIST not ok')
} }
@ -258,18 +262,18 @@ pub fn (ftp FTP) dir() ?[]string {
pub fn (ftp FTP) get(file string) ?[]byte { pub fn (ftp FTP) get(file string) ?[]byte {
dtp := ftp.pasv() or { dtp := ftp.pasv() or {
return error('cant stablish data connection') return error('Cannot stablish data connection')
} }
ftp.write('RETR $file') or {} ftp.write('RETR $file') or {}
code,_ := ftp.read() code, _ := ftp.read()
if code == Denied { if code == Denied {
return error('permission denied') return error('Permission denied')
} }
if code != OpenDataConnection { if code != OpenDataConnection {
return error('data connection not ready') return error('Data connection not ready')
} }
blob := dtp.read() blob := dtp.read()
@ -277,3 +281,28 @@ pub fn (ftp FTP) get(file string) ?[]byte {
return blob return blob
} }
fn is_dtp_message_valid(msg string) bool {
// An example of message:
// '227 Entering Passive Mode (209,132,183,61,48,218)'
return msg.contains('(') && msg.contains(')') && msg.contains(',')
}
fn get_host_ip_from_dtp_message(msg string) (string, int) {
mut par_start_idx := -1
mut par_end_idx := -1
for i, c in msg {
if c == `(` {
par_start_idx = i + 1
} else if c == `)` {
par_end_idx = i
}
}
data := msg[par_start_idx..par_end_idx].split(',')
ip := data[0..4].join('.')
port := data[4].int() * 256 + data[5].int()
return ip, port
}