Skip to content

Commit 2dbfdfe

Browse files
authored
feat: add read_line (#49)
1 parent d13c71d commit 2dbfdfe

File tree

5 files changed

+404
-20
lines changed

5 files changed

+404
-20
lines changed

lib/resty/apisix/stream/xrpc/socket.lua

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ typedef struct ngx_stream_lua_socket_tcp_upstream_s
2323
int
2424
ngx_stream_lua_ffi_socket_tcp_read_buf(ngx_stream_lua_request_t *r,
2525
ngx_stream_lua_socket_tcp_upstream_t *u, u_char **res, size_t len,
26-
u_char *errbuf, size_t *errbuf_size);
26+
size_t *actual_len, u_char *errbuf, size_t *errbuf_size);
2727

2828
int
2929
ngx_stream_lua_ffi_socket_tcp_get_read_buf_result(ngx_stream_lua_request_t *r,
30-
ngx_stream_lua_socket_tcp_upstream_t *u, u_char **res, size_t len,
31-
u_char *errbuf, size_t *errbuf_size);
30+
ngx_stream_lua_socket_tcp_upstream_t *u, u_char **buf, size_t len,
31+
size_t *actual_len, u_char *errbuf, size_t *errbuf_size);
3232

3333
int
3434
ngx_stream_lua_ffi_socket_tcp_send_from_socket(ngx_stream_lua_request_t *r,
@@ -53,7 +53,8 @@ local socket_tcp_reset_read_buf = C.ngx_stream_lua_ffi_socket_tcp_reset_read_buf
5353

5454
local ERR_BUF_SIZE = 256
5555
local SOCKET_CTX_INDEX = 1
56-
local resbuf = ffi.new("u_char*[1]")
56+
local res_buf = ffi.new("u_char*[1]")
57+
local actual_len_buf = ffi.new("size_t[1]")
5758
local Downstream = {}
5859
local Upstream = {}
5960
local downstream_mt
@@ -70,7 +71,7 @@ local function get_tcp_socket(cosocket)
7071
end
7172

7273

73-
local function _read(cosocket, len, single_buf)
74+
local function _read(cosocket, len, single_buf, eol)
7475
local r = get_request()
7576
if not r then
7677
error("no request found", 2)
@@ -80,14 +81,19 @@ local function _read(cosocket, len, single_buf)
8081

8182
local buf
8283
if single_buf then
83-
buf = resbuf
84+
buf = res_buf
85+
end
86+
87+
local len_buf
88+
if eol then
89+
len_buf = actual_len_buf
8490
end
8591

8692
local errbuf = get_string_buf(ERR_BUF_SIZE)
8793
local errbuf_size = get_size_ptr()
8894
errbuf_size[0] = ERR_BUF_SIZE
8995

90-
local rc = socket_tcp_read(r, u, buf, len, errbuf, errbuf_size)
96+
local rc = socket_tcp_read(r, u, buf, len, len_buf, errbuf, errbuf_size)
9197
if rc == FFI_DONE then
9298
error(ffi_str(errbuf, errbuf_size[0]), 2)
9399
end
@@ -99,7 +105,11 @@ local function _read(cosocket, len, single_buf)
99105

100106
if rc >= 0 then
101107
if single_buf then
102-
return resbuf[0]
108+
if eol then
109+
return res_buf[0], nil, tonumber(len_buf[0])
110+
end
111+
112+
return res_buf[0]
103113
end
104114

105115
return true
@@ -112,13 +122,16 @@ local function _read(cosocket, len, single_buf)
112122
errbuf = get_string_buf(ERR_BUF_SIZE)
113123
errbuf_size = get_size_ptr()
114124
errbuf_size[0] = ERR_BUF_SIZE
115-
rc = socket_tcp_get_read_result(r, u, buf, len, errbuf, errbuf_size)
125+
rc = socket_tcp_get_read_result(r, u, buf, len, len_buf, errbuf, errbuf_size)
116126
end
117127
end
118128

119129

120130
-- read the given length of data to a buffer in C land and return the buffer address
121131
-- return error if the read data is less than given length
132+
--
133+
-- Note: we will allocate a buffer with the given length, so better avoid to specify
134+
-- a length which is too big.
122135
local function read(cosocket, len)
123136
if len <= 0 then
124137
error("bad length: length of data should be positive, got " .. len, 2)
@@ -128,7 +141,28 @@ local function read(cosocket, len)
128141
error("bad length: length of data too big, got " .. len, 2)
129142
end
130143

131-
return _read(cosocket, len, true)
144+
return _read(cosocket, len, true, false)
145+
end
146+
147+
148+
-- read_line like `read` method but read until hitting the `\n` or the read data
149+
-- is equal to the given length.
150+
-- return nil, error if the `\n` is not found.
151+
-- return buffer address, nil, actual read len (excluding `\n` and optional `\r` before `\n`)
152+
-- if the `\n` is found.
153+
--
154+
-- Note: we will allocate a buffer with the given length, so better avoid to specify
155+
-- a length which is too big. And the specified length contains the '\n' and optional '\r'.
156+
local function read_line(cosocket, len)
157+
if len <= 0 then
158+
error("bad length: length of data should be positive, got " .. len, 2)
159+
end
160+
161+
if len > 4 * 1024 * 1024 then
162+
error("bad length: length of data too big, got " .. len, 2)
163+
end
164+
165+
return _read(cosocket, len, true, true)
132166
end
133167

134168

@@ -140,7 +174,7 @@ local function drain(cosocket, len)
140174
error("bad length: length of data should be positive, got " .. len, 2)
141175
end
142176

143-
return _read(cosocket, len, false)
177+
return _read(cosocket, len, false, false)
144178
end
145179

146180

@@ -219,6 +253,7 @@ local function patch_methods(sk)
219253

220254
copy.read = read
221255
copy.drain = drain
256+
copy.read_line = read_line
222257
copy.move = move
223258
copy.reset_read_buf = reset_read_buf
224259

0 commit comments

Comments
 (0)