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;
}
Ejemplo n.º 4
0
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;
                }
            }
        }
    }
}