moonbridge

changeset 156:0c4221702ce1

Further work on new HTTP layer (read body, without parsing yet)
author jbe
date Tue May 26 02:06:17 2015 +0200 (2015-05-26)
parents 2c22b0f222c7
children 99a70d18e47c
files moonbridge_http.lua
line diff
     1.1 --- a/moonbridge_http.lua	Mon May 25 02:28:34 2015 +0200
     1.2 +++ b/moonbridge_http.lua	Tue May 26 02:06:17 2015 +0200
     1.3 @@ -140,6 +140,7 @@
     1.4    self._input_chunk_size = options.maximum_input_chunk_size or options.chunk_size or 16384
     1.5    self._output_chunk_size = options.minimum_output_chunk_size or options.chunk_size or 1024
     1.6    self._header_size_limit = options.header_size_limit or 1024*1024
     1.7 +  self._body_size_limit = options.body_size_limit or 64*1024*1024
     1.8    local function init_timeout(name, default)
     1.9      local value = options[name]
    1.10      if value == nil then
    1.11 @@ -449,6 +450,89 @@
    1.12    end
    1.13  end
    1.14  
    1.15 +function request_pt:_read_body()
    1.16 +  self:_assert_not_faulty()
    1.17 +  local remaining = self._body_size_limit
    1.18 +  if request.headers_flags["Transfer-Encoding"]["chunked"] then
    1.19 +    while true do
    1.20 +      local line, status = self:_read(32 + remaining, "\n")
    1.21 +      if status == "maxlen" then
    1.22 +        self:_error("400 Bad Request", "Request body size limit exceeded")
    1.23 +        return false
    1.24 +      elseif status == "eof" then
    1.25 +        self:_error("400 Bad Request", "Encoding error or unexpected EOF while reading next chunk of request body")
    1.26 +        return false
    1.27 +      end
    1.28 +      local zeros, lenstr = string.match(line, "^(0*)([1-9A-Fa-f]+[0-9A-Fa-f]*)\r?\n$")
    1.29 +      local chunkext
    1.30 +      if lenstr then
    1.31 +        chunkext = ""
    1.32 +      else
    1.33 +        zeros, lenstr, chunkext = string.match(line, "^(0*)([1-9A-Fa-f]+[0-9A-Fa-f]*)([ \t;].-)\r?\n$")
    1.34 +      end
    1.35 +      if not lenstr or #lenstr > 13 then
    1.36 +        self:_error("400 Bad Request", "Encoding error while reading chunk of request body")
    1.37 +        return false
    1.38 +      end
    1.39 +      local len = tonumber("0x" .. lenstr)
    1.40 +      remaining = remaining - (#zeros + #chunkext + len)
    1.41 +      if remaining < 0 then
    1.42 +        self:_error("400 Bad Request", "Request body size limit exceeded")
    1.43 +        return false
    1.44 +      end
    1.45 +      if len == 0 then break end
    1.46 +      if self:_read_body_bytes(len) == false then
    1.47 +        return false
    1.48 +      end
    1.49 +      local term, status = self:_read(2, "\n")
    1.50 +      if status == "eof" then
    1.51 +        self:_error("400 Bad Request", "Unexpected EOF while reading next chunk of request body")
    1.52 +        return false
    1.53 +      end
    1.54 +      if term ~= "\r\n" and term ~= "\n" then
    1.55 +        self:_error("400 Bad Request", "Encoding error while reading chunk of request body")
    1.56 +        return false
    1.57 +      end
    1.58 +    end
    1.59 +    while true do
    1.60 +      local line, status = self:_read(2 + remaining, "\n")
    1.61 +      if status == "eof" then
    1.62 +        self:_error("400 Bad Request", "Unexpected EOF while reading chunk of request body")
    1.63 +        return false
    1.64 +      end
    1.65 +      if line == "\r\n" or line == "\n" then break end
    1.66 +      remaining = remaining - #line
    1.67 +      if remaining < 0 then
    1.68 +        request_error(true, "413 Request Entity Too Large", "Request body size limit exceeded while reading trailer section of chunked request body")
    1.69 +      end
    1.70 +    end
    1.71 +  elseif request_body_content_length then
    1.72 +    if self._read_body_bytes(request_body_content_length) == false then
    1.73 +      return false
    1.74 +    end
    1.75 +  end
    1.76 +end
    1.77 +
    1.78 +function request_pt:_read_body_bytes(remaining, callback)
    1.79 +  while remaining > 0 do
    1.80 +    local limit
    1.81 +    if remaining > self._input_chunk_size then
    1.82 +      limit = self._input_chunk_size
    1.83 +    else
    1.84 +      limit = remaining
    1.85 +    end
    1.86 +    local chunk, status = self:_read(limit)
    1.87 +    if status == "eof" then
    1.88 +      self:_error("400 Bad Request", "Unexpected EOF while reading chunk of request body")
    1.89 +      return false
    1.90 +    end
    1.91 +    remaining = remaining - limit
    1.92 +    if self._body_streamer then
    1.93 +      self._body_streamer(chunk)
    1.94 +    end
    1.95 +  end
    1.96 +end
    1.97 +
    1.98  function request_pt:_assert_not_faulty()
    1.99    assert(not self._faulty, "Tried to use faulty request handle")
   1.100  end

Impressum / About Us