Pergunta

Eu tive sucesso com LuaSocket 's instalação de TCP, mas eu estou tendo problemas com seu módulo de FTP. Eu sempre obter um tempo limite ao tentar recuperar um arquivo (pequeno). Eu posso baixar o arquivo muito bem usando o Firefox ou ftp no modo passivo (no Ubuntu Dapper Linux).

Eu pensei que poderia ser que eu preciso LuaSocket usar FTP passivo, mas depois descobri que ela parece fazer isso por padrão. O arquivo que eu estou tentando recuperar via FTP podem ser acessados ??com FTP passivo através de outros programas na minha máquina, mas não via modo ativo. Eu encontrei alguma conversa sobre "hacking" modo passivo apoiar em LuaSocket, e que a discussão implica que versões posteriores parou de usar o modo passivo, mas a minha versão parece usar de qualquer maneira passiva (estou usando o 2.0.1; mais recente é 2.0.2 e não parece ter quaisquer alterações relevantes para o meu uso caso). Estou um pouco confuso sobre como esse post podem dizer respeito a minha situação, em parte porque é muito antiga e fonte de LuaSocket agora tem pouca semelhança com o código em que a discussão).

Eu fervida meu código resume a isto:

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

Isso me dá um tempo limite. Corri-lo sob strace no Linux (o mesmo que ptrace no Solaris). Aqui está uma transcrição resumida:

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)

Existe outro site que eu tentei ligar, mas ele tem uma senha que eu não posso postar aqui, mas, nesse caso, os resultados foram um pouco diferente ... Eu tenho traço como o acima, mas com select() sucedendo no final, então este:

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)

Compare isso com o traço do meu programa "ftp" em modo passivo (que funciona bem, embora note que ele não define as bases para bloqueante como LuaSocket faz):

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

LuaSocket Então eu tentei contra esses dois sites FTP diferentes, com diferentes mas semelhantes falhas. Eu também tentei a partir de outra máquina onde obras FTP ativas, e não tinha nenhum melhor sorte lá (presumivelmente porque LuaSocket está sempre usando o modo passivo, desde que eu posso dizer, lendo a fonte em socket/ftp.lua).

Então, alguém pode aqui fazer a LuaSocket dois-liner no topo trabalho? Note-se que na minha máquina, FTP ativo para o site da Dell não funciona (eu posso ligar, mas assim que eu faço ls ele desconecta), então se você get LuaSocket ao trabalho devem ser observados também se FTP ativo para o site da Dell de outro programa obras em sua máquina.

Foi útil?

Solução

Hm. Parece que o problema é que LuaSocket usa "pasv" em letras minúsculas. Vou tentar descobrir uma solução alternativa.


Hm. Não, parece bastante elegantemente soldadas. A melhor coisa a fazer é provavelmente a cópia esse arquivo em particular para o seu lugar equivalente em uma hierarquia em um caminho no início LUA_PATH. Ou seja, (normalmente) fazer uma cópia local do arquivo, por exemplo, path/to/your/project/socket/ftp.lua.

Em seguida, edite o arquivo 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"))

Perversamente, uma expedição navelnaut usando getfenv, getmetatable, etc não parecia valer a pena. Eu considero isso um problema sério com o design. (De LuaSocket)

É importante notar que RFC0959 usa comandos em maiúsculas. (Provavelmente porque é da era ASCII 7-bit.)

Outras dicas

Note que o servidor não está a seguir a especificação do FTP, que afirma comandos são insensíveis ao caso. Veja RFC959, secção 5.3 "O comando códigos são quatro ou menos caracteres alfabéticos. Maiúsculas e minúsculas caracteres alfabéticos são para ser tratados identicamente. Assim, qualquer um dos seguintes pode representar o comando recuperar: RETR Retr ret ret ret "

Este problema foi corrigido, com a questão e primeira resposta uma grande ajuda.

Luasocket é correto RFC 959 (primeiro comentário aqui não está certo sobre o caso superior, ver secção RFC959 5.2)

Pelo menos servidor de FTP da Microsoft não é compatível. Pode haver outros.

A solução é a mudança pasv para PASV e é uma solução para um servidor sensível caso de comando. Os detalhes estão na lista de e-mail Lua, onde o arquivo será web acessível em poucos dias.

(linha de edição 59 da ftp.lua)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top