如何使用Lua在NodeMCU上解析分块的HTTP内容?

我有一个脚本,用于NodeMCU和我的服务器之间的通信。它在我的本地主机上工作良好,并在我发送GET请求时解析从我的服务器检索到的响应。问题是,当我将其全部上传到我的网站时,传输编码是分块的。尽管请求是合法和正确的,但我无法检索内容。代码是用Lua编写的,我正在尝试在我的NodeMCU设备上工作。

conn=net.createConnection(net.TCP, 0)
    conn:on("connection",function(conn, payload)
    conn:send("GET /mypath/node.php?id=1&update"..
                " HTTP/1.1\r\n"..
                "Host: www.mydomain.com\r\n"..
                "Accept: */*\r\n"..
                "User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)"..
                "\r\n\r\n")
            end)

    conn:on("receive", function(conn, payload)
        if string.find(payload, "UPDATE")~=nil then
            node.restart()
        end

        conn:close()
        conn = nil

    end)
    conn:connect(80,"www.mydomain.com")
end

再强调一下,这个GET请求是可以正常工作的,并且已经在本地和手动上进行了测试。唯一的问题是有分块内容,我不知道如何解析它。

更新:我通过将HTTP/1.1更改为HTTP/1.0来删除分块编码,但是我仍然有问题

使用此代码

conn:on("receive", function(conn, payload)
        print(payload)

我得到的响应如下

HTTP/1.1 200 OK
Date: Tue, 09 Jan 2018 02:34:25 GMT
Server: Apache
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=9m226vr20r4baa634bagk8k2k3; path=/
Connection: close
Content-Type: text/html; charset=utf-8

更新2

我刚刚创建了一个名为http.php的文件,并包含“php”文本。我将其上传到本地主机和我的域名。一旦我尝试从NodeMCU访问我的本地主机,然后访问域名。结果是不同的

这是请求

conn:send("GET /"..s.path.."/http.php"..
                " HTTP/1.0\r\n"..
                "Host: "..s.domain.."\r\n"..
                "Accept: */*\r\n"..
                "User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)"..
                "\r\n\r\n")
            end)

s.domain和s.path对应于本地主机和我的域名上的不同路径和域名

结果是

域名上的结果

HTTP/1.1 200 OK
Date: Tue, 09 Jan 2018 03:09:28 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=UTF-8

本地主机上的结果

TTP/1.1 200 OK
Date: Tue, 09 Jan 2018 03:08:48 GMT
Server: Apache/2.4.27 (Win64) PHP/7.0.23
X-Powered-By: PHP/7.0.23
Content-Length: 3
Connection: close
Content-Type: text/html; charset=UTF-8

php

正如您所看到的,本地主机显示内容"php",域名仅显示标题。当我键入一些文件不存在时,域名会向我显示HTML代码。

点赞
用户5016720
用户5016720

我正在使用以下代码将块组合在一起。不管怎样,我想知道为什么您从服务器收到的响应缺少 Content-Length 头。

conn:on("receive", function(client, payload)

  -- 受启示于 https://github.com/marcoskirsch/nodemcu-httpserver/blob/master/httpserver.lua
  -- 收集数据包,直到 HTTP 正文大小满足头中声明的 Content-Length
  if payload:find("Content%-Length:") or bBodyMissing then
      if fullPayload then fullPayload = fullPayload .. payload else fullPayload = payload end
      if (tonumber(string.match(fullPayload, "%d+", fullPayload:find("Content%-Length:")+16)) > #fullPayload:sub(fullPayload:find("\r\n\r\n", 1, true)+4, #fullPayload)) then
          bBodyMissing = true
          return
      else
          payload = fullPayload
          fullPayload, bBodyMissing = nil
      end
  end

  if (bBodyMissing == nil) then
      local _, headerEnd = payload:find("\r\n\r\n")
      local body = payload:sub(headerEnd + 1)
      print (body)
  end
end)
2018-01-15 21:44:26