static void nchan_publisher_body_handler(ngx_http_request_t *r) { ngx_str_t *channel_id; nchan_loc_conf_t *cf = ngx_http_get_module_loc_conf(r, ngx_nchan_module); ngx_table_elt_t *content_length_elt; ngx_http_complex_value_t *authorize_request_url_ccv = cf->authorize_request_url; if((channel_id = nchan_get_channel_id(r, PUB, 1))==NULL) { nchan_http_finalize_request(r, r->headers_out.status ? NGX_OK : NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if(!authorize_request_url_ccv) { nchan_publisher_body_handler_continued(r, channel_id, cf); } else { nchan_pub_subrequest_stuff_t *psr_stuff; if((psr_stuff = ngx_palloc(r->pool, sizeof(*psr_stuff))) == NULL) { nchan_log_request_error(r, "can't allocate memory for publisher auth subrequest"); nchan_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } ngx_http_post_subrequest_t *psr = &psr_stuff->psr; nchan_pub_subrequest_data_t *psrd = &psr_stuff->psr_data; ngx_http_request_t *sr; ngx_str_t auth_request_url; ngx_http_complex_value(r, authorize_request_url_ccv, &auth_request_url); psr->handler = nchan_publisher_body_authorize_handler; psr->data = psrd; psrd->ch_id = channel_id; ngx_http_subrequest(r, &auth_request_url, NULL, &sr, psr, 0); if((sr->request_body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t))) == NULL) { nchan_log_request_error(r, "can't allocate memory for publisher auth subrequest body"); nchan_http_finalize_request(r, r->headers_out.status ? NGX_OK : NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if((content_length_elt = ngx_palloc(r->pool, sizeof(*content_length_elt))) == NULL) { nchan_log_request_error(r, "can't allocate memory for publisher auth subrequest content-length header"); nchan_http_finalize_request(r, r->headers_out.status ? NGX_OK : NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if(sr->headers_in.content_length) { *content_length_elt = *sr->headers_in.content_length; content_length_elt->value.len=1; content_length_elt->value.data=(u_char *)"0"; sr->headers_in.content_length = content_length_elt; } sr->headers_in.content_length_n = 0; sr->args = r->args; sr->header_only = 1; } }
static ngx_int_t nchan_publisher_body_authorize_handler(ngx_http_request_t *r, void *data, ngx_int_t rc) { nchan_pub_subrequest_data_t *d = data; if(rc == NGX_OK) { nchan_loc_conf_t *cf = ngx_http_get_module_loc_conf(r->parent, nchan_module); ngx_int_t code = r->headers_out.status; if(code >= 200 && code <299) { //authorized. proceed as planned nchan_publisher_body_handler_continued(r->parent, d->ch_id, cf); } else { //anything else means forbidden ngx_http_finalize_request(r->parent, NGX_HTTP_FORBIDDEN); } } else { ngx_http_finalize_request(r->parent, NGX_HTTP_INTERNAL_SERVER_ERROR); } return NGX_OK; }