diff --git a/.travis.yml b/.travis.yml index 8e247b5..f8ff652 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ python: env: - LUA="luajit" -install: +before_install: - sudo pip install autobahntestsuite - sudo apt-get install libev-dev - sudo apt-get install luajit @@ -12,7 +12,17 @@ install: - sudo luarocks install luacov-coveralls - sudo luarocks install busted 1.11.1-1 -script: "sudo luarocks make rockspecs/lua-websockets-scm-1.rockspec && ./test.sh" +install: + - sudo luarocks make rockspecs/lua-websockets-core-scm-1.rockspec + - sudo luarocks make rockspecs/lua-websockets-sync-scm-1.rockspec + - sudo luarocks make rockspecs/lua-websockets-copas-scm-1.rockspec + - sudo luarocks make rockspecs/lua-websockets-ev-scm-1.rockspec + - sudo luarocks make rockspecs/lua-websockets-scm-1.rockspec + +script: + - ./test.sh after_success: - luacov-coveralls + + diff --git a/rockspecs/lua-websockets-copas-scm-1.rockspec b/rockspecs/lua-websockets-copas-scm-1.rockspec new file mode 100644 index 0000000..361850a --- /dev/null +++ b/rockspecs/lua-websockets-copas-scm-1.rockspec @@ -0,0 +1,31 @@ +package = "lua-websockets-copas" +version = "scm-1" + +source = { + url = "git://github.com/lipp/lua-websockets.git", +} + +description = { + summary = "copas backend for websockets for Lua", + homepage = "http://github.com/lipp/lua-websockets", + license = "MIT/X11", + detailed = "Provides async client and server for copas." +} + +dependencies = { + "lua >= 5.1", + "lua-websockets-core", + "luasocket", + "copas" +} + +build = { + type = 'none', + install = { + lua = { + ['websocket.client_copas'] = 'src/websocket/client_copas.lua', + ['websocket.server_copas'] = 'src/websocket/server_copas.lua', + } + } +} + diff --git a/rockspecs/lua-websockets-core-scm-1.rockspec b/rockspecs/lua-websockets-core-scm-1.rockspec new file mode 100644 index 0000000..9bcec15 --- /dev/null +++ b/rockspecs/lua-websockets-core-scm-1.rockspec @@ -0,0 +1,37 @@ +package = "lua-websockets-core" +version = "scm-1" + +source = { + url = "git://github.com/lipp/lua-websockets.git", +} + +description = { + summary = "Websockets for Lua", + homepage = "http://github.com/lipp/lua-websockets", + license = "MIT/X11", + detailed = "Provides base functionality to implement websocket protocol." +} + +dependencies = { + "lua >= 5.1", + "struct", + "bit32", + "basexx", +} + +build = { + type = 'none', + install = { + lua = { + ['websocket'] = 'src/websocket.lua', + ['websocket.sync'] = 'src/websocket/sync.lua', + ['websocket.client'] = 'src/websocket/client.lua', + ['websocket.server'] = 'src/websocket/server.lua', + ['websocket.handshake'] = 'src/websocket/handshake.lua', + ['websocket.tools'] = 'src/websocket/tools.lua', + ['websocket.frame'] = 'src/websocket/frame.lua', + ['websocket.bit'] = 'src/websocket/bit.lua', + } + } +} + diff --git a/rockspecs/lua-websockets-ev-scm-1.rockspec b/rockspecs/lua-websockets-ev-scm-1.rockspec new file mode 100644 index 0000000..2ca95e1 --- /dev/null +++ b/rockspecs/lua-websockets-ev-scm-1.rockspec @@ -0,0 +1,32 @@ +package = "lua-websockets-ev" +version = "scm-1" + +source = { + url = "git://github.com/lipp/lua-websockets.git", +} + +description = { + summary = "libev backend for websockets for Lua", + homepage = "http://github.com/lipp/lua-websockets", + license = "MIT/X11", + detailed = "Provides async client and server for lua-ev." +} + +dependencies = { + "lua >= 5.1", + "lua-websockets-core", + "luasocket", + "lua-ev", +} + +build = { + type = 'none', + install = { + lua = { + ['websocket.client_ev'] = 'src/websocket/client_ev.lua', + ['websocket.ev_common'] = 'src/websocket/ev_common.lua', + ['websocket.server_ev'] = 'src/websocket/server_ev.lua', + } + } +} + diff --git a/rockspecs/lua-websockets-scm-1.rockspec b/rockspecs/lua-websockets-scm-1.rockspec index f72b44b..85a6077 100644 --- a/rockspecs/lua-websockets-scm-1.rockspec +++ b/rockspecs/lua-websockets-scm-1.rockspec @@ -13,33 +13,10 @@ description = { } dependencies = { - "lua >= 5.1", - "struct", - "luasocket", - "luabitop", - "lua-ev", - "copas" -} - -build = { - type = 'none', - install = { - lua = { - ['websocket'] = 'src/websocket.lua', - ['websocket.sync'] = 'src/websocket/sync.lua', - ['websocket.client'] = 'src/websocket/client.lua', - ['websocket.client_sync'] = 'src/websocket/client_sync.lua', - ['websocket.client_ev'] = 'src/websocket/client_ev.lua', - ['websocket.client_copas'] = 'src/websocket/client_copas.lua', - ['websocket.ev_common'] = 'src/websocket/ev_common.lua', - ['websocket.server'] = 'src/websocket/server.lua', - ['websocket.server_ev'] = 'src/websocket/server_ev.lua', - ['websocket.server_copas'] = 'src/websocket/server_copas.lua', - ['websocket.handshake'] = 'src/websocket/handshake.lua', - ['websocket.tools'] = 'src/websocket/tools.lua', - ['websocket.frame'] = 'src/websocket/frame.lua', - ['websocket.bit'] = 'src/websocket/bit.lua', - } - } + "lua-websockets-core", + "lua-websockets-sync", + "lua-websockets-copas", + "lua-websockets-ev", } +build = {type = "builtin", modules = {}} diff --git a/rockspecs/lua-websockets-sync-scm-1.rockspec b/rockspecs/lua-websockets-sync-scm-1.rockspec new file mode 100644 index 0000000..e685d1b --- /dev/null +++ b/rockspecs/lua-websockets-sync-scm-1.rockspec @@ -0,0 +1,29 @@ +package = "lua-websockets-sync" +version = "scm-1" + +source = { + url = "git://github.com/lipp/lua-websockets.git", +} + +description = { + summary = "Sunc backend for websockets for Lua", + homepage = "http://github.com/lipp/lua-websockets", + license = "MIT/X11", + detailed = "Provides sync client" +} + +dependencies = { + "lua >= 5.1", + "lua-websockets-core", + "luasocket", +} + +build = { + type = 'none', + install = { + lua = { + ['websocket.client_sync'] = 'src/websocket/client_sync.lua', + } + } +} + diff --git a/src/websocket/tools.lua b/src/websocket/tools.lua index 38a76e8..3ee8846 100644 --- a/src/websocket/tools.lua +++ b/src/websocket/tools.lua @@ -15,20 +15,43 @@ local tinsert = table.insert local tconcat = table.concat local mrandom = math.random +local function prequire(m) + local ok, err = pcall(require, m) + if ok then return err, m end + return nil, err +end + +local function orequire(...) + for _, name in ipairs{...} do + local mod = prequire(name) + if mod then return mod, name end + end +end + +local function vrequire(...) + local m, n = orequire(...) + if m then return m, n end + error("Can not fine any of this modules: " .. table.concat({...}, "/"), 2) +end + -- used for generate key random ops math.randomseed(os.time()) --- SHA1 hashing from luacrypto, if available -local sha1_crypto -local done,crypto = pcall(require,'crypto') -if done then - sha1_crypto = function(msg) - return crypto.digest('sha1',msg,true) +-- SHA1 hashing from luacrypto, ldigest if available +local shalib, name = orequire('crypto', 'sha1', 'digest') +local sha1_digest if name == 'sha1' then + sha1_digest = function(str) return shalib.digest(str, true) end +elseif name == 'crypto' then + sha1_digest = function(str) return shalib.digest('sha1', str, true) end +elseif name == 'digest' then + if _G.sha1 and _G.sha1.digest then + shalib = _G.sha1 + sha1_digest = function(str) return shalib.digest(str, true) end end end - +if not sha1_digest then -- from wiki article, not particularly clever impl -local sha1_wiki = function(msg) +sha1_digest = function(msg) local h0 = 0x67452301 local h1 = 0xEFCDAB89 local h2 = 0x98BADCFE @@ -113,10 +136,19 @@ local sha1_wiki = function(msg) return struct.pack('>i>i>i>i>i',h0,h1,h2,h3,h4) end +end + +local base, name = vrequire("base64", "mime", "basexx") -local base64_encode = function(data) - local mime = require'mime' - return (mime.b64(data)) +local base64 = {} if name == 'basexx' then + base64.encode = function(str) return base.to_base64(str) end + base64.decode = function(str) return base.from_base64(str) end +elseif name == 'mime' then + base64.encode = function(str) return base.b64(str) end + base64.decode = function(str) return base.ub64(str) end +elseif name == 'base64' then + base64.encode = function(str) return base.encode(str) end + base64.decode = function(str) return base.decode(str) end end local parse_url = function(url) @@ -143,14 +175,12 @@ local generate_key = function() local r4 = mrandom(0,0xfffffff) local key = struct.pack('IIII',r1,r2,r3,r4) assert(#key==16,#key) - return base64_encode(key) + return base64.encode(key) end return { - sha1 = sha1_crypto or sha1_wiki, - base64 = { - encode = base64_encode - }, + sha1 = sha1_digest, + base64 = base64, parse_url = parse_url, generate_key = generate_key, }