mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 12:28:21 +01:00
Stupid bug in http.lua.
This commit is contained in:
parent
b22f6f3830
commit
8b114f3bf4
3
FIX
3
FIX
@ -7,6 +7,7 @@ get rid of a = socket.try() in the manual, except for protected cases.
|
|||||||
get rid of "base." kludge
|
get rid of "base." kludge
|
||||||
check all "require("http")" etc in the manual.
|
check all "require("http")" etc in the manual.
|
||||||
make sure sock_gethostname.* only return success if the hp is not null!
|
make sure sock_gethostname.* only return success if the hp is not null!
|
||||||
change 'l' prefix in C libraries to 'l-something'...
|
change 'l' prefix in C libraries to 'c'
|
||||||
don't forget the declarations in luasocket.h and mime.h!!!
|
don't forget the declarations in luasocket.h and mime.h!!!
|
||||||
setpeername was using udp{unconnected}
|
setpeername was using udp{unconnected}
|
||||||
|
fixed a bug in http.lua that caused some requests to fail
|
||||||
|
@ -39,7 +39,7 @@ if code == 200 then
|
|||||||
if not data then
|
if not data then
|
||||||
print(error or code)
|
print(error or code)
|
||||||
else
|
else
|
||||||
for i,v in data do
|
for i,v in pairs(data) do
|
||||||
io.write(i, ': ', v, '\n')
|
io.write(i, ': ', v, '\n')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
51
src/http.lua
51
src/http.lua
@ -27,6 +27,51 @@ PORT = 80
|
|||||||
-- user agent field sent in request
|
-- user agent field sent in request
|
||||||
USERAGENT = socket.VERSION
|
USERAGENT = socket.VERSION
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Extra sources and sinks
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
socket.sourcet["http-chunked"] = function(sock)
|
||||||
|
return base.setmetatable({
|
||||||
|
getfd = function() return sock:getfd() end,
|
||||||
|
dirty = function() return sock:dirty() end
|
||||||
|
}, {
|
||||||
|
__call = function()
|
||||||
|
-- get chunk size, skip extention
|
||||||
|
local line, err = sock:receive()
|
||||||
|
if err then return nil, err end
|
||||||
|
local size = base.tonumber(string.gsub(line, ";.*", ""), 16)
|
||||||
|
if not size then return nil, "invalid chunk size" end
|
||||||
|
-- was it the last chunk?
|
||||||
|
if size <= 0 then
|
||||||
|
-- skip trailer headers, if any
|
||||||
|
local line, err = sock:receive()
|
||||||
|
while not err and line ~= "" do
|
||||||
|
line, err = sock:receive()
|
||||||
|
end
|
||||||
|
return nil, err
|
||||||
|
else
|
||||||
|
-- get chunk and skip terminating CRLF
|
||||||
|
local chunk, err, part = sock:receive(size)
|
||||||
|
if chunk then sock:receive() end
|
||||||
|
return chunk, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
socket.sinkt["http-chunked"] = function(sock)
|
||||||
|
return base.setmetatable({
|
||||||
|
getfd = function() return sock:getfd() end,
|
||||||
|
dirty = function() return sock:dirty() end
|
||||||
|
}, {
|
||||||
|
__call = function(self, chunk, err)
|
||||||
|
if not chunk then return sock:send("0\r\n\r\n") end
|
||||||
|
local size = string.format("%X\r\n", string.len(chunk))
|
||||||
|
return sock:send(size .. chunk .. "\r\n")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Low level HTTP API
|
-- Low level HTTP API
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
@ -155,7 +200,7 @@ end
|
|||||||
local function adjustheaders(headers, host)
|
local function adjustheaders(headers, host)
|
||||||
local lower = {}
|
local lower = {}
|
||||||
-- override with user values
|
-- override with user values
|
||||||
for i,v in (headers or lower) do
|
for i,v in pairs(headers or lower) do
|
||||||
lower[string.lower(i)] = v
|
lower[string.lower(i)] = v
|
||||||
end
|
end
|
||||||
lower["user-agent"] = lower["user-agent"] or USERAGENT
|
lower["user-agent"] = lower["user-agent"] or USERAGENT
|
||||||
@ -175,7 +220,7 @@ local function adjustrequest(reqt)
|
|||||||
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
|
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
|
||||||
local t = url.parse(reqt.url, default)
|
local t = url.parse(reqt.url, default)
|
||||||
-- explicit components override url
|
-- explicit components override url
|
||||||
for i,v in reqt do nreqt[i] = reqt[i] end
|
for i,v in pairs(reqt) do nreqt[i] = v end
|
||||||
socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'")
|
socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'")
|
||||||
-- compute uri if user hasn't overriden
|
-- compute uri if user hasn't overriden
|
||||||
nreqt.uri = reqt.uri or adjusturi(nreqt)
|
nreqt.uri = reqt.uri or adjusturi(nreqt)
|
||||||
@ -238,7 +283,7 @@ function trequest(reqt)
|
|||||||
local h = open(reqt.host, reqt.port, reqt.connect)
|
local h = open(reqt.host, reqt.port, reqt.connect)
|
||||||
h:sendrequestline(reqt.method, reqt.uri)
|
h:sendrequestline(reqt.method, reqt.uri)
|
||||||
h:sendheaders(reqt.headers)
|
h:sendheaders(reqt.headers)
|
||||||
h:sendbody(reqt.headers, reqt.source, reqt.step)
|
if reqt.source then h:sendbody(reqt.headers, reqt.source, reqt.step) end
|
||||||
local code, headers, status
|
local code, headers, status
|
||||||
code, status = h:receivestatusline()
|
code, status = h:receivestatusline()
|
||||||
headers = h:receiveheaders()
|
headers = h:receiveheaders()
|
||||||
|
32
src/mime.lua
32
src/mime.lua
@ -15,9 +15,9 @@ local mime = require("cmime")
|
|||||||
module("mime")
|
module("mime")
|
||||||
|
|
||||||
-- encode, decode and wrap algorithm tables
|
-- encode, decode and wrap algorithm tables
|
||||||
mime.encodet = {}
|
encodet = {}
|
||||||
mime.decodet = {}
|
decodet = {}
|
||||||
mime.wrapt = {}
|
wrapt = {}
|
||||||
|
|
||||||
-- creates a function that chooses a filter by name from a given table
|
-- creates a function that chooses a filter by name from a given table
|
||||||
local function choose(table)
|
local function choose(table)
|
||||||
@ -32,21 +32,21 @@ local function choose(table)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- define the encoding filters
|
-- define the encoding filters
|
||||||
mime.encodet['base64'] = function()
|
encodet['base64'] = function()
|
||||||
return ltn12.filter.cycle(b64, "")
|
return ltn12.filter.cycle(b64, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
mime.encodet['quoted-printable'] = function(mode)
|
encodet['quoted-printable'] = function(mode)
|
||||||
return ltn12.filter.cycle(qp, "",
|
return ltn12.filter.cycle(qp, "",
|
||||||
(mode == "binary") and "=0D=0A" or "\r\n")
|
(mode == "binary") and "=0D=0A" or "\r\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- define the decoding filters
|
-- define the decoding filters
|
||||||
mime.decodet['base64'] = function()
|
decodet['base64'] = function()
|
||||||
return ltn12.filter.cycle(unb64, "")
|
return ltn12.filter.cycle(unb64, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
mime.decodet['quoted-printable'] = function()
|
decodet['quoted-printable'] = function()
|
||||||
return ltn12.filter.cycle(unqp, "")
|
return ltn12.filter.cycle(unqp, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -60,29 +60,29 @@ local function format(chunk)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- define the line-wrap filters
|
-- define the line-wrap filters
|
||||||
mime.wrapt['text'] = function(length)
|
wrapt['text'] = function(length)
|
||||||
length = length or 76
|
length = length or 76
|
||||||
return ltn12.filter.cycle(wrp, length, length)
|
return ltn12.filter.cycle(wrp, length, length)
|
||||||
end
|
end
|
||||||
mime.wrapt['base64'] = wrapt['text']
|
wrapt['base64'] = wrapt['text']
|
||||||
mime.wrapt['default'] = wrapt['text']
|
wrapt['default'] = wrapt['text']
|
||||||
|
|
||||||
mime.wrapt['quoted-printable'] = function()
|
wrapt['quoted-printable'] = function()
|
||||||
return ltn12.filter.cycle(qpwrp, 76, 76)
|
return ltn12.filter.cycle(qpwrp, 76, 76)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- function that choose the encoding, decoding or wrap algorithm
|
-- function that choose the encoding, decoding or wrap algorithm
|
||||||
mime.encode = choose(encodet)
|
encode = choose(encodet)
|
||||||
mime.decode = choose(decodet)
|
decode = choose(decodet)
|
||||||
mime.wrap = choose(wrapt)
|
wrap = choose(wrapt)
|
||||||
|
|
||||||
-- define the end-of-line normalization filter
|
-- define the end-of-line normalization filter
|
||||||
function mime.normalize(marker)
|
function normalize(marker)
|
||||||
return ltn12.filter.cycle(eol, 0, marker)
|
return ltn12.filter.cycle(eol, 0, marker)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- high level stuffing filter
|
-- high level stuffing filter
|
||||||
function mime.stuff()
|
function stuff()
|
||||||
return ltn12.filter.cycle(dot, 2)
|
return ltn12.filter.cycle(dot, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ static int collect_fd(lua_State *L, int tab, int max_fd,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fd = getfd(L);
|
fd = getfd(L);
|
||||||
if (fd > 0) {
|
if (fd >= 0) {
|
||||||
FD_SET(fd, set);
|
FD_SET(fd, set);
|
||||||
if (max_fd < fd) max_fd = fd;
|
if (max_fd < fd) max_fd = fd;
|
||||||
lua_pushnumber(L, fd);
|
lua_pushnumber(L, fd);
|
||||||
@ -150,7 +150,7 @@ static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fd = getfd(L);
|
fd = getfd(L);
|
||||||
if (fd > 0 && dirty(L)) {
|
if (fd >= 0 && dirty(L)) {
|
||||||
lua_pushnumber(L, ++ndirty);
|
lua_pushnumber(L, ++ndirty);
|
||||||
lua_pushvalue(L, -2);
|
lua_pushvalue(L, -2);
|
||||||
lua_settable(L, dtab);
|
lua_settable(L, dtab);
|
||||||
|
@ -211,7 +211,7 @@ end
|
|||||||
-- set defaul headers
|
-- set defaul headers
|
||||||
local function adjust_headers(mesgt)
|
local function adjust_headers(mesgt)
|
||||||
local lower = {}
|
local lower = {}
|
||||||
for i,v in (mesgt.headers or lower) do
|
for i,v in base.pairs(mesgt.headers or lower) do
|
||||||
lower[string.lower(i)] = v
|
lower[string.lower(i)] = v
|
||||||
end
|
end
|
||||||
lower["date"] = lower["date"] or
|
lower["date"] = lower["date"] or
|
||||||
|
@ -62,19 +62,6 @@ socket.sinkt = {}
|
|||||||
|
|
||||||
socket.BLOCKSIZE = 2048
|
socket.BLOCKSIZE = 2048
|
||||||
|
|
||||||
socket.sinkt["http-chunked"] = function(sock)
|
|
||||||
return base.setmetatable({
|
|
||||||
getfd = function() return sock:getfd() end,
|
|
||||||
dirty = function() return sock:dirty() end
|
|
||||||
}, {
|
|
||||||
__call = function(self, chunk, err)
|
|
||||||
if not chunk then return sock:send("0\r\n\r\n") end
|
|
||||||
local size = string.format("%X\r\n", string.len(chunk))
|
|
||||||
return sock:send(size .. chunk .. "\r\n")
|
|
||||||
end
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
socket.sinkt["close-when-done"] = function(sock)
|
socket.sinkt["close-when-done"] = function(sock)
|
||||||
return base.setmetatable({
|
return base.setmetatable({
|
||||||
getfd = function() return sock:getfd() end,
|
getfd = function() return sock:getfd() end,
|
||||||
@ -140,34 +127,6 @@ socket.sourcet["until-closed"] = function(sock)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
socket.sourcet["http-chunked"] = function(sock)
|
|
||||||
return base.setmetatable({
|
|
||||||
getfd = function() return sock:getfd() end,
|
|
||||||
dirty = function() return sock:dirty() end
|
|
||||||
}, {
|
|
||||||
__call = function()
|
|
||||||
-- get chunk size, skip extention
|
|
||||||
local line, err = sock:receive()
|
|
||||||
if err then return nil, err end
|
|
||||||
local size = base.tonumber(string.gsub(line, ";.*", ""), 16)
|
|
||||||
if not size then return nil, "invalid chunk size" end
|
|
||||||
-- was it the last chunk?
|
|
||||||
if size <= 0 then
|
|
||||||
-- skip trailer headers, if any
|
|
||||||
local line, err = sock:receive()
|
|
||||||
while not err and line ~= "" do
|
|
||||||
line, err = sock:receive()
|
|
||||||
end
|
|
||||||
return nil, err
|
|
||||||
else
|
|
||||||
-- get chunk and skip terminating CRLF
|
|
||||||
local chunk, err = sock:receive(size)
|
|
||||||
if chunk then sock:receive() end
|
|
||||||
return chunk, err
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
socket.sourcet["default"] = socket.sourcet["until-closed"]
|
socket.sourcet["default"] = socket.sourcet["until-closed"]
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ end
|
|||||||
function parse(url, default)
|
function parse(url, default)
|
||||||
-- initialize default parameters
|
-- initialize default parameters
|
||||||
local parsed = {}
|
local parsed = {}
|
||||||
for i,v in (default or parsed) do parsed[i] = v end
|
for i,v in base.pairs(default or parsed) do parsed[i] = v end
|
||||||
-- empty url is parsed to nil
|
-- empty url is parsed to nil
|
||||||
if not url or url == "" then return nil, "invalid url" end
|
if not url or url == "" then return nil, "invalid url" end
|
||||||
-- remove whitespace
|
-- remove whitespace
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
local dict = require"socket.dict"
|
local dict = require"socket.dict"
|
||||||
|
|
||||||
for i,v in dict.get("dict://localhost/d:teste") do print(v) end
|
for i,v in pairs(dict.get("dict://localhost/d:teste")) do print(v) end
|
||||||
|
@ -32,7 +32,7 @@ index_file = "test/index.html"
|
|||||||
index = readfile(index_file)
|
index = readfile(index_file)
|
||||||
|
|
||||||
local check_result = function(response, expect, ignore)
|
local check_result = function(response, expect, ignore)
|
||||||
for i,v in response do
|
for i,v in pairs(response) do
|
||||||
if not ignore[i] then
|
if not ignore[i] then
|
||||||
if v ~= expect[i] then
|
if v ~= expect[i] then
|
||||||
local f = io.open("err", "w")
|
local f = io.open("err", "w")
|
||||||
@ -42,7 +42,7 @@ local check_result = function(response, expect, ignore)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for i,v in expect do
|
for i,v in pairs(expect) do
|
||||||
if not ignore[i] then
|
if not ignore[i] then
|
||||||
if v ~= response[i] then
|
if v ~= response[i] then
|
||||||
local f = io.open("err", "w")
|
local f = io.open("err", "w")
|
||||||
|
@ -70,7 +70,7 @@ end
|
|||||||
local check_headers = function(sent, got)
|
local check_headers = function(sent, got)
|
||||||
sent = sent or {}
|
sent = sent or {}
|
||||||
got = got or {}
|
got = got or {}
|
||||||
for i,v in sent do
|
for i,v in pairs(sent) do
|
||||||
if not similar(v, got[i]) then fail("header " .. v .. "failed!") end
|
if not similar(v, got[i]) then fail("header " .. v .. "failed!") end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -75,7 +75,7 @@ local check_parse_url = function(gaba)
|
|||||||
if v ~= parsed[i] then
|
if v ~= parsed[i] then
|
||||||
io.write("parse: In test for '", url, "' expected ", i, " = '",
|
io.write("parse: In test for '", url, "' expected ", i, " = '",
|
||||||
v, "' but got '", tostring(parsed[i]), "'\n")
|
v, "' but got '", tostring(parsed[i]), "'\n")
|
||||||
for i,v in parsed do print(i,v) end
|
for i,v in pairs(parsed) do print(i,v) end
|
||||||
exit()
|
exit()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -83,7 +83,7 @@ local check_parse_url = function(gaba)
|
|||||||
if v ~= gaba[i] then
|
if v ~= gaba[i] then
|
||||||
io.write("parse: In test for '", url, "' expected ", i, " = '",
|
io.write("parse: In test for '", url, "' expected ", i, " = '",
|
||||||
tostring(gaba[i]), "' but got '", v, "'\n")
|
tostring(gaba[i]), "' but got '", v, "'\n")
|
||||||
for i,v in parsed do print(i,v) end
|
for i,v in pairs(parsed) do print(i,v) end
|
||||||
exit()
|
exit()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user