Exemplo n.º 1
0
subscriber_t *http_multipart_subscriber_create(ngx_http_request_t *r, nchan_msg_id_t *msg_id) {
  subscriber_t         *sub = longpoll_subscriber_create(r, msg_id);
  full_subscriber_t    *fsub = (full_subscriber_t *)sub;
  multipart_privdata_t *multipart_data;
  nchan_request_ctx_t  *ctx = ngx_http_get_module_ctx(fsub->sub.request, nchan_module);
  
  if(multipart_fn == NULL) {
    multipart_fn = &multipart_fn_data;
    *multipart_fn = *sub->fn;
    multipart_fn->enqueue = multipart_enqueue;
    multipart_fn->respond_message = multipart_respond_message;
    multipart_fn->respond_status = multipart_respond_status;
  }
  
  fsub->data.shook_hands = 0;
  
  fsub->privdata = ngx_palloc(sub->request->pool, sizeof(multipart_privdata_t));
  multipart_data = (multipart_privdata_t *)fsub->privdata;
  multipart_data->boundary_end = ngx_snprintf(multipart_data->boundary, 50, "\r\n--%V", nchan_request_multipart_boundary(fsub->sub.request, ctx));
  
  //header bufs -- unique per response
  ctx->output_str_queue = ngx_palloc(r->pool, sizeof(*ctx->output_str_queue));
  nchan_reuse_queue_init(ctx->output_str_queue, offsetof(headerbuf_t, prev), offsetof(headerbuf_t, next), headerbuf_alloc, NULL, sub->request->pool);
  
  ctx->bcp = ngx_palloc(r->pool, sizeof(nchan_bufchain_pool_t));
  nchan_bufchain_pool_init(ctx->bcp, r->pool);
  
  nchan_subscriber_common_setup(sub, HTTP_MULTIPART, &sub_name, multipart_fn, 0);
  return sub;
}
Exemplo n.º 2
0
static void nchan_output_reserve_message_queue(ngx_http_request_t *r, nchan_msg_t *msg) {
  nchan_request_ctx_t  *ctx = ngx_http_get_module_ctx(r, ngx_nchan_module);
  ngx_http_cleanup_t   *cln;
  
  if(msg->storage != NCHAN_MSG_SHARED) {
    if((msg = nchan_msg_derive_alloc(msg)) == NULL) {
      ERR("Coudln't alloc derived msg for output_reserve_message_queue");
      return;
    }
  }
  
  if(!ctx->reserved_msg_queue) {
    if((ctx->reserved_msg_queue = ngx_palloc(r->pool, sizeof(*ctx->reserved_msg_queue))) == NULL) {
      ERR("Coudln't palloc reserved_msg_queue");
      return;
    }
    nchan_reuse_queue_init(ctx->reserved_msg_queue, offsetof(rsvmsg_queue_t, prev), offsetof(rsvmsg_queue_t, next), rsvmsg_queue_palloc, rsvmsg_queue_release, r);
    
    if((cln = ngx_http_cleanup_add(r, 0)) == NULL) {
      ERR("Unable to add request cleanup for reserved_msg_queue queue");
      assert(0);
      return;
    }
    
    cln->data = ctx;
    cln->handler = nchan_reserve_msg_cleanup;
  }
  
  rsvmsg_queue_t   *qmsg = nchan_reuse_queue_push(ctx->reserved_msg_queue);
  qmsg->msg = msg;
  msg_reserve(msg, "output reservation");
}
Exemplo n.º 3
0
subscriber_t *http_chunked_subscriber_create(ngx_http_request_t *r, nchan_msg_id_t *msg_id) {
  subscriber_t         *sub = longpoll_subscriber_create(r, msg_id);
  full_subscriber_t    *fsub = (full_subscriber_t *)sub;
  nchan_request_ctx_t  *ctx = ngx_http_get_module_ctx(sub->request, ngx_nchan_module);
  if(chunked_fn == NULL) {
    chunked_fn = &chunked_fn_data;
    *chunked_fn = *sub->fn;
    chunked_fn->enqueue = chunked_enqueue;
    chunked_fn->respond_message = chunked_respond_message;
    chunked_fn->respond_status = chunked_respond_status;
  }
  
  fsub->data.shook_hands = 0;
  
  ctx->output_str_queue = ngx_palloc(r->pool, sizeof(*ctx->output_str_queue));
  nchan_reuse_queue_init(ctx->output_str_queue, offsetof(chunksizebuf_t, prev), offsetof(chunksizebuf_t, next), chunksizebuf_alloc, NULL, r->pool);
  
  ctx->bcp = ngx_palloc(r->pool, sizeof(nchan_bufchain_pool_t));
  nchan_bufchain_pool_init(ctx->bcp, r->pool);
  
  nchan_subscriber_common_setup(sub, HTTP_CHUNKED, &sub_name, chunked_fn, 1, 0);
  return sub;
}
Exemplo n.º 4
0
ngx_int_t nchan_subscriber_init_msgid_reusepool(nchan_request_ctx_t *ctx, ngx_pool_t *request_pool) {
  ctx->output_str_queue = ngx_palloc(request_pool, sizeof(*ctx->output_str_queue));
  nchan_reuse_queue_init(ctx->output_str_queue, offsetof(msgidbuf_t, prev), offsetof(msgidbuf_t, next), msgidbuf_alloc, NULL, request_pool);
  return NGX_OK;
}
Exemplo n.º 5
0
subscriber_t *websocket_subscriber_create(ngx_http_request_t *r, nchan_msg_id_t *msg_id) {
  nchan_request_ctx_t  *ctx = ngx_http_get_module_ctx(r, ngx_nchan_module);
  
  DBG("create for req %p", r);
  full_subscriber_t  *fsub;
  if((fsub = ngx_alloc(sizeof(*fsub), ngx_cycle->log)) == NULL) {
    ERR("Unable to allocate");
    return NULL;
  }
  
  nchan_subscriber_init(&fsub->sub, &new_websocket_sub, r, msg_id);
  fsub->cln = NULL;
  fsub->ctx = ctx;
  fsub->ws_meta_subprotocol = 0;
  fsub->finalize_request = 0;
  fsub->holding = 0;
  fsub->shook_hands = 0;
  fsub->connected = 0;
  fsub->pinging = 0;
  fsub->closing = 0;
  ngx_memzero(&fsub->ping_ev, sizeof(fsub->ping_ev));
  nchan_subscriber_init_timeout_timer(&fsub->sub, &fsub->timeout_ev);
  fsub->dequeue_handler = empty_handler;
  fsub->dequeue_handler_data = NULL;
  fsub->awaiting_destruction = 0;
  
  ngx_memzero(&fsub->closing_ev, sizeof(fsub->closing_ev));
#if nginx_version >= 1008000  
  fsub->closing_ev.cancelable = 1;
#endif
  
  //what should the buffers look like?
  
  /*
  //mesage buf
  b->last_buf = 1;
  b->last_in_chain = 1;
  b->flush = 1;
  b->memory = 1;
  b->temporary = 0;
  */
  
  if(fsub->sub.cf->pub.websocket) {
    fsub->publish_channel_id = nchan_get_channel_id(r, PUB, 0);
  }
  
  fsub->upstream_stuff = NULL;
  
  websocket_init_frame(&fsub->frame);
  
  //http request sudden close cleanup
  if((fsub->cln = ngx_http_cleanup_add(r, 0)) == NULL) {
    ERR("Unable to add request cleanup for websocket subscriber");
    return NULL;
  }
  fsub->cln->data = fsub;
  fsub->cln->handler = (ngx_http_cleanup_pt )sudden_abort_handler;
  DBG("%p created for request %p", &fsub->sub, r);
  
  assert(ctx != NULL);
  ctx->sub = &fsub->sub; //gonna need this for recv
  ctx->subscriber_type = fsub->sub.name;
  
  #if NCHAN_SUBSCRIBER_LEAK_DEBUG
    subscriber_debug_add(&fsub->sub);
  #endif

  //send-frame buffer
  ctx->output_str_queue = ngx_palloc(r->pool, sizeof(*ctx->output_str_queue));
  nchan_reuse_queue_init(ctx->output_str_queue, offsetof(framebuf_t, prev), offsetof(framebuf_t, next), framebuf_alloc, NULL, r->pool);
  
  //bufchain pool
  ctx->bcp = ngx_palloc(r->pool, sizeof(nchan_bufchain_pool_t));
  nchan_bufchain_pool_init(ctx->bcp, r->pool);
  
  return &fsub->sub;
}