Skip to content

Commit 72b7e72

Browse files
committed
Merge pull request #108 from matsumoto-r/support-requestbody
Support read request body
2 parents a990427 + ddfd730 commit 72b7e72

File tree

5 files changed

+93
-16
lines changed

5 files changed

+93
-16
lines changed

mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ def document_root
66
#def document_root=(path)
77
# Nginx::Var.new.set "document_root", path
88
#end
9+
def body
10+
self.read_body
11+
self.get_body
12+
end
913
end
1014
class Headers_in
1115
def user_agent

src/ngx_http_mruby_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ typedef struct ngx_http_mruby_ctx_t {
2121
u_char *body;
2222
u_char *last;
2323
size_t body_length;
24+
ngx_str_t request_body_ctx;
25+
unsigned request_body_more:1;
2426
} ngx_http_mruby_ctx_t;
2527

2628
void ngx_mrb_raise_error(mrb_state *mrb, mrb_value obj, ngx_http_request_t *r);

src/ngx_http_mruby_request.c

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,29 +135,40 @@ NGX_MRUBY_DEFINE_METHOD_NGX_GET_REQUEST_MEMBER_STR(content_type,
135135
NGX_MRUBY_DEFINE_METHOD_NGX_SET_REQUEST_MEMBER_STR(content_type,
136136
r->headers_out.content_type);
137137

138-
139-
static mrb_value ngx_mrb_get_request_body(mrb_state *mrb, mrb_value self)
138+
static void read_request_body_cb(ngx_http_request_t *r)
140139
{
141140
ngx_chain_t *cl;
142141
size_t len;
143142
u_char *p;
144143
u_char *buf;
145-
ngx_http_request_t *r = ngx_mrb_get_request();
144+
ngx_http_mruby_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_mruby_module);
146145

147-
if (r->request_body == NULL || r->request_body->temp_file
148-
|| r->request_body->bufs == NULL) {
149-
mrb_raise(mrb, E_RUNTIME_ERROR, "This pahse don't have request_body");
146+
if (r->request_body == NULL || r->request_body->bufs == NULL) {
147+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
148+
"This pahse don't have request_body");
149+
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
150+
return;
150151
}
151152

152153
cl = r->request_body->bufs;
153154

154155
if (cl->next == NULL) {
155156
len = cl->buf->last - cl->buf->pos;
156157
if (len == 0) {
157-
return mrb_nil_value();
158+
return;
158159
}
159160

160-
return mrb_str_new(mrb, (const char *)cl->buf->pos, len);
161+
ctx->request_body_ctx.data = cl->buf->pos;
162+
ctx->request_body_ctx.len = len;
163+
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
164+
"request_body(%d): %V", len, &ctx->request_body_ctx);
165+
if (ctx->request_body_more) {
166+
ctx->request_body_more = 0;
167+
ngx_http_core_run_phases(r);
168+
} else {
169+
ngx_http_finalize_request(r, NGX_DONE);
170+
}
171+
return;
161172
}
162173

163174
len = 0;
@@ -167,17 +178,62 @@ static mrb_value ngx_mrb_get_request_body(mrb_state *mrb, mrb_value self)
167178
}
168179

169180
if (len == 0) {
170-
return mrb_nil_value();
181+
return;
171182
}
172183

173-
buf = (u_char *)mrb_malloc(mrb, len);
184+
buf = ngx_palloc(r->pool, len);
174185

175186
p = buf;
176187
for (cl = r->request_body->bufs; cl; cl = cl->next) {
177188
p = ngx_copy(p, cl->buf->pos, cl->buf->last - cl->buf->pos);
178189
}
179190

