【问题标题】:Produce a download file from CGI in Lua在 Lua 中从 CGI 生成下载文件
【发布时间】:2015-06-26 15:45:02
【问题描述】:

我正在用 lua 编写一个简单的 CGI 程序。我想要实现的是从 CGI 产生响应,使文件能够从浏览器下载。但我就是无法打印数据。我不知道这里发生了什么。下面是代码:

print("Content-Type: text/html; charset=UTF-8")
print("Content-Length:" .. sys.getenv("CONTENT_LENGTH"))
print("Content-Disposition:",'attachment;filename="backup.tar.gz"\n')
print("Content-Type:application/x-tar-gz\n\n")
file=io.popen("some command")
output = file:read('*a')
print(output)
--file:close()

问题是我无法打印内容为二进制的输出。我可以看到输出的类型是字符串。

有什么问题?请给出一些提示。谢谢。

ADD :我不知道这个问题在哪里。让我提供有关我要运行的命令的更多信息。但我认为这并不重要。

  1. 其实我在openwrt工作,web服务器uhttpd。 (这里没有 LuCI)
  2. 命令是:sysupgrade -b - 2>/dev/null。该命令用于备份配置文件。我想写一个 CGI 来从网上下载备份文件。
  3. 但我无法将输出打印到服务器。即使在终端中(在 lua IDE 中),除了一两个凌乱的代码外,我也无法打印输出。但我可以将输出写入终端中的文件。可能和out的内容有些关系。
  4. 当我逐行打印内容时,它会打印一些,但不是全部。我下载文件后。我打不开。

【问题讨论】:

  • output 值 (#output) 的长度是否与 some command 生成的输出大小匹配?当你说你不能打印时,你是什么意思?如果知道输出的大小,为什么不包括 Content-Length?
  • 对不起,这是一个错字。长度是对的。我的意思是打印功能什么也不打印。但是输出的是字符串,长度是对的。
  • 第二个语句不会报错吗?
  • 不要将其作为 CGI 脚本运行;尝试在本地运行它并将内容打印到文件中,然后检查文件的内容。我没有看到代码的问题(除了应该设置内容长度的第二行的几个问题)。
  • 不,@hjpotter92 表示您的第二行缺少连接和右括号。

标签: lua cgi


【解决方案1】:
print("Content-Disposition:",'attachment;filename="backup.tar.gz"\n')
print("Content-Type:application/x-tar-gz\n\n")

我认为你的新行太多了。首先,您可以在Content-Disposition 中换行,这是print 添加的换行符的补充,它结束了标题并使Content-Type 成为有效负载的一部分(这会破坏内容)。 Content-Type 中还有两个换行符,您只需要一个(因为一个是由 print 命令添加的)。

我认为这样的事情应该可行:

local file = io.popen("some command")
local output = file:read('*a')
file:close()
print("Content-Type: text/html; charset=UTF-8")
print("Content-Length: " .. #output)
print("Content-Disposition: " .. 'attachment;filename="backup.tar.gz"')
print("Content-Type: application/x-tar-gz\r\n")
print(output)

【讨论】:

  • 它应该可以工作,但没有。当我尝试在终端中打印输出时,它只会给出一两个混乱的代码。不是所有的内容。 .tar.gz 文件是空的,没有数据。
  • 好的,你可以查看打印了多少个字符并推断它在哪个字符上停止;然后在“some command”的原始输出中检查该字符。这可能是有用的信息。
  • 我在 openwrt 中给出了 sysupgrade -b - 命令。它生成 tar.gz 的二进制流。我认为某些代码会阻止打印功能连续打印。我不知道如何处理这个。即使我测试了一些其他纯文本,我仍然无法打开 tar.gz 文件。但我可以将其作为文本打开。为什么?
  • HTTP 标头使用 CRLF \r\n 而不是 LF \n
  • @EgorSkriptunoff,正确,尽管有 Tolerant Applications 部分允许单个 LF。我更新了答案。
猜你喜欢
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-28
  • 2021-02-21
  • 2023-01-27
  • 1970-01-01
  • 2021-07-13
相关资源
最近更新 更多