//print information about a channel
ngx_int_t nchan_channel_info(ngx_http_request_t *r, ngx_uint_t messages, ngx_uint_t subscribers, time_t last_seen, nchan_msg_id_t *msgid) {
  ngx_buf_t                      *b;
  ngx_str_t                      *content_type;
  ngx_str_t                      *accept_header = NULL;
  
  if(r->headers_in.accept) {
    accept_header = &r->headers_in.accept->value;
  }
  
  b = nchan_channel_info_buf(accept_header, messages, subscribers, last_seen, msgid, &content_type);
  
  return nchan_respond_membuf(r, NGX_HTTP_OK, content_type, b, 0);
}
示例#2
0
static ngx_int_t websocket_publish_callback(ngx_int_t status, nchan_channel_t *ch, full_subscriber_t *fsub) {
  time_t                 last_seen = 0;
  ngx_uint_t             subscribers = 0;
  ngx_uint_t             messages = 0;
  nchan_msg_id_t        *msgid = NULL;
  ngx_http_request_t    *r = fsub->sub.request;
  ngx_str_t             *accept_header = NULL;
  ngx_buf_t             *tmp_buf;
  nchan_buf_and_chain_t *bc = nchan_bufchain_pool_reserve(fsub->ctx->bcp, 1);
  if(ch) {
    subscribers = ch->subscribers;
    last_seen = ch->last_seen;
    messages  = ch->messages;
    msgid = &ch->last_published_msg_id;
  }
  
  if(websocket_release(&fsub->sub, 0) == NGX_ABORT) {
    //zombie publisher
    //nothing more to do, we're finished here
    return NGX_OK;
  }
  
  switch(status) {
    case NCHAN_MESSAGE_QUEUED:
    case NCHAN_MESSAGE_RECEIVED:
      if(fsub->sub.cf->sub.websocket) {
        //don't reply with status info, this websocket is used for subscribing too,
        //so it should only be recieving messages
        return NGX_OK;
      }
      if(r->headers_in.accept) {
        accept_header = &r->headers_in.accept->value;
      }
      tmp_buf = nchan_channel_info_buf(accept_header, messages, subscribers, last_seen, msgid, NULL);
      ngx_memcpy(&bc->buf, tmp_buf, sizeof(*tmp_buf));
      bc->buf.last_buf=1;
      
      nchan_output_filter(fsub->sub.request, websocket_frame_header_chain(fsub, WEBSOCKET_TEXT_LAST_FRAME_BYTE, ngx_buf_size((&bc->buf)), &bc->chain));
      break;
    case NGX_ERROR:
    case NGX_HTTP_INTERNAL_SERVER_ERROR:
      assert(0);
      break;
  }
  return NGX_OK;
}
示例#3
0
static ngx_int_t websocket_publish_callback(ngx_int_t status, nchan_channel_t *ch, full_subscriber_t *fsub) {
  time_t               last_seen = 0;
  ngx_uint_t           subscribers = 0;
  ngx_uint_t           messages = 0;
  ngx_http_request_t  *r = fsub->request;
  ngx_str_t           *accept_header = NULL;
  ngx_buf_t           *tmp_buf;
  if(ch) {
    subscribers = ch->subscribers;
    last_seen = ch->last_seen;
    messages  = ch->messages;
  }
  
  switch(status) {
    case NCHAN_MESSAGE_QUEUED:
    case NCHAN_MESSAGE_RECEIVED:
      if(fsub->sub.cf->sub.websocket) {
        //don't reply with status info, this websocket is used for subscribing too,
        //so it should only be recieving messages
        return NGX_OK;
      }
      if(r->headers_in.accept) {
        accept_header = &r->headers_in.accept->value;
      }
      tmp_buf = nchan_channel_info_buf(accept_header, messages, subscribers, last_seen, NULL);
      ngx_memcpy(&fsub->msg_buf, tmp_buf, sizeof(*tmp_buf));
      fsub->msg_buf.last_buf=1;
      
      nchan_output_filter(fsub->request, websocket_frame_header_chain(fsub, WEBSOCKET_TEXT_LAST_FRAME_BYTE, ngx_buf_size((&fsub->msg_buf))));
      break;
    case NGX_ERROR:
    case NGX_HTTP_INTERNAL_SERVER_ERROR:
      assert(0);
      break;
  }
  return NGX_OK;
}
示例#4
0
//print information about a channel
static ngx_int_t nchan_channel_info(ngx_http_request_t *r, ngx_uint_t messages, ngx_uint_t subscribers, time_t last_seen) {
  ngx_buf_t                      *b;
  ngx_str_t                      *content_type;
  ngx_str_t                      *accept_header = NULL;
  
  if(r->headers_in.accept) {
    accept_header = &r->headers_in.accept->value;
  }
  
  b = nchan_channel_info_buf(accept_header, messages, subscribers, last_seen, &content_type);
  
  //not sure why this is needed, but content-type directly from the request can't be reliably used in the response 
  //(it probably can, but i'm just doing it wrong)
  /*if(content_type != &TEXT_PLAIN) {
    ERR("WTF why must i do this %p %V", content_type, content_type);
    content_type_copy.len = content_type->len;
    content_type_copy.data = ngx_palloc(r->pool, content_type_copy.len);
    assert(content_type_copy.data);
    ngx_memcpy(content_type_copy.data, content_type->data, content_type_copy.len);
    content_type = &content_type_copy;
  }*/
  
  return nchan_respond_membuf(r, NGX_HTTP_OK, content_type, b, 0);
}