ngx_http_process_request_line 함수 해석

6052 단어 nginx
요청 행 처리, 일반 http 요청 과정 중, ngxhttp_process_request_line 함수 피 ngxhttp_wait_request_handler 호출, 그리고 ngxhttp_wait_request_handler 에서 읽 기 이벤트 의 리 셋 함수 로 설정 되 었 습 니 다.연결 이 accept 된 후 데이터 가 도착 하면 ngx 를 실행 합 니 다.http_create_request 함수, 그 다음 에 읽 기 이벤트 가 실 행 될 때 호출 되 는 반전 함수 가 ngx 입 니 다.http_process_request_line。주요 코드 와 해석 은 다음 과 같다.
시간 초과 여 부 를 판단 하고 시간 초과 시 잘못 보고 하고 요청 을 끝 냅 니 다.
if (rev->timedout) {
    ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
    c->timedout = 1;
    ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
    return;
}

나머지 과정 은 모두 for (;) {...} 블록 에서 실 행 됩 니 다.
ngx_http_read_request_header 함수 가 NGX 로 돌아 가면AGAIN, 아직 데이터 가 다 받 아들 여지 지 않 았 음 을 설명 합 니 다. 읽 기 이벤트 가 실 행 될 수 있 고 읽 기 이벤트 리 셋 함수 가 여전히 ngx 입 니 다.http_process_request_line。NGX 로 돌아 가면ERROR, 문제 가 생 겼 다 는 것 을 설명 하고 요청 을 끝내 야 합 니 다.정상 이면, ngxhttp_read_request_header 는 받 아들 인 문자 의 개 수 를 되 돌려 주 었 고 이미 받 아 들 였 다 는 것 을 설명 했다.
if (rc == NGX_AGAIN) {
    n = ngx_http_read_request_header(r);
    if (n == NGX_AGAIN || n == NGX_ERROR) {
        return;
    }
}

ngx_http_read_request_header 함수 가 받 아들 인 내용 을 r - > header 에 저장 합 니 다.in, 다음 ngxhttp_parse_request_line 함수 해석 요청 줄.ngx_http_parse_request_line 함수 가 되 돌아 올 수 있 는 결 과 는 세 가지 가 있 습 니 다. 하 나 는 NGX 입 니 다.OK, 하 나 는 INVALID 와 관련 된 것 이 고 다른 하 나 는 NGXAGAIN, 다음 분류 로 분석 하 겠 습 니 다.
rc = ngx_http_parse_request_line(r, r->header_in);

