static int ngx_http_lua_ngx_req_append_body(lua_State *L) { ngx_http_request_t *r; int n; ngx_http_request_body_t *rb; ngx_str_t body; size_t size, rest; size_t offset = 0; n = lua_gettop(L); if (n != 1) { return luaL_error(L, "expecting 1 arguments but seen %d", n); } body.data = (u_char *) luaL_checklstring(L, 1, &body.len); lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r->request_body == NULL || r->request_body->buf == NULL || r->request_body->bufs == NULL) { return luaL_error(L, "request_body not initalized"); } rb = r->request_body; rest = body.len; while (rest > 0) { if (rb->buf->last == rb->buf->end) { if (ngx_http_lua_write_request_body(r, rb->bufs) != NGX_OK) { return luaL_error(L, "fail to write file"); } rb->buf->last = rb->buf->start; } size = rb->buf->end - rb->buf->last; if (size > rest) { size = rest; } ngx_memcpy(rb->buf->last, body.data + offset, size); rb->buf->last += size; rest -= size; offset += size; r->headers_in.content_length_n += size; } return 0; }
static int ngx_http_lua_ngx_req_body_finish(lua_State *L) { ngx_http_request_t *r; int n; ngx_http_request_body_t *rb; ngx_buf_t *b; size_t size; ngx_str_t value; ngx_str_t key; ngx_int_t rc; n = lua_gettop(L); if (n != 0) { return luaL_error(L, "expecting 0 argument but seen %d", n); } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request found"); } ngx_http_lua_check_fake_request(L, r); if (r->request_body == NULL || r->request_body->buf == NULL || r->request_body->bufs == NULL) { return luaL_error(L, "request_body not initalized"); } rb = r->request_body; if (rb->temp_file) { /* save the last part */ if (ngx_http_lua_write_request_body(r, rb->bufs) != NGX_OK) { return luaL_error(L, "fail to write file"); } b = ngx_calloc_buf(r->pool); if (b == NULL) { return luaL_error(L, "no memory"); } b->in_file = 1; b->file_pos = 0; b->file_last = rb->temp_file->file.offset; b->file = &rb->temp_file->file; if (rb->bufs->next) { rb->bufs->next->buf = b; } else { rb->bufs->buf = b; } } /* override input header Content-Length (value must be null terminated) */ value.data = ngx_palloc(r->pool, NGX_SIZE_T_LEN + 1); if (value.data == NULL) { return luaL_error(L, "no memory"); } size = (size_t) r->headers_in.content_length_n; value.len = ngx_sprintf(value.data, "%uz", size) - value.data; value.data[value.len] = '\0'; dd("setting request Content-Length to %.*s (%d)", (int) value.len, value.data, (int) size); if (r->headers_in.content_length) { r->headers_in.content_length->value.data = value.data; r->headers_in.content_length->value.len = value.len; } else { ngx_str_set(&key, "Content-Length"); rc = ngx_http_lua_set_input_header(r, key, value, 1 /* override */); if (rc != NGX_OK) { return luaL_error(L, "failed to reset the Content-Length " "input header"); } } return 0; }