nchan_msg_id_t *nchan_subscriber_get_msg_id(ngx_http_request_t *r) { static nchan_msg_id_t id = NCHAN_ZERO_MSGID; ngx_str_t *if_none_match; nchan_loc_conf_t *cf = ngx_http_get_module_loc_conf(r, nchan_module); int i; if(!cf->msg_in_etag_only && r->headers_in.if_modified_since != NULL) { id.time=ngx_http_parse_time(r->headers_in.if_modified_since->value.data, r->headers_in.if_modified_since->value.len); if_none_match = nchan_subscriber_get_etag(r); if(if_none_match==NULL) { id.tagcount=1; id.tagactive=0; } else { nchan_parse_msg_tag(if_none_match->data, if_none_match->data + if_none_match->len, &id); } return &id; } else if(cf->msg_in_etag_only && (if_none_match = nchan_subscriber_get_etag(r)) != NULL) { if(nchan_parse_compound_msgid(&id, if_none_match) == NGX_OK) { return &id; } } else { nchan_complex_value_arr_t *alt_msgid_cv_arr = &cf->last_message_id; u_char buf[128]; ngx_str_t str; ngx_int_t rc; int n = alt_msgid_cv_arr->n; str.len = 0; str.data = buf; for(i=0; i < n; i++) { rc = ngx_http_complex_value_noalloc(r, alt_msgid_cv_arr->cv[i], &str, 128); if(str.len > 0 && rc == NGX_OK) { if(nchan_parse_compound_msgid(&id, &str) == NGX_OK) { return &id; } } } } //eh, we didn't find a valid alt_msgid value from variables. use the defaults id.time = cf->subscriber_start_at_oldest_message ? 0 : -1; id.tagcount=1; id.tagactive=0; id.tag.fixed[0] = 0; return &id; }
static ngx_int_t subscribe_intervalpoll_callback(nchan_msg_status_t msg_search_outcome, nchan_msg_t *msg, ngx_http_request_t *r) { //inefficient, but close enough for now ngx_str_t *etag; char *err; switch(msg_search_outcome) { case MSG_EXPECTED: //interval-polling subscriber requests get a 304 with their entity tags preserved. if (r->headers_in.if_modified_since != NULL) { r->headers_out.last_modified_time=ngx_http_parse_time(r->headers_in.if_modified_since->value.data, r->headers_in.if_modified_since->value.len); } if ((etag=nchan_subscriber_get_etag(r)) != NULL) { nchan_add_response_header(r, &NCHAN_HEADER_ETAG, etag); } nchan_respond_status(r, NGX_HTTP_NOT_MODIFIED, NULL, 1); break; case MSG_FOUND: if(nchan_respond_msg(r, msg, NULL, 1, &err) != NGX_OK) { nchan_respond_cstring(r, NGX_HTTP_INTERNAL_SERVER_ERROR, &TEXT_PLAIN, err, 1); } break; case MSG_NOTFOUND: case MSG_EXPIRED: nchan_respond_status(r, NGX_HTTP_NOT_FOUND, NULL, 1); break; default: nchan_respond_status(r, NGX_HTTP_INTERNAL_SERVER_ERROR, NULL, 1); return NGX_ERROR; } return NGX_DONE; }
static ngx_int_t nchan_subscriber_get_msg_id(ngx_http_request_t *r, nchan_msg_id_t *id) { static ngx_str_t last_event_id_header = ngx_string("Last-Event-ID"); ngx_str_t *last_event_id; ngx_str_t *if_none_match; if((last_event_id = nchan_get_header_value(r, last_event_id_header)) != NULL) { u_char *split, *last; ngx_int_t time; //"<msg_time>:<msg_tag>" last = last_event_id->data + last_event_id->len; if((split = ngx_strlchr(last_event_id->data, last, ':')) != NULL) { time = ngx_atoi(last_event_id->data, split - last_event_id->data); split++; if(time != NGX_ERROR) { id->time = time; nchan_parse_msg_tag(split, last, id); return NGX_OK; } } } if_none_match = nchan_subscriber_get_etag(r); id->time=(r->headers_in.if_modified_since == NULL) ? 0 : ngx_http_parse_time(r->headers_in.if_modified_since->value.data, r->headers_in.if_modified_since->value.len); if(if_none_match==NULL) { int i; for(i=0; i< NCHAN_MULTITAG_MAX; i++) { id->tag[i]=0; } id->tagcount=1; } else { nchan_parse_msg_tag(if_none_match->data, if_none_match->data + if_none_match->len, id); } return NGX_OK; }
nchan_msg_id_t *nchan_subscriber_get_msg_id(ngx_http_request_t *r) { static nchan_msg_id_t id = NCHAN_ZERO_MSGID; ngx_str_t *if_none_match; nchan_loc_conf_t *cf = ngx_http_get_module_loc_conf(r, ngx_nchan_module); nchan_request_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_nchan_module); int i; ngx_int_t rc; if_none_match = nchan_subscriber_get_etag(r); if(!cf->msg_in_etag_only && r->headers_in.if_modified_since != NULL) { id.time=ngx_http_parse_time(r->headers_in.if_modified_since->value.data, r->headers_in.if_modified_since->value.len); if(id.time <= 0) { //anything before 1-1-1970 is reserved and treated as no msgid provided set_default_id(cf, &id); return &id; } u_char *first = NULL, *last = NULL; if(if_none_match != NULL) { first = if_none_match->data; last = if_none_match->data + if_none_match->len; } if(nchan_parse_msg_tag(first, last, &id, ctx->channel_id_count) == NGX_ERROR) { return NULL; } return &id; } else if((cf->msg_in_etag_only || r->headers_in.if_modified_since == NULL) && if_none_match) { rc = nchan_parse_compound_msgid(&id, if_none_match, ctx->channel_id_count); if(rc == NGX_OK) { return &id; } else if(rc == NGX_ERROR) { return NULL; } } else { nchan_complex_value_arr_t *alt_msgid_cv_arr = &cf->last_message_id; u_char buf[128]; ngx_str_t str; int n = alt_msgid_cv_arr->n; ngx_int_t rc2; str.len = 0; str.data = buf; for(i=0; i < n; i++) { rc = ngx_http_complex_value_noalloc(r, alt_msgid_cv_arr->cv[i], &str, 128); if(str.len > 0 && rc == NGX_OK) { rc2 = nchan_parse_compound_msgid(&id, nchan_urldecode_str(r, &str), ctx->channel_id_count); if(rc2 == NGX_OK) { return &id; } else if(rc2 == NGX_ERROR) { return NULL; } } } } set_default_id(cf, &id); return &id; }