static ngx_int_t websocket_publisher_upstream_handler(ngx_http_request_t *sr, void *data, ngx_int_t rc) { ngx_http_request_t *r = sr->parent; nchan_pub_upstream_data_t *d = (nchan_pub_upstream_data_t *)data; full_subscriber_t *fsub = d->fsub; r->main->subrequests++; //avoid tripping up subrequest loop detection if(r->connection->data == sr) { r->connection->data = r; } if(r->postponed) { r->postponed = NULL; } r->pool = d->original_pool; //ERR("request %p orig pool %p", r, r->pool); //discard cleanup r->cleanup = d->original_cleanup; r->count--; //don't destroy the temp pool just yet, if(rc == NGX_OK) { ngx_int_t code = sr->headers_out.status; ngx_int_t content_length; ngx_chain_t *request_chain; switch(code) { case NGX_HTTP_OK: case NGX_HTTP_CREATED: case NGX_HTTP_ACCEPTED: if(sr->upstream) { ngx_buf_t *buf; ngx_pool_t *tmp_pool = NULL; content_length = sr->upstream->headers_in.content_length_n > 0 ? sr->upstream->headers_in.content_length_n : 0; request_chain = sr->upstream->out_bufs; if (request_chain->next != NULL) { if((tmp_pool = ngx_create_pool(NCHAN_WS_UPSTREAM_TMP_POOL_SIZE, ngx_cycle->log))==NULL) { ERR("can't create temp upstream handler pool"); return NGX_ERROR; } buf = nchan_chain_to_single_buffer(tmp_pool, request_chain, content_length); } else { buf = request_chain->buf; if(buf->memory) { buf->start = buf->pos; buf->end = buf->last; buf->last_in_chain = 1; buf->last_buf = 1; } } websocket_publish_continue(fsub, buf); if (tmp_pool != NULL) { ngx_destroy_pool(tmp_pool); } } else { //content_length = 0; request_chain = NULL; ERR("upstream missing from upstream subrequest"); } break; case NGX_HTTP_NOT_MODIFIED: websocket_publish_continue(fsub, &d->buf); break; case NGX_HTTP_NO_CONTENT: //cancel publication break; default: websocket_respond_status(&fsub->sub, NGX_HTTP_FORBIDDEN, NULL); break; } } else { websocket_respond_status(&fsub->sub, NGX_HTTP_INTERNAL_SERVER_ERROR, NULL); } return NGX_OK; }
static void nchan_publisher_post_request(ngx_http_request_t *r, ngx_str_t *content_type, size_t content_length, ngx_chain_t *request_body_chain, ngx_str_t *channel_id, nchan_loc_conf_t *cf) { ngx_buf_t *buf; struct timeval tv; nchan_msg_t *msg; ngx_str_t *eventsource_event; #if FAKESHARD memstore_pub_debug_start(); #endif if((msg = ngx_pcalloc(r->pool, sizeof(*msg))) == NULL) { ngx_log_error(NGX_LOG_ERR, (r)->connection->log, 0, "nchan: can't allocate msg in request pool"); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } msg->shared = 0; if(cf->eventsource_event.len > 0) { msg->eventsource_event = cf->eventsource_event; } else if((eventsource_event = nchan_get_header_value(r, NCHAN_HEADER_EVENTSOURCE_EVENT)) != NULL) { msg->eventsource_event = *eventsource_event; } //content type if(content_type) { msg->content_type = *content_type; } if(content_length == 0) { buf = ngx_create_temp_buf(r->pool, 0); } else if(request_body_chain!=NULL) { buf = nchan_chain_to_single_buffer(r->pool, request_body_chain, content_length); } else { ngx_log_error(NGX_LOG_ERR, (r)->connection->log, 0, "nchan: unexpected publisher message request body buffer location. please report this to the nchan developers."); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } ngx_gettimeofday(&tv); msg->id.time = tv.tv_sec; msg->id.tag.fixed[0] = 0; msg->id.tagactive = 0; msg->id.tagcount = 1; msg->buf = buf; #if NCHAN_MSG_LEAK_DEBUG msg->lbl = r->uri; #endif #if NCHAN_BENCHMARK nchan_request_ctx_t *ctx = ngx_http_get_module_ctx(r, nchan_module); msg->start_tv = ctx->start_tv; #endif cf->storage_engine->publish(channel_id, msg, cf, (callback_pt) &publish_callback, r); #if FAKESHARD memstore_pub_debug_end(); #endif }
static void nchan_publisher_post_request(ngx_http_request_t *r, ngx_str_t *content_type, size_t content_length, ngx_chain_t *request_body_chain, ngx_str_t *channel_id, nchan_loc_conf_t *cf) { ngx_buf_t *buf; nchan_msg_t *msg; ngx_str_t *eventsource_event; safe_request_ptr_t *pd; #if FAKESHARD memstore_pub_debug_start(); #endif if((msg = ngx_pcalloc(r->pool, sizeof(*msg))) == NULL) { nchan_log_request_error(r, "can't allocate msg in request pool"); nchan_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } msg->storage = NCHAN_MSG_POOL; if(cf->eventsource_event.len > 0) { msg->eventsource_event = &cf->eventsource_event; } else if((eventsource_event = nchan_get_header_value(r, NCHAN_HEADER_EVENTSOURCE_EVENT)) != NULL) { msg->eventsource_event = eventsource_event; } //content type if(content_type) { msg->content_type = content_type; } if(content_length == 0) { buf = ngx_create_temp_buf(r->pool, 0); } else if(request_body_chain!=NULL) { buf = nchan_chain_to_single_buffer(r->pool, request_body_chain, content_length); } else { nchan_log_request_error(r, "unexpected publisher message request body buffer location. please report this to the nchan developers."); nchan_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } msg->id.time = 0; msg->id.tag.fixed[0] = 0; msg->id.tagactive = 0; msg->id.tagcount = 1; msg->buf = *buf; #if NCHAN_MSG_LEAK_DEBUG msg->lbl = r->uri; #endif #if NCHAN_BENCHMARK nchan_request_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_nchan_module); msg->start_tv = ctx->start_tv; #endif nchan_deflate_message_if_needed(msg, cf, r, r->pool); if((pd = nchan_set_safe_request_ptr(r)) == NULL) { return; } cf->storage_engine->publish(channel_id, msg, cf, (callback_pt) &publish_callback, pd); nchan_update_stub_status(total_published_messages, 1); #if FAKESHARD memstore_pub_debug_end(); #endif }