Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSAPI doesn't parse truncated requests #22

Open
edzius opened this issue Sep 27, 2013 · 0 comments
Open

WSAPI doesn't parse truncated requests #22

edzius opened this issue Sep 27, 2013 · 0 comments

Comments

@edzius
Copy link

edzius commented Sep 27, 2013

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant