Stupid bug in http.lua.

This commit is contained in:
Diego Nehab
2005-06-12 22:02:21 +00:00
parent b22f6f3830
commit 8b114f3bf4
12 changed files with 78 additions and 73 deletions

View File

@ -27,6 +27,51 @@ PORT = 80
-- user agent field sent in request
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
-----------------------------------------------------------------------------
@ -70,7 +115,7 @@ function metat.__index:sendheaders(headers)
end
function metat.__index:sendbody(headers, source, step)
source = source or ltn12.source.empty()
source = source or ltn12.source.empty()
step = step or ltn12.pump.step
-- if we don't know the size in advance, send chunked and hope for the best
local mode = "http-chunked"
@ -155,7 +200,7 @@ end
local function adjustheaders(headers, host)
local lower = {}
-- 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
end
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 t = url.parse(reqt.url, default)
-- 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) .. "'")
-- compute uri if user hasn't overriden
nreqt.uri = reqt.uri or adjusturi(nreqt)
@ -238,7 +283,7 @@ function trequest(reqt)
local h = open(reqt.host, reqt.port, reqt.connect)
h:sendrequestline(reqt.method, reqt.uri)
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
code, status = h:receivestatusline()
headers = h:receiveheaders()

View File

@ -15,9 +15,9 @@ local mime = require("cmime")
module("mime")
-- encode, decode and wrap algorithm tables
mime.encodet = {}
mime.decodet = {}
mime.wrapt = {}
encodet = {}
decodet = {}
wrapt = {}
-- creates a function that chooses a filter by name from a given table
local function choose(table)
@ -32,21 +32,21 @@ local function choose(table)
end
-- define the encoding filters
mime.encodet['base64'] = function()
encodet['base64'] = function()
return ltn12.filter.cycle(b64, "")
end
mime.encodet['quoted-printable'] = function(mode)
encodet['quoted-printable'] = function(mode)
return ltn12.filter.cycle(qp, "",
(mode == "binary") and "=0D=0A" or "\r\n")
end
-- define the decoding filters
mime.decodet['base64'] = function()
decodet['base64'] = function()
return ltn12.filter.cycle(unb64, "")
end
mime.decodet['quoted-printable'] = function()
decodet['quoted-printable'] = function()
return ltn12.filter.cycle(unqp, "")
end
@ -60,29 +60,29 @@ local function format(chunk)
end
-- define the line-wrap filters
mime.wrapt['text'] = function(length)
wrapt['text'] = function(length)
length = length or 76
return ltn12.filter.cycle(wrp, length, length)
end
mime.wrapt['base64'] = wrapt['text']
mime.wrapt['default'] = wrapt['text']
wrapt['base64'] = wrapt['text']
wrapt['default'] = wrapt['text']
mime.wrapt['quoted-printable'] = function()
wrapt['quoted-printable'] = function()
return ltn12.filter.cycle(qpwrp, 76, 76)
end
-- function that choose the encoding, decoding or wrap algorithm
mime.encode = choose(encodet)
mime.decode = choose(decodet)
mime.wrap = choose(wrapt)
encode = choose(encodet)
decode = choose(decodet)
wrap = choose(wrapt)
-- define the end-of-line normalization filter
function mime.normalize(marker)
function normalize(marker)
return ltn12.filter.cycle(eol, 0, marker)
end
-- high level stuffing filter
function mime.stuff()
function stuff()
return ltn12.filter.cycle(dot, 2)
end

View File

@ -124,7 +124,7 @@ static int collect_fd(lua_State *L, int tab, int max_fd,
break;
}
fd = getfd(L);
if (fd > 0) {
if (fd >= 0) {
FD_SET(fd, set);
if (max_fd < fd) max_fd = fd;
lua_pushnumber(L, fd);
@ -150,7 +150,7 @@ static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) {
break;
}
fd = getfd(L);
if (fd > 0 && dirty(L)) {
if (fd >= 0 && dirty(L)) {
lua_pushnumber(L, ++ndirty);
lua_pushvalue(L, -2);
lua_settable(L, dtab);

View File

@ -211,7 +211,7 @@ end
-- set defaul headers
local function adjust_headers(mesgt)
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
end
lower["date"] = lower["date"] or

View File

@ -62,19 +62,6 @@ socket.sinkt = {}
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)
return base.setmetatable({
getfd = function() return sock:getfd() end,
@ -140,34 +127,6 @@ socket.sourcet["until-closed"] = function(sock)
})
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"]

View File

@ -119,7 +119,7 @@ end
function parse(url, default)
-- initialize default parameters
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
if not url or url == "" then return nil, "invalid url" end
-- remove whitespace