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; }
ngx_int_t nchan_parse_compound_msgid(nchan_msg_id_t *id, ngx_str_t *str, ngx_int_t expected_tag_count) { //parse url-unescaped compound msgid u_char *split, *last; ngx_int_t time; uint8_t len; //"<msg_time>:<msg_tag>" last = str->data + str->len; if((split = ngx_strlchr(str->data, last, ':')) != NULL) { len = 1; } else { len = 0; //placate dumb GCC warning } if(split) { time = ngx_atoi(str->data, split - str->data); split += len; if(time != NGX_ERROR) { id->time = time; return nchan_parse_msg_tag(split, last, id, expected_tag_count); } else { return NGX_ERROR; } } return NGX_DECLINED; }
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 nchan_parse_compound_msgid(nchan_msg_id_t *id, ngx_str_t *str){ u_char *split, *last; ngx_int_t time; //"<msg_time>:<msg_tag>" last = str->data + str->len; if((split = ngx_strlchr(str->data, last, ':')) != NULL) { time = ngx_atoi(str->data, split - str->data); split++; if(time != NGX_ERROR) { id->time = time; nchan_parse_msg_tag(split, last, id); return NGX_OK; } else { return NGX_ERROR; } } return NGX_DECLINED; }
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; }