코드 순 으로 먼저 NGX 로 돌 아 왔 습 니 다.OK, NGX 로 돌아 가기OK 는 요청 줄 이 완전히 받 아들 여지 고 해석 되 었 음 을 설명 합 니 다. 주요 코드 는 다음 과 같 습 니 다.
if (rc == NGX_OK) {

    요청 행 분석 결과 에 따라 r 구조 체 초기 화
    r->request_line.len = r->request_end - r->request_start;
    r->request_line.data = r->request_start;
    r->request_length = r->header_in->pos - r->request_start;
    r->method_name.len = r->method_end - r->request_start + 1;
    r->method_name.data = r->request_line.data;
    if (r->http_protocol.data) {
        r->http_protocol.len = r->request_end - r->http_protocol.data;
    }

    uri 를 분석 합 니 다. 함수 에 서 는 r 구조 체 의 uri 와 args 와 관련 된 변 수 를 초기 화하 고 요청 줄 에 불법 문자 가 있 는 지 판단 합 니 다.
    if (ngx_http_process_request_uri(r) != NGX_OK) {
        return;
    }

    host 에 대하 여start 와 hostend 재 ngxhttp_parse_request_line 함수 에서 값 을 부여 할 수 있 습 니 다.이 컴퓨터 에서 nginx 를 시작 하면 80 포트 를 감청 하고 curl 도구 로 이러한 요청 을 보 냅 니 다: curl - x 127.0.0.1: 80http://192.168.119.51:80/test.html。GDB 디 버 깅 을 하면 요청 줄 을 볼 수 있 습 니 다. GET 입 니 다.http://192.168.119.51:80/test.html HTTP/1.1xxxxxx。매우 보 이 는 GET / test. html HTTP / 1.1xxxxx.개인 적 으로 http 0.9 를 호 환 하기 위해 서 라 고 생각 합 니 다.이때 상술 한 두 변 수 는 0x0 이 아니다.타 오 바 오 팀 의 nginx 블 로그 에 서 는 요청 행 uri 에 도 메 인 이름 부분 이 포함 되 어 있 습 니 다.본인 도 잘 모 르 겠 어 요.
    if (r->host_start && r->host_end) {
        host.len = r->host_end - r->host_start;
        host.data = r->host_start;
        rc = ngx_http_validate_host(&host, r->pool, 0);
        if (rc == NGX_DECLINED) {
            ngx_log_error(NGX_LOG_INFO, c->log, 0,
                          "client sent invalid host in request line");
            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
            return;
        }
        if (rc == NGX_ERROR) {
            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
            return;
        }
        if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
            return;
        }
        r->headers_in.server = host;
    }

    http 0.9 요청 헤드 를 분석 하지 않 고 요청 을 직접 처리 하면 됩 니 다.r->headers_in. server 변 수 는 이전 if 블록 에서 할당 되 었 습 니 다.http 0.9 요청 을 어떻게 모 의 하 는 지...
    if (r->http_version headers_in.server.len == 0
            && ngx_http_set_virtual_server(r, &r->headers_in.server)
               == NGX_ERROR)
        {
            return;
        }
        ngx_http_process_request(r);
        return;
    }
    if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
                      sizeof(ngx_table_elt_t))
        != NGX_OK)
    {
        ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
        return;
    }
    c->log->action = "reading client request headers";

    읽 기 이벤트 리 셋 함 수 를 설정 하고 데이터 가 도 착 했 을 때 요청 헤더 처리 함 수 를 호출 합 니 다.현재 요청 헤더 데 이 터 를 받 았 을 수도 있 으 니 바로 실행 하 십시오.
    rev->handler = ngx_http_process_request_headers;
    ngx_http_process_request_headers(rev);
    return;
}

ngx_http_parse_request_line 함수 반환 결과 NGX 가 아니라면OK, NGX 도 아니 고AGAIN, 그것 은 틀림없이 INVALID 와 관련 된 것 입 니 다. 오 류 를 되 돌려 주 고 요청 을 끝내 야 합 니 다.
if (rc != NGX_AGAIN) {
    ngx_log_error(NGX_LOG_INFO, c->log, 0,
                  ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
    ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
    return;
}

마지막 남 은 ngxhttp_parse_request_line 함수 반환 NGXAGAIN 의 상황 입 니 다.요청 이 머리 가 너무 큰 지, 너무 크 면 더 큰 buffer 를 열 고 ngx 를 실행 해 야 합 니 다.http_finalize_request 함수, 이 함 수 는 비교적 복잡 합 니 다. 우 리 는 일반적인 http 요청 만 토론 합 니 다.여기 서 수행 하 는 ngxhttp_finalize_request 요청 은 요청 을 정말로 끝내 지 않 고 이 함수 에 다시 들 어 갈 것 입 니 다.머리 가 너무 큰 경우 가 없 으 면 for 순환 문 구 를 다시 실행 하고 ngx 를 계속 실행 해 야 합 니 다.http_read_request_header 함수, 버퍼 의 데 이 터 를 읽 고 계속 ngxhttp_parse_request_line 함수.
if (r->header_in->pos == r->header_in->end) {
    rv = ngx_http_alloc_large_header_buffer(r, 1);
    if (rv == NGX_ERROR) {
        ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
        return;
    }
    if (rv == NGX_DECLINED) {
        r->request_line.len = r->header_in->end - r->request_start;
        r->request_line.data = r->request_start;
        ngx_log_error(NGX_LOG_INFO, c->log, 0,
                      "client sent too long URI");
        ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
        return;
    }
}

좋은 웹페이지 즐겨찾기