diff --git a/src/ngx_stream_lua_socket_tcp.c b/src/ngx_stream_lua_socket_tcp.c index 46808113..0e9080ff 100644 --- a/src/ngx_stream_lua_socket_tcp.c +++ b/src/ngx_stream_lua_socket_tcp.c @@ -88,6 +88,7 @@ static int ngx_stream_lua_socket_write_error_retval_handler( ngx_stream_session_t *s, ngx_stream_lua_socket_tcp_upstream_t *u, lua_State *L); static ngx_int_t ngx_stream_lua_socket_read_all(void *data, ssize_t bytes); +static ngx_int_t ngx_stream_lua_socket_read_bsd(void *data, ssize_t bytes); static ngx_int_t ngx_stream_lua_socket_read_until(void *data, ssize_t bytes); static ngx_int_t ngx_stream_lua_socket_read_chunk(void *data, ssize_t bytes); static int ngx_stream_lua_socket_tcp_receiveuntil(lua_State *L); @@ -1736,6 +1737,10 @@ ngx_stream_lua_socket_tcp_receive(lua_State *L) u->input_filter = ngx_stream_lua_socket_read_all; break; + case 'b': + u->input_filter = ngx_stream_lua_socket_read_bsd; + break; + default: return luaL_argerror(L, 2, "bad pattern argument"); break; @@ -1991,6 +1996,38 @@ ngx_stream_lua_socket_read_line(void *data, ssize_t bytes) } +static ngx_int_t +ngx_stream_lua_socket_read_bsd(void *data, ssize_t bytes) +{ + ngx_stream_lua_socket_tcp_upstream_t *u = data; + + ngx_buf_t *b; + +#if (NGX_DEBUG) + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, u->request->connection->log, 0, + "stream lua tcp socket read bsd"); +#endif + + if (bytes == 0) { + u->ft_type |= NGX_STREAM_LUA_SOCKET_FT_CLOSED; + return NGX_ERROR; + } + + b = &u->buffer; + + dd("already read: %p: %.*s", u->buf_in, + (int) (u->buf_in->buf->last - u->buf_in->buf->pos), + u->buf_in->buf->pos); + + dd("data read: %.*s", (int) bytes, b->pos); + + u->buf_in->buf->last = ngx_cpymem(u->buf_in->buf->last, b->pos, bytes); + b->pos += bytes; + + return NGX_OK; +} + + static ngx_int_t ngx_stream_lua_socket_tcp_read(ngx_stream_session_t *s, ngx_stream_lua_socket_tcp_upstream_t *u) diff --git a/t/137-tcp-socket-receive-bsd-style.t b/t/137-tcp-socket-receive-bsd-style.t new file mode 100644 index 00000000..d73f4de0 --- /dev/null +++ b/t/137-tcp-socket-receive-bsd-style.t @@ -0,0 +1,85 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua::Stream 'no_plan'; + +repeat_each(2); + +log_level 'debug'; + +run_tests(); + +__DATA__ + +=== TEST 1: *b pattern for receive +--- config + location = /t { + content_by_lua_block { + local sock = ngx.socket.tcp() + sock:settimeout(100) + assert(sock:connect("127.0.0.1", 5678)) + + sock:send("1") + ngx.sleep(0.01) + + sock:send("22") + ngx.sleep(0.01) + + local t = { + 'test', + 'send', + 'table', + } + sock:send(t) + ngx.sleep(0.01) + + sock:send("hello world") + + local data, _ = sock:receive('*a') + ngx.say(data) + + sock:close() + } + } +--- main_config + stream { + server { + listen 5678; + content_by_lua_block { + local sock = ngx.req.socket(true) + local data, _ = sock:receive('*b') + if data ~= '1' then + ngx.log(ngx.ERR, "unexcepted result of: ", data) + return + end + + data, _ = sock:receive('*b') + if data ~= '22' then + ngx.log(ngx.ERR, "unexcepted result of: ", data) + return + end + + data, _ = sock:receive('*b') + if data ~= 'testsendtable' then + ngx.log(ngx.ERR, "unexcepted result of: ", data) + return + end + + data, _ = sock:receive('*b') + if data ~= 'hello world' then + ngx.log(ngx.ERR, "unexcepted result of: ", data) + return + end + + sock:send('ok') + } + } + } + +--- request +GET /t +--- response_body +ok +--- no_error_log +[error] +--- error_log +stream lua tcp socket read bsd