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; }
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; }
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; }