mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 04:28:20 +01:00
Using core.so instead of csocket.so and cmime.so.
This commit is contained in:
parent
65c35845c5
commit
4d455c6206
3
TODO
3
TODO
@ -1,3 +1,6 @@
|
||||
clean timeout argument to open functions in SMTP, HTTP and FTP
|
||||
add create field to FTP and SMTP
|
||||
talk about new create field in HTTP, FTP and SMTP
|
||||
talk about the non-blocking connect in the manual
|
||||
test it on Windows!!!
|
||||
|
||||
|
98
src/http.lua
98
src/http.lua
@ -27,10 +27,41 @@ PORT = 80
|
||||
-- user agent field sent in request
|
||||
USERAGENT = socket._VERSION
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Reads MIME headers from a connection, unfolding where needed
|
||||
-----------------------------------------------------------------------------
|
||||
local function receiveheaders(sock, headers)
|
||||
local line, name, value, err
|
||||
headers = headers or {}
|
||||
-- get first line
|
||||
line, err = sock:receive()
|
||||
if err then return nil, err end
|
||||
-- headers go until a blank line is found
|
||||
while line ~= "" do
|
||||
-- get field-name and value
|
||||
name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
|
||||
if not (name and value) then return nil, "malformed reponse headers" end
|
||||
name = string.lower(name)
|
||||
-- get next line (value might be folded)
|
||||
line, err = sock:receive()
|
||||
if err then return nil, err end
|
||||
-- unfold any folded values
|
||||
while string.find(line, "^%s") do
|
||||
value = value .. line
|
||||
line = sock:receive()
|
||||
if err then return nil, err end
|
||||
end
|
||||
-- save pair in table
|
||||
if headers[name] then headers[name] = headers[name] .. ", " .. value
|
||||
else headers[name] = value end
|
||||
end
|
||||
return headers
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Extra sources and sinks
|
||||
-----------------------------------------------------------------------------
|
||||
socket.sourcet["http-chunked"] = function(sock)
|
||||
socket.sourcet["http-chunked"] = function(sock, headers)
|
||||
return base.setmetatable({
|
||||
getfd = function() return sock:getfd() end,
|
||||
dirty = function() return sock:dirty() end
|
||||
@ -42,18 +73,15 @@ socket.sourcet["http-chunked"] = function(sock)
|
||||
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
|
||||
if size > 0 then
|
||||
-- if not, get chunk and skip terminating CRLF
|
||||
local chunk, err, part = sock:receive(size)
|
||||
if chunk then sock:receive() end
|
||||
return chunk, err
|
||||
else
|
||||
-- if it was, read trailers into headers table
|
||||
headers, err = receiveheaders(sock, headers)
|
||||
if not headers then return nil, err end
|
||||
end
|
||||
end
|
||||
})
|
||||
@ -78,8 +106,8 @@ end
|
||||
local metat = { __index = {} }
|
||||
|
||||
-- default connect function, respecting the timeout
|
||||
local function connect(host, port)
|
||||
local c, e = socket.tcp()
|
||||
local function connect(host, port, create)
|
||||
local c, e = (create or socket.tcp)()
|
||||
if not c then return nil, e end
|
||||
c:settimeout(TIMEOUT)
|
||||
local r, e = c:connect(host, port or PORT)
|
||||
@ -90,9 +118,9 @@ local function connect(host, port)
|
||||
return c
|
||||
end
|
||||
|
||||
function open(host, port, user)
|
||||
function open(host, port, create)
|
||||
-- create socket with user connect function, or with default
|
||||
local c = socket.try((user or connect)(host, port))
|
||||
local c = socket.try(connect(host, port, create))
|
||||
-- create our http request object, pointing to the socket
|
||||
local h = base.setmetatable({ c = c }, metat)
|
||||
-- make sure the object close gets called on exception
|
||||
@ -130,37 +158,16 @@ function metat.__index:receivestatusline()
|
||||
end
|
||||
|
||||
function metat.__index:receiveheaders()
|
||||
local line, name, value
|
||||
local headers = {}
|
||||
-- get first line
|
||||
line = self.try(self.c:receive())
|
||||
-- headers go until a blank line is found
|
||||
while line ~= "" do
|
||||
-- get field-name and value
|
||||
name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
|
||||
self.try(name and value, "malformed reponse headers")
|
||||
name = string.lower(name)
|
||||
-- get next line (value might be folded)
|
||||
line = self.try(self.c:receive())
|
||||
-- unfold any folded values
|
||||
while string.find(line, "^%s") do
|
||||
value = value .. line
|
||||
line = self.try(self.c:receive())
|
||||
end
|
||||
-- save pair in table
|
||||
if headers[name] then headers[name] = headers[name] .. ", " .. value
|
||||
else headers[name] = value end
|
||||
end
|
||||
return headers
|
||||
return self.try(receiveheaders(self.c))
|
||||
end
|
||||
|
||||
function metat.__index:receivebody(headers, sink, step)
|
||||
sink = sink or ltn12.sink.null()
|
||||
step = step or ltn12.pump.step
|
||||
local length = base.tonumber(headers["content-length"])
|
||||
local TE = headers["transfer-encoding"]
|
||||
local t = headers["transfer-encoding"] -- shortcut
|
||||
local mode = "default" -- connection close
|
||||
if TE and TE ~= "identity" then mode = "http-chunked"
|
||||
if t and t ~= "identity" then mode = "http-chunked"
|
||||
elseif base.tonumber(headers["content-length"]) then mode = "by-length" end
|
||||
return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
|
||||
sink, step))
|
||||
@ -198,16 +205,21 @@ local function adjustproxy(reqt)
|
||||
end
|
||||
|
||||
local function adjustheaders(headers, host)
|
||||
local lower = {}
|
||||
-- override with user values
|
||||
-- default headers
|
||||
local lower = {
|
||||
["user-agent"] = USERAGENT,
|
||||
["host"] = host,
|
||||
["connection"] = "close, TE",
|
||||
["te"] = "trailers"
|
||||
}
|
||||
-- override with user headers
|
||||
for i,v in pairs(headers or lower) do
|
||||
lower[string.lower(i)] = v
|
||||
end
|
||||
lower["user-agent"] = lower["user-agent"] or USERAGENT
|
||||
lower["host"] = lower["host"] or host
|
||||
return lower
|
||||
end
|
||||
|
||||
-- default url parts
|
||||
local default = {
|
||||
host = "",
|
||||
port = PORT,
|
||||
@ -280,7 +292,7 @@ end
|
||||
|
||||
function trequest(reqt)
|
||||
reqt = adjustrequest(reqt)
|
||||
local h = open(reqt.host, reqt.port, reqt.connect)
|
||||
local h = open(reqt.host, reqt.port, reqt.create)
|
||||
h:sendrequestline(reqt.method, reqt.uri)
|
||||
h:sendheaders(reqt.headers)
|
||||
if reqt.source then h:sendbody(reqt.headers, reqt.source, reqt.step) end
|
||||
|
@ -108,7 +108,7 @@ static int base_open(lua_State *L) {
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Initializes all library modules.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
LUASOCKET_API int luaopen_csocket(lua_State *L) {
|
||||
LUASOCKET_API int luaopen_socketcore(lua_State *L) {
|
||||
int i;
|
||||
base_open(L);
|
||||
for (i = 0; mod[i].name; i++) mod[i].func(L);
|
||||
|
@ -27,6 +27,6 @@
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Initializes the library.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
LUASOCKET_API int luaopen_csocket(lua_State *L);
|
||||
LUASOCKET_API int luaopen_socketcore(lua_State *L);
|
||||
|
||||
#endif /* LUASOCKET_H */
|
||||
|
@ -78,7 +78,7 @@ static UC b64unbase[256];
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Initializes module
|
||||
\*-------------------------------------------------------------------------*/
|
||||
MIME_API int luaopen_cmime(lua_State *L)
|
||||
MIME_API int luaopen_mimecore(lua_State *L)
|
||||
{
|
||||
luaL_openlib(L, "mime", func, 0);
|
||||
/* initialize lookup tables */
|
||||
|
@ -19,6 +19,6 @@
|
||||
#define MIME_API extern
|
||||
#endif
|
||||
|
||||
MIME_API int luaopen_cmime(lua_State *L);
|
||||
MIME_API int luaopen_mimecore(lua_State *L);
|
||||
|
||||
#endif /* MIME_H */
|
||||
|
@ -10,7 +10,9 @@
|
||||
-----------------------------------------------------------------------------
|
||||
local base = _G
|
||||
local ltn12 = require("ltn12")
|
||||
local mime = require("cmime")
|
||||
local mime = require("mime.core")
|
||||
local io = require("io")
|
||||
local string = require("string")
|
||||
module("mime")
|
||||
|
||||
-- encode, decode and wrap algorithm tables
|
||||
@ -49,8 +51,6 @@ decodet['quoted-printable'] = function()
|
||||
return ltn12.filter.cycle(unqp, "")
|
||||
end
|
||||
|
||||
local io, string = io, string
|
||||
|
||||
local function format(chunk)
|
||||
if chunk then
|
||||
if chunk == "" then return "''"
|
||||
|
@ -10,13 +10,13 @@
|
||||
local base = _G
|
||||
local string = require("string")
|
||||
local math = require("math")
|
||||
local socket = require("csocket")
|
||||
local socket = require("socket.core")
|
||||
module("socket")
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Auxiliar functions
|
||||
-- Exported auxiliar functions
|
||||
-----------------------------------------------------------------------------
|
||||
function socket.connect(address, port, laddress, lport)
|
||||
function connect(address, port, laddress, lport)
|
||||
local sock, err = socket.tcp()
|
||||
if not sock then return nil, err end
|
||||
if laddress then
|
||||
@ -28,7 +28,7 @@ function socket.connect(address, port, laddress, lport)
|
||||
return sock
|
||||
end
|
||||
|
||||
function socket.bind(host, port, backlog)
|
||||
function bind(host, port, backlog)
|
||||
local sock, err = socket.tcp()
|
||||
if not sock then return nil, err end
|
||||
sock:setoption("reuseaddr", true)
|
||||
@ -39,9 +39,9 @@ function socket.bind(host, port, backlog)
|
||||
return sock
|
||||
end
|
||||
|
||||
socket.try = socket.newtry()
|
||||
try = newtry()
|
||||
|
||||
function socket.choose(table)
|
||||
function choose(table)
|
||||
return function(name, opt1, opt2)
|
||||
if base.type(name) ~= "string" then
|
||||
name, opt1, opt2 = "default", name, opt1
|
||||
@ -56,12 +56,12 @@ end
|
||||
-- Socket sources and sinks, conforming to LTN12
|
||||
-----------------------------------------------------------------------------
|
||||
-- create namespaces inside LuaSocket namespace
|
||||
socket.sourcet = {}
|
||||
socket.sinkt = {}
|
||||
sourcet = {}
|
||||
sinkt = {}
|
||||
|
||||
socket.BLOCKSIZE = 2048
|
||||
BLOCKSIZE = 2048
|
||||
|
||||
socket.sinkt["close-when-done"] = function(sock)
|
||||
sinkt["close-when-done"] = function(sock)
|
||||
return base.setmetatable({
|
||||
getfd = function() return sock:getfd() end,
|
||||
dirty = function() return sock:dirty() end
|
||||
@ -75,7 +75,7 @@ socket.sinkt["close-when-done"] = function(sock)
|
||||
})
|
||||
end
|
||||
|
||||
socket.sinkt["keep-open"] = function(sock)
|
||||
sinkt["keep-open"] = function(sock)
|
||||
return base.setmetatable({
|
||||
getfd = function() return sock:getfd() end,
|
||||
dirty = function() return sock:dirty() end
|
||||
@ -87,11 +87,11 @@ socket.sinkt["keep-open"] = function(sock)
|
||||
})
|
||||
end
|
||||
|
||||
socket.sinkt["default"] = socket.sinkt["keep-open"]
|
||||
sinkt["default"] = sinkt["keep-open"]
|
||||
|
||||
socket.sink = socket.choose(socket.sinkt)
|
||||
sink = choose(sinkt)
|
||||
|
||||
socket.sourcet["by-length"] = function(sock, length)
|
||||
sourcet["by-length"] = function(sock, length)
|
||||
return base.setmetatable({
|
||||
getfd = function() return sock:getfd() end,
|
||||
dirty = function() return sock:dirty() end
|
||||
@ -107,7 +107,7 @@ socket.sourcet["by-length"] = function(sock, length)
|
||||
})
|
||||
end
|
||||
|
||||
socket.sourcet["until-closed"] = function(sock)
|
||||
sourcet["until-closed"] = function(sock)
|
||||
local done
|
||||
return base.setmetatable({
|
||||
getfd = function() return sock:getfd() end,
|
||||
@ -127,8 +127,9 @@ socket.sourcet["until-closed"] = function(sock)
|
||||
end
|
||||
|
||||
|
||||
socket.sourcet["default"] = socket.sourcet["until-closed"]
|
||||
sourcet["default"] = sourcet["until-closed"]
|
||||
|
||||
socket.source = socket.choose(socket.sourcet)
|
||||
source = choose(sourcet)
|
||||
|
||||
--getmetatable(_M).__index = nil
|
||||
-- clear globals from namespace
|
||||
getmetatable(_M).__index = nil
|
||||
|
@ -22,7 +22,7 @@ http.TIMEOUT = 10
|
||||
|
||||
local t = socket.gettime()
|
||||
|
||||
host = host or "diego.student.princeton.edu"
|
||||
host = host or "localhost" -- "diego.student.princeton.edu"
|
||||
proxy = proxy or "http://localhost:3128"
|
||||
prefix = prefix or "/luasocket-test"
|
||||
cgiprefix = cgiprefix or "/luasocket-test-cgi"
|
||||
@ -146,6 +146,7 @@ ignore = {
|
||||
check_request(request, expect, ignore)
|
||||
|
||||
------------------------------------------------------------------------
|
||||
--[[
|
||||
io.write("testing proxy with post method: ")
|
||||
request = {
|
||||
url = "http://" .. host .. cgiprefix .. "/cat",
|
||||
@ -163,6 +164,7 @@ ignore = {
|
||||
headers = 1
|
||||
}
|
||||
check_request(request, expect, ignore)
|
||||
]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
io.write("testing simple post function: ")
|
||||
@ -249,6 +251,7 @@ ignore = {
|
||||
check_request(request, expect, ignore)
|
||||
|
||||
------------------------------------------------------------------------
|
||||
--[[
|
||||
io.write("testing proxy with redirection: ")
|
||||
request = {
|
||||
url = "http://" .. host .. prefix,
|
||||
@ -263,6 +266,7 @@ ignore = {
|
||||
headers = 1
|
||||
}
|
||||
check_request(request, expect, ignore)
|
||||
]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
io.write("testing automatic auth failure: ")
|
||||
|
Loading…
Reference in New Issue
Block a user