#define H1_MF_XFER_ENC 0x00000200 // transfer-encoding is present
#define H1_MF_NO_PHDR 0x00000400 // don't add pseudo-headers in the header list
#define H1_MF_HDRS_ONLY 0x00000800 // parse headers only
-#define H1_MF_CLEAN_CONN_HDR 0x00001000 // skip close/keep-alive values of connection headers during parsing
+#define H1_MF_CLEAN_CONN_HDR 0x00001000 // skip close/keep-alive values of connection headers and h2c/h2 values of upgrade headers during parsing (rewrites the buffer)
#define H1_MF_METH_CONNECT 0x00002000 // Set for a response to a CONNECT request
#define H1_MF_METH_HEAD 0x00004000 // Set for a response to a HEAD request
#define H1_MF_UPG_WEBSOCKET 0x00008000 // Set for a Websocket upgrade handshake
/* Parse the Upgrade: header of an HTTP/1 request.
* If "websocket" is found, set H1_MF_UPG_WEBSOCKET flag
- * If "h2c" or "h2" found, the value is skipped. The header value is rewritten
- * in place and the bytes freed at the end of the original value are replaced
- * with spaces so that parsing the same area again gives the same value.
+ * If "h2c" or "h2" found and the flag H1_MF_CLEAN_CONN_HDR is set, the value is
+ * skipped. The header value is rewritten in place and the bytes freed at the
+ * end of the original value are replaced with spaces so that parsing the same
+ * area again gives the same value. Without H1_MF_CLEAN_CONN_HDR, the value is
+ * never modified.
*/
void h1_parse_upgrade_header(struct h1m *h1m, struct ist *value)
{
if (isteqi(word, ist("websocket")))
h1m->flags |= H1_MF_UPG_WEBSOCKET;
- else if (isteqi(word, ist("h2c")) || isteqi(word, ist("h2")))
+ else if ((h1m->flags & H1_MF_CLEAN_CONN_HDR) &&
+ (isteqi(word, ist("h2c")) || isteqi(word, ist("h2"))))
goto skip_val;
if (value->ptr + value->len == p) {
}
/* blank the freed area to make the operation idempotent */
- if (value->ptr + value->len < e)
+ if ((h1m->flags & H1_MF_CLEAN_CONN_HDR) && value->ptr + value->len < e)
memset(value->ptr + value->len, ' ', e - (value->ptr + value->len));
if (istlen(*value))