سؤال

لقد حققت النجاح مع لواسوكيتمرفق TCP الخاص به، ولكني أواجه مشكلة مع وحدة FTP الخاصة به.أحصل دائمًا على مهلة عند محاولة استرداد ملف (صغير).يمكنني تنزيل الملف جيدًا باستخدام Firefox أو ftp في الوضع السلبي (على Ubuntu Dapper Linux).

اعتقدت أنه قد أحتاج إلى LuaSocket لاستخدام FTP السلبي، ولكن بعد ذلك وجدت أنه يبدو أنه يفعل ذلك بشكل افتراضي.يمكن الوصول إلى الملف الذي أحاول استعادته عبر FTP باستخدام FTP السلبي عبر برامج أخرى على جهازي، ولكن ليس عبر الوضع النشط.وجدت بعض الحديث حول "اختراق" دعم الوضع السلبي في LuaSocket، وتشير هذه المناقشة إلى أن الإصدارات الأحدث توقفت عن استخدام الوضع السلبي، ولكن يبدو أن الإصدار الخاص بي يستخدم الوضع السلبي على أي حال (أنا أستخدم 2.0.1؛الأحدث هو 2.0.2 ولا يبدو أنه يحتوي على أي تغييرات ذات صلة بحالة الاستخدام الخاصة بي).أنا في حيرة من أمري بشأن كيفية ارتباط هذا المنشور بوضعي، ويرجع ذلك جزئيًا إلى أنه قديم جدًا وأن مصدر LuaSocket الآن لا يشبه كثيرًا الكود الموجود في تلك المناقشة).

لقد قمت بغلي الكود الخاص بي إلى هذا:

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

وهذا يعطيني مهلة.ركضت تحت strace على نظام Linux (مثل ptrace على سولاريس).وهنا نسخة مختصرة:

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)

هناك موقع آخر حاولت الاتصال به، ولكنه يحتوي على كلمة مرور لا يمكنني نشرها هنا، ولكن في هذه الحالة كانت النتائج مختلفة قليلاً...لقد حصلت على تتبع مثل ما ورد أعلاه ولكن مع select() النجاح في النهاية، ثم هذا:

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)

قارن هذا بتتبع برنامج "ftp" الخاص بي في الوضع السلبي (والذي يعمل بشكل جيد، مع ملاحظة أنه لا يضبط المقابس على عدم الحظر كما يفعل LuaSocket):

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 ضد موقعي FTP المختلفين مع إخفاقات مختلفة ولكن متشابهة.لقد جربته أيضًا من جهاز آخر حيث يعمل FTP النشط، ولم يكن حظه أفضل هناك (ربما لأن LuaSocket يستخدم دائمًا الوضع السلبي، مما يمكنني قوله من خلال قراءة المصدر في socket/ftp.lua).

فهل يمكن لأي شخص هنا أن يجعل LuaSocket ثنائي البطانة في الأعلى يعمل؟لاحظ أنه على جهازي، لا يعمل بروتوكول FTP النشط إلى موقع Dell (يمكنني الاتصال ولكن بمجرد القيام بذلك ls يتم قطع الاتصال)، لذا إذا جعلت LuaSocket يعمل، فيرجى أيضًا ملاحظة ما إذا كان FTP النشط إلى موقع Dell من برنامج آخر يعمل على جهازك.

هل كانت مفيدة؟

المحلول

حسنًا.يبدو أن المشكلة تكمن في أن LuaSocket يستخدم "pasv" بأحرف صغيرة.سأحاول اكتشاف حل بديل.


حسنًا.لا، يبدو الإغلاق ملحومًا بشكل أنيق للغاية.ربما يكون أسهل ما يمكنك فعله هو النسخ هذا الملف بالذات إلى مكانه المكافئ في التسلسل الهرمي في مسار سابق في LUA_PATH.أي (عادة) عمل نسخة محلية من الملف، على سبيل المثال. path/to/your/project/socket/ftp.lua.

ثم قم بتحرير الملف المحلي:

-    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"))

على العكس من ذلك، لا يبدو أن رحلة استكشافية navelnaut باستخدام getfenv وgetmetatable وما إلى ذلك تستحق العناء.أنا أعتبرها مشكلة خطيرة في التصميم.(من لواسوكيت)

ومن الجدير بالذكر أن RFC0959 يستخدم أوامر الحروف الكبيرة.(ربما لأنه من عصر ASCII ذو 7 بتات.)

نصائح أخرى

لاحظ أن الخادم يفشل في اتباع مواصفات FTP، التي تنص على أن الأوامر غير حساسة لحالة الأحرف.راجع RFC959، القسم 5.3 "رموز الأوامر مكونة من أربعة أحرف أبجدية أو أقل.يجب التعامل مع الأحرف الأبجدية العلوية والسفلية بشكل متماثل.وبالتالي ، قد يمثل أي مما يلي أمر استرداد:ريتر ريتر ريتر ريتر ريتر"

تم الآن إصلاح هذه المشكلة، حيث يقدم السؤال والإجابة الأولى مساعدة كبيرة.

Luasocket صحيح بالنسبة إلى RFC 959 (التعليق الأول هنا ليس صحيحًا بشأن الأحرف الكبيرة، راجع قسم RFC959 5.2)

على الأقل خادم Microsoft FTP غير متوافق.قد يكون هناك آخرون.

الحل هو تغيير pasv إلى PASV وهو حل بديل لخادم حساس لحالة الأوامر.التفاصيل موجودة في قائمة البريد الإلكتروني في Lua، حيث سيكون الأرشيف متاحًا للوصول إلى الويب خلال أيام قليلة.

(تحرير السطر 59 من ftp.lua)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top