Been trying to get an example module for reading a post, followed some examples I have found on the forum and got some bit on the way, but now I'm stuck at reading the buffs.
The following is a snippet of the code I have been trying with:
static ngx_int_t
ngx_http_demo_handler(ngx_http_request_t *r) {
ngx_int_t rc;
ngx_http_demo_loc_conf_t *fplcf;
fplcf = ngx_http_get_module_loc_conf(r, ngx_http_demo_module);
if (!(r->method & (NGX_HTTP_POST))) {
return NGX_HTTP_NOT_ALLOWED;
}
if (r->method & NGX_HTTP_POST) {
rc = ngx_http_read_client_request_body(r, ngx_http_demo_handle_post);
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return rc;
}
return NGX_DONE;
}
return NGX_DONE;
}
// and the callback function:
static void
ngx_http_demo_handle_post(ngx_http_request_t *r) {
u_char *p;
size_t len;
ngx_buf_t *b, *buf;
ngx_chain_t *cl;
ngx_chain_t *in;
ngx_chain_t out;
ngx_int_t rc;
if (r->request_body == NULL) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Read post data");
in = r->request_body->bufs;
// calculate length
len = 0;
for (cl = in; cl; cl = cl->next) {
b = cl->buf;
len += b->last - b->pos;
}
// copy the incoming data to buffer
p = ngx_pnalloc(r->pool, len);
for (cl = in; cl; cl = cl->next) {
b = cl->buf;
if (ngx_buf_in_memory(b)) {
p = ngx_copy(p, b->pos, b->last - b->pos);
}
}
// dump content to log
for (int i = 0; i < len; i++) {
fprintf(stderr, "0x%02x, ", p[i]);
if ((i + 1) % 16 == 0)
fprintf(stderr, "\n");
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "response length: %i", len);
buf = ngx_pcalloc(r->pool, sizeof (ngx_buf_t));
out.buf = buf;
out.next = NULL;
buf->pos = p;
buf->last = p + len;
buf->memory = 1;
buf->last_buf = 1;
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 = len;
rc = ngx_http_send_header(r);
ngx_http_output_filter(r, &out);
}
The output in the log dump is only an array initialised to 0 of the correct content length, after my reading in the forum I thought that the callback to my method was done then the data from the client was read into the buffs. But I guess there is something I have missed on how the lifecycle for a post is. Anyone that can give me a pointer on what I have done wrong?
Best Regards
lodakai
The following is a snippet of the code I have been trying with:
static ngx_int_t
ngx_http_demo_handler(ngx_http_request_t *r) {
ngx_int_t rc;
ngx_http_demo_loc_conf_t *fplcf;
fplcf = ngx_http_get_module_loc_conf(r, ngx_http_demo_module);
if (!(r->method & (NGX_HTTP_POST))) {
return NGX_HTTP_NOT_ALLOWED;
}
if (r->method & NGX_HTTP_POST) {
rc = ngx_http_read_client_request_body(r, ngx_http_demo_handle_post);
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return rc;
}
return NGX_DONE;
}
return NGX_DONE;
}
// and the callback function:
static void
ngx_http_demo_handle_post(ngx_http_request_t *r) {
u_char *p;
size_t len;
ngx_buf_t *b, *buf;
ngx_chain_t *cl;
ngx_chain_t *in;
ngx_chain_t out;
ngx_int_t rc;
if (r->request_body == NULL) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Read post data");
in = r->request_body->bufs;
// calculate length
len = 0;
for (cl = in; cl; cl = cl->next) {
b = cl->buf;
len += b->last - b->pos;
}
// copy the incoming data to buffer
p = ngx_pnalloc(r->pool, len);
for (cl = in; cl; cl = cl->next) {
b = cl->buf;
if (ngx_buf_in_memory(b)) {
p = ngx_copy(p, b->pos, b->last - b->pos);
}
}
// dump content to log
for (int i = 0; i < len; i++) {
fprintf(stderr, "0x%02x, ", p[i]);
if ((i + 1) % 16 == 0)
fprintf(stderr, "\n");
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "response length: %i", len);
buf = ngx_pcalloc(r->pool, sizeof (ngx_buf_t));
out.buf = buf;
out.next = NULL;
buf->pos = p;
buf->last = p + len;
buf->memory = 1;
buf->last_buf = 1;
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 = len;
rc = ngx_http_send_header(r);
ngx_http_output_filter(r, &out);
}
The output in the log dump is only an array initialised to 0 of the correct content length, after my reading in the forum I thought that the callback to my method was done then the data from the client was read into the buffs. But I guess there is something I have missed on how the lifecycle for a post is. Anyone that can give me a pointer on what I have done wrong?
Best Regards
lodakai