예제 #1
0
ngx_str_t *msgtag_to_str(nchan_msg_id_t *id) {
  size_t len;
  len = msgtag_to_strptr(id, msgtag_str_buf);
  msgtag_str.len = len;
  msgtag_str.data = (u_char *)msgtag_str_buf;
  return &msgtag_str;
}
예제 #2
0
ngx_str_t *msgid_to_str(nchan_msg_id_t *id) {
  int   l1, l2;
  char *cur;
  l1 = sprintf(msgtag_str_buf, "%li:", id->time);
  cur = &msgtag_str_buf[l1];
  l2 = msgtag_to_strptr(id, cur);
  msgtag_str.len = l1 + l2;
  msgtag_str.data = (u_char *)msgtag_str_buf;
  return &msgtag_str;
}
예제 #3
0
static ngx_int_t multipart_respond_message(subscriber_t *sub,  nchan_msg_t *msg) {
  
  full_subscriber_t      *fsub = (full_subscriber_t  *)sub;
  ngx_buf_t              *buf, *msg_buf = msg->buf, *msgid_buf;
  ngx_int_t               rc;
  nchan_loc_conf_t       *cf = ngx_http_get_module_loc_conf(fsub->sub.request, nchan_module);
  nchan_request_ctx_t    *ctx = ngx_http_get_module_ctx(fsub->sub.request, nchan_module);
  ngx_int_t               n;
  nchan_buf_and_chain_t  *bc;
  ngx_chain_t            *chain;
  ngx_file_t             *file_copy;
  multipart_privdata_t   *mpd = (multipart_privdata_t *)fsub->privdata;
  
  headerbuf_t            *headerbuf = nchan_reuse_queue_push(ctx->output_str_queue);
  u_char                 *cur = headerbuf->charbuf;
  
  if(fsub->data.timeout_ev.timer_set) {
    ngx_del_timer(&fsub->data.timeout_ev);
    ngx_add_timer(&fsub->data.timeout_ev, sub->cf->subscriber_timeout * 1000);
  }
  
  //generate the headers
  if(!cf->msg_in_etag_only) {
    //msgtime
    cur = ngx_cpymem(cur, "\r\nLast-Modified: ", sizeof("\r\nLast-Modified: ") - 1);
    cur = ngx_http_time(cur, msg->id.time);
    *cur++ = CR; *cur++ = LF;
    //msgtag
    cur = ngx_cpymem(cur, "Etag: ", sizeof("Etag: ") - 1);
    cur += msgtag_to_strptr(&msg->id, (char *)cur);
    *cur++ = CR; *cur++ = LF;
  }
  else {
    ngx_str_t   *tmp_etag = msgid_to_str(&msg->id);
    cur = ngx_snprintf(cur, 58 + 10*NCHAN_FIXED_MULTITAG_MAX, "\r\nEtag: %V\r\n", tmp_etag);
  }
  
  n=4;
  if(msg->content_type.len == 0) {
    //don't need content_type buf'n'chain
    n--;
  }
  if(ngx_buf_size(msg_buf) == 0) {
    //don't need msgbuf
    n --;
  }
  if((bc = nchan_bufchain_pool_reserve(ctx->bcp, n)) == NULL) {
    ERR("cant allocate buf-and-chains for multipart/mixed client output");
    return NGX_ERROR;
  }
  
  chain = &bc->chain;
  msgid_buf = chain->buf;
  
  //message id
  ngx_memzero(chain->buf, sizeof(ngx_buf_t));
  chain->buf->memory = 1;
  chain->buf->start = headerbuf->charbuf;
  chain->buf->pos = headerbuf->charbuf;
  
  //content_type maybe
  if(msg->content_type.len > 0) {
    chain = chain->next;
    buf = chain->buf;
    
    msgid_buf->last = cur;
    msgid_buf->end = cur;
    
    ngx_memzero(buf, sizeof(ngx_buf_t));
    buf->memory = 1;
    buf->start = cur;
    buf->pos = cur;
    buf->last = ngx_snprintf(cur, 255, "Content-Type: %V\r\n\r\n", &msg->content_type);
    buf->end = buf->last;
  }
  else {
    *cur++ = CR; *cur++ = LF;
    msgid_buf->last = cur;
    msgid_buf->end = cur;
  }
  
  chain = chain->next;
  buf = chain->buf;
  //msgbuf
  if(ngx_buf_size(msg_buf) > 0) {
    ngx_memcpy(buf, msg_buf, sizeof(*msg_buf));
    if(msg_buf->file) {
      file_copy = nchan_bufchain_pool_reserve_file(ctx->bcp);
      nchan_msg_buf_open_fd_if_needed(buf, file_copy, NULL);
    }
    buf->last_buf = 0;
    buf->last_in_chain = 0;
    buf->flush = 0;
  }
  
  chain = chain->next;
  buf = chain->buf;
  ngx_memzero(buf, sizeof(ngx_buf_t));
  buf->start = &mpd->boundary[0];
  buf->pos = buf->start;
  buf->end = mpd->boundary_end;
  buf->last = buf->end;
  buf->memory = 1;
  buf->last_buf = 0;
  buf->last_in_chain = 1;
  buf->flush = 1;
  
  ctx->prev_msg_id = fsub->sub.last_msgid;
  update_subscriber_last_msg_id(sub, msg);
  ctx->msg_id = fsub->sub.last_msgid;
  
  multipart_ensure_headers_sent(fsub);
  
  DBG("%p output msg to subscriber", sub);
  
  rc = nchan_output_msg_filter(fsub->sub.request, msg, &bc->chain);
  
  return rc;
}