comparison src/http/ngx_http_request.c @ 8024:ef6a3a99a81a

Reworked multi headers to use linked lists. Multi headers are now using linked lists instead of arrays. Notably, the following fields were changed: r->headers_in.cookies (renamed to r->headers_in.cookie), r->headers_in.x_forwarded_for, r->headers_out.cache_control, r->headers_out.link, u->headers_in.cache_control u->headers_in.cookies (renamed to u->headers_in.set_cookie). The r->headers_in.cookies and u->headers_in.cookies fields were renamed to r->headers_in.cookie and u->headers_in.set_cookie to match header names. The ngx_http_parse_multi_header_lines() and ngx_http_parse_set_cookie_lines() functions were changed accordingly. With this change, multi headers are now essentially equivalent to normal headers, and following changes will further make them equivalent.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 30 May 2022 21:25:33 +0300
parents 0e562a332529
children c263f9ffa1fd
comparison
equal deleted inserted replaced
8023:08b3ea81ff5f 8024:ef6a3a99a81a
194 194
195 { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date), 195 { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date),
196 ngx_http_process_header_line }, 196 ngx_http_process_header_line },
197 #endif 197 #endif
198 198
199 { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies), 199 { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookie),
200 ngx_http_process_multi_header_lines }, 200 ngx_http_process_multi_header_lines },
201 201
202 { ngx_null_string, 0, NULL } 202 { ngx_null_string, 0, NULL }
203 }; 203 };
204 204
1742 1742
1743 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset); 1743 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
1744 1744
1745 if (*ph == NULL) { 1745 if (*ph == NULL) {
1746 *ph = h; 1746 *ph = h;
1747 h->next = NULL;
1747 } 1748 }
1748 1749
1749 return NGX_OK; 1750 return NGX_OK;
1750 } 1751 }
1751 1752
1758 1759
1759 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset); 1760 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
1760 1761
1761 if (*ph == NULL) { 1762 if (*ph == NULL) {
1762 *ph = h; 1763 *ph = h;
1764 h->next = NULL;
1763 return NGX_OK; 1765 return NGX_OK;
1764 } 1766 }
1765 1767
1766 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, 1768 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1767 "client sent duplicate header line: \"%V: %V\", " 1769 "client sent duplicate header line: \"%V: %V\", "
1790 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 1792 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1791 return NGX_ERROR; 1793 return NGX_ERROR;
1792 } 1794 }
1793 1795
1794 r->headers_in.host = h; 1796 r->headers_in.host = h;
1797 h->next = NULL;
1795 1798
1796 host = h->value; 1799 host = h->value;
1797 1800
1798 rc = ngx_http_validate_host(&host, r->pool, 0); 1801 rc = ngx_http_validate_host(&host, r->pool, 0);
1799 1802
1851 if (r->headers_in.user_agent) { 1854 if (r->headers_in.user_agent) {
1852 return NGX_OK; 1855 return NGX_OK;
1853 } 1856 }
1854 1857
1855 r->headers_in.user_agent = h; 1858 r->headers_in.user_agent = h;
1859 h->next = NULL;
1856 1860
1857 /* check some widespread browsers while the header is in CPU cache */ 1861 /* check some widespread browsers while the header is in CPU cache */
1858 1862
1859 user_agent = h->value.data; 1863 user_agent = h->value.data;
1860 1864
1917 1921
1918 static ngx_int_t 1922 static ngx_int_t
1919 ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h, 1923 ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
1920 ngx_uint_t offset) 1924 ngx_uint_t offset)
1921 { 1925 {
1922 ngx_array_t *headers;
1923 ngx_table_elt_t **ph; 1926 ngx_table_elt_t **ph;
1924 1927
1925 headers = (ngx_array_t *) ((char *) &r->headers_in + offset); 1928 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
1926 1929
1927 if (headers->elts == NULL) { 1930 while (*ph) { ph = &(*ph)->next; }
1928 if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *))
1929 != NGX_OK)
1930 {
1931 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1932 return NGX_ERROR;
1933 }
1934 }
1935
1936 ph = ngx_array_push(headers);
1937 if (ph == NULL) {
1938 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1939 return NGX_ERROR;
1940 }
1941 1931
1942 *ph = h; 1932 *ph = h;
1933 h->next = NULL;
1934
1943 return NGX_OK; 1935 return NGX_OK;
1944 } 1936 }
1945 1937
1946 1938
1947 ngx_int_t 1939 ngx_int_t