[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: luasocket passive ftp hack
- From: Steve Elkins <sgelkins@...>
- Date: Sun, 21 Sep 2003 17:52:22 -0400
The support for passive ftp in luasocket is partial, at least in what I
downloaded at the end of last month. Since passive ftp is all I can do
from behind my firewall, I had to come up with a cheap trick. In case
anyone else can use it, I explain it below.
The new function is Private.pasv, which is based on Private.port:
function Private.pasv(control)
local code,answer = Private.command(control, "pasv", nil, {227})
if not code then
print("Private.pasv(): not code: "..answer)
control:close()
end
local host,port = Private.get_pasv(answer)
if not host or not port then
return nil,"couldn't extract host/port from: "..answer
end
server,answer = socket.tcp()
if not server then return nil,answer end
ret,err = server:connect(host,port)
if not ret then return nil,err end
return server
end
Private.get_pasv() is the support for passive ftp that exists in my
copy of luasocket. Private.pasv gets called in Private.download:
@@ -488,7 +499,7 @@
return "Invalid file path"
end
-- setup passive connection
- local server, answer = Private.port(control)
+ local server, answer = Private.pasv(control)
if not server then return answer end
-- ask server to send file or directory listing
code, answer = Private.retrieve(control, server, name,
Note the comment just before the line I changed. When I first read it
I thought: Maybe an honest implementation of passive ftp is planned
sometime! :) But no, the *connection* *is* passive, so the comment's
correct. The passive ftp I mean is getting the server to play the
passive role in the data connection. Anyway, the hackery really shows
in Private.retrieve:
@@ -292,18 +309,12 @@
code, answer = Private.command(control, "retr", name, {150, 125})
end
if not code then return nil, answer end
- data, answer = server:accept()
- server:close()
- if not data then
- control:close()
- return answer
- end
- answer = Private.receive_indirect(data, content_cb)
+ answer = Private.receive_indirect(server, content_cb)
if answer then
control:close()
return answer
end
- data:close()
+ server:close() -- perhaps unnecessary
-- make sure file transfered ok
return Private.check_answer(control, {226, 250})
end
Pretty icky/lazy, but it Works For Me and uploading should be similar
when needed.
Cheers,
Steve