diff --git a/src/lua/bsdsocket.lua b/src/lua/bsdsocket.lua index ab3ae58eb8e648f9787934644653b9a5dc98ba27..d5431929955fd8f468c1d930bab71634e06ec3c6 100644 --- a/src/lua/bsdsocket.lua +++ b/src/lua/bsdsocket.lua @@ -500,19 +500,11 @@ socket_methods.accept = function(self) return socket end -socket_methods.read = function(self, size, timeout) - if timeout == nil then - timeout = TIMEOUT_INFINITY - end - +local function readchunk(self, size, timeout) if self.rbuf == nil then self.rbuf = '' end - if size == nil then - size = 4294967295 - end - if string.len(self.rbuf) >= size then self._errno = nil local data = string.sub(self.rbuf, 1, size) @@ -574,34 +566,11 @@ local function readline_check(self, eols, limit) return nil end -socket_methods.readline = function(self, limit, eol, timeout) - if type(limit) == 'table' then -- :readline({eol}[, timeout ]) - if eol ~= nil then - timeout = eol - eol = limit - limit = nil - else - eol = limit - limit = nil - end - elseif eol ~= nil then - if type(eol) ~= 'table' then - eol = { eol } - end - end - - if timeout == nil then - timeout = TIMEOUT_INFINITY - end - +local function readline(self, limit, eol, timeout) if self.rbuf == nil then self.rbuf = '' end - if limit == nil then - limit = 4294967295 - end - self._errno = nil local data = readline_check(self, eol, limit) if data ~= nil then @@ -651,6 +620,26 @@ socket_methods.readline = function(self, limit, eol, timeout) end end +socket_methods.read = function(self, opts, timeout) + timeout = timeout and tonumber(timeout) or TIMEOUT_INFINITY + if type(opts) == 'number' then + return readchunk(self, opts, timeout) + elseif type(opts) == 'string' then + return readline(self, 4294967295, { opts }, timeout) + elseif type(opts) == 'table' then + local chunk = opts.chunk or opts.size or 4294967295 + local delimiter = opts.delimiter or opts.line + if delimiter == nil then + return readchunk(self, chunk, timeout) + elseif type(delimiter) == 'string' then + return readline(self, chunk, { delimiter }, timeout) + elseif type(delimiter) == 'table' then + return readline(self, chunk, delimiter, timeout) + end + end + error('Usage: s:read(delimiter|chunk|{delimiter = x, chunk = x}, timeout)') +end + socket_methods.write = function(self, octets, timeout) if timeout == nil then timeout = TIMEOUT_INFINITY diff --git a/test/box/bsdsocket.result b/test/box/bsdsocket.result index aff05e6d658b3b98293ea2597cfe4e37b4d216ad..845e1e3d4f4e0318c936ff607fb312beecd664ed 100644 --- a/test/box/bsdsocket.result +++ b/test/box/bsdsocket.result @@ -386,20 +386,20 @@ lua sc:send("\nnew line") --- - true ... -lua sa:readline({'\n'}, 1) +lua sa:read('\n', 1) --- - Hello, world ... -lua sa:readline(1, {'ine'}, 1) +lua sa:read({chunk = 1, line = 'ine'}, 1) --- - n ... -lua sa:readline({'ine'}, 1) +lua sa:read('ine', 1) --- - ew line ... -lua sa:readline({'ine'}, 0.1) +lua sa:read('ine', 0.1) --- - nil ... @@ -407,7 +407,7 @@ lua sc:send('Hello, world') --- - true ... -lua sa:readline({','}, 1) +lua sa:read(',', 1) --- - Hello, ... @@ -715,7 +715,7 @@ lua s:write('HEAD / HTTP/1.0\r\nHost: tarantool.org\r\n\r\n') --- - true ... -lua header = s:readline(4000, { '\n\n', '\r\n\r\n' }, 1) +lua header = s:read({chunk = 4000, line = { '\n\n', '\r\n\r\n' }}, 1) --- ... lua string.match(header, '\r\n\r\n$') ~= nil @@ -855,3 +855,145 @@ lua s:error() --- - Connection timed out ... +lua path = '/tmp/tarantool-test-socket' +--- +... +lua s = box.socket('PF_UNIX', 'SOCK_STREAM', 'ip') +--- +... +lua s:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true) +--- + - true +... +lua s:error() +--- + - nil +... +lua s:bind('unix/', path) +--- + - true +... +lua s:error() +--- + - nil +... +lua s:listen(128) +--- + - true +... +lua f = box.fiber.wrap(function() for i=1,2 do s:readable() local sc = s:accept(); sc:write('ok!'); sc:shutdown(); sc:close() end end) +--- +... +lua c = box.socket.tcp_connect('unix/', path) +--- +... +lua c:error() +--- + - nil +... +lua x = c:read('!') +--- +... +lua x, type(x), #x +--- + - ok! + - string + - 3 +... +lua x = c:read('!') +--- +... +lua c:error() +--- + - nil +... +lua x, type(x), #x +--- + - + - string + - 0 +... +lua x = c:read('!') +--- +... +lua c:error() +--- + - nil +... +lua x, type(x), #x +--- + - + - string + - 0 +... +lua c:close() +--- + - true +... +lua c = box.socket.tcp_connect('unix/', path) +--- +... +lua c:error() +--- + - nil +... +lua x = c:read(3) +--- +... +lua c:error() +--- + - nil +... +lua x, type(x), #x +--- + - ok! + - string + - 3 +... +lua x = c:read(1) +--- +... +lua c:error() +--- + - nil +... +lua x, type(x), #x +--- + - + - string + - 0 +... +lua x = c:read(1) +--- +... +lua c:error() +--- + - nil +... +lua x, type(x), #x +--- + - + - string + - 0 +... +lua x = c:sysread(1) +--- +... +lua c:error() +--- + - nil +... +lua x, type(x), #x +--- + - + - string + - 0 +... +lua c:close() +--- + - true +... +lua s:close() +--- + - true +... diff --git a/test/box/bsdsocket.test b/test/box/bsdsocket.test index c29876d7f0b052ebd30d8c0c28b152056c36a6ef..8ca6a8931eae214d21e5c72b5b4a50c950205ae7 100644 --- a/test/box/bsdsocket.test +++ b/test/box/bsdsocket.test @@ -117,13 +117,13 @@ exec admin "lua sa:recv()" exec admin "lua sc:send('Hello')" exec admin "lua sc:send(', world')" exec admin "lua sc:send(\"\\nnew line\")" -exec admin "lua sa:readline({'\\n'}, 1)" -exec admin "lua sa:readline(1, {'ine'}, 1)" -exec admin "lua sa:readline({'ine'}, 1)" -exec admin "lua sa:readline({'ine'}, 0.1)" +exec admin "lua sa:read('\\n', 1)" +exec admin "lua sa:read({chunk = 1, line = 'ine'}, 1)" +exec admin "lua sa:read('ine', 1)" +exec admin "lua sa:read('ine', 0.1)" exec admin "lua sc:send('Hello, world')" -exec admin "lua sa:readline({','}, 1)" +exec admin "lua sa:read(',', 1)" exec admin "lua sc:shutdown('W')" exec admin "lua sa:read(100, 1)" exec admin "lua sa:read(100, 1)" @@ -223,7 +223,7 @@ exec admin "lua s = box.socket.tcp_connect('tarantool.org', 80)" exec admin "lua string.match(tostring(s), ', aka') ~= nil" exec admin "lua string.match(tostring(s), ', peer') ~= nil" exec admin "lua s:write('HEAD / HTTP/1.0\\r\\nHost: tarantool.org\\r\\n\\r\\n')" -exec admin "lua header = s:readline(4000, { '\\n\\n', '\\r\\n\\r\\n' }, 1)" +exec admin "lua header = s:read({chunk = 4000, line = { '\\n\\n', '\\r\\n\\r\\n' }}, 1)" exec admin "lua string.match(header, '\\r\\n\\r\\n$') ~= nil" # exec admin "lua string.match(header, '200 [Oo][Kk]') ~= nil" exec admin "lua s:close()" @@ -272,3 +272,47 @@ exec admin "lua box.fiber.sleep(.1)" exec admin "lua s:close()" exec admin "lua ch:get(1)" exec admin "lua s:error()" + +path = '/tmp/tarantool-test-socket' +if os.path.exists(path): + os.unlink(path) +exec admin "lua path = '%s'" % path +exec admin "lua s = box.socket('PF_UNIX', 'SOCK_STREAM', 'ip')" +exec admin "lua s:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)" +exec admin "lua s:error()" +exec admin "lua s:bind('unix/', path)" +exec admin "lua s:error()" +exec admin "lua s:listen(128)" +exec admin "lua f = box.fiber.wrap(function() for i=1,2 do s:readable() local sc = s:accept(); sc:write('ok!'); sc:shutdown(); sc:close() end end)" + +exec admin "lua c = box.socket.tcp_connect('unix/', path)" +exec admin "lua c:error()" +exec admin "lua x = c:read('!')" +exec admin "lua x, type(x), #x" +exec admin "lua x = c:read('!')" +exec admin "lua c:error()" +exec admin "lua x, type(x), #x" +exec admin "lua x = c:read('!')" +exec admin "lua c:error()" +exec admin "lua x, type(x), #x" +exec admin "lua c:close()" + +exec admin "lua c = box.socket.tcp_connect('unix/', path)" +exec admin "lua c:error()" +exec admin "lua x = c:read(3)" +exec admin "lua c:error()" +exec admin "lua x, type(x), #x" +exec admin "lua x = c:read(1)" +exec admin "lua c:error()" +exec admin "lua x, type(x), #x" +exec admin "lua x = c:read(1)" +exec admin "lua c:error()" +exec admin "lua x, type(x), #x" +exec admin "lua x = c:sysread(1)" +exec admin "lua c:error()" +exec admin "lua x, type(x), #x" +exec admin "lua c:close()" + +exec admin "lua s:close()" + +os.unlink(path)