ngx_http_process_request_headers函數解析

來源:互聯網
上載者:User

標籤:nginx

ngx_http_process_request_headers函數被ngx_http_process_request_line函數調用,將要求標頭逐個放到r->headers_in.headers結構體中。由於不確定請求中一共有多少個header,所以這個函數主要功能也是在for(;;){}迴圈中完成,一下所有的代碼都是在上述迴圈內部的。主要代碼和解析如下:

判斷是否逾時,如果逾時,報錯並結束請求。

    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;
   }

ngx_http_parse_header_line函數解析請求行,如果返回NGX_OK表示成功的解析出來一個header,如果返回NGX_HTTP_PARSE_HEADER_DONE表示所有的header都解析完了,如果返回NGX_AGAIN表示尚有header沒有解析完,剩下的傳回值說明出錯了。

        rc = ngx_http_parse_header_line(r, r->header_in,
                                       cscf->underscores_in_headers);
       if (rc == NGX_OK) {
           r->request_length += r->header_in->pos - r->header_name_start;
           if (r->invalid_header && cscf->ignore_invalid_headers) {
               /* there was error while a header line parsing */
               ngx_log_error(NGX_LOG_INFO, c->log, 0,
                             "client sent invalid header line: \"%*s\"",
                             r->header_end - r->header_name_start,
                             r->header_name_start);
               continue;
           }

r->headers_in.headers是一個ngx_list_t結構體,向其添加元素的順序是先通過ngx_list_push函數返回一個元素,實際上在ngx_list_push中完成了開闢記憶體的工作,之後再對返回的元素進行賦值。

            h = ngx_list_push(&r->headers_in.headers);
           if (h == NULL) {
               ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
               return;
           }
           h->hash = r->header_hash;

r->header_name_end和r->header_name_start兩個變數貌似就是專門為了指向每個頭的key的開始和結束,其他地方沒看到被使用過

            h->key.len = r->header_name_end - r->header_name_start;
           h->key.data = r->header_name_start;
           h->key.data[h->key.len] = ‘\0‘;
           h->value.len = r->header_end - r->header_start;
           h->value.data = r->header_start;
           h->value.data[h->value.len] = ‘\0‘;
           h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
           if (h->lowcase_key == NULL) {
               ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
               return;
           }
           if (h->key.len == r->lowcase_index) {
               ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
           } else {
               ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
           }

針對某些頭,可能又一些處理函數,比如說User-Agent頭的處理函數會提取瀏覽器相關的一些資訊

            hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
                              h->lowcase_key, h->key.len);
           if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
               return;
           }
           ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                          "http header: \"%V: %V\"",
                          &h->key, &h->value);


在一個頭全都操作完成之後需要繼續解析下一個(如果還有的話)。

            continue;
       }

如果所有的header都解析完了,在經過一些簡單的判斷(ngx_http_process_request_header函數中完成)之後,就進入了正式的請求處理邏輯

    if (rc == NGX_HTTP_PARSE_HEADER_DONE) {        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,            "http header done");        r->request_length += r->header_in->pos - r->header_name_start;        r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;        rc = ngx_http_process_request_header(r);        if (rc != NGX_OK) {            return;        }        ngx_http_process_request(r);        return;    }











ngx_http_process_request_headers函數解析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.