ngxin处理post请求的handler

1. 在主handler中,判断如果是POST请求,转向一个post_handler,因为在不同事件中需要回调用这个post_handler,所以不要在主handler中处理。

2.因为其它事件回调这个post_hander时只能传入request,所以不要传入out,应该把out放在一个自己定义的context中

所以主handler中逻辑应该是

if (r->method == NGX_HTTP_POST) {
ctx = ngx_http_get_module_ctx(r, ngx_module_test);
if (ctx == NULL) {
ctx = ngx_pcalloc(r->pool, sizeof (ngx_test_request_ctx_t));
if (ctx == NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate request context.");
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ctx->post_read_okay = 0;
ctx->request_out = &out;
ngx_http_set_ctx(r, ctx, ngx_module_test);
}
return ngx_test_post_handler(r);

}


3.out从外部传入是为了和get等方法统一处理,也可以在这个post_handler要输出的时候再申请一个内存池作

static ngx_int_t ngx_test_post_handler(ngx_http_request_t *r) {

ngx_int_t rc;
ngx_test_request_ctx_t *ctx;
ngx_str_t input;
ngx_chain_t * out;
u_char * content;
content = (u_char *) "This is a post demo handler for nginx.";

ctx = ngx_http_get_module_ctx(r, ngx_module_test);
if (ctx == NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer.");
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}

if (!ctx->post_read_okay) {
rc = ngx_http_read_client_request_body(r, ngx_test_post_read_request_body_handler);
//ngx_test_post_read_request_body_handler只能有一个参数r,它又需要回调post_handler,

//所以它也只能传一个参数给post_handler,所以上面的out被放到ctx中。


if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return rc;
}
return NGX_DONE;
}

// get input request body
input = ngx_test_post_get_requst_body(r); //这个方法可以放在动态库中处理
if (input.len == 0) {
return NGX_DECLINED;
}

printf("post content:%s\n",(char* )input.data);

r->headers_out.content_type.len = sizeof ("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = ngx_strlen(content);

out = ctx->request_out;
out->buf->pos = content;
out->buf->last = content + (ngx_strlen(content));
out->buf->memory = 1;
out->buf->last_buf = 1;

ngx_http_send_header(r);
return ngx_http_output_filter(r, out);
}

static void ngx_test_post_read_request_body_handler(ngx_http_request_t *r) {
ngx_test_request_ctx_t *ctx;
ctx = ngx_http_get_module_ctx(r, ngx_module_test);

if (ctx == NULL) {
return ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
}
ctx->post_read_okay = 1;
ngx_http_finalize_request(r, ngx_test_post_handler(r));
}



static ngx_str_t ngx_test_post_get_requst_body(ngx_http_request_t *r) {
u_char *p;
u_char *data;
size_t len;
ngx_buf_t *buf, *next;
ngx_chain_t *cl;
ngx_str_t body = ngx_null_string;
if (r->request_body == NULL
|| r->request_body->bufs == NULL) {
return body;
}
if (r->request_body->temp_file) {
printf("Please read the content from file: %s\n", (char*) r->request_body->temp_file->file.name.data);
body = r->request_body->temp_file->file.name;
return body;
} else {

cl = r->request_body->bufs;

buf = cl->buf;

if (cl->next == NULL) {
len = (buf->last - buf->pos);
p = ngx_pnalloc(r->pool, len + 1);
if (p == NULL) {
return body;
}
data = p;
ngx_memcpy(p, buf->pos, len);
data[len] = 0;

} else {
next = cl->next->buf;
len = (buf->last - buf->pos) + (next->last - next->pos);
p = ngx_pnalloc(r->pool, len + 1);
data = p;
if (p == NULL) {
return body;
}
p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
ngx_memcpy(p, next->pos, next->last - next->pos);
data[len] = 0;
}
}

body.len = len;
body.data = data;
return body;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值