180-
return mrb_str_new(mrb, (const char *)buf, len);
191+
ctx->request_body_ctx.data = buf;
192+
ctx->request_body_ctx.len = len;
193+
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
194+
"multi request_body(%d): %V", len, &ctx->request_body_ctx);
195+
if (ctx->request_body_more) {
196+
ctx->request_body_more = 0;
197+
ngx_http_core_run_phases(r);
198+
} else {
199+
ngx_http_finalize_request(r, NGX_DONE);
200+
}
201+
return;
202+
}
203+
204+
static mrb_value ngx_mrb_read_request_body(mrb_state *mrb, mrb_value self)
205+
{
206+
ngx_http_request_t *r = ngx_mrb_get_request();
207+
ngx_int_t rc;
208+
ngx_http_mruby_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_mruby_module);
209+
210+
if (r->method != NGX_HTTP_POST && r->method != NGX_HTTP_PUT) {
211+
mrb_raise(mrb, E_RUNTIME_ERROR, "ngx_mrb_read_request_body can't read"
212+
" when r->mehtod is neither POST nor PUT");
213+
}
214+
215+
rc = ngx_http_read_client_request_body(r, read_request_body_cb);
216+
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
217+
mrb_raise(mrb, E_RUNTIME_ERROR, "ngx_http_read_client_request_body failed");
218+
}
219+
if (rc == NGX_AGAIN) {
220+
ctx->request_body_more = 1;
221+
}
222+
223+
return mrb_fixnum_value(rc);
224+
}
225+
226+
static mrb_value ngx_mrb_get_request_body(mrb_state *mrb, mrb_value self)
227+
{
228+
ngx_http_request_t *r = ngx_mrb_get_request();
229+
ngx_http_mruby_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_mruby_module);
230+
231+
if (ctx->request_body_ctx.len != 0) {
232+
return mrb_str_new(mrb, (const char *)ctx->request_body_ctx.data,
233+
ctx->request_body_ctx.len);
234+
} else {
235+
return mrb_nil_value();
236+
}
181237
}
182238

183239
static mrb_value ngx_mrb_get_request_header(mrb_state *mrb, ngx_list_t *headers)
@@ -376,7 +432,8 @@ void ngx_mrb_request_class_init(mrb_state *mrb, struct RClass *class)
376432
struct RClass *class_headers_out;
377433

378434
class_request = mrb_define_class_under(mrb, class, "Request", mrb->object_class);
379-
mrb_define_method(mrb, class_request, "body", ngx_mrb_get_request_body, MRB_ARGS_NONE());
435+
mrb_define_method(mrb, class_request, "get_body", ngx_mrb_get_request_body, MRB_ARGS_NONE());
436+
mrb_define_method(mrb, class_request, "read_body", ngx_mrb_read_request_body, MRB_ARGS_NONE());
380437
mrb_define_method(mrb, class_request, "content_type=", ngx_mrb_set_content_type, MRB_ARGS_ANY());
381438
mrb_define_method(mrb, class_request, "content_type", ngx_mrb_get_content_type, MRB_ARGS_NONE());
382439
mrb_define_method(mrb, class_request, "request_line", ngx_mrb_get_request_request_line, MRB_ARGS_NONE());

test/conf/nginx.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,15 @@ http {
245245
';
246246
}
247247

248+
# test for request_body
249+
location /request_body_manual {
250+
mruby_rewrite_handler_code '
251+
r = Nginx::Request.new
252+
r.read_body
253+
Nginx.rputs r.get_body
254+
';
255+
}
256+
248257
# test for request_body
249258
location /request_body {
250259
mruby_rewrite_handler_code '

test/t/ngx_mruby.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,15 @@ def base
131131
t.assert_equal 500, res.code
132132
end
133133

134-
#t.assert('ngx_mruby - request_body', 'location /request_body') do
135-
# res = HttpRequest.new.post base + '/request_body', "request body test"
136-
# t.assert_equal "request body test", res["body"]
137-
#end
134+
t.assert('ngx_mruby - request_body', 'location /request_body_manual') do
135+
res = HttpRequest.new.post base + '/request_body_manual', "request body manual test"
136+
t.assert_equal "request body manual test", res["body"]
137+
end
138+
139+
t.assert('ngx_mruby - request_body', 'location /request_body') do
140+
res = HttpRequest.new.post base + '/request_body', "request body test"
141+
t.assert_equal "request body test", res["body"]
142+
end
138143

139144
t.assert('ngx_mruby - get server class name', 'location /server_class') do
140145
res = HttpRequest.new.get base + '/server_class'

0 commit comments

Comments
 (0)