ngx_http_lua_socket_push_input_data(ngx_http_request_t *r,
ngx_http_lua_ctx_t *ctx, ngx_http_lua_socket_tcp_upstream_t *u,
lua_State *L)
{
ngx_chain_t *cl;
ngx_chain_t **ll;
size_t size;
ngx_buf_t *b;
size_t nbufs;
luaL_Buffer luabuf;
dd("bufs_in: %p, buf_in: %p", u->bufs_in, u->buf_in);
size = 0;
nbufs = 0;
ll = NULL;
luaL_buffinit(L, &luabuf);
for (cl = u->bufs_in; cl; cl = cl->next) {
ptrdiff_t chunk_size;
b = cl->buf;
chunk_size = b->last - b->pos;
dd("copying input data chunk from %p: \"%.*s\"", cl,
(int) chunk_size, b->pos);
luaL_addlstring(&luabuf, (char *) b->pos, (size_t) chunk_size);
if (cl->next) {
ll = &cl->next;
}
size += chunk_size;
nbufs++;
}
luaL_pushresult(&luabuf);
dd("size: %d, nbufs: %d", (int) size, (int) nbufs);
ngx_http_lua_probe_socket_tcp_receive_done(r, u, lua_tostring(L, -1), size);
if (nbufs > 1 && ll) {
dd("recycle buffers: %d", (int) (nbufs - 1));
*ll = ctx->free_recv_bufs;
ctx->free_recv_bufs = u->bufs_in;
u->bufs_in = u->buf_in;
}
if (u->buffer.pos == u->buffer.last) {
dd("resetting u->buffer pos & last");
u->buffer.pos = u->buffer.start;
u->buffer.last = u->buffer.start;
}
if (u->bufs_in) {
u->buf_in->buf->last = u->buffer.pos;
u->buf_in->buf->pos = u->buffer.pos;
}
return NGX_OK;
}