ngx_int_t ngx_http_echo_exec_echo_blocking_sleep(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_str_t *computed_arg; ngx_str_t *computed_arg_elts; ngx_int_t delay; /* in msec */ computed_arg_elts = computed_args->elts; computed_arg = &computed_arg_elts[0]; delay = ngx_atofp(computed_arg->data, computed_arg->len, 3); if (delay == NGX_ERROR) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "invalid sleep duration \"%V\"", &computed_arg_elts[0]); return NGX_HTTP_BAD_REQUEST; } dd("blocking delay: %lu ms", (unsigned long) delay); ngx_msleep((ngx_msec_t) delay); return NGX_OK; }
static char * ngx_http_sysguard_mem(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_conn_conf_t *lccf = conf; ngx_str_t *value, ss; ngx_uint_t i; value = cf->args->elts; i = 1; if (ngx_strncmp(value[i].data, "swapratio=", 10) == 0) { if (lccf->swap != NGX_CONF_UNSET) { return "is duplicate"; } if (value[i].data[value[i].len - 1] != '%') { goto invalid; } lccf->swap = ngx_atofp(value[i].data + 10, value[i].len - 11, 2); if (lccf->swap == NGX_ERROR) { goto invalid; } if (cf->args->nelts == 2) { return NGX_CONF_OK; } return NGX_CONF_OK; } else if (ngx_strncmp(value[i].data, "free=", 5) == 0) { if (lccf->free != NGX_CONF_UNSET_SIZE) { return "is duplicate"; } ss.data = value[i].data + 5; ss.len = value[i].len - 5; lccf->free = ngx_parse_size(&ss); if (lccf->free == (size_t) NGX_ERROR) { goto invalid; } if (cf->args->nelts == 2) { return NGX_CONF_OK; } return NGX_CONF_OK; } invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; }
ngx_int_t nchan_detect_chunked_subscriber_request(ngx_http_request_t *r) { static ngx_str_t TE_HEADER = ngx_string("TE"); ngx_str_t *tmp; u_char *cur, *last; if(r->method != NGX_HTTP_GET) { return 0; } if((tmp = nchan_get_header_value(r, TE_HEADER)) != NULL) { last = tmp->data + tmp->len; cur = ngx_strlcasestrn(tmp->data, last, (u_char *)"chunked", 7 - 1); if(cur == NULL) { return 0; } //see if there's a qvalue cur += 7; if((cur + 1 <= last) && cur[0]==' ') { //no qvalue. assume non-zero, meaning it's legit return 1; } else if((cur + 4) < last) { //maybe there is... if(cur[0]==';' && cur[1]=='q' && cur[2]=='=') { //parse the freaking qvalue cur += 3; ngx_int_t qval_fp; qval_fp = ngx_atofp(cur, last - cur, 2); if(qval_fp == NGX_ERROR) { DBG("invalid qval. reject."); return 0; } else if(qval_fp > 0) { //got nonzero qval. accept return 1; } else { //qval=0. reject return 0; } } else { //we're looking at "chunkedsomething", not "chunked;q=<...>". reject. return 0; } } else if (cur == last){ //last thing in the header. "chunked". accept return 1; } else { //too small to have a qvalue, not followed by a space. must be "chunkedsomething" return 0; } } else return 0; }
static char * ngx_http_sysguard_mem(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_sysguard_conf_t *glcf = conf; ngx_str_t *value; ngx_uint_t i; value = cf->args->elts; i = 1; if (ngx_strncmp(value[i].data, "swapratio=", 10) == 0) { if (glcf->swap != NGX_CONF_UNSET) { return "is duplicate"; } if (value[i].data[value[i].len - 1] != '%') { goto invalid; } glcf->swap = ngx_atofp(value[i].data + 10, value[i].len - 11, 2); if (glcf->swap == NGX_ERROR) { goto invalid; } if (cf->args->nelts == 2) { return NGX_CONF_OK; } i++; if (ngx_strncmp(value[i].data, "action=", 7) != 0) { goto invalid; } if (value[i].len == 7) { goto invalid; } if (value[i].data[7] != '/' && value[i].data[7] != '@') { goto invalid; } glcf->swap_action.data = value[i].data + 7; glcf->swap_action.len = value[i].len - 7; return NGX_CONF_OK; } invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; }
static char * ngx_http_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) { ngx_int_t n; ngx_str_t *value; ngx_http_split_clients_ctx_t *ctx; ngx_http_split_clients_part_t *part; ctx = cf->ctx; value = cf->args->elts; part = ngx_array_push(&ctx->parts); if (part == NULL) { return NGX_CONF_ERROR; } if (value[0].len == 1 && value[0].data[0] == '*') { part->percent = 0; } else { if (value[0].data[value[0].len - 1] != '%') { goto invalid; } n = ngx_atofp(value[0].data, value[0].len - 1, 2); if (n == NGX_ERROR || n == 0) { goto invalid; } part->percent = (uint32_t) n; } part->value.len = value[1].len; part->value.valid = 1; part->value.no_cacheable = 0; part->value.not_found = 0; part->value.data = value[1].data; return NGX_CONF_OK; invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid percent value \"%V\"", &value[0]); return NGX_CONF_ERROR; }
ngx_int_t ngx_http_echo_exec_echo_sleep(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_str_t *computed_arg; ngx_str_t *computed_arg_elts; ngx_int_t delay; /* in msec */ ngx_http_cleanup_t *cln; computed_arg_elts = computed_args->elts; computed_arg = &computed_arg_elts[0]; delay = ngx_atofp(computed_arg->data, computed_arg->len, 3); if (delay == NGX_ERROR) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "invalid sleep duration \"%V\"", &computed_arg_elts[0]); return NGX_HTTP_BAD_REQUEST; } dd("adding timer with delay %lu ms, r:%.*s", (unsigned long) delay, (int) r->uri.len, r->uri.data); ngx_add_timer(&ctx->sleep, (ngx_msec_t) delay); /* we don't check broken downstream connections * ourselves so even if the client shuts down * the connection prematurely, nginx will still * go on waiting for our timers to get properly * expired. However, we'd still register a * cleanup handler for completeness. */ cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { return NGX_ERROR; } cln->handler = ngx_http_echo_sleep_cleanup; cln->data = r; return NGX_AGAIN; }
static char * ngx_http_sysguard_load(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_conn_conf_t *lccf = conf; ngx_str_t *value; ngx_uint_t i; value = cf->args->elts; i = 1; if (ngx_strncmp(value[i].data, "load=", 5) == 0) { if (lccf->load != NGX_CONF_UNSET) { return "is duplicate"; } if (value[i].len == 5) { goto invalid; } lccf->load = ngx_atofp(value[i].data + 5, value[i].len - 5, 3); if (lccf->load == NGX_ERROR) { goto invalid; } if (cf->args->nelts == 2) { return NGX_CONF_OK; } return NGX_CONF_OK; } invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; }
static char * ngx_http_sysguard_load(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_sysguard_conf_t *glcf = conf; ngx_str_t *value; ngx_uint_t i, scale; value = cf->args->elts; i = 1; scale = 1; if (ngx_strncmp(value[i].data, "load=", 5) == 0) { if (glcf->load != NGX_CONF_UNSET) { return "is duplicate"; } if (value[i].len == 5) { goto invalid; } value[i].data += 5; value[i].len -= 5; if (ngx_strncmp(value[i].data, "ncpu*", 5) == 0) { value[i].data += 5; value[i].len -= 5; scale = ngx_ncpu; } glcf->load = ngx_atofp(value[i].data, value[i].len, 3); if (glcf->load == NGX_ERROR) { goto invalid; } glcf->load = glcf->load * scale; if (cf->args->nelts == 2) { return NGX_CONF_OK; } i++; if (ngx_strncmp(value[i].data, "action=", 7) != 0) { goto invalid; } if (value[i].len == 7) { goto invalid; } if (value[i].data[7] != '/' && value[i].data[7] != '@') { goto invalid; } glcf->load_action.data = value[i].data + 7; glcf->load_action.len = value[i].len - 7; return NGX_CONF_OK; } invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; }
static ngx_int_t ngx_http_reqstat_log_handler(ngx_http_request_t *r) { u_char *p; ngx_int_t *indicator, iv; ngx_uint_t i, j, k, status, utries; ngx_time_t *tp; ngx_msec_int_t ms, total_ms; ngx_shm_zone_t **shm_zone, *z; ngx_http_reqstat_ctx_t *ctx; ngx_http_reqstat_conf_t *rcf; ngx_http_reqstat_store_t *store; ngx_http_reqstat_rbnode_t *fnode, **fnode_store; ngx_http_upstream_state_t *state; ngx_http_variable_value_t *v; switch (ngx_http_reqstat_check_enable(r, &rcf, &store)) { case NGX_ERROR: return NGX_ERROR; case NGX_DECLINED: case NGX_AGAIN: return NGX_OK; default: break; } shm_zone = rcf->monitor->elts; fnode_store = store->monitor_index.elts; for (i = 0; i < store->monitor_index.nelts; i++) { fnode = fnode_store[i]; if (r->connection->requests == 1) { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_CONN_TOTAL, 1); } ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_REQ_TOTAL, 1); ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_BYTES_IN, ngx_http_request_received(r) - (store ? store->recv : 0)); if (r->err_status) { status = r->err_status; } else if (r->headers_out.status) { status = r->headers_out.status; } else if (r->http_version == NGX_HTTP_VERSION_9) { status = 9; } else { status = 0; } if (status >= 200 && status < 300) { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_2XX, 1); switch (status) { case 200: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_200, 1); break; case 206: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_206, 1); break; default: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1); break; } } else if (status >= 300 && status < 400) { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_3XX, 1); switch (status) { case 302: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_302, 1); break; case 304: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_304, 1); break; default: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1); break; } } else if (status >= 400 && status < 500) { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_4XX, 1); switch (status) { case 403: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_403, 1); break; case 404: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_404, 1); break; case 416: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_416, 1); break; case 499: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_499, 1); break; default: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1); break; } } else if (status >= 500 && status < 600) { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_5XX, 1); switch (status) { case 500: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_500, 1); break; case 502: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_502, 1); break; case 503: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_503, 1); break; case 504: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_504, 1); break; case 508: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_508, 1); break; default: ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1); break; } } else { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_STATUS, 1); ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1); } /* response status of last upstream peer */ if (r->upstream_states != NULL && r->upstream_states->nelts > 0) { ngx_http_upstream_state_t *state = r->upstream_states->elts; status = state[r->upstream_states->nelts - 1].status; if (status >= 400 && status < 500) { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_4XX, 1); } else if (status >= 500 && status < 600) { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_5XX, 1); } } tp = ngx_timeofday(); ms = (ngx_msec_int_t) ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec)); ms = ngx_max(ms, 0); ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_RT, ms); if (r->upstream_states != NULL && r->upstream_states->nelts > 0) { ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_REQ, 1); j = 0; total_ms = 0; utries = 0; state = r->upstream_states->elts; for ( ;; ) { utries++; #if nginx_version >= 1009002 ms = state[j].response_time; #else ms = (ngx_msec_int_t) (state[j].response_sec * 1000 + state[j].response_msec); #endif ms = ngx_max(ms, 0); total_ms += ms; if (++j == r->upstream_states->nelts) { break; } if (state[j].peer == NULL) { if (++j == r->upstream_states->nelts) { break; } } } ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_RT, total_ms); ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_TRIES, utries); } z = shm_zone[i]; ctx = z->data; if (ctx->user_defined) { indicator = ctx->user_defined->elts; for (j = 0; j < ctx->user_defined->nelts; j++) { v = ngx_http_get_indexed_variable(r, indicator[j]); if (v == NULL || v->not_found || !v->valid) { ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "variable is uninitialized"); continue; } for (k = 0, p = v->data + v->len - 1; p >= v->data; p--) { if (*p == '.') { k = v->data + v->len - 1 - p; continue; } if (*p < '0' || *p > '9') { break; } } p++; if (k) { iv = ngx_atofp(p, v->data + v->len - p, k); } else { iv = ngx_atoi(p, v->data + v->len - p); } if (iv == NGX_ERROR) { continue; } ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_EXTRA(j), iv); } } } return NGX_OK; }