|
@@ -11535,7 +11535,7 @@ handle_cgi_request(struct mg_connection *conn,
|
|
size_t buflen;
|
|
size_t buflen;
|
|
int headers_len, data_len, i, truncated;
|
|
int headers_len, data_len, i, truncated;
|
|
int fdin[2] = {-1, -1}, fdout[2] = {-1, -1}, fderr[2] = {-1, -1};
|
|
int fdin[2] = {-1, -1}, fdout[2] = {-1, -1}, fderr[2] = {-1, -1};
|
|
- const char *status, *status_text, *connection_state;
|
|
|
|
|
|
+ const char *status, *status_text;
|
|
char *pbuf, dir[UTF8_PATH_MAX], *p;
|
|
char *pbuf, dir[UTF8_PATH_MAX], *p;
|
|
struct mg_request_info ri;
|
|
struct mg_request_info ri;
|
|
struct cgi_environment blk;
|
|
struct cgi_environment blk;
|
|
@@ -11783,9 +11783,8 @@ handle_cgi_request(struct mg_connection *conn,
|
|
} else {
|
|
} else {
|
|
conn->status_code = 200;
|
|
conn->status_code = 200;
|
|
}
|
|
}
|
|
- connection_state =
|
|
|
|
- get_header(ri.http_headers, ri.num_headers, "Connection");
|
|
|
|
- if (!header_has_option(connection_state, "keep-alive")) {
|
|
|
|
|
|
+
|
|
|
|
+ if (!should_keep_alive(conn)) {
|
|
conn->must_close = 1;
|
|
conn->must_close = 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -13855,30 +13854,40 @@ handle_websocket_request(struct mg_connection *conn,
|
|
static int
|
|
static int
|
|
should_switch_to_protocol(const struct mg_connection *conn)
|
|
should_switch_to_protocol(const struct mg_connection *conn)
|
|
{
|
|
{
|
|
- const char *upgrade, *connection;
|
|
|
|
|
|
+ const char *connection_headers[8];
|
|
|
|
+ const char *upgrade_to;
|
|
|
|
+ int connection_header_count, i, should_upgrade;
|
|
|
|
|
|
/* A websocket protocoll has the following HTTP headers:
|
|
/* A websocket protocoll has the following HTTP headers:
|
|
*
|
|
*
|
|
* Connection: Upgrade
|
|
* Connection: Upgrade
|
|
* Upgrade: Websocket
|
|
* Upgrade: Websocket
|
|
|
|
+ *
|
|
|
|
+ * It seems some clients use multiple headers:
|
|
|
|
+ * see https://github.com/civetweb/civetweb/issues/1083
|
|
*/
|
|
*/
|
|
-
|
|
|
|
- connection = mg_get_header(conn, "Connection");
|
|
|
|
- if (connection == NULL) {
|
|
|
|
- return PROTOCOL_TYPE_HTTP1;
|
|
|
|
|
|
+ connection_header_count = get_req_headers(&conn->request_info,
|
|
|
|
+ "Connection",
|
|
|
|
+ connection_headers,
|
|
|
|
+ 8);
|
|
|
|
+ should_upgrade = 0;
|
|
|
|
+ for (i = 0; i < connection_header_count; i++) {
|
|
|
|
+ if (0 != mg_strcasestr(connection_headers[i], "upgrade")) {
|
|
|
|
+ should_upgrade = 1;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- if (!mg_strcasestr(connection, "upgrade")) {
|
|
|
|
|
|
+ if (!should_upgrade) {
|
|
return PROTOCOL_TYPE_HTTP1;
|
|
return PROTOCOL_TYPE_HTTP1;
|
|
}
|
|
}
|
|
|
|
|
|
- upgrade = mg_get_header(conn, "Upgrade");
|
|
|
|
- if (upgrade == NULL) {
|
|
|
|
|
|
+ upgrade_to = mg_get_header(conn, "Upgrade");
|
|
|
|
+ if (upgrade_to == NULL) {
|
|
/* "Connection: Upgrade" without "Upgrade" Header --> Error */
|
|
/* "Connection: Upgrade" without "Upgrade" Header --> Error */
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/* Upgrade to ... */
|
|
/* Upgrade to ... */
|
|
- if (0 != mg_strcasestr(upgrade, "websocket")) {
|
|
|
|
|
|
+ if (0 != mg_strcasestr(upgrade_to, "websocket")) {
|
|
/* The headers "Host", "Sec-WebSocket-Key", "Sec-WebSocket-Protocol" and
|
|
/* The headers "Host", "Sec-WebSocket-Key", "Sec-WebSocket-Protocol" and
|
|
* "Sec-WebSocket-Version" are also required.
|
|
* "Sec-WebSocket-Version" are also required.
|
|
* Don't check them here, since even an unsupported websocket protocol
|
|
* Don't check them here, since even an unsupported websocket protocol
|
|
@@ -13887,7 +13896,7 @@ should_switch_to_protocol(const struct mg_connection *conn)
|
|
*/
|
|
*/
|
|
return PROTOCOL_TYPE_WEBSOCKET; /* Websocket */
|
|
return PROTOCOL_TYPE_WEBSOCKET; /* Websocket */
|
|
}
|
|
}
|
|
- if (0 != mg_strcasestr(upgrade, "h2")) {
|
|
|
|
|
|
+ if (0 != mg_strcasestr(upgrade_to, "h2")) {
|
|
return PROTOCOL_TYPE_HTTP2; /* Websocket */
|
|
return PROTOCOL_TYPE_HTTP2; /* Websocket */
|
|
}
|
|
}
|
|
|
|
|