📄 ngx_http_proxy_module.c
字号:
ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); if (ctx == NULL) { return NGX_OK; } ctx->status = 0; ctx->status_count = 0; ctx->status_start = NULL; ctx->status_end = NULL; r->upstream->process_header = ngx_http_proxy_process_status_line; return NGX_OK;}static ngx_int_tngx_http_proxy_process_status_line(ngx_http_request_t *r){ ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_proxy_ctx_t *ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); if (ctx == NULL) { return NGX_ERROR; } rc = ngx_http_proxy_parse_status_line(r, ctx); if (rc == NGX_AGAIN) { return rc; } u = r->upstream; if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent no valid HTTP/1.0 header");#if 0 if (u->accel) { return NGX_HTTP_UPSTREAM_INVALID_HEADER; }#endif r->http_version = NGX_HTTP_VERSION_9; u->headers_in.status_n = NGX_HTTP_OK; u->state->status = NGX_HTTP_OK; return NGX_OK; } u->headers_in.status_n = ctx->status; u->state->status = ctx->status; u->headers_in.status_line.len = ctx->status_end - ctx->status_start; u->headers_in.status_line.data = ngx_palloc(r->pool, u->headers_in.status_line.len); if (u->headers_in.status_line.data == NULL) { return NGX_ERROR; } ngx_memcpy(u->headers_in.status_line.data, ctx->status_start, u->headers_in.status_line.len); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http proxy status %ui \"%V\"", u->headers_in.status_n, &u->headers_in.status_line); u->process_header = ngx_http_proxy_process_header; return ngx_http_proxy_process_header(r);}static ngx_int_tngx_http_proxy_parse_status_line(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx){ u_char ch; u_char *p; ngx_http_upstream_t *u; enum { sw_start = 0, sw_H, sw_HT, sw_HTT, sw_HTTP, sw_first_major_digit, sw_major_digit, sw_first_minor_digit, sw_minor_digit, sw_status, sw_space_after_status, sw_status_text, sw_almost_done } state; u = r->upstream; state = r->state; for (p = u->buffer.pos; p < u->buffer.last; p++) { ch = *p; switch (state) { /* "HTTP/" */ case sw_start: switch (ch) { case 'H': state = sw_H; break; default: return NGX_HTTP_PROXY_PARSE_NO_HEADER; } break; case sw_H: switch (ch) { case 'T': state = sw_HT; break; default: return NGX_HTTP_PROXY_PARSE_NO_HEADER; } break; case sw_HT: switch (ch) { case 'T': state = sw_HTT; break; default: return NGX_HTTP_PROXY_PARSE_NO_HEADER; } break; case sw_HTT: switch (ch) { case 'P': state = sw_HTTP; break; default: return NGX_HTTP_PROXY_PARSE_NO_HEADER; } break; case sw_HTTP: switch (ch) { case '/': state = sw_first_major_digit; break; default: return NGX_HTTP_PROXY_PARSE_NO_HEADER; } break; /* the first digit of major HTTP version */ case sw_first_major_digit: if (ch < '1' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; } state = sw_major_digit; break; /* the major HTTP version or dot */ case sw_major_digit: if (ch == '.') { state = sw_first_minor_digit; break; } if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; } break; /* the first digit of minor HTTP version */ case sw_first_minor_digit: if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; } state = sw_minor_digit; break; /* the minor HTTP version or the end of the request line */ case sw_minor_digit: if (ch == ' ') { state = sw_status; break; } if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; } break; /* HTTP status code */ case sw_status: if (ch == ' ') { break; } if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; } ctx->status = ctx->status * 10 + ch - '0'; if (++ctx->status_count == 3) { state = sw_space_after_status; ctx->status_start = p - 2; } break; /* space or end of line */ case sw_space_after_status: switch (ch) { case ' ': state = sw_status_text; break; case '.': /* IIS may send 403.1, 403.2, etc */ state = sw_status_text; break; case CR: state = sw_almost_done; break; case LF: goto done; default: return NGX_HTTP_PROXY_PARSE_NO_HEADER; } break; /* any text until end of line */ case sw_status_text: switch (ch) { case CR: state = sw_almost_done; break; case LF: goto done; } break; /* end of status line */ case sw_almost_done: ctx->status_end = p - 1; switch (ch) { case LF: goto done; default: return NGX_HTTP_PROXY_PARSE_NO_HEADER; } } } u->buffer.pos = p; r->state = state; return NGX_AGAIN;done: u->buffer.pos = p + 1; if (ctx->status_end == NULL) { ctx->status_end = p; } r->state = sw_start; return NGX_OK;}static ngx_int_tngx_http_proxy_process_header(ngx_http_request_t *r){ ngx_int_t rc; ngx_uint_t i; ngx_table_elt_t *h; ngx_http_upstream_header_t *hh; ngx_http_upstream_main_conf_t *umcf; umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); for ( ;; ) { rc = ngx_http_parse_header_line(r, &r->upstream->buffer); if (rc == NGX_OK) { /* a header line has been parsed successfully */ h = ngx_list_push(&r->upstream->headers_in.headers); if (h == NULL) { return NGX_ERROR; } h->hash = r->header_hash; h->key.len = r->header_name_end - r->header_name_start; h->value.len = r->header_end - r->header_start; h->key.data = ngx_palloc(r->pool, h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { return NGX_ERROR; } h->value.data = h->key.data + h->key.len + 1; h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1; ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); if (h->key.len == r->lowcase_index) { ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); } else { for (i = 0; i < h->key.len; i++) { h->lowcase_key[i] = ngx_tolower(h->key.data[i]); } } hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len); if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { return NGX_ERROR; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http proxy header: \"%V: %V\"", &h->key, &h->value); continue; } if (rc == NGX_HTTP_PARSE_HEADER_DONE) { /* a whole header has been parsed successfully */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http proxy header done"); /* * if no "Server" and "Date" in header line, * then add the special empty headers */ if (r->upstream->headers_in.server == NULL) { h = ngx_list_push(&r->upstream->headers_in.headers); if (h == NULL) { return NGX_ERROR; } h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash( ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r'); h->key.len = sizeof("Server") - 1; h->key.data = (u_char *) "Server"; h->value.len = 0; h->value.data = NULL; h->lowcase_key = (u_char *) "server"; } if (r->upstream->headers_in.date == NULL) { h = ngx_list_push(&r->upstream->headers_in.headers); if (h == NULL) { return NGX_ERROR; } h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e'); h->key.len = sizeof("Date") - 1; h->key.data = (u_char *) "Date"; h->value.len = 0; h->value.data = NULL; h->lowcase_key = (u_char *) "date"; } return NGX_OK; } if (rc == NGX_AGAIN) { return NGX_AGAIN; } /* there was error while a header line parsing */ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent invalid header"); return NGX_HTTP_UPSTREAM_INVALID_HEADER; }}static voidngx_http_proxy_abort_request(ngx_http_request_t *r){ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "abort http proxy request"); return;}static voidngx_http_proxy_finalize_request(ngx_http_request_t *r, ngx_int_t rc){ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "finalize http proxy request"); return;}static ngx_int_tngx_http_proxy_host_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data){ ngx_http_proxy_ctx_t *ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); if (ctx == NULL) { v->not_found = 1; return NGX_OK; } v->len = ctx->vars.host_header.len; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; v->data = ctx->vars.host_header.data; return NGX_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -