Skip to content
This repository was archived by the owner on Nov 6, 2022. It is now read-only.

Commit 05525c5

Browse files
bnoordhuisindutny
authored andcommitted
Ignore Upgrade header outside of 101 response.
PR-URL: #364 Reviewed-By: Fedor Indutny <[email protected]>
1 parent 260c522 commit 05525c5

File tree

2 files changed

+175
-5
lines changed

2 files changed

+175
-5
lines changed

http_parser.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,10 +1731,17 @@ size_t http_parser_execute (http_parser *parser,
17311731
UPDATE_STATE(s_headers_done);
17321732

17331733
/* Set this here so that on_headers_complete() callbacks can see it */
1734-
parser->upgrade =
1735-
((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) ==
1736-
(F_UPGRADE | F_CONNECTION_UPGRADE) ||
1737-
parser->method == HTTP_CONNECT);
1734+
if ((parser->flags & F_UPGRADE) &&
1735+
(parser->flags & F_CONNECTION_UPGRADE)) {
1736+
/* For responses, "Upgrade: foo" and "Connection: upgrade" are
1737+
* mandatory only when it is a 101 Switching Protocols response,
1738+
* otherwise it is purely informational, to announce support.
1739+
*/
1740+
parser->upgrade =
1741+
(parser->type == HTTP_REQUEST || parser->status_code == 101);
1742+
} else {
1743+
parser->upgrade = (parser->method == HTTP_CONNECT);
1744+
}
17381745

17391746
/* Here we call the headers_complete callback. This is somewhat
17401747
* different than other callbacks because if the user returns 1, we

test.c

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1772,6 +1772,167 @@ const struct message responses[] =
17721772
,.chunk_lengths= { 2 }
17731773
}
17741774

1775+
#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER 22
1776+
, {.name= "HTTP 101 response with Upgrade header"
1777+
,.type= HTTP_RESPONSE
1778+
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
1779+
"Connection: upgrade\r\n"
1780+
"Upgrade: h2c\r\n"
1781+
"\r\n"
1782+
"proto"
1783+
,.should_keep_alive= TRUE
1784+
,.message_complete_on_eof= FALSE
1785+
,.http_major= 1
1786+
,.http_minor= 1
1787+
,.status_code= 101
1788+
,.response_status= "Switching Protocols"
1789+
,.upgrade= "proto"
1790+
,.num_headers= 2
1791+
,.headers=
1792+
{ { "Connection", "upgrade" }
1793+
, { "Upgrade", "h2c" }
1794+
}
1795+
}
1796+
1797+
#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 23
1798+
, {.name= "HTTP 101 response with Upgrade and Content-Length header"
1799+
,.type= HTTP_RESPONSE
1800+
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
1801+
"Connection: upgrade\r\n"
1802+
"Upgrade: h2c\r\n"
1803+
"Content-Length: 4\r\n"
1804+
"\r\n"
1805+
"body"
1806+
"proto"
1807+
,.should_keep_alive= TRUE
1808+
,.message_complete_on_eof= FALSE
1809+
,.http_major= 1
1810+
,.http_minor= 1
1811+
,.status_code= 101
1812+
,.response_status= "Switching Protocols"
1813+
,.body= "body"
1814+
,.upgrade= "proto"
1815+
,.num_headers= 3
1816+
,.headers=
1817+
{ { "Connection", "upgrade" }
1818+
, { "Upgrade", "h2c" }
1819+
, { "Content-Length", "4" }
1820+
}
1821+
}
1822+
1823+
#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 24
1824+
, {.name= "HTTP 101 response with Upgrade and Transfer-Encoding header"
1825+
,.type= HTTP_RESPONSE
1826+
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
1827+
"Connection: upgrade\r\n"
1828+
"Upgrade: h2c\r\n"
1829+
"Transfer-Encoding: chunked\r\n"
1830+
"\r\n"
1831+
"2\r\n"
1832+
"bo\r\n"
1833+
"2\r\n"
1834+
"dy\r\n"
1835+
"0\r\n"
1836+
"\r\n"
1837+
"proto"
1838+
,.should_keep_alive= TRUE
1839+
,.message_complete_on_eof= FALSE
1840+
,.http_major= 1
1841+
,.http_minor= 1
1842+
,.status_code= 101
1843+
,.response_status= "Switching Protocols"
1844+
,.body= "body"
1845+
,.upgrade= "proto"
1846+
,.num_headers= 3
1847+
,.headers=
1848+
{ { "Connection", "upgrade" }
1849+
, { "Upgrade", "h2c" }
1850+
, { "Transfer-Encoding", "chunked" }
1851+
}
1852+
,.num_chunks_complete= 3
1853+
,.chunk_lengths= { 2, 2 }
1854+
}
1855+
1856+
#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER 25
1857+
, {.name= "HTTP 200 response with Upgrade header"
1858+
,.type= HTTP_RESPONSE
1859+
,.raw= "HTTP/1.1 200 OK\r\n"
1860+
"Connection: upgrade\r\n"
1861+
"Upgrade: h2c\r\n"
1862+
"\r\n"
1863+
"body"
1864+
,.should_keep_alive= FALSE
1865+
,.message_complete_on_eof= TRUE
1866+
,.http_major= 1
1867+
,.http_minor= 1
1868+
,.status_code= 200
1869+
,.response_status= "OK"
1870+
,.body= "body"
1871+
,.upgrade= NULL
1872+
,.num_headers= 2
1873+
,.headers=
1874+
{ { "Connection", "upgrade" }
1875+
, { "Upgrade", "h2c" }
1876+
}
1877+
}
1878+
1879+
#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 26
1880+
, {.name= "HTTP 200 response with Upgrade and Content-Length header"
1881+
,.type= HTTP_RESPONSE
1882+
,.raw= "HTTP/1.1 200 OK\r\n"
1883+
"Connection: upgrade\r\n"
1884+
"Upgrade: h2c\r\n"
1885+
"Content-Length: 4\r\n"
1886+
"\r\n"
1887+
"body"
1888+
,.should_keep_alive= TRUE
1889+
,.message_complete_on_eof= FALSE
1890+
,.http_major= 1
1891+
,.http_minor= 1
1892+
,.status_code= 200
1893+
,.response_status= "OK"
1894+
,.num_headers= 3
1895+
,.body= "body"
1896+
,.upgrade= NULL
1897+
,.headers=
1898+
{ { "Connection", "upgrade" }
1899+
, { "Upgrade", "h2c" }
1900+
, { "Content-Length", "4" }
1901+
}
1902+
}
1903+
1904+
#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 27
1905+
, {.name= "HTTP 200 response with Upgrade and Transfer-Encoding header"
1906+
,.type= HTTP_RESPONSE
1907+
,.raw= "HTTP/1.1 200 OK\r\n"
1908+
"Connection: upgrade\r\n"
1909+
"Upgrade: h2c\r\n"
1910+
"Transfer-Encoding: chunked\r\n"
1911+
"\r\n"
1912+
"2\r\n"
1913+
"bo\r\n"
1914+
"2\r\n"
1915+
"dy\r\n"
1916+
"0\r\n"
1917+
"\r\n"
1918+
,.should_keep_alive= TRUE
1919+
,.message_complete_on_eof= FALSE
1920+
,.http_major= 1
1921+
,.http_minor= 1
1922+
,.status_code= 200
1923+
,.response_status= "OK"
1924+
,.num_headers= 3
1925+
,.body= "body"
1926+
,.upgrade= NULL
1927+
,.headers=
1928+
{ { "Connection", "upgrade" }
1929+
, { "Upgrade", "h2c" }
1930+
, { "Transfer-Encoding", "chunked" }
1931+
}
1932+
,.num_chunks_complete= 3
1933+
,.chunk_lengths= { 2, 2 }
1934+
}
1935+
17751936
, {.name= NULL } /* sentinel */
17761937
};
17771938

@@ -2481,7 +2642,9 @@ message_eq (int index, int connect, const struct message *expected)
24812642
if (!r) return 0;
24822643
}
24832644

2484-
MESSAGE_CHECK_STR_EQ(expected, m, upgrade);
2645+
if (!connect) {
2646+
MESSAGE_CHECK_STR_EQ(expected, m, upgrade);
2647+
}
24852648

24862649
return 1;
24872650
}

0 commit comments

Comments
 (0)