blob: 34b76eb745bc13fb9c796a8aed53dd94a771cedb [file]
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
-- THttpTransport accumulates the header block four bytes at a time until it
-- sees the blank line that ends it. A peer that never sends one decides how
-- much is accumulated, and how often the block is rescanned looking for it.
--
-- lua lib/lua/test/test_http_headers.lua
local script_dir = arg[0]:match('(.*[/\\])') or './'
package.path = script_dir .. '../?.lua;' .. package.path
-- The header handling under test is pure Lua. The C extensions only do byte
-- packing, which Lua 5.3+ provides natively, so functional pure-Lua stand-ins
-- let the test run without building them.
package.preload['libluabitwise'] = function()
return {
bor = function(a, b) return a | b end,
band = function(a, b) return a & b end,
bxor = function(a, b) return a ~ b end,
shiftl = function(a, n) return (a << n) & 0xFFFFFFFF end,
shiftr = function(a, n) return a >> n end,
}
end
package.preload['libluabpack'] = function()
local fmt = {c = '>i1', C = '>I1', s = '>i2', S = '>I2',
i = '>i4', I = '>I4', l = '>i8', d = '>d'}
return {
bpack = function(code, val) return string.pack(fmt[code], val) end,
bunpack = function(code, data) return (string.unpack(fmt[code], data)) end,
}
end
package.preload['liblualongnumber'] = function()
return {new = function(_, v) return v or 0 end, tonumber = function(v) return v end}
end
require('Thrift')
require('TTransport')
require('TMemoryBuffer')
require('THttpTransport')
local failures = 0
local function check(condition, message)
if condition then
print('ok - ' .. message)
else
failures = failures + 1
print('not ok - ' .. message)
end
end
local function transportFor(wire)
local buffer = TMemoryBuffer:new{}
buffer:resetBuffer(wire)
return THttpTransport:new{trans = buffer, isServer = true}
end
-- An ordinary request is still read.
do
local wire = 'POST / HTTP/1.1\r\n' ..
'X-Filler: ' .. string.rep('A', 4000) .. '\r\n' ..
'Content-Length: 5\r\n\r\nhello'
local http = transportFor(wire)
local ok, body = pcall(function() return http:read(5) end)
check(ok and body == 'hello',
'a request with a large but bounded header block is read')
end
-- A header block that never ends is refused rather than accumulated.
do
local wire = 'POST / HTTP/1.1\r\nX-Filler: ' .. string.rep('A', 200000)
local http = transportFor(wire)
http.maxHeaderSize = 16 * 1024
local ok, err = pcall(function() return http:read(5) end)
check(not ok, 'headers without an end are refused')
check(ok or tostring(err):find('maximum', 1, true) ~= nil,
'the refusal names the maximum: ' .. tostring(err))
end
-- A peer that stops sending does not leave the loop spinning.
do
local http = transportFor('POST / HTTP/1.1\r\nX-Filler: short')
local ok = pcall(function() return http:read(5) end)
check(not ok, 'a truncated header block is refused')
end
if failures > 0 then
print(failures .. ' failure(s)')
os.exit(1)
end
print('all ok')