From 88a5c1441fd1b4f95902d84199e52aa953568e3e Mon Sep 17 00:00:00 2001 From: Anatoli Papirovski Date: Tue, 19 Sep 2017 09:56:09 -0400 Subject: [PATCH] http2: expand list of known headers Add access-control-*, dnt, forwarded, trailer, tk, upgrade-insecure-requests, warning, x-content-type-options and x-frame-options to known list of headers for HTTP2. Expand tests to account for these headers. Fixes: https://github.com/nodejs/node/issues/15337 Refs: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers Refs: https://www.w3.org/TR/cors/#syntax Refs: https://www.w3.org/2011/tracking-protection/drafts/tracking-dnt.html#dnt-header-field Refs: https://tools.ietf.org/html/rfc7239#section-4 Refs: https://tools.ietf.org/html/rfc7230#section-4.4 Refs: https://www.w3.org/2011/tracking-protection/drafts/tracking-dnt.html#response-header-field Refs: https://www.w3.org/TR/upgrade-insecure-requests/#preference Refs: https://tools.ietf.org/html/rfc7234#section-5.5 Refs: https://fetch.spec.whatwg.org/#x-content-type-options-header Refs: https://tools.ietf.org/html/rfc7034 --- lib/internal/http2/util.js | 16 ++++++++- src/node_http2.h | 15 ++++++++ test/parallel/test-http2-binding.js | 15 ++++++++ test/parallel/test-http2-util-headers-list.js | 36 +++++++++++++++++-- 4 files changed, 79 insertions(+), 3 deletions(-) diff --git a/lib/internal/http2/util.js b/lib/internal/http2/util.js index 267ea4fe4fb6a4..baa233e5b0468c 100644 --- a/lib/internal/http2/util.js +++ b/lib/internal/http2/util.js @@ -12,6 +12,9 @@ const { HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_SCHEME, HTTP2_HEADER_PATH, + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, + HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE, + HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD, HTTP2_HEADER_AGE, HTTP2_HEADER_AUTHORIZATION, HTTP2_HEADER_CONTENT_ENCODING, @@ -23,6 +26,7 @@ const { HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_COOKIE, HTTP2_HEADER_DATE, + HTTP2_HEADER_DNT, HTTP2_HEADER_ETAG, HTTP2_HEADER_EXPIRES, HTTP2_HEADER_FROM, @@ -39,7 +43,10 @@ const { HTTP2_HEADER_REFERER, HTTP2_HEADER_RETRY_AFTER, HTTP2_HEADER_SET_COOKIE, + HTTP2_HEADER_TK, + HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS, HTTP2_HEADER_USER_AGENT, + HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS, HTTP2_HEADER_CONNECTION, HTTP2_HEADER_UPGRADE, @@ -74,6 +81,9 @@ const kSingleValueHeaders = new Set([ HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_SCHEME, HTTP2_HEADER_PATH, + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, + HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE, + HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD, HTTP2_HEADER_AGE, HTTP2_HEADER_AUTHORIZATION, HTTP2_HEADER_CONTENT_ENCODING, @@ -84,6 +94,7 @@ const kSingleValueHeaders = new Set([ HTTP2_HEADER_CONTENT_RANGE, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_DATE, + HTTP2_HEADER_DNT, HTTP2_HEADER_ETAG, HTTP2_HEADER_EXPIRES, HTTP2_HEADER_FROM, @@ -99,7 +110,10 @@ const kSingleValueHeaders = new Set([ HTTP2_HEADER_RANGE, HTTP2_HEADER_REFERER, HTTP2_HEADER_RETRY_AFTER, - HTTP2_HEADER_USER_AGENT + HTTP2_HEADER_TK, + HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS, + HTTP2_HEADER_USER_AGENT, + HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS ]); // The HTTP methods in this set are specifically defined as assigning no diff --git a/src/node_http2.h b/src/node_http2.h index a5029bec378765..68801eeb54eb31 100644 --- a/src/node_http2.h +++ b/src/node_http2.h @@ -69,7 +69,14 @@ using v8::MaybeLocal; V(ACCEPT_LANGUAGE, "accept-language") \ V(ACCEPT_RANGES, "accept-ranges") \ V(ACCEPT, "accept") \ + V(ACCESS_CONTROL_ALLOW_CREDENTIALS, "access-control-allow-credentials") \ + V(ACCESS_CONTROL_ALLOW_HEADERS, "access-control-allow-headers") \ + V(ACCESS_CONTROL_ALLOW_METHODS, "access-control-allow-methods") \ V(ACCESS_CONTROL_ALLOW_ORIGIN, "access-control-allow-origin") \ + V(ACCESS_CONTROL_EXPOSE_HEADERS, "access-control-expose-headers") \ + V(ACCESS_CONTROL_MAX_AGE, "access-control-max-age") \ + V(ACCESS_CONTROL_REQUEST_HEADERS, "access-control-request-headers") \ + V(ACCESS_CONTROL_REQUEST_METHOD, "access-control-request-method") \ V(AGE, "age") \ V(ALLOW, "allow") \ V(AUTHORIZATION, "authorization") \ @@ -85,9 +92,11 @@ using v8::MaybeLocal; V(CONTENT_TYPE, "content-type") \ V(COOKIE, "cookie") \ V(DATE, "date") \ + V(DNT, "dnt") \ V(ETAG, "etag") \ V(EXPECT, "expect") \ V(EXPIRES, "expires") \ + V(FORWARDED, "forwarded") \ V(FROM, "from") \ V(HOST, "host") \ V(IF_MATCH, "if-match") \ @@ -109,13 +118,19 @@ using v8::MaybeLocal; V(SERVER, "server") \ V(SET_COOKIE, "set-cookie") \ V(STRICT_TRANSPORT_SECURITY, "strict-transport-security") \ + V(TRAILER, "trailer") \ V(TRANSFER_ENCODING, "transfer-encoding") \ V(TE, "te") \ + V(TK, "tk") \ + V(UPGRADE_INSECURE_REQUESTS, "upgrade-insecure-requests") \ V(UPGRADE, "upgrade") \ V(USER_AGENT, "user-agent") \ V(VARY, "vary") \ V(VIA, "via") \ + V(WARNING, "warning") \ V(WWW_AUTHENTICATE, "www-authenticate") \ + V(X_CONTENT_TYPE_OPTIONS, "x-content-type-options") \ + V(X_FRAME_OPTIONS, "x-frame-options") \ V(HTTP2_SETTINGS, "http2-settings") \ V(KEEP_ALIVE, "keep-alive") \ V(PROXY_CONNECTION, "proxy-connection") diff --git a/test/parallel/test-http2-binding.js b/test/parallel/test-http2-binding.js index 919ee5908facbb..22c4783b1fabf5 100644 --- a/test/parallel/test-http2-binding.js +++ b/test/parallel/test-http2-binding.js @@ -105,7 +105,14 @@ const expectedHeaderNames = { HTTP2_HEADER_ACCEPT_LANGUAGE: 'accept-language', HTTP2_HEADER_ACCEPT_RANGES: 'accept-ranges', HTTP2_HEADER_ACCEPT: 'accept', + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS: 'access-control-allow-credentials', // eslint-disable-line max-len + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_HEADERS: 'access-control-allow-headers', + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_METHODS: 'access-control-allow-methods', HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN: 'access-control-allow-origin', + HTTP2_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS: 'access-control-expose-headers', + HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE: 'access-control-max-age', + HTTP2_HEADER_ACCESS_CONTROL_REQUEST_HEADERS: 'access-control-request-headers', + HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD: 'access-control-request-method', HTTP2_HEADER_AGE: 'age', HTTP2_HEADER_ALLOW: 'allow', HTTP2_HEADER_AUTHORIZATION: 'authorization', @@ -119,9 +126,11 @@ const expectedHeaderNames = { HTTP2_HEADER_CONTENT_TYPE: 'content-type', HTTP2_HEADER_COOKIE: 'cookie', HTTP2_HEADER_CONNECTION: 'connection', + HTTP2_HEADER_DNT: 'dnt', HTTP2_HEADER_ETAG: 'etag', HTTP2_HEADER_EXPECT: 'expect', HTTP2_HEADER_EXPIRES: 'expires', + HTTP2_HEADER_FORWARDED: 'forwarded', HTTP2_HEADER_FROM: 'from', HTTP2_HEADER_HOST: 'host', HTTP2_HEADER_IF_MATCH: 'if-match', @@ -144,11 +153,17 @@ const expectedHeaderNames = { HTTP2_HEADER_SERVER: 'server', HTTP2_HEADER_SET_COOKIE: 'set-cookie', HTTP2_HEADER_STRICT_TRANSPORT_SECURITY: 'strict-transport-security', + HTTP2_HEADER_TRAILER: 'trailer', HTTP2_HEADER_TRANSFER_ENCODING: 'transfer-encoding', + HTTP2_HEADER_TK: 'tk', + HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS: 'upgrade-insecure-requests', HTTP2_HEADER_USER_AGENT: 'user-agent', HTTP2_HEADER_VARY: 'vary', HTTP2_HEADER_VIA: 'via', + HTTP2_HEADER_WARNING: 'warning', HTTP2_HEADER_WWW_AUTHENTICATE: 'www-authenticate', + HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS: 'x-content-type-options', + HTTP2_HEADER_X_FRAME_OPTIONS: 'x-frame-options', HTTP2_HEADER_KEEP_ALIVE: 'keep-alive', HTTP2_HEADER_CONTENT_MD5: 'content-md5', HTTP2_HEADER_TE: 'te', diff --git a/test/parallel/test-http2-util-headers-list.js b/test/parallel/test-http2-util-headers-list.js index ac86e3473ea347..8d665120c14776 100644 --- a/test/parallel/test-http2-util-headers-list.js +++ b/test/parallel/test-http2-util-headers-list.js @@ -14,6 +14,9 @@ const { HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_SCHEME, HTTP2_HEADER_PATH, + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, + HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE, + HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD, HTTP2_HEADER_AGE, HTTP2_HEADER_AUTHORIZATION, HTTP2_HEADER_CONTENT_ENCODING, @@ -24,6 +27,7 @@ const { HTTP2_HEADER_CONTENT_RANGE, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_DATE, + HTTP2_HEADER_DNT, HTTP2_HEADER_ETAG, HTTP2_HEADER_EXPIRES, HTTP2_HEADER_FROM, @@ -33,24 +37,33 @@ const { HTTP2_HEADER_IF_RANGE, HTTP2_HEADER_IF_UNMODIFIED_SINCE, HTTP2_HEADER_LAST_MODIFIED, + HTTP2_HEADER_LOCATION, HTTP2_HEADER_MAX_FORWARDS, HTTP2_HEADER_PROXY_AUTHORIZATION, HTTP2_HEADER_RANGE, HTTP2_HEADER_REFERER, HTTP2_HEADER_RETRY_AFTER, + HTTP2_HEADER_TK, + HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS, HTTP2_HEADER_USER_AGENT, + HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS, HTTP2_HEADER_ACCEPT_CHARSET, HTTP2_HEADER_ACCEPT_ENCODING, HTTP2_HEADER_ACCEPT_LANGUAGE, HTTP2_HEADER_ACCEPT_RANGES, HTTP2_HEADER_ACCEPT, + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_HEADERS, + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_METHODS, HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, + HTTP2_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, + HTTP2_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, HTTP2_HEADER_ALLOW, HTTP2_HEADER_CACHE_CONTROL, HTTP2_HEADER_CONTENT_DISPOSITION, HTTP2_HEADER_COOKIE, HTTP2_HEADER_EXPECT, + HTTP2_HEADER_FORWARDED, HTTP2_HEADER_LINK, HTTP2_HEADER_PREFER, HTTP2_HEADER_PROXY_AUTHENTICATE, @@ -58,9 +71,12 @@ const { HTTP2_HEADER_SERVER, HTTP2_HEADER_SET_COOKIE, HTTP2_HEADER_STRICT_TRANSPORT_SECURITY, + HTTP2_HEADER_TRAILER, HTTP2_HEADER_VARY, HTTP2_HEADER_VIA, + HTTP2_HEADER_WARNING, HTTP2_HEADER_WWW_AUTHENTICATE, + HTTP2_HEADER_X_FRAME_OPTIONS, HTTP2_HEADER_CONNECTION, HTTP2_HEADER_UPGRADE, @@ -145,6 +161,9 @@ const { HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_SCHEME, HTTP2_HEADER_PATH, + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, + HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE, + HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD, HTTP2_HEADER_AGE, HTTP2_HEADER_AUTHORIZATION, HTTP2_HEADER_CONTENT_ENCODING, @@ -155,6 +174,7 @@ const { HTTP2_HEADER_CONTENT_RANGE, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_DATE, + HTTP2_HEADER_DNT, HTTP2_HEADER_ETAG, HTTP2_HEADER_EXPIRES, HTTP2_HEADER_FROM, @@ -164,12 +184,16 @@ const { HTTP2_HEADER_IF_RANGE, HTTP2_HEADER_IF_UNMODIFIED_SINCE, HTTP2_HEADER_LAST_MODIFIED, + HTTP2_HEADER_LOCATION, HTTP2_HEADER_MAX_FORWARDS, HTTP2_HEADER_PROXY_AUTHORIZATION, HTTP2_HEADER_RANGE, HTTP2_HEADER_REFERER, HTTP2_HEADER_RETRY_AFTER, - HTTP2_HEADER_USER_AGENT + HTTP2_HEADER_TK, + HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS, + HTTP2_HEADER_USER_AGENT, + HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS ].forEach((name) => { const msg = `Header field "${name}" must have only a single value`; common.expectsError({ @@ -184,12 +208,17 @@ const { HTTP2_HEADER_ACCEPT_LANGUAGE, HTTP2_HEADER_ACCEPT_RANGES, HTTP2_HEADER_ACCEPT, + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_HEADERS, + HTTP2_HEADER_ACCESS_CONTROL_ALLOW_METHODS, HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, + HTTP2_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, + HTTP2_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, HTTP2_HEADER_ALLOW, HTTP2_HEADER_CACHE_CONTROL, HTTP2_HEADER_CONTENT_DISPOSITION, HTTP2_HEADER_COOKIE, HTTP2_HEADER_EXPECT, + HTTP2_HEADER_FORWARDED, HTTP2_HEADER_LINK, HTTP2_HEADER_PREFER, HTTP2_HEADER_PROXY_AUTHENTICATE, @@ -197,9 +226,12 @@ const { HTTP2_HEADER_SERVER, HTTP2_HEADER_SET_COOKIE, HTTP2_HEADER_STRICT_TRANSPORT_SECURITY, + HTTP2_HEADER_TRAILER, HTTP2_HEADER_VARY, HTTP2_HEADER_VIA, - HTTP2_HEADER_WWW_AUTHENTICATE + HTTP2_HEADER_WARNING, + HTTP2_HEADER_WWW_AUTHENTICATE, + HTTP2_HEADER_X_FRAME_OPTIONS ].forEach((name) => { assert(!(mapToHeaders({ [name]: [1, 2, 3] }) instanceof Error), name); });