Due to network timings (latency, heavy load) not all requests received
in one peace. Those one who are not received in one peace (truncated)
interpreted by wsapi as empty string. This is why wsapi must read until
whole content length received or connection closed on other side.
Maybe my patch can help, take a look:
diff --git a/lua-modules/wsapi-1.6/src/wsapi/request.lua b/lua-modules/wsapi-1.6/src/wsapi/request.lua
index 15fa602..d4d1bbd 100644
--- a/lua-modules/wsapi-1.6/src/wsapi/request.lua
+++ b/lua-modules/wsapi-1.6/src/wsapi/request.lua
@@ -1,4 +1,5 @@
local util = require"wsapi.util"
+local sockreader = require"wsapi.sockreader"
local _M = {}
@@ -118,16 +119,11 @@ local function parse_post_data(wsapi_env, tab, overwrite)
tab = tab or {}
local input_type = wsapi_env.CONTENT_TYPE
if string.find(input_type, "x-www-form-urlencoded", 1, true) then
- local length = tonumber(wsapi_env.CONTENT_LENGTH) or 0
- parse_qs(wsapi_env.input:read(length) or "", tab, overwrite)
+ parse_qs(sockreader.read_post_data(wsapi_env) or "", tab, overwrite)
elseif string.find(input_type, "multipart/form-data", 1, true) then
- local length = tonumber(wsapi_env.CONTENT_LENGTH) or 0
- if length > 0 then
- parse_multipart_data(wsapi_env.input:read(length) or "", input_type, tab, overwrite)
- end
+ parse_multipart_data(sockreader.read_post_data(wsapi_env) or "", input_type, tab, overwrite)
else
- local length = tonumber(wsapi_env.CONTENT_LENGTH) or 0
- tab.post_data = wsapi_env.input:read(length) or ""
+ tab.post_data = sockreader.read_post_data(wsapi_env) or ""
end
return tab
end
diff --git a/lua-modules/wsapi-1.6/src/wsapi/sockreader.lua b/lua-modules/wsapi-1.6/src/wsapi/sockreader.lua
new file mode 100644
index 0000000..cdb3dc4
--- /dev/null
+++ b/lua-modules/wsapi-1.6/src/wsapi/sockreader.lua
@@ -0,0 +1,35 @@
+--
+-- Helper functions to read all data from socket correctly
+--
+
+local _M = {}
+
+function _M.read_all(input, length)
+
+ local response = ""
+ local count = length
+
+ while true do
+ if count <= 0 then
+ break
+ end
+
+ local rv, err, part = input:read(count)
+ if err == "closed" then
+ return nil, err
+ end
+
+ local data = rv or part
+ response = response .. data
+ count = count - #data
+ end
+
+ return response
+end
+
+function _M.read_post_data(wsapi_env)
+ local length = tonumber(wsapi_env.CONTENT_LENGTH) or 0
+ return _M.read_all(wsapi_env.input, length)
+end
+
+return _M
Those post read methods placed in separate file (sockreader.lua)
due to i need exposed functions to manually read post payload in
smaller chunks.
Due to network timings (latency, heavy load) not all requests received in one peace. Those one who are not received in one peace (truncated) interpreted by wsapi as empty string. This is why wsapi must read until whole content length received or connection closed on other side.
Maybe my patch can help, take a look:
Those post read methods placed in separate file (sockreader.lua) due to i need exposed functions to manually read post payload in smaller chunks.