nginx 요청 체 읽 기 (2)
클 라 이언 트 가 보 낸 요청 체 를 주동 적 으로 버 리 려 면 nginx 핵심 이 제공 하 는 ngx 를 호출 할 수 있 습 니 다.http_discard_request_body () 인터페이스, 주동 적 으로 버 리 는 원인 은 여러 가지 가 있 을 수 있 습 니 다. 예 를 들 어 모듈 의 업무 논리 가 요청 체 를 필요 로 하지 않 고 클 라 이언 트 가 너무 큰 요청 체 를 보 냈 습 니 다. 또한 http 1.1 프로 토 콜 의 pipeline 요청 을 호 환 하기 위해 모듈 은 필요 하지 않 은 요청 체 를 자발적으로 버 릴 의무 가 있 습 니 다.한 마디 로 하면 좋 은 클 라 이언 트 호환성 을 유지 하기 위해 nginx 는 쓸모없는 요청 체 를 자발적으로 버 려 야 합 니 다.다음은 ngx 분석 시작http_discard_request_body () 함수:
ngx_int_t
ngx_http_discard_request_body(ngx_http_request_t *r)
{
ssize_t size;
ngx_event_t *rev;
if (r != r->main || r->discard_body) {
return NGX_OK;
}
if (ngx_http_test_expect(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
rev = r->connection->read;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body");
if (rev->timer_set) {
ngx_del_timer(rev);
}
if (r->headers_in.content_length_n <= 0 || r->request_body) {
return NGX_OK;
}
size = r->header_in->last - r->header_in->pos;
if (size) {
if (r->headers_in.content_length_n > size) {
r->header_in->pos += size;
r->headers_in.content_length_n -= size;
} else {
r->header_in->pos += (size_t) r->headers_in.content_length_n;
r->headers_in.content_length_n = 0;
return NGX_OK;
}
}
r->read_event_handler = ngx_http_discarded_request_body_handler;
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
if (ngx_http_read_discarded_request_body(r) == NGX_OK) {
r->lingering_close = 0;
} else {
r->count++;
r->discard_body = 1;
}
return NGX_OK;
}
함수 가 길지 않 기 때문에 여기 서 그것 을 완전 하 게 열 거 했 습 니 다. 함수 의 시작 역시 먼저 처리 할 필요 가 없 는 상황 을 판단 하 였 습 니 다. 하위 요청 은 처리 할 필요 가 없고 이미 이 함 수 를 호출 한 것 도 다시 처리 할 필요 가 없습니다.이어서 ngx 호출http_test_expect () 가 http 1.1 expect 를 처리 하 는 경우 http 1.1 의 expect 메커니즘 에 따라 클 라 이언 트 가 expect 헤드 를 보 냈 고 서버 가 요청 체 를 받 아들 이지 않 으 려 면 417 (Expectation Failed) 오 류 를 되 돌려 야 합 니 다.nginx 는 이렇게 하지 않 았 습 니 다. 클 라 이언 트 에 게 요청 체 를 보 내 고 버 리 라 고 간단하게 했 을 뿐 입 니 다.그 다음 에 함수 가 읽 기 이벤트 의 타 이 머 를 삭 제 했 습 니 다. 이 때 는 요청 체 가 필요 하지 않 기 때문에 클 라 이언 트 가 빨리 보 내 든 느 리 든 상관 없습니다. 물론 나중에 도착 할 것 입 니 다. nginx 가 이 요청 을 처 리 했 지만 클 라 이언 트 가 쓸모없는 요청 체 를 보 내지 않 았 을 때 nginx 는 읽 기 이벤트 에 타 이 머 를 다시 걸 것 입 니 다.
함수 역시 요청 헤더 에 있 는 content - length 헤드 를 검사 합 니 다. 클 라 이언 트 가 요청 체 를 보 내 려 면 content - length 헤드 를 보 내야 합 니 다. 또한 다른 곳 에서 요청 체 를 읽 었 는 지 확인 해 야 합 니 다.처리 해 야 할 요청 체 가 확실 하 다 면 함수 가 요청 헤더 buffer 에서 미리 읽 은 데 이 터 를 검사 하면 미리 읽 은 데 이 터 는 바로 버 려 집 니 다. 물론 요청 체 가 모두 미리 읽 었 다 면 함 수 는 바로 돌아 갑 니 다.
다음, 남 은 요청 체 가 처리 되 지 않 으 면 이 함수 호출 ngxhandle_read_이벤트 () 는 이벤트 처리 메커니즘 에 읽 기 이 벤트 를 마 운 트 하고 읽 기 이벤트 의 처리 함 수 를 ngx 로 설정 합 니 다.http_discarded_request_body_handler。이 준 비 를 마 친 후, 이 함 수 는 마지막 으로 ngx 를 호출 합 니 다.http_read_discarded_request_body () 인 터 페 이 스 는 클 라 이언 트 가 온 요청 체 를 읽 고 버 립 니 다.클 라 이언 트 가 요청 체 를 한 번 도 보 내지 않 으 면 함수 가 되 돌아 오고 나머지 데 이 터 는 다음 읽 기 이벤트 가 올 때 까지 ngx 에 게 건 네 줍 니 다.http_discarded_request_body_handler () 가 처리 합 니 다. 이때 요청 한 discardbody 는 이러한 상황 을 표시 하기 위해 1 로 설 정 됩 니 다.또한 요청 한 인용 수 (count) 도 1 을 추가 합 니 다. 이렇게 하 는 목적 은 클 라 이언 트 가 nginx 가 요청 을 처리 한 후에 도 보 낼 요청 체 를 완전 하 게 보 내지 않 을 수 있 습 니 다. 인용 을 추가 하 는 것 은 nginx 핵심 이 요청 을 처리 한 후에 요청 한 관련 자원 을 직접 방출 하 는 것 을 방지 하 는 것 입 니 다.
ngx_http_read_discarded_request_body () 함 수 는 매우 간단 합 니 다. 링크 에서 데 이 터 를 읽 고 버 립 니 다. 수신 버퍼 의 모든 데 이 터 를 읽 을 때 까지 요청 체 가 읽 혔 다 면 이 함 수 는 읽 기 이벤트 의 처리 함 수 를 ngx 로 설정 합 니 다.http_block_reading, 이 함 수 는 수평 으로 트리거 된 읽 기 이벤트 만 삭제 하여 같은 이벤트 가 계속 발생 하 는 것 을 방지 합 니 다.
읽 기 이벤트 의 처리 함수 ngxhttp_discarded_request_body_handler, 이 함 수 는 이 벤트 를 읽 을 때마다 호출 됩 니 다. 먼저 원본 코드 를 보십시오.
void
ngx_http_discarded_request_body_handler(ngx_http_request_t *r)
{
...
c = r->connection;
rev = c->read;
if (rev->timedout) {
c->timedout = 1;
c->error = 1;
ngx_http_finalize_request(r, NGX_ERROR);
return;
}
if (r->lingering_time) {
timer = (ngx_msec_t) (r->lingering_time - ngx_time());
if (timer <= 0) {
r->discard_body = 0;
r->lingering_close = 0;
ngx_http_finalize_request(r, NGX_ERROR);
return;
}
} else {
timer = 0;
}
rc = ngx_http_read_discarded_request_body(r);
if (rc == NGX_OK) {
r->discard_body = 0;
r->lingering_close = 0;
ngx_http_finalize_request(r, NGX_DONE);
return;
}
/* rc == NGX_AGAIN */
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
c->error = 1;
ngx_http_finalize_request(r, NGX_ERROR);
return;
}
if (timer) {
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
timer *= 1000;
if (timer > clcf->lingering_timeout) {
timer = clcf->lingering_timeout;
}
ngx_add_timer(rev, timer);
}
}
함수 가 처음부터 읽 기 이벤트 시간 초과 상황 을 처 리 했 습 니 다. 전에 ngxhttp_discard_request_body () 함수 에서 이 벤트 를 읽 는 타 이 머 를 삭 제 했 습 니 다. 타 이 머 는 언제 설정 합 니까?정 답 은 nginx 에서 이 요청 을 처 리 했 지만 요청 한 요청 체 를 완전히 버 리 지 않 았 을 때 (클 라 이언 트 가 아직 보 내지 않 았 을 수도 있 습 니 다), ngxhttp_finalize_connection () 함수 에서 버 리 지 않 은 요청 체 가 있 는 지 확인 하면 nginx 는 읽 기 이벤트 타 이 머 를 추가 합 니 다. 시간 은 lingering 입 니 다.timeout 명령 에 의 해 지정 되 었 습 니 다. 기본 값 은 5 초 입 니 다. 그러나 이 시간 은 두 번 의 읽 기 이벤트 사이 의 시간 초과 입 니 다. 요청 체 를 기다 리 는 총 시간 은 lingering 입 니 다.time 명령 이 지정 한 기본 값 은 30 초 입 니 다.이런 상황 에서
이 함수 가 시간 초과 이 벤트 를 감지 하면 바로 되 돌아 와 연결 을 끊 습 니 다.마찬가지 로, 모든 버 려 진 요청 체 의 시간 을 제어 해 야 합 니 다. lingeringtime 설정 시간 이 최대 시간 을 초과 하면 바로 돌아 와 연결 을 끊 습 니 다.
읽 기 이벤트 가 처리 요청 이 완료 되 기 전에 발생 하면 시간 초과 사건 을 처리 하지 않 아 도 되 고 타 이 머 를 설정 하지 않 아 도 됩 니 다. 함 수 는 간단 한 호출 ngx 입 니 다.http_read_discarded_request_body () 는 데 이 터 를 읽 고 버 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.