static void ngx_http_push_stream_send_old_messages(ngx_http_request_t *r, ngx_http_push_stream_channel_t *channel, ngx_uint_t backtrack, time_t if_modified_since, ngx_int_t tag, time_t greater_message_time, ngx_int_t greater_message_tag, ngx_str_t *last_event_id) { ngx_http_push_stream_module_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_push_stream_module); ngx_http_push_stream_msg_t *message; ngx_queue_t *q; if (ngx_http_push_stream_has_old_messages_to_send(channel, backtrack, if_modified_since, tag, greater_message_time, greater_message_tag, last_event_id)) { if (backtrack > 0) { ngx_uint_t qtd = (backtrack > channel->stored_messages) ? channel->stored_messages : backtrack; ngx_uint_t start = channel->stored_messages - qtd; ngx_shmtx_lock(channel->mutex); // positioning at first message, and send the others for (q = ngx_queue_head(&channel->message_queue); (qtd > 0) && q != ngx_queue_sentinel(&channel->message_queue); q = ngx_queue_next(q)) { message = ngx_queue_data(q, ngx_http_push_stream_msg_t, queue); if (message->deleted) { break; } if (start == 0) { qtd--; ngx_http_push_stream_send_response_message(r, channel, message, 0, ctx->message_sent); } else { start--; } } ngx_shmtx_unlock(channel->mutex); } else if ((last_event_id != NULL) || (if_modified_since >= 0)) { ngx_flag_t found = 0; ngx_shmtx_lock(channel->mutex); for (q = ngx_queue_head(&channel->message_queue); q != ngx_queue_sentinel(&channel->message_queue); q = ngx_queue_next(q)) { message = ngx_queue_data(q, ngx_http_push_stream_msg_t, queue); if (message->deleted) { break; } if ((!found) && (last_event_id != NULL) && (message->event_id != NULL) && (ngx_memn2cmp(message->event_id->data, last_event_id->data, message->event_id->len, last_event_id->len) == 0)) { found = 1; continue; } if ((!found) && (if_modified_since >= 0) && ((message->time > if_modified_since) || ((message->time == if_modified_since) && (tag >= 0) && (message->tag >= tag)))) { found = 1; if ((message->time == if_modified_since) && (message->tag == tag)) { continue; } } if (found && (((greater_message_time == 0) && (greater_message_tag == -1)) || (greater_message_time > message->time) || ((greater_message_time == message->time) && (greater_message_tag >= message->tag)))) { ngx_http_push_stream_send_response_message(r, channel, message, 0, ctx->message_sent); } } ngx_shmtx_unlock(channel->mutex); } } }
static void ngx_http_push_stream_send_old_messages(ngx_http_request_t *r, ngx_http_push_stream_channel_t *channel, ngx_uint_t backtrack, time_t if_modified_since, ngx_int_t tag, time_t greater_message_time, ngx_int_t greater_message_tag, ngx_str_t *last_event_id) { ngx_http_push_stream_msg_t *message; ngx_queue_t *cur; if (ngx_http_push_stream_has_old_messages_to_send(channel, backtrack, if_modified_since, tag, greater_message_time, greater_message_tag, last_event_id)) { cur = &channel->message_queue; if (backtrack > 0) { ngx_uint_t qtd = (backtrack > channel->stored_messages) ? channel->stored_messages : backtrack; ngx_uint_t start = channel->stored_messages - qtd; // positioning at first message, and send the others while ((qtd > 0) && (cur = ngx_queue_next(cur)) && (cur != NULL) && (cur != &channel->message_queue)) { message = (ngx_http_push_stream_msg_t *) ngx_queue_data(cur, ngx_http_push_stream_msg_t, queue); if (message->deleted) { break; } if (start == 0) { ngx_http_push_stream_send_response_message(r, channel, message, 0, 1); qtd--; } else { start--; } } } else if ((last_event_id != NULL) || (if_modified_since >= 0)) { ngx_flag_t found = 0; while ((cur = ngx_queue_next(cur)) && (cur != NULL) && (cur != &channel->message_queue)) { message = (ngx_http_push_stream_msg_t *) ngx_queue_data(cur, ngx_http_push_stream_msg_t, queue); if (message->deleted) { break; } if ((!found) && (last_event_id != NULL) && (message->event_id != NULL) && (ngx_memn2cmp(message->event_id->data, last_event_id->data, message->event_id->len, last_event_id->len) == 0)) { found = 1; continue; } if ((!found) && (last_event_id == NULL) && (if_modified_since >= 0) && ((message->time > if_modified_since) || ((message->time == if_modified_since) && (tag >= 0) && (message->tag >= tag)))) { found = 1; if ((message->time == if_modified_since) && (message->tag == tag)) { continue; } } if (found && (((greater_message_time == 0) && (greater_message_tag == -1)) || (greater_message_time > message->time) || ((greater_message_time == message->time) && (greater_message_tag >= message->tag)))) { ngx_http_push_stream_send_response_message(r, channel, message, 0, 1); } } } } }
static ngx_int_t ngx_http_push_stream_respond_to_subscribers(ngx_http_push_stream_channel_t *channel, ngx_http_push_stream_queue_elem_t *subscribers_sentinel, ngx_http_push_stream_msg_t *msg) { ngx_http_push_stream_queue_elem_t *cur = subscribers_sentinel; if (subscribers_sentinel == NULL) { return NGX_ERROR; } if (msg != NULL) { // now let's respond to some requests! while ((cur = (ngx_http_push_stream_queue_elem_t *) ngx_queue_next(&cur->queue)) != subscribers_sentinel) { ngx_http_push_stream_subscriber_t *subscriber = (ngx_http_push_stream_subscriber_t *) cur->value; if (subscriber->longpolling) { ngx_http_push_stream_queue_elem_t *prev = (ngx_http_push_stream_queue_elem_t *) ngx_queue_prev(&cur->queue); ngx_http_push_stream_add_response_header(subscriber->request, &NGX_HTTP_PUSH_STREAM_HEADER_TRANSFER_ENCODING, &NGX_HTTP_PUSH_STREAM_HEADER_CHUNCKED); ngx_http_push_stream_add_polling_headers(subscriber->request, msg->time, msg->tag, subscriber->request->pool); ngx_http_send_header(subscriber->request); //Adam Konrad: putting If-Modified-Since and etag to the response body ngx_http_push_stream_send_http_time( subscriber->request, msg->time, msg->tag, subscriber->request->pool); ngx_http_push_stream_send_response_content_header(subscriber->request, ngx_http_get_module_loc_conf(subscriber->request, ngx_http_push_stream_module)); ngx_http_push_stream_send_response_message(subscriber->request, channel, msg, 1, 0); ngx_http_push_stream_send_response_finalize(subscriber->request); cur = prev; } else { if (ngx_http_push_stream_send_response_message(subscriber->request, channel, msg, 0, 0) != NGX_OK) { ngx_http_push_stream_queue_elem_t *prev = (ngx_http_push_stream_queue_elem_t *) ngx_queue_prev(&cur->queue); ngx_http_push_stream_send_response_finalize(subscriber->request); cur = prev; } else { ngx_http_push_stream_subscriber_ctx_t *ctx = ngx_http_get_module_ctx(subscriber->request, ngx_http_push_stream_module); ngx_http_push_stream_loc_conf_t *pslcf = ngx_http_get_module_loc_conf(subscriber->request, ngx_http_push_stream_module); ngx_http_push_stream_timer_reset(pslcf->ping_message_interval, ctx->ping_timer); } } } } return NGX_OK; }
static void ngx_http_push_stream_send_old_messages(ngx_http_request_t *r, ngx_http_push_stream_channel_t *channel, ngx_uint_t backtrack, time_t if_modified_since, ngx_int_t tag, time_t greater_message_time, ngx_int_t greater_message_tag, ngx_str_t *last_event_id, ngx_int_t *message_count_had_send) { ngx_http_push_stream_msg_t *message; ngx_queue_t *cur; time_t next_greater_message_time = greater_message_time;//add by xinlu ngx_int_t next_greater_message_tag = greater_message_tag;//add by xinlu if (ngx_http_push_stream_has_old_messages_to_send(channel, backtrack, if_modified_since, tag, greater_message_time, greater_message_tag, last_event_id, &next_greater_message_time, &next_greater_message_tag) >= 2) { cur = &channel->message_queue; if ((last_event_id != NULL) || (if_modified_since >= 0)) { ngx_flag_t found = 0; while ((cur = ngx_queue_next(cur)) && (cur != NULL) && (cur != &channel->message_queue)) { message = (ngx_http_push_stream_msg_t *) ngx_queue_data(cur, ngx_http_push_stream_msg_t, queue); if (message->deleted) { break; } if ((!found) && (last_event_id != NULL) && (message->event_id != NULL) && (ngx_memn2cmp(message->event_id->data, last_event_id->data, message->event_id->len, last_event_id->len) == 0)) { found = 1; continue; } if ((!found) && (last_event_id == NULL) && (if_modified_since >= 0) && ((message->time > if_modified_since) || ((message->time == if_modified_since) && (tag >= 0) && (message->tag >= tag)))) { found = 1; if ((message->time == if_modified_since) && (message->tag == tag)) { continue; } } //if (found && (((greater_message_time == 0) && (greater_message_tag == -1)) || (greater_message_time > message->time) || ((greater_message_time == message->time) && (greater_message_tag >= message->tag)))) if (found && (greater_message_time == message->time) && (greater_message_tag == message->tag)) { ngx_http_push_stream_send_response_message(r, channel, message, 0, 1); (*message_count_had_send)++; return; } } } } }