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

Ignore Upgrade header outside of 101 response. #364

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions http_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1794,10 +1794,17 @@ size_t http_parser_execute (http_parser *parser,
UPDATE_STATE(s_headers_done);

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

/* Here we call the headers_complete callback. This is somewhat
* different than other callbacks because if the user returns 1, we
Expand Down
167 changes: 165 additions & 2 deletions test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,7 @@ const struct message requests[] =
}

#define UNLINK_REQUEST 41
, {.name = "link request"
, {.name = "unlink request"
,.type= HTTP_REQUEST
,.raw= "UNLINK /images/my_dog.jpg HTTP/1.1\r\n"
"Host: example.com\r\n"
Expand Down Expand Up @@ -1771,6 +1771,167 @@ const struct message responses[] =
,.chunk_lengths= { 2 }
}

#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER 22
, {.name= "HTTP 101 response with Upgrade header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
"Connection: upgrade\r\n"
"Upgrade: h2c\r\n"
"\r\n"
"proto"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 101
,.response_status= "Switching Protocols"
,.upgrade= "proto"
,.num_headers= 2
,.headers=
{ { "Connection", "upgrade" }
, { "Upgrade", "h2c" }
}
}

#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 23
, {.name= "HTTP 101 response with Upgrade and Content-Length header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
"Connection: upgrade\r\n"
"Upgrade: h2c\r\n"
"Content-Length: 4\r\n"
"\r\n"
"body"
"proto"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 101
,.response_status= "Switching Protocols"
,.body= "body"
,.upgrade= "proto"
,.num_headers= 3
,.headers=
{ { "Connection", "upgrade" }
, { "Upgrade", "h2c" }
, { "Content-Length", "4" }
}
}

#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 24
, {.name= "HTTP 101 response with Upgrade and Transfer-Encoding header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
"Connection: upgrade\r\n"
"Upgrade: h2c\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"2\r\n"
"bo\r\n"
"2\r\n"
"dy\r\n"
"0\r\n"
"\r\n"
"proto"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 101
,.response_status= "Switching Protocols"
,.body= "body"
,.upgrade= "proto"
,.num_headers= 3
,.headers=
{ { "Connection", "upgrade" }
, { "Upgrade", "h2c" }
, { "Transfer-Encoding", "chunked" }
}
,.num_chunks_complete= 3
,.chunk_lengths= { 2, 2 }
}

#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER 25
, {.name= "HTTP 200 response with Upgrade header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
"Connection: upgrade\r\n"
"Upgrade: h2c\r\n"
"\r\n"
"body"
,.should_keep_alive= FALSE
,.message_complete_on_eof= TRUE
,.http_major= 1
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
,.body= "body"
,.upgrade= NULL
,.num_headers= 2
,.headers=
{ { "Connection", "upgrade" }
, { "Upgrade", "h2c" }
}
}

#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 26
, {.name= "HTTP 200 response with Upgrade and Content-Length header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
"Connection: upgrade\r\n"
"Upgrade: h2c\r\n"
"Content-Length: 4\r\n"
"\r\n"
"body"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
,.num_headers= 3
,.body= "body"
,.upgrade= NULL
,.headers=
{ { "Connection", "upgrade" }
, { "Upgrade", "h2c" }
, { "Content-Length", "4" }
}
}

#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 27
, {.name= "HTTP 200 response with Upgrade and Transfer-Encoding header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
"Connection: upgrade\r\n"
"Upgrade: h2c\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"2\r\n"
"bo\r\n"
"2\r\n"
"dy\r\n"
"0\r\n"
"\r\n"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
,.num_headers= 3
,.body= "body"
,.upgrade= NULL
,.headers=
{ { "Connection", "upgrade" }
, { "Upgrade", "h2c" }
, { "Transfer-Encoding", "chunked" }
}
,.num_chunks_complete= 3
,.chunk_lengths= { 2, 2 }
}

, {.name= NULL } /* sentinel */
};

Expand Down Expand Up @@ -2476,7 +2637,9 @@ message_eq (int index, int connect, const struct message *expected)
if (!r) return 0;
}

MESSAGE_CHECK_STR_EQ(expected, m, upgrade);
if (!connect) {
MESSAGE_CHECK_STR_EQ(expected, m, upgrade);
}

This comment was marked as off-topic.


return 1;
}
Expand Down