2008-10-16 6 views
3

J'ai eu du succès avec la fonction TCP de LuaSocket, mais j'ai des problèmes avec son module FTP. Je reçois toujours un délai d'attente en essayant de récupérer un (petit) fichier. Je peux très bien télécharger le fichier en utilisant Firefox ou ftp en mode passif (sur Ubuntu Dapper Linux).LuaSocket FTP expire toujours

Je pensais que j'avais besoin de LuaSocket pour utiliser FTP passif, mais j'ai ensuite trouvé que cela semblait être le cas par défaut. Le fichier que j'essaie de récupérer via FTP est accessible via FTP passif via d'autres programmes de mon ordinateur, mais pas via le mode actif. J'ai trouvé some talk à propos de "hacker" support de mode passif dans LuaSocket, et cette discussion implique que les versions ultérieures ont cessé d'utiliser le mode passif, mais ma version semble utiliser passive de toute façon (j'utilise 2.0.1; semblent avoir des changements pertinents à mon cas d'utilisation). Je suis un peu perplexe quant à la façon dont ce post peut se rapporter à ma situation, en partie parce que c'est très vieux et la source de LuaSocket ressemble maintenant peu au code dans cette discussion).

J'ai fait bouillir mon code à ceci:

local ftp = require "socket.ftp" 
ftp.TIMEOUT = 10 
print(ftp.get("ftp://ftp.us.dell.com/app/dpart.txt")) 

Cela me donne un délai d'attente. Je l'ai couru sous strace sous Linux (identique à ptrace sous Solaris). Voici une transcription abrégée:

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 
recv(3, "230-Welcome to the Dell FTP site."..., 8192, 0) = 971 
send(3, "pasv\r\n", 6, 0)    = 6 
recv(3, 0x8089a58, 8192, 0)    = -1 EAGAIN (Resource temporarily unavailable) 
select(4, [3], NULL, NULL, {9, 999934}) = 0 (Timeout) 

Il y a un autre site que j'ai essayé de se connecter à, mais il a un mot de passe que je ne peux pas poster ici, mais dans ce cas, les résultats étaient légèrement différents ... Je suis trace comme le mais avec select() succédant à la fin, alors ceci:

recv(3, "227 Entering Passive Mode (123,456,789,0,12,34)\r\n", 8192, 0) = 49 
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4 
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0 
connect(4, {sa_family=AF_INET, sin_port=htons(12345), sin_addr=inet_addr("123.456.789.0")}, 16) = -1 EINPROGRESS (Operation now in progress) 
select(5, [4], [4], NULL, {9, 999694}) = 0 (Timeout) 

Comparez cela à la trace de mon programme « ftp » en mode passif (qui fonctionne très bien, mais note qu'il ne fixe pas les prises de courant à non bloquant comme LuaSocket fait):

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 6 
write(5, "PASV\r\n", 6)     = 6 
read(3, "227 Entering Passive Mode (123,456,789,0,12,34)\r\n", 1024) = 51 
connect(6, {sa_family=AF_INET, sin_port=htons(12345), sin_addr=inet_addr("123.456.789.0")}, 16) = 0 

J'ai donc essayé LuaSocket contre ces deux sites FTP différents avec des échecs différents mais similaires. Je l'ai aussi essayé à partir d'une autre machine où le FTP actif fonctionne, et il n'y a pas eu de meilleure chance (probablement parce que LuaSocket utilise toujours le mode passif, d'après ce que je peux dire en lisant la source en socket/ftp.lua).

Alors, est-ce que quelqu'un peut faire en sorte que le LuaSocket soit deux fois plus haut? Notez que sur ma machine, le FTP actif sur le site de Dell ne fonctionne pas (je peux me connecter mais dès que je le sais, il se déconnecte), donc si vous utilisez LuaSocket, veuillez également noter si FTP fonctionne sur le site de Dell depuis un autre programme sur votre machine.

Répondre

3

Hm. Il semble que le problème est que LuaSocket utilise "pasv" en minuscules. Je vais essayer de trouver une solution.


Hm. Non, il a l'air assez soudé soudé. La chose la plus facile à faire est probablement de copier ce fichier particulier à son emplacement équivalent dans une hiérarchie dans un chemin antérieur dans LUA_PATH. C'est-à-dire (habituellement) faire une copie locale du fichier, par ex. path/to/your/project/socket/ftp.lua.

ensuite modifier le fichier local:

- self.try(self.tp:command("user", user or USER)) 
+ self.try(self.tp:command("USER", user or USER)) 
-  self.try(self.tp:command("pass", password or PASSWORD)) 
+  self.try(self.tp:command("PASS", password or PASSWORD)) 
- self.try(self.tp:command("pasv")) 
+ self.try(self.tp:command("PASV")) 
- self.try(self.tp:command("port", arg)) 
+ self.try(self.tp:command("PORT", arg)) 
- local command = sendt.command or "stor" 
+ local command = sendt.command or "STOR" 
- self.try(self.tp:command("cwd", dir)) 
+ self.try(self.tp:command("CWD", dir)) 
- self.try(self.tp:command("type", type)) 
+ self.try(self.tp:command("TYPE", type)) 
- self.try(self.tp:command("quit")) 
+ self.try(self.tp:command("QUIT")) 

Perversement, une expédition navelnaut utilisant getfenv, getmetatable, etc ne semble pas valoir la peine. Je considère que c'est un problème sérieux avec le design.(de LuaSocket)

Il est à noter que RFC0959 utilise des commandes de majuscules. (Probablement parce qu'il provient de l'ère ASCII à 7 bits.)

+0

Cela fonctionne totalement. En plus de votre liste, j'ai aussi changé "retr" en "RETR", mais c'est tout. Bien joué. –

+0

J'ai également envoyé ceci au mainteneur de LuaSocket. J'espère que la prochaine version sera corrigée. –

1

Notez que le serveur ne respecte pas la spécification FTP, qui indique que les commandes ne sont pas sensibles à la casse. Voir RFC959, section 5.3 "Les codes de commande sont au maximum de quatre caractères alphabétiques Les caractères alphabétiques majuscules et minuscules doivent être traités de manière identique Ainsi, l'un des éléments suivants peut représenter la commande de récupération : RETR Retr Retr ReTr rETr"

1

Ce problème est maintenant résolu, avec la question et la première réponse d'une grande aide.

luasocket est correct à la RFC 959 (premier commentaire ici n'est pas juste au sujet de majuscules, voir la section RFC959 5.2)

Au moins serveur FTP de Microsoft est non conforme. Il pourrait y en avoir d'autres.

La solution est de passer PASV à PASV et est une solution de contournement pour un serveur sensible à la casse de commande. Les détails sont sur la liste d'email de Lua, où l'archive sera accessible sur le web dans quelques jours.

(modifier la ligne 59 de ftp.lua)