aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2005-06-17 04:04:55 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2005-06-17 04:04:55 +0000
commit4d455c6206747ca65b14d65f75d34e16450d352b (patch)
tree4607fc690526e4d227e5c5148025ffa9ba879843
parent65c35845c54c7f84b1cf5b0e3d4c7bbdaf1014e3 (diff)
downloadluasocket-4d455c6206747ca65b14d65f75d34e16450d352b.tar.gz
luasocket-4d455c6206747ca65b14d65f75d34e16450d352b.tar.bz2
luasocket-4d455c6206747ca65b14d65f75d34e16450d352b.zip
Using core.so instead of csocket.so and cmime.so.
-rw-r--r--TODO3
-rw-r--r--src/http.lua98
-rw-r--r--src/luasocket.c2
-rw-r--r--src/luasocket.h2
-rw-r--r--src/mime.c2
-rw-r--r--src/mime.h2
-rw-r--r--src/mime.lua6
-rw-r--r--src/socket.lua37
-rw-r--r--test/httptest.lua6
9 files changed, 89 insertions, 69 deletions
diff --git a/TODO b/TODO
index 8749ea8..5772ae1 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,6 @@
1clean timeout argument to open functions in SMTP, HTTP and FTP
2add create field to FTP and SMTP
3talk about new create field in HTTP, FTP and SMTP
1talk about the non-blocking connect in the manual 4talk about the non-blocking connect in the manual
2test it on Windows!!! 5test it on Windows!!!
3 6
diff --git a/src/http.lua b/src/http.lua
index 1a7b101..91c52da 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -28,9 +28,40 @@ PORT = 80
28USERAGENT = socket._VERSION 28USERAGENT = socket._VERSION
29 29
30----------------------------------------------------------------------------- 30-----------------------------------------------------------------------------
31-- Reads MIME headers from a connection, unfolding where needed
32-----------------------------------------------------------------------------
33local function receiveheaders(sock, headers)
34 local line, name, value, err
35 headers = headers or {}
36 -- get first line
37 line, err = sock:receive()
38 if err then return nil, err end
39 -- headers go until a blank line is found
40 while line ~= "" do
41 -- get field-name and value
42 name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
43 if not (name and value) then return nil, "malformed reponse headers" end
44 name = string.lower(name)
45 -- get next line (value might be folded)
46 line, err = sock:receive()
47 if err then return nil, err end
48 -- unfold any folded values
49 while string.find(line, "^%s") do
50 value = value .. line
51 line = sock:receive()
52 if err then return nil, err end
53 end
54 -- save pair in table
55 if headers[name] then headers[name] = headers[name] .. ", " .. value
56 else headers[name] = value end
57 end
58 return headers
59end
60
61-----------------------------------------------------------------------------
31-- Extra sources and sinks 62-- Extra sources and sinks
32----------------------------------------------------------------------------- 63-----------------------------------------------------------------------------
33socket.sourcet["http-chunked"] = function(sock) 64socket.sourcet["http-chunked"] = function(sock, headers)
34 return base.setmetatable({ 65 return base.setmetatable({
35 getfd = function() return sock:getfd() end, 66 getfd = function() return sock:getfd() end,
36 dirty = function() return sock:dirty() end 67 dirty = function() return sock:dirty() end
@@ -42,18 +73,15 @@ socket.sourcet["http-chunked"] = function(sock)
42 local size = base.tonumber(string.gsub(line, ";.*", ""), 16) 73 local size = base.tonumber(string.gsub(line, ";.*", ""), 16)
43 if not size then return nil, "invalid chunk size" end 74 if not size then return nil, "invalid chunk size" end
44 -- was it the last chunk? 75 -- was it the last chunk?
45 if size <= 0 then 76 if size > 0 then
46 -- skip trailer headers, if any 77 -- if not, get chunk and skip terminating CRLF
47 local line, err = sock:receive()
48 while not err and line ~= "" do
49 line, err = sock:receive()
50 end
51 return nil, err
52 else
53 -- get chunk and skip terminating CRLF
54 local chunk, err, part = sock:receive(size) 78 local chunk, err, part = sock:receive(size)
55 if chunk then sock:receive() end 79 if chunk then sock:receive() end
56 return chunk, err 80 return chunk, err
81 else
82 -- if it was, read trailers into headers table
83 headers, err = receiveheaders(sock, headers)
84 if not headers then return nil, err end
57 end 85 end
58 end 86 end
59 }) 87 })
@@ -78,8 +106,8 @@ end
78local metat = { __index = {} } 106local metat = { __index = {} }
79 107
80-- default connect function, respecting the timeout 108-- default connect function, respecting the timeout
81local function connect(host, port) 109local function connect(host, port, create)
82 local c, e = socket.tcp() 110 local c, e = (create or socket.tcp)()
83 if not c then return nil, e end 111 if not c then return nil, e end
84 c:settimeout(TIMEOUT) 112 c:settimeout(TIMEOUT)
85 local r, e = c:connect(host, port or PORT) 113 local r, e = c:connect(host, port or PORT)
@@ -90,9 +118,9 @@ local function connect(host, port)
90 return c 118 return c
91end 119end
92 120
93function open(host, port, user) 121function open(host, port, create)
94 -- create socket with user connect function, or with default 122 -- create socket with user connect function, or with default
95 local c = socket.try((user or connect)(host, port)) 123 local c = socket.try(connect(host, port, create))
96 -- create our http request object, pointing to the socket 124 -- create our http request object, pointing to the socket
97 local h = base.setmetatable({ c = c }, metat) 125 local h = base.setmetatable({ c = c }, metat)
98 -- make sure the object close gets called on exception 126 -- make sure the object close gets called on exception
@@ -130,37 +158,16 @@ function metat.__index:receivestatusline()
130end 158end
131 159
132function metat.__index:receiveheaders() 160function metat.__index:receiveheaders()
133 local line, name, value 161 return self.try(receiveheaders(self.c))
134 local headers = {}
135 -- get first line
136 line = self.try(self.c:receive())
137 -- headers go until a blank line is found
138 while line ~= "" do
139 -- get field-name and value
140 name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
141 self.try(name and value, "malformed reponse headers")
142 name = string.lower(name)
143 -- get next line (value might be folded)
144 line = self.try(self.c:receive())
145 -- unfold any folded values
146 while string.find(line, "^%s") do
147 value = value .. line
148 line = self.try(self.c:receive())
149 end
150 -- save pair in table
151 if headers[name] then headers[name] = headers[name] .. ", " .. value
152 else headers[name] = value end
153 end
154 return headers
155end 162end
156 163
157function metat.__index:receivebody(headers, sink, step) 164function metat.__index:receivebody(headers, sink, step)
158 sink = sink or ltn12.sink.null() 165 sink = sink or ltn12.sink.null()
159 step = step or ltn12.pump.step 166 step = step or ltn12.pump.step
160 local length = base.tonumber(headers["content-length"]) 167 local length = base.tonumber(headers["content-length"])
161 local TE = headers["transfer-encoding"] 168 local t = headers["transfer-encoding"] -- shortcut
162 local mode = "default" -- connection close 169 local mode = "default" -- connection close
163 if TE and TE ~= "identity" then mode = "http-chunked" 170 if t and t ~= "identity" then mode = "http-chunked"
164 elseif base.tonumber(headers["content-length"]) then mode = "by-length" end 171 elseif base.tonumber(headers["content-length"]) then mode = "by-length" end
165 return self.try(ltn12.pump.all(socket.source(mode, self.c, length), 172 return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
166 sink, step)) 173 sink, step))
@@ -198,16 +205,21 @@ local function adjustproxy(reqt)
198end 205end
199 206
200local function adjustheaders(headers, host) 207local function adjustheaders(headers, host)
201 local lower = {} 208 -- default headers
202 -- override with user values 209 local lower = {
210 ["user-agent"] = USERAGENT,
211 ["host"] = host,
212 ["connection"] = "close, TE",
213 ["te"] = "trailers"
214 }
215 -- override with user headers
203 for i,v in pairs(headers or lower) do 216 for i,v in pairs(headers or lower) do
204 lower[string.lower(i)] = v 217 lower[string.lower(i)] = v
205 end 218 end
206 lower["user-agent"] = lower["user-agent"] or USERAGENT
207 lower["host"] = lower["host"] or host
208 return lower 219 return lower
209end 220end
210 221
222-- default url parts
211local default = { 223local default = {
212 host = "", 224 host = "",
213 port = PORT, 225 port = PORT,
@@ -280,7 +292,7 @@ end
280 292
281function trequest(reqt) 293function trequest(reqt)
282 reqt = adjustrequest(reqt) 294 reqt = adjustrequest(reqt)
283 local h = open(reqt.host, reqt.port, reqt.connect) 295 local h = open(reqt.host, reqt.port, reqt.create)
284 h:sendrequestline(reqt.method, reqt.uri) 296 h:sendrequestline(reqt.method, reqt.uri)
285 h:sendheaders(reqt.headers) 297 h:sendheaders(reqt.headers)
286 if reqt.source then h:sendbody(reqt.headers, reqt.source, reqt.step) end 298 if reqt.source then h:sendbody(reqt.headers, reqt.source, reqt.step) end
diff --git a/src/luasocket.c b/src/luasocket.c
index 2c3b526..ed26b1f 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -108,7 +108,7 @@ static int base_open(lua_State *L) {
108/*-------------------------------------------------------------------------*\ 108/*-------------------------------------------------------------------------*\
109* Initializes all library modules. 109* Initializes all library modules.
110\*-------------------------------------------------------------------------*/ 110\*-------------------------------------------------------------------------*/
111LUASOCKET_API int luaopen_csocket(lua_State *L) { 111LUASOCKET_API int luaopen_socketcore(lua_State *L) {
112 int i; 112 int i;
113 base_open(L); 113 base_open(L);
114 for (i = 0; mod[i].name; i++) mod[i].func(L); 114 for (i = 0; mod[i].name; i++) mod[i].func(L);
diff --git a/src/luasocket.h b/src/luasocket.h
index 768e335..34a7693 100644
--- a/src/luasocket.h
+++ b/src/luasocket.h
@@ -27,6 +27,6 @@
27/*-------------------------------------------------------------------------*\ 27/*-------------------------------------------------------------------------*\
28* Initializes the library. 28* Initializes the library.
29\*-------------------------------------------------------------------------*/ 29\*-------------------------------------------------------------------------*/
30LUASOCKET_API int luaopen_csocket(lua_State *L); 30LUASOCKET_API int luaopen_socketcore(lua_State *L);
31 31
32#endif /* LUASOCKET_H */ 32#endif /* LUASOCKET_H */
diff --git a/src/mime.c b/src/mime.c
index 67f9f5b..70e0db9 100644
--- a/src/mime.c
+++ b/src/mime.c
@@ -78,7 +78,7 @@ static UC b64unbase[256];
78/*-------------------------------------------------------------------------*\ 78/*-------------------------------------------------------------------------*\
79* Initializes module 79* Initializes module
80\*-------------------------------------------------------------------------*/ 80\*-------------------------------------------------------------------------*/
81MIME_API int luaopen_cmime(lua_State *L) 81MIME_API int luaopen_mimecore(lua_State *L)
82{ 82{
83 luaL_openlib(L, "mime", func, 0); 83 luaL_openlib(L, "mime", func, 0);
84 /* initialize lookup tables */ 84 /* initialize lookup tables */
diff --git a/src/mime.h b/src/mime.h
index d596861..34031a1 100644
--- a/src/mime.h
+++ b/src/mime.h
@@ -19,6 +19,6 @@
19#define MIME_API extern 19#define MIME_API extern
20#endif 20#endif
21 21
22MIME_API int luaopen_cmime(lua_State *L); 22MIME_API int luaopen_mimecore(lua_State *L);
23 23
24#endif /* MIME_H */ 24#endif /* MIME_H */
diff --git a/src/mime.lua b/src/mime.lua
index f6509a0..e112f8a 100644
--- a/src/mime.lua
+++ b/src/mime.lua
@@ -10,7 +10,9 @@
10----------------------------------------------------------------------------- 10-----------------------------------------------------------------------------
11local base = _G 11local base = _G
12local ltn12 = require("ltn12") 12local ltn12 = require("ltn12")
13local mime = require("cmime") 13local mime = require("mime.core")
14local io = require("io")
15local string = require("string")
14module("mime") 16module("mime")
15 17
16-- encode, decode and wrap algorithm tables 18-- encode, decode and wrap algorithm tables
@@ -49,8 +51,6 @@ decodet['quoted-printable'] = function()
49 return ltn12.filter.cycle(unqp, "") 51 return ltn12.filter.cycle(unqp, "")
50end 52end
51 53
52local io, string = io, string
53
54local function format(chunk) 54local function format(chunk)
55 if chunk then 55 if chunk then
56 if chunk == "" then return "''" 56 if chunk == "" then return "''"
diff --git a/src/socket.lua b/src/socket.lua
index d1c7846..13b474d 100644
--- a/src/socket.lua
+++ b/src/socket.lua
@@ -10,13 +10,13 @@
10local base = _G 10local base = _G
11local string = require("string") 11local string = require("string")
12local math = require("math") 12local math = require("math")
13local socket = require("csocket") 13local socket = require("socket.core")
14module("socket") 14module("socket")
15 15
16----------------------------------------------------------------------------- 16-----------------------------------------------------------------------------
17-- Auxiliar functions 17-- Exported auxiliar functions
18----------------------------------------------------------------------------- 18-----------------------------------------------------------------------------
19function socket.connect(address, port, laddress, lport) 19function connect(address, port, laddress, lport)
20 local sock, err = socket.tcp() 20 local sock, err = socket.tcp()
21 if not sock then return nil, err end 21 if not sock then return nil, err end
22 if laddress then 22 if laddress then
@@ -28,7 +28,7 @@ function socket.connect(address, port, laddress, lport)
28 return sock 28 return sock
29end 29end
30 30
31function socket.bind(host, port, backlog) 31function bind(host, port, backlog)
32 local sock, err = socket.tcp() 32 local sock, err = socket.tcp()
33 if not sock then return nil, err end 33 if not sock then return nil, err end
34 sock:setoption("reuseaddr", true) 34 sock:setoption("reuseaddr", true)
@@ -39,9 +39,9 @@ function socket.bind(host, port, backlog)
39 return sock 39 return sock
40end 40end
41 41
42socket.try = socket.newtry() 42try = newtry()
43 43
44function socket.choose(table) 44function choose(table)
45 return function(name, opt1, opt2) 45 return function(name, opt1, opt2)
46 if base.type(name) ~= "string" then 46 if base.type(name) ~= "string" then
47 name, opt1, opt2 = "default", name, opt1 47 name, opt1, opt2 = "default", name, opt1
@@ -56,12 +56,12 @@ end
56-- Socket sources and sinks, conforming to LTN12 56-- Socket sources and sinks, conforming to LTN12
57----------------------------------------------------------------------------- 57-----------------------------------------------------------------------------
58-- create namespaces inside LuaSocket namespace 58-- create namespaces inside LuaSocket namespace
59socket.sourcet = {} 59sourcet = {}
60socket.sinkt = {} 60sinkt = {}
61 61
62socket.BLOCKSIZE = 2048 62BLOCKSIZE = 2048
63 63
64socket.sinkt["close-when-done"] = function(sock) 64sinkt["close-when-done"] = function(sock)
65 return base.setmetatable({ 65 return base.setmetatable({
66 getfd = function() return sock:getfd() end, 66 getfd = function() return sock:getfd() end,
67 dirty = function() return sock:dirty() end 67 dirty = function() return sock:dirty() end
@@ -75,7 +75,7 @@ socket.sinkt["close-when-done"] = function(sock)
75 }) 75 })
76end 76end
77 77
78socket.sinkt["keep-open"] = function(sock) 78sinkt["keep-open"] = function(sock)
79 return base.setmetatable({ 79 return base.setmetatable({
80 getfd = function() return sock:getfd() end, 80 getfd = function() return sock:getfd() end,
81 dirty = function() return sock:dirty() end 81 dirty = function() return sock:dirty() end
@@ -87,11 +87,11 @@ socket.sinkt["keep-open"] = function(sock)
87 }) 87 })
88end 88end
89 89
90socket.sinkt["default"] = socket.sinkt["keep-open"] 90sinkt["default"] = sinkt["keep-open"]
91 91
92socket.sink = socket.choose(socket.sinkt) 92sink = choose(sinkt)
93 93
94socket.sourcet["by-length"] = function(sock, length) 94sourcet["by-length"] = function(sock, length)
95 return base.setmetatable({ 95 return base.setmetatable({
96 getfd = function() return sock:getfd() end, 96 getfd = function() return sock:getfd() end,
97 dirty = function() return sock:dirty() end 97 dirty = function() return sock:dirty() end
@@ -107,7 +107,7 @@ socket.sourcet["by-length"] = function(sock, length)
107 }) 107 })
108end 108end
109 109
110socket.sourcet["until-closed"] = function(sock) 110sourcet["until-closed"] = function(sock)
111 local done 111 local done
112 return base.setmetatable({ 112 return base.setmetatable({
113 getfd = function() return sock:getfd() end, 113 getfd = function() return sock:getfd() end,
@@ -127,8 +127,9 @@ socket.sourcet["until-closed"] = function(sock)
127end 127end
128 128
129 129
130socket.sourcet["default"] = socket.sourcet["until-closed"] 130sourcet["default"] = sourcet["until-closed"]
131 131
132socket.source = socket.choose(socket.sourcet) 132source = choose(sourcet)
133 133
134--getmetatable(_M).__index = nil 134-- clear globals from namespace
135getmetatable(_M).__index = nil
diff --git a/test/httptest.lua b/test/httptest.lua
index 963b947..86f14a4 100644
--- a/test/httptest.lua
+++ b/test/httptest.lua
@@ -22,7 +22,7 @@ http.TIMEOUT = 10
22 22
23local t = socket.gettime() 23local t = socket.gettime()
24 24
25host = host or "diego.student.princeton.edu" 25host = host or "localhost" -- "diego.student.princeton.edu"
26proxy = proxy or "http://localhost:3128" 26proxy = proxy or "http://localhost:3128"
27prefix = prefix or "/luasocket-test" 27prefix = prefix or "/luasocket-test"
28cgiprefix = cgiprefix or "/luasocket-test-cgi" 28cgiprefix = cgiprefix or "/luasocket-test-cgi"
@@ -146,6 +146,7 @@ ignore = {
146check_request(request, expect, ignore) 146check_request(request, expect, ignore)
147 147
148------------------------------------------------------------------------ 148------------------------------------------------------------------------
149--[[
149io.write("testing proxy with post method: ") 150io.write("testing proxy with post method: ")
150request = { 151request = {
151 url = "http://" .. host .. cgiprefix .. "/cat", 152 url = "http://" .. host .. cgiprefix .. "/cat",
@@ -163,6 +164,7 @@ ignore = {
163 headers = 1 164 headers = 1
164} 165}
165check_request(request, expect, ignore) 166check_request(request, expect, ignore)
167]]
166 168
167------------------------------------------------------------------------ 169------------------------------------------------------------------------
168io.write("testing simple post function: ") 170io.write("testing simple post function: ")
@@ -249,6 +251,7 @@ ignore = {
249check_request(request, expect, ignore) 251check_request(request, expect, ignore)
250 252
251------------------------------------------------------------------------ 253------------------------------------------------------------------------
254--[[
252io.write("testing proxy with redirection: ") 255io.write("testing proxy with redirection: ")
253request = { 256request = {
254 url = "http://" .. host .. prefix, 257 url = "http://" .. host .. prefix,
@@ -263,6 +266,7 @@ ignore = {
263 headers = 1 266 headers = 1
264} 267}
265check_request(request, expect, ignore) 268check_request(request, expect, ignore)
269]]
266 270
267------------------------------------------------------------------------ 271------------------------------------------------------------------------
268io.write("testing automatic auth failure: ") 272io.write("testing automatic auth failure: ")