//print information about a channel static ngx_int_t ngx_http_push_channel_info(ngx_http_request_t *r, ngx_uint_t messages, ngx_uint_t subscribers, time_t last_seen) { ngx_buf_t *b; ngx_uint_t len; ngx_str_t content_type = ngx_string("text/plain"); const ngx_str_t *format = &NGX_HTTP_PUSH_CHANNEL_INFO_PLAIN; time_t time_elapsed = ngx_time() - last_seen; if(r->headers_in.accept) { //lame content-negotiation (without regard for qvalues) u_char *accept = r->headers_in.accept->value.data; size_t len = r->headers_in.accept->value.len; size_t rem; u_char *cur = accept; u_char *priority=&accept[len-1]; for(rem=len; (cur = ngx_strnstr(cur, "text/", rem))!=NULL; cur += sizeof("text/")-1) { rem=len - ((size_t)(cur-accept)+sizeof("text/")-1); if(ngx_strncmp(cur+sizeof("text/")-1, "plain", rem<5 ? rem : 5)==0) { if(priority) { format = &NGX_HTTP_PUSH_CHANNEL_INFO_PLAIN; priority = cur+sizeof("text/")-1; //content-type is already set by default } } ngx_http_push_match_channel_info_subtype(sizeof("text/")-1, cur, rem, &priority, &format, &content_type); } cur = accept; for(rem=len; (cur = ngx_strnstr(cur, "application/", rem))!=NULL; cur += sizeof("application/")-1) { rem=len - ((size_t)(cur-accept)+sizeof("application/")-1); ngx_http_push_match_channel_info_subtype(sizeof("application/")-1, cur, rem, &priority, &format, &content_type); } } r->headers_out.content_type.len = content_type.len; r->headers_out.content_type.data = content_type.data; r->headers_out.content_type_len = r->headers_out.content_type.len; len = format->len - 8 - 1 + 3*NGX_INT_T_LEN; //minus 8 sprintf if ((b = ngx_create_temp_buf(r->pool, len)) == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b->last = ngx_sprintf(b->last, (char *)format->data, messages, last_seen==0 ? -1 : (ngx_int_t) time_elapsed ,subscribers); //lastly, set the content-length, because if the status code isn't 200, nginx may not do so automatically r->headers_out.content_length_n = ngx_buf_size(b); if (ngx_http_send_header(r) > NGX_HTTP_SPECIAL_RESPONSE) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } return ngx_http_output_filter(r, ngx_http_push_create_output_chain(b, r->pool, r->connection->log)); }
static u_char* ngx_http_find_location(ngx_http_advertise_ctx_t *ctx, ngx_http_advertise_format *adver) { u_char *location = NULL; u_char *strbpk = ngx_strnstr(adver->anchor.data, (char*)g_advertise_strbpk_s.data, adver->anchor.len); if (strbpk) { size_t anchor_new_length = strbpk - adver->anchor.data; location = ngx_strlcasestrn(ctx->html, ctx->last, adver->anchor.data, anchor_new_length - 1); if (location == NULL) { return NULL; } if (adver->location == 0) { return location; } u_char *suffix = strbpk + g_advertise_strbpk_s.len; size_t suffix_len = adver->anchor.data + adver->anchor.len - suffix; location = ngx_strlcasestrn(location + anchor_new_length, ctx->last, suffix, suffix_len - 1); if (location) { return location + suffix_len; } } else { location = ngx_strlcasestrn(ctx->html, ctx->last, adver->anchor.data, adver->anchor.len - 1); if (location) { location = (adver->location == 0) ? location : location + adver->anchor.len; } } return location; }
// old url: http://cdn_hostname/download/nginx.zip/9405801ae719fb8458b0c479efe87f30/536D4489 // new url: http://cdn_hostname/download/nginx.zip?k=9405801ae719fb8458b0c479efe87f30&e=536D4489 static ngx_int_t ngx_http_secure_download_split_uri(ngx_http_request_t *r, ngx_http_secure_download_split_uri_t *sdsu) { int len = r->uri.len; size_t args_len = r->args.len; u_char *args = r->args.data; const char *uri = (char*)r->uri.data; ngx_http_secure_download_loc_conf_t *sdc = ngx_http_get_module_loc_conf(r, ngx_http_secure_download_module); if (args == NULL){ ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "timestamp and md5 is not found"); return NGX_ERROR; } // potential problems: // 1) args may not ends with "\0" // 2) checking the length of timestamp and md5 is postponed sdsu->timestamp = (char*)ngx_strnstr(args, "e=", args_len); if (sdsu->timestamp == NULL) { ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "timestamp not found"); return NGX_ERROR; } else { sdsu->timestamp += 2; } sdsu->md5 = (char*)ngx_strnstr(args, "k=", args_len); if (sdsu->md5 == NULL) { ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "md5 not found"); return NGX_ERROR; } else { sdsu->md5 += 2; } sdsu->path = uri; sdsu->path_len = len; if(sdc->path_mode == FOLDER_MODE) { while(len && uri[--len] != '/'); } sdsu->path_to_hash_len = len; return NGX_OK; }
ngx_int_t nchan_detect_multipart_subscriber_request(ngx_http_request_t *r) { ngx_str_t *accept_header; if(r->headers_in.accept == NULL) { return 0; } accept_header = &r->headers_in.accept->value; if(ngx_strnstr(accept_header->data, "multipart/mixed", accept_header->len)) { return 1; } return 0; }
static ngx_int_t nchan_detect_eventsource_request(ngx_http_request_t *r) { ngx_str_t *accept_header; if(r->headers_in.accept == NULL) { return 0; } accept_header = &r->headers_in.accept->value; if(ngx_strnstr(accept_header->data, "text/event-stream", accept_header->len)) { return 1; } return 0; }
static ngx_int_t yy_sec_waf_execute_str(ngx_http_request_t *r, ngx_str_t *str, ngx_http_yy_sec_waf_rule_t *rule) { if (str == NULL || str->data == NULL) { return NGX_ERROR; } if (rule->str != NULL) { /* STR */ if (ngx_strnstr(str->data, (char*) rule->str->data, str->len)) { return RULE_MATCH; } } return RULE_NO_MATCH; }
static ngx_int_t ngx_http_advertise_header_filter(ngx_http_request_t *r) { off_t len; ngx_http_advertise_ctx_t *ctx; ngx_http_advertise_conf_t *conf; ngx_http_variable_value_t *vv; if ((r->headers_out.status != NGX_HTTP_OK && r->headers_out.status < NGX_HTTP_BAD_REQUEST) || r != r->main || r->header_only || r->headers_out.content_length_n == 0 || !(r->method & NGX_HTTP_GET)) { return ngx_http_next_header_filter(r); } ctx = ngx_http_get_module_ctx(r, ngx_http_advertise_module); if (ctx) { ngx_http_set_ctx(r, NULL, ngx_http_advertise_module); return ngx_http_next_header_filter(r); } conf = ngx_http_get_module_loc_conf(r, ngx_http_advertise_module); if (conf->inject == 0 \ || conf->advertise_array == NGX_CONF_UNSET_PTR \ || conf->advertise_array->nelts == 0 || conf->max_advertise_len == 0) { return ngx_http_next_header_filter(r); } if (ngx_http_blackhosts_test(r) == NGX_OK) { return ngx_http_next_header_filter(r); } vv = ngx_http_get_indexed_variable(r, (ngx_uint_t)conf->index); if (vv == NULL) { return NGX_ERROR; } ctx = (ngx_http_advertise_ctx_t*)(vv->data); if (ctx == NULL) { return NGX_ERROR; } if (r->headers_out.content_encoding && ngx_strnstr(r->headers_out.content_encoding->value.data, (char *) "gzip", r->headers_out.content_encoding->value.len)) { ctx->status = 2; ctx->phase = NGX_HTTP_ADVERTISE_PASS; return ngx_http_next_header_filter(r); } if (r->headers_out.content_type.len < sizeof("text/html") - 1 || !ngx_strnstr(r->headers_out.content_type.data, (char *)"text/html", r->headers_out.content_type.len)) { ctx->status = 3; ctx->phase = NGX_HTTP_ADVERTISE_PASS; return ngx_http_next_header_filter(r); } len = r->headers_out.content_length_n; if (len != -1 && (len > (off_t) conf->buffer_size || len < (off_t)conf->min_content_len)) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "advertise: too big or too small response: %O", len); ctx->status = 4; ctx->phase = NGX_HTTP_ADVERTISE_PASS; return ngx_http_next_header_filter(r); } if (len == -1) { ctx->length = conf->buffer_size; } else { ctx->length = (size_t) len; } ctx->alength = conf->max_advertise_len; ngx_http_set_ctx(r, ctx, ngx_http_advertise_module); if (r->headers_out.refresh) { r->headers_out.refresh->hash = 0; } r->main_filter_need_in_memory = 1; r->allow_ranges = 0; return NGX_OK; }
static ngx_int_t ngx_http_session_sticky_get_cookie(ngx_http_request_t *r) { time_t now; u_char *p, *v, *vv, *st, *last, *end; ngx_int_t diff, delimiter, legal, rc; ngx_str_t *cookie; ngx_uint_t i; ngx_table_elt_t **cookies; ngx_http_ss_ctx_t *ctx; ngx_http_upstream_ss_srv_conf_t *sscf; enum { pre_key = 0, key, pre_equal, pre_value, value } state; legal = 1; ctx = ngx_http_get_module_ctx(r, ngx_http_upstream_session_sticky_module); sscf = ctx->sscf; ctx->tries = 1; p = NULL; cookie = NULL; now = ngx_time(); cookies = (ngx_table_elt_t **) r->headers_in.cookies.elts; for (i = 0; i < r->headers_in.cookies.nelts; i++) { cookie = &cookies[i]->value; p = ngx_strnstr(cookie->data, (char *) sscf->cookie.data, cookie->len); if (p == NULL) { continue; } if (*(p + sscf->cookie.len) == ' ' || *(p + sscf->cookie.len) == '=') { break; } } if (i >= r->headers_in.cookies.nelts) { goto not_found; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "session sticky cookie: \"%V\"", &cookies[i]->value); st = p; v = p + sscf->cookie.len + 1; last = cookie->data + cookie->len; state = 0; while (p < last) { switch (state) { case pre_key: if (*p == ';') { goto not_found; } else if (!is_space(*p)) { state = key; } break; case key: if (is_space(*p)) { state = pre_equal; } else if (*p == '=') { state = pre_value; } break; case pre_equal: if (*p == '=') { state = pre_value; } else if (!is_space(*p)) { goto not_found; } break; case pre_value: if (!is_space(*p)) { state = value; v = p--; } break; case value: if (*p == ';') { end = p + 1; goto success; } if (p + 1 == last) { end = last; p++; goto success; } break; default: break; } p++; } not_found: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "session sticky [firstseen]"); ctx->frist = 1; ctx->sid.len = 0; ctx->sid.data = NULL; ctx->firstseen = now; ctx->lastseen = now; ngx_http_session_sticky_tmtoa(r, &ctx->s_lastseen, ctx->lastseen); ngx_http_session_sticky_tmtoa(r, &ctx->s_firstseen, ctx->firstseen); if (ctx->s_lastseen.data == NULL || ctx->s_firstseen.data == NULL) { return NGX_ERROR; } return NGX_OK; success: if (sscf->flag & NGX_HTTP_SESSION_STICKY_PREFIX) { for (vv = v; vv < p; vv++) { if (*vv == '~') { end = vv + 1; break; } } if (vv >= p) { goto not_found; } st = v; } else { vv = p; } if ((sscf->flag & NGX_HTTP_SESSION_STICKY_INSERT) && sscf->maxidle != NGX_CONF_UNSET) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "session_sticky mode [insert]"); delimiter = 0; for (p = v; p < vv; p++) { if (*p == NGX_HTTP_SESSION_STICKY_DELIMITER) { delimiter++; if (delimiter == 1) { ctx->sid.len = p - v; ctx->sid.data = ngx_pnalloc(r->pool, ctx->sid.len); if (ctx->sid.data == NULL) { return NGX_ERROR; } ngx_memcpy(ctx->sid.data, v, ctx->sid.len); v = p + 1; } else if(delimiter == 2) { ctx->s_lastseen.len = p - v; ctx->s_lastseen.data = ngx_pnalloc(r->pool, ctx->s_lastseen.len); if (ctx->s_lastseen.data == NULL) { return NGX_ERROR; } ngx_memcpy(ctx->s_lastseen.data, v, ctx->s_lastseen.len); v = p + 1; break; } else { legal = 0; goto finish; } } } if (p >= vv || v >= vv) { legal = 0; goto finish; } ctx->s_firstseen.len = vv - v; ctx->s_firstseen.data = ngx_pnalloc(r->pool, ctx->s_firstseen.len); if (ctx->s_firstseen.data == NULL) { return NGX_ERROR; } ngx_memcpy(ctx->s_firstseen.data, v, ctx->s_firstseen.len); ctx->firstseen = ngx_atotm(ctx->s_firstseen.data, ctx->s_firstseen.len); ctx->lastseen = ngx_atotm(ctx->s_lastseen.data, ctx->s_lastseen.len); if (ctx->firstseen == NGX_ERROR || ctx->lastseen == NGX_ERROR) { legal = 0; goto finish; } if (ctx->sid.len != 0) { diff = (ngx_int_t) (now - ctx->lastseen); if (diff > ctx->sscf->maxidle || diff < -86400) { legal = 0; goto finish; } diff = (ngx_int_t) (now - ctx->firstseen); if (diff > ctx->sscf->maxlife || diff < -86400) { legal = 0; goto finish; } } ngx_http_session_sticky_tmtoa(r, &ctx->s_lastseen, now); } else { ctx->sid.len = vv - v; ctx->sid.data = ngx_pnalloc(r->pool, ctx->sid.len); if (ctx->sid.data == NULL) { return NGX_ERROR; } ngx_memcpy(ctx->sid.data, v, ctx->sid.len); } finish: if (sscf->flag & (NGX_HTTP_SESSION_STICKY_PREFIX | NGX_HTTP_SESSION_STICKY_INDIRECT)) { cookie->len -= (end - st); if (cookie->len == 0) { rc = ngx_list_delete(&r->headers_in.headers, cookies[i]); if (rc != NGX_OK) { return NGX_ERROR; } } while (end < last) { *st++ = *end++; } } if (legal == 0) { goto not_found; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "session sticky sid [%V]", &ctx->sid); return NGX_OK; }
ngx_int_t nchan_pubsub_handler(ngx_http_request_t *r) { nchan_loc_conf_t *cf = ngx_http_get_module_loc_conf(r, nchan_module); ngx_str_t *channel_id; subscriber_t *sub; nchan_msg_id_t *msg_id; ngx_int_t rc = NGX_DONE; nchan_request_ctx_t *ctx; ngx_str_t *origin_header; #if NCHAN_BENCHMARK struct timeval tv; ngx_gettimeofday(&tv); #endif if((ctx = ngx_pcalloc(r->pool, sizeof(nchan_request_ctx_t))) == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, ctx, nchan_module); #if NCHAN_BENCHMARK ctx->start_tv = tv; #endif if((origin_header = nchan_get_header_value(r, NCHAN_HEADER_ORIGIN)) != NULL) { ctx->request_origin_header = *origin_header; if(!(cf->allow_origin.len == 1 && cf->allow_origin.data[0] == '*')) { if(!(origin_header->len == cf->allow_origin.len && ngx_strnstr(origin_header->data, (char *)cf->allow_origin.data, origin_header->len) != NULL)) { //CORS origin match failed! return a 403 forbidden goto forbidden; } } } else { ctx->request_origin_header.len=0; ctx->request_origin_header.data=NULL; } if((channel_id = nchan_get_channel_id(r, SUB, 1)) == NULL) { //just get the subscriber_channel_id for now. the publisher one is handled elsewhere return r->headers_out.status ? NGX_OK : NGX_HTTP_INTERNAL_SERVER_ERROR; } if(nchan_detect_websocket_request(r)) { //want websocket? if(cf->sub.websocket) { //we prefer to subscribe #if FAKESHARD memstore_sub_debug_start(); #endif if((msg_id = nchan_subscriber_get_msg_id(r)) == NULL) { goto bad_msgid; } if((sub = websocket_subscriber_create(r, msg_id)) == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "unable to create websocket subscriber"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } sub->fn->subscribe(sub, channel_id); #if FAKESHARD memstore_sub_debug_end(); #endif } else if(cf->pub.websocket) { //no need to subscribe, but keep a connection open for publishing //not yet implemented nchan_create_websocket_publisher(r); } else goto forbidden; return NGX_DONE; } else { subscriber_t *(*sub_create)(ngx_http_request_t *r, nchan_msg_id_t *msg_id) = NULL; switch(r->method) { case NGX_HTTP_GET: if(cf->sub.eventsource && nchan_detect_eventsource_request(r)) { sub_create = eventsource_subscriber_create; } else if(cf->sub.http_chunked && nchan_detect_chunked_subscriber_request(r)) { sub_create = http_chunked_subscriber_create; } else if(cf->sub.http_multipart && nchan_detect_multipart_subscriber_request(r)) { sub_create = http_multipart_subscriber_create; } else if(cf->sub.poll) { sub_create = intervalpoll_subscriber_create; } else if(cf->sub.longpoll) { sub_create = longpoll_subscriber_create; } else if(cf->pub.http) { nchan_http_publisher_handler(r); } else { goto forbidden; } if(sub_create) { #if FAKESHARD memstore_sub_debug_start(); #endif if((msg_id = nchan_subscriber_get_msg_id(r)) == NULL) { goto bad_msgid; } if((sub = sub_create(r, msg_id)) == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "unable to create subscriber"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } sub->fn->subscribe(sub, channel_id); #if FAKESHARD memstore_sub_debug_end(); #endif } break; case NGX_HTTP_POST: case NGX_HTTP_PUT: if(cf->pub.http) { nchan_http_publisher_handler(r); } else goto forbidden; break; case NGX_HTTP_DELETE: if(cf->pub.http) { nchan_http_publisher_handler(r); } else goto forbidden; break; case NGX_HTTP_OPTIONS: if(cf->pub.http) { nchan_OPTIONS_respond(r, &cf->allow_origin, &NCHAN_ACCESS_CONTROL_ALLOWED_PUBLISHER_HEADERS, &NCHAN_ALLOW_GET_POST_PUT_DELETE); } else if(cf->sub.poll || cf->sub.longpoll || cf->sub.eventsource || cf->sub.websocket) { nchan_OPTIONS_respond(r, &cf->allow_origin, &NCHAN_ACCESS_CONTROL_ALLOWED_SUBSCRIBER_HEADERS, &NCHAN_ALLOW_GET); } else goto forbidden; break; } } return rc; forbidden: nchan_respond_status(r, NGX_HTTP_FORBIDDEN, NULL, 0); return NGX_OK; bad_msgid: nchan_respond_cstring(r, NGX_HTTP_BAD_REQUEST, &NCHAN_CONTENT_TYPE_TEXT_PLAIN, "Message ID invalid", 0); return NGX_OK; }
static void gridfs_parse_range(ngx_http_request_t* r, ngx_str_t* range_str, uint64_t* range_start, uint64_t* range_end, gridfs_offset content_length) { u_char *p, *last; off_t start, end; ngx_uint_t bad; enum { sw_start = 0, sw_first_byte_pos, sw_first_byte_pos_n, sw_last_byte_pos, sw_last_byte_pos_n, sw_done } state = 0; p = (u_char *) ngx_strnstr(range_str->data, "bytes=", range_str->len); if (p == NULL) { return; } p += sizeof("bytes=") - 1; last = range_str->data + range_str->len; /* * bytes= contain ranges compatible with RFC 2616, "14.35.1 Byte Ranges", * but no whitespaces permitted */ bad = 0; start = 0; end = 0; while (p < last) { switch (state) { case sw_start: case sw_first_byte_pos: if (*p == '-') { p++; state = sw_last_byte_pos; break; } start = 0; state = sw_first_byte_pos_n; /* fall through */ case sw_first_byte_pos_n: if (*p == '-') { p++; state = sw_last_byte_pos; break; } if (*p < '0' || *p > '9') { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "bytes header filter: unexpected char '%c'" " (expected first-byte-pos)", *p); bad = 1; break; } start = start * 10 + *p - '0'; p++; break; case sw_last_byte_pos: if (*p == ',' || *p == '&' || *p == ';') { /* no last byte pos, assume end of file */ end = content_length - 1; state = sw_done; break; } end = 0; state = sw_last_byte_pos_n; /* fall though */ case sw_last_byte_pos_n: if (*p == ',' || *p == '&' || *p == ';') { state = sw_done; break; } if (*p < '0' || *p > '9') { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "bytes header filter: unexpected char '%c'" " (expected last-byte-pos)", *p); bad = 1; break; } end = end * 10 + *p - '0'; p++; break; case sw_done: *range_start = start; *range_end = end; break; } if (bad) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "bytes header filter: invalid range specification"); return; } } switch (state) { case sw_last_byte_pos: end = content_length - 1; case sw_last_byte_pos_n: if (start > end) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "bytes header filter: invalid range specification"); return; } *range_start = start; *range_end = end; break; default: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "bytes header filter: invalid range specification"); return; } }
/* check the mail address validity */ ngx_int_t oc_mail_addr_validate(ngx_str_t *addr) { /* 邮件地址的格式: local-part@domain local-part由字母、数字和特殊字符组成,总长度不超过64 domain由字母和"."组成,不超过253 邮件地址总长度不超过254 */ ngx_uint_t i, dn_len; ngx_uint_t last_dot = 0; u_char char_spec[]= "!#$%&'*+-/=?^_`{|}~"; u_char ca[] = {0,0}; //声明一个数组用于strnstr()函数 if (addr->len > OC_MAIL_ADDR_LEN_MAX) return OC_MAIL_ADDR_TOO_LONG; //定位"@"字符,同时检查local part的字符是否符合标准 for (i=0; i<addr->len; i++){ ca[0] = addr->data[i]; if (ca[0] == '@'){ if (i > OC_MAIL_ADDR_LOCAL_PART_LEN_MAX) return OC_MAIL_ADDR_LOCAL_TOO_LONG; break; } if (ca[0] == '.') { if (last_dot) { //连接两个"."是不允许的 return OC_MAIL_ADDR_INVALID; } last_dot = 1; continue; } else { last_dot = 0; } //有效字符判断 if ((ca[0]>='A' && ca[0]<='Z') || (ca[0]>='a' && ca[0]<='z') || (ca[0]>='0' && ca[0]<='9') || ngx_strnstr(char_spec, (char *)ca, sizeof("!#$%&'*+-/=?^_`{|}~"))) { continue; } else { return OC_MAIL_ADDR_INVALID; } } if (addr->data[0] == '.' || last_dot) { //local part的开始和结束是允许是'.' return OC_MAIL_ADDR_INVALID; } if (i==0 || i>OC_MAIL_ADDR_LOCAL_PART_LEN_MAX){ //local part 不允许长度为0,也不允许超过64 return OC_MAIL_ADDR_INVALID; } dn_len = addr->len - i - 1; if ( dn_len == 0 || dn_len > OC_MAIL_ADDR_DOMAIN_LEN_MAX) { //域名长度不允许为空,也不允许超过最大长度 return OC_MAIL_ADDR_INVALID; } //todo: 对域名的有效性进行判断 return OC_MAIL_ADDR_OK; }
static ngx_int_t ngx_http_flv_handler(ngx_http_request_t *r) { u_char *p, *n, *last; off_t start, len; size_t root; ngx_int_t rc; ngx_uint_t level, i; ngx_str_t path; ngx_log_t *log; ngx_buf_t *b; ngx_chain_t out[2]; ngx_open_file_info_t of; ngx_http_core_loc_conf_t *clcf; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; } if (r->uri.data[r->uri.len - 1] == '/') { return NGX_DECLINED; } /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_DECLINED; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } last = ngx_http_map_uri_to_path(r, &path, &root, 0); if (last == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } log = r->connection->log; path.len = last - path.data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http flv filename: \"%V\"", &path); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); of.test_dir = 0; of.valid = clcf->open_file_cache_valid; of.min_uses = clcf->open_file_cache_min_uses; of.errors = clcf->open_file_cache_errors; of.events = clcf->open_file_cache_events; if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { switch (of.err) { case 0: return NGX_HTTP_INTERNAL_SERVER_ERROR; case NGX_ENOENT: case NGX_ENOTDIR: case NGX_ENAMETOOLONG: level = NGX_LOG_ERR; rc = NGX_HTTP_NOT_FOUND; break; case NGX_EACCES: level = NGX_LOG_ERR; rc = NGX_HTTP_FORBIDDEN; break; default: level = NGX_LOG_CRIT; rc = NGX_HTTP_INTERNAL_SERVER_ERROR; break; } if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) { ngx_log_error(level, log, of.err, ngx_open_file_n " \"%s\" failed", path.data); } return rc; } if (!of.is_file) { if (ngx_close_file(of.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, ngx_close_file_n " \"%s\" failed", path.data); } return NGX_DECLINED; } start = 0; len = of.size; i = 1; if (r->args.len) { p = (u_char *) ngx_strnstr(r->args.data, "start=", r->args.len); if (p) { p += 6; for (n = p; n < r->args.data + r->args.len; n++) { if (*n == '&') { break; } } start = ngx_atoof(p, n - p); if (start == NGX_ERROR || start >= len) { start = 0; } if (start) { len = sizeof(ngx_flv_header) - 1 + len - start; i = 0; } } } log->action = "sending flv to client"; r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = len; r->headers_out.last_modified_time = of.mtime; if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (i == 0) { b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b->pos = ngx_flv_header; b->last = ngx_flv_header + sizeof(ngx_flv_header) - 1; b->memory = 1; out[0].buf = b; out[0].next = &out[1]; } else { r->allow_ranges = 1; } b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); if (b->file == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } b->file_pos = start; b->file_last = of.size; b->in_file = b->file_last ? 1: 0; b->last_buf = 1; b->last_in_chain = 1; b->file->fd = of.fd; b->file->name = path; b->file->log = log; out[1].buf = b; out[1].next = NULL; return ngx_http_output_filter(r, &out[i]); }
ngx_buf_t *nchan_channel_info_buf(ngx_str_t *accept_header, ngx_uint_t messages, ngx_uint_t subscribers, time_t last_seen, nchan_msg_id_t *last_msgid, ngx_str_t **generated_content_type) { ngx_buf_t *b = &channel_info_buf; ngx_uint_t len; const ngx_str_t *format = &NCHAN_CHANNEL_INFO_PLAIN; time_t time_elapsed = ngx_time() - last_seen; static nchan_msg_id_t zero_msgid = NCHAN_ZERO_MSGID; if(!last_msgid) { last_msgid = &zero_msgid; } ngx_memcpy(&channel_info_content_type, &NCHAN_CONTENT_TYPE_TEXT_PLAIN, sizeof(NCHAN_CONTENT_TYPE_TEXT_PLAIN)); b->start = channel_info_buf_str; b->pos = b->start; b->last_buf = 1; b->last_in_chain = 1; b->flush = 1; b->memory = 1; if(accept_header) { //lame content-negotiation (without regard for qvalues) u_char *accept = accept_header->data; len = accept_header->len; size_t rem; u_char *cur = accept; u_char *priority=&accept[len-1]; for(rem=len; (cur = ngx_strnstr(cur, "text/", rem))!=NULL; cur += sizeof("text/")-1) { rem=len - ((size_t)(cur-accept)+sizeof("text/")-1); if(ngx_strncmp(cur+sizeof("text/")-1, "plain", rem<5 ? rem : 5)==0) { if(priority) { format = &NCHAN_CHANNEL_INFO_PLAIN; priority = cur+sizeof("text/")-1; //content-type is already set by default } } nchan_match_channel_info_subtype(sizeof("text/")-1, cur, rem, &priority, &format, &channel_info_content_type); } cur = accept; for(rem=len; (cur = ngx_strnstr(cur, "application/", rem))!=NULL; cur += sizeof("application/")-1) { rem=len - ((size_t)(cur-accept)+sizeof("application/")-1); nchan_match_channel_info_subtype(sizeof("application/")-1, cur, rem, &priority, &format, &channel_info_content_type); } } if(generated_content_type) { *generated_content_type = &channel_info_content_type; } len = format->len - 8 - 1 + 3*NGX_INT_T_LEN; //minus 8 sprintf if(len > 512) { ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "NCHAN: Channel info string too long: max: 512, is: %i", len); len = 512; } b->last = ngx_sprintf(b->start, (char *)format->data, messages, last_seen==0 ? -1 : (ngx_int_t) time_elapsed, subscribers, msgid_to_str(last_msgid)); b->end = b->last; return b; }
static ngx_int_t ngx_http_recaptcha_form_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { u_char *head, *value, *last; ngx_str_t *name; ngx_http_recaptcha_conf_t *rcf; ngx_http_variable_value_t *vv; rcf = ngx_http_get_module_loc_conf(r, ngx_http_recaptcha_module); vv = ngx_http_get_indexed_variable(r, rcf->body_index); if (vv == NULL || vv->not_found || vv->len == 0) { goto not_found; } name = (ngx_str_t *) data; if (name == NULL) { goto not_found; } ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "request_body: \"%*s\", param name = \"%V\"", vv->len, vv->data, name); head = ngx_strnstr((u_char *)vv->data, (char *)name->data, (size_t)vv->len); if (head == NULL) { goto not_found; } value = head + name->len; if (*value != '=') { goto not_found; } value++; last = value; while (last < (vv->data + vv->len)) { if (*last == '&' || *last == CR || *last == LF) { break; } last++; } v->data = value; v->len = last - value; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; return NGX_OK; not_found: v->not_found = 1; return NGX_OK; }