download.lua 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #!/usr/local/bin/lua
  2. require"luasocket"
  3. function receive (connection)
  4. connection:settimeout(0)
  5. local s, status = connection:receive (2^10)
  6. if status == "timeout" then
  7. coroutine.yield (connection)
  8. end
  9. return s, status
  10. end
  11. function download (host, file, outfile)
  12. --local f = assert (io.open (outfile, "w"))
  13. local c = assert (socket.connect (host, 80))
  14. c:send ("GET "..file.." HTTP/1.0\r\n\r\n")
  15. while true do
  16. local s, status = receive (c)
  17. --f:write (s)
  18. if status == "closed" then
  19. break
  20. end
  21. end
  22. c:close()
  23. --f:close()
  24. end
  25. local threads = {}
  26. function get (host, file, outfile)
  27. print (string.format ("Downloading %s from %s to %s", file, host, outfile))
  28. local co = coroutine.create (function ()
  29. return download (host, file, outfile)
  30. end)
  31. table.insert (threads, co)
  32. end
  33. function dispatcher ()
  34. while true do
  35. local n = table.getn (threads)
  36. if n == 0 then
  37. break
  38. end
  39. local connections = {}
  40. for i = 1, n do
  41. local status, res = coroutine.resume (threads[i])
  42. if not res then
  43. table.remove (threads, i)
  44. break
  45. else
  46. table.insert (connections, res)
  47. end
  48. end
  49. if table.getn (connections) == n then
  50. socket.select (connections)
  51. end
  52. end
  53. end
  54. local url = arg[1]
  55. if not url then
  56. print (string.format ("usage: %s url [times]", arg[0]))
  57. os.exit()
  58. end
  59. local times = arg[2] or 5
  60. url = string.gsub (url, "^http.?://", "")
  61. local _, _, host, file = string.find (url, "^([^/]+)(/.*)")
  62. local _, _, fn = string.find (file, "([^/]+)$")
  63. for i = 1, times do
  64. get (host, file, fn..i)
  65. end
  66. dispatcher ()