Add client hints headers as CORS safe headers

Client hints are device-specific and not origin specific. This
brings Chromium to be spec-compliant.

Bug: 830118
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: I5a645c1d89fb7800168a2bdf571122f1dce01743
Reviewed-on: https://chromium-review.googlesource.com/1000879
Commit-Queue: Tarun Bansal <tbansal@chromium.org>
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556518}
diff --git a/cors/client-hint-request-headers.htm b/cors/client-hint-request-headers.htm
new file mode 100644
index 0000000..ee6c7ea
--- /dev/null
+++ b/cors/client-hint-request-headers.htm
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CORS - client hint request headers - Access-Control-Allow-Headers</title>
+
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=support.js?pipe=sub></script>
+
+<h1>Request headers</h1>
+<div id=log></div>
+<script>
+
+test(function() {
+    var client = new XMLHttpRequest()
+    client.open('GET', CROSSDOMAIN + 'resources/cors-makeheader.py?headers=x-print,', false)
+    client.setRequestHeader('x-print', 'unicorn')
+    client.setRequestHeader('content-type', 'text/plain')
+    client.setRequestHeader('accept', 'test')
+    client.setRequestHeader('accept-language', 'nn')
+    client.setRequestHeader('content-language', 'nn')
+    client.setRequestHeader('save-data', 'on')
+    client.setRequestHeader('device-memory', '1.0')
+    client.setRequestHeader('dpr', '2.0')
+    client.setRequestHeader('width', '35')
+    client.setRequestHeader('viewport-width', '42')
+    client.send(null)
+
+    const res = JSON.parse(client.response)
+    assert_equals(res['x-print'], 'unicorn')
+    assert_equals(res['content-type'], 'text/plain')
+    assert_equals(res['accept'], 'test')
+    assert_equals(res['accept-language'], 'nn')
+    assert_equals(res['content-language'], 'nn')
+    assert_equals(res['save-data'], 'on')
+    assert_equals(res['device-memory'], '1.0')
+    assert_equals(res['dpr'], '2.0')
+    assert_equals(res['width'], '35')
+    assert_equals(res['viewport-width'], '42')
+}, 'Client hint headers are simple headers')
+
+test(function() {
+    var client = new XMLHttpRequest()
+    client.open('GET', CROSSDOMAIN + 'resources/cors-makeheader.py?headers=x-print', false)
+    client.setRequestHeader('x-print', 'unicorn')
+    client.setRequestHeader('y-print', 'unicorn')
+    assert_throws("NetworkError", function() { client.send(null) })
+}, 'Unspecified request headers are disallowed')
+
+test(function() {
+    var client = new XMLHttpRequest()
+    client.open('GET', CROSSDOMAIN + 'resources/cors-makeheader.py?headers=x-print', false)
+    client.setRequestHeader('device-memory', '')
+    assert_throws("NetworkError", function() { client.send(null) })
+}, 'Unextractable device-memory client hint header is disallowed')
+
+test(function() {
+    var client = new XMLHttpRequest()
+    client.open('GET', CROSSDOMAIN + 'resources/cors-makeheader.py?headers=x-print', false)
+    client.setRequestHeader('dpr', '')
+    assert_throws("NetworkError", function() { client.send(null) })
+}, 'Unextractable DPR client hint header is disallowed')
+
+test(function() {
+    var client = new XMLHttpRequest()
+    client.open('GET', CROSSDOMAIN + 'resources/cors-makeheader.py?headers=x-print', false)
+    client.setRequestHeader('width', '')
+    assert_throws("NetworkError", function() { client.send(null) })
+}, 'Unextractable width client hint header is disallowed')
+
+test(function() {
+    var client = new XMLHttpRequest()
+    client.open('GET', CROSSDOMAIN + 'resources/cors-makeheader.py?headers=x-print', false)
+    client.setRequestHeader('viewport-width', '')
+    assert_throws("NetworkError", function() { client.send(null) })
+}, 'Unextractable viewport-width client hint header is disallowed')
+
+</script>
diff --git a/cors/simple-requests.htm b/cors/simple-requests.htm
index 441a8c1..77ed8ee 100644
--- a/cors/simple-requests.htm
+++ b/cors/simple-requests.htm
@@ -61,10 +61,17 @@
                         'content-type': 'text/plain; parameter=whatever'
                      })
 
+check_simple_headers({
+                        'save-data': 'on',
+                        'device-memory': '2.0',
+                        'dpr': '3.0',
+                        'width': '1200',
+                        'viewport-width': '1300'
+                     })
+
 check_simple('Get', {'content-type': 'text/plain; parameter=extra_bonus'})
 check_simple('post', {'content-type': 'text/plain'})
 
-
 /* Extra async test */
 
 var simple_async = async_test("Check simple headers (async)")