Import Cobalt 19.master.0.203780

Includes the following patches:
  https://cobalt-review.googlesource.com/c/cobalt/+/5210
    by errong.leng@samsung.com
  https://cobalt-review.googlesource.com/c/cobalt/+/5270
    by linus.wang@samsung.com
diff --git a/src/third_party/web_platform_tests/eventsource/README.md b/src/third_party/web_platform_tests/eventsource/README.md
new file mode 100644
index 0000000..6b58a1e
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/README.md
@@ -0,0 +1,54 @@
+# Server-Sent Events Test Collection
+
+Server-Sent Events [latest draft](http://dev.w3.org/html5/eventsource/).
+
+Following up work done during the TestTWF 2012 Paris event:
+
+Most tests comes from [Opera](http://tc.labs.opera.com/apis/EventSource/), are from august 2010 and probably only valid against [spec rev. ~1.139](http://dev.w3.org/cvsweb/~checkout~/html5/eventsource/Overview.html?rev=1.139;content-type=text%2Fhtml). You can check the following diff :
+
+[diff between 1.139 (23 Jul 2010) and 1.229 (25 Oct. 2012) revisions](http://dev.w3.org/cvsweb/html5/eventsource/Overview.html.diff?r1=text&tr1=1.139&r2=text&tr2=1.229)
+
+to get an idea of what needs to get updated.
+
+##DONE (updated against rev. 1.229):
+- **eventsource-constructor-url-bogus.htm**: whatwg r6602: renamed SYNTAX_ERR to SyntaxError
+
+- **eventsource-constructor-stringify.htm**: still valid. bugfix.
+
+##TODO (need to be updated against rev. 1.229):
+- **eventsource-cross-origin.htm**, **eventsource-constructor-non-same-origin.htm**: whatwg 6255 6257: allow CORS
+
+##TOCHECK (need to check if the test is still valid against rev.1.229):
+eventsource-close.htm
+eventsource-constructor-document-domain.htm
+eventsource-constructor-url-multi-window.htm
+eventsource-eventtarget.htm
+eventsource-onmessage.htm
+eventsource-onopen.htm
+eventsource-prototype.htm
+eventsource-reconnect.htm
+eventsource-url.htm
+format-bom-2.htm
+format-bom.htm
+format-comments.htm
+format-field-data.htm
+format-field-event-empty.htm
+format-field-event.htm
+format-field-id-2.htm
+format-field-id.htm
+format-field-parsing.htm
+format-field-retry-bogus.htm
+format-field-retry-empty.htm
+format-field-retry.htm
+format-field-unknown.htm
+format-leading-space.htm
+format-mime-bogus.htm
+format-mime-trailing-semicolon.htm
+format-mime-valid-bogus.htm
+format-newlines.htm
+format-utf-8.htm
+request-accept.htm
+request-cache-control.htm
+request-credentials.htm
+request-redirect.htm
+request-status-error.htm
diff --git a/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-close.htm b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-close.htm
new file mode 100644
index 0000000..42ebb1d
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-close.htm
@@ -0,0 +1,36 @@
+<!--
+try {
+  var source = new EventSource("../resources/message.py")
+  source.onopen = function(e) {
+    this.close()
+    postMessage([true, this.readyState])
+  }
+} catch(e) {
+  postMessage([false, String(e)])
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>dedicated worker - EventSource: close()</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test();
+      test.step(function() {
+        var worker = new Worker('#')
+        worker.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], EventSource.CLOSED, 'this.readyState')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm
new file mode 100644
index 0000000..9fe515d
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm
@@ -0,0 +1,49 @@
+<!--
+try {
+  var url = decodeURIComponent(location.hash.substr(1))
+  var source = new EventSource(url)
+  source.onerror = function(e) {
+    postMessage([true, this.readyState, 'data' in e])
+    this.close();
+  }
+} catch(e) {
+  postMessage([false, String(e)])
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>dedicated worker - EventSource: constructor (act as if there is a network error)</title>
+    <meta name=timeout content=long>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      function fetchFail(url) {
+        var test = async_test(document.title + " (" + url + ")", { timeout: 20000 })
+        test.step(function() {
+          var worker = new Worker('#'+encodeURIComponent(url))
+          worker.onmessage = function(e) {
+            test.step(function() {
+              assert_true(e.data[0], e.data[1])
+              assert_equals(e.data[1], EventSource.CLOSED, 'source.readyState')
+              assert_false(e.data[2], "'data' in e");
+            })
+            test.done()
+          }
+        })
+      }
+      fetchFail("http://example.not/")
+      fetchFail("https://example.not/test")
+      fetchFail("ftp://example.not/")
+      fetchFail("about:blank")
+      fetchFail("mailto:whatwg@awesome.example")
+      fetchFail("javascript:alert('FAIL')")
+    </script>
+    <!-- This tests "fails the connection" as well as making sure a simple
+         event is dispatched and not a MessageEvent -->
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-constructor-url-bogus.htm b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-constructor-url-bogus.htm
new file mode 100644
index 0000000..5ffdec8
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-constructor-url-bogus.htm
@@ -0,0 +1,34 @@
+<!--
+try {
+  var source = new EventSource("http://this is invalid/")
+  postMessage([false, 'no exception thrown'])
+  source.close()
+} catch(e) {
+  postMessage([true, e.code])
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>dedicated worker - EventSource: constructor (invalid URL)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var worker = new Worker('#')
+        worker.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], DOMException.SYNTAX_ERR, 'e.code')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
\ No newline at end of file
diff --git a/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-eventtarget.htm b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-eventtarget.htm
new file mode 100644
index 0000000..ff40c59
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-eventtarget.htm
@@ -0,0 +1,37 @@
+<!--
+try {
+  var source = new EventSource("../resources/message.py")
+  source.addEventListener("message", listener, false)
+  function listener(e) {
+    postMessage([true, e.data])
+    this.close()
+  }
+} catch(e) {
+  postMessage([false, String(e)])
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>dedicated worker - EventSource: addEventListener()</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var worker = new Worker('#')
+        worker.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], 'data', 'e.data')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-onmesage.htm b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-onmesage.htm
new file mode 100644
index 0000000..2de142c
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-onmesage.htm
@@ -0,0 +1,36 @@
+<!--
+try {
+  var source = new EventSource("../resources/message.py")
+  source.onmessage = function(e) {
+    postMessage([true, e.data])
+    this.close()
+  }
+} catch(e) {
+  postMessage([false, String(e)])
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>dedicated worker - EventSource: onmessage</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var worker = new Worker('#')
+        worker.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], "data", 'e.data')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-onopen.htm b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-onopen.htm
new file mode 100644
index 0000000..e753b42
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-onopen.htm
@@ -0,0 +1,39 @@
+<!--
+try {
+  var source = new EventSource("../resources/message.py")
+  source.onopen = function(e) {
+    postMessage([true, source.readyState, 'data' in e, e.bubbles, e.cancelable])
+    this.close()
+  }
+} catch(e) {
+  postMessage([false, String(e)])
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>dedicated worker - EventSource: onopen (announcing the connection)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var worker = new Worker('#')
+        worker.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], EventSource.OPEN, 'source.readyState')
+            assert_false(e.data[2], "'data' in e")
+            assert_false(e.data[3], 'e.bubbles')
+            assert_false(e.data[4], 'e.calcelable')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-prototype.htm b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-prototype.htm
new file mode 100644
index 0000000..b16e24c
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-prototype.htm
@@ -0,0 +1,36 @@
+<!--
+try {
+  EventSource.prototype.ReturnTrue = function() { return true }
+  var source = new EventSource("../resources/message.py")
+  postMessage([true, source.ReturnTrue(), 'EventSource' in self])
+  source.close()
+} catch(e) {
+  postMessage([false, String(e)])
+}
+/*-->
+<!DoCtYpE hTMl>
+<html>
+  <heAd>
+    <title>dedicated worker - EventSource: prototype et al</tiTle>
+    <scrIpt src="/resources/testharness.js"></scripT>
+    <scriPt src="/resources/testharnessreport.js"></Script>
+  </heaD>
+  <boDy>
+    <diV iD="log"></Div>
+    <sCript>
+      var test = async_test();
+      test.step(function() {
+        var worker = new Worker('#')
+        worker.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_true(e.data[1], 'source.ReturnTrue()')
+            assert_true(e.data[2], "'EventSource' in self")
+          })
+          test.done()
+        }
+      })
+    </scrIpt>
+  </bOdy>
+</htMl>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-url.htm b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-url.htm
new file mode 100644
index 0000000..c1ed078
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/dedicated-worker/eventsource-url.htm
@@ -0,0 +1,35 @@
+<!--
+try {
+  var source = new EventSource("../resources/message.py")
+  postMessage([true, source.url])
+  source.close()
+} catch(e) {
+  postMessage([false, String(e)])
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>dedicated worker - EventSource: url</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test();
+      test.step(function() {
+        var url = "resources/message.py"
+        var worker = new Worker('#')
+        worker.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1]);
+            assert_equals(e.data[1].substr(-(url.length)), url)
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/event-data.html b/src/third_party/web_platform_tests/eventsource/event-data.html
new file mode 100644
index 0000000..8f74a01
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/event-data.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: lines and data parsing</title>
+    <meta rel=help href="http://dev.w3.org/html5/eventsource/#event-stream-interpretation">
+  <meta rel=assert title="If the line is empty (a blank line) Dispatch the event, as defined below.">
+  <meta rel=assert title="If the line starts with a U+003A COLON character (:) Ignore the line.">
+  <meta rel=assert title="If the line contains a U+003A COLON character (:)
+  Collect the characters on the line before the first U+003A COLON character (:), and let field be that string.
+  Collect the characters on the line after the first U+003A COLON character (:), and let value be that string. If value starts with a U+0020 SPACE character, remove it from value.
+  Process the field using the steps described below, using field as the field name and value as the field value.
+  ">
+  <meta rel=assert title="Otherwise, the string is not empty but does not contain a U+003A COLON character (:)
+Process the field using the steps described below, using the whole line as the field name, and the empty string as the field value.
+  ">
+
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test(document.title);
+      test.step(function() {
+        var source = new EventSource("resources/message2.py"),
+            counter = 0;
+        source.onmessage = test.step_func(function(e) {
+          if(counter == 0) {
+            assert_equals(e.data,"msg\nmsg");
+          } else if(counter == 1) {
+            assert_equals(e.data,"");
+          } else if(counter == 2) {
+            assert_equals(e.data,"end");
+            source.close();
+            test.done();
+          } else {
+            assert_unreached();
+          }
+          counter++;
+        });
+      });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-close.htm b/src/third_party/web_platform_tests/eventsource/eventsource-close.htm
new file mode 100644
index 0000000..92d98de
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-close.htm
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: close()</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py")
+        assert_equals(source.readyState, source.CONNECTING, "connecting readyState");
+        source.onopen = this.step_func(function() {
+          assert_equals(source.readyState, source.OPEN, "open readyState");
+          source.close()
+          assert_equals(source.readyState, source.CLOSED, "closed readyState");
+          this.done()
+        })
+      })
+
+      var test2 = async_test(document.title + ", test events", { timeout: 9000 });
+      test2.step(function() {
+        var count = 0, reconnected = false,
+            source = new EventSource("resources/reconnect-fail.py?id=" + new Date().getTime());
+
+        source.onerror = this.step_func(function(e) {
+          assert_equals(e.type, 'error');
+          switch(count) {
+            // reconnecting after first message
+            case 1:
+              assert_equals(source.readyState, source.CONNECTING, "reconnecting readyState");
+
+              reconnected = true;
+              break;
+
+            // one more reconnect to get to the closing
+            case 2:
+              assert_equals(source.readyState, source.CONNECTING, "last reconnecting readyState");
+              count++;
+              break;
+
+            // close
+            case 3:
+              assert_equals(source.readyState, source.CLOSED, "closed readyState");
+
+              // give some time for errors to hit us
+              setTimeout(this.step_func(function() { this.done(); }), 100);
+              break;
+
+            default:
+              assert_unreached("Error handler with msg count " + count);
+          }
+
+        });
+
+        source.onmessage = this.step_func(function(e) {
+          switch(count) {
+            case 0:
+              assert_true(!reconnected, "no error event run");
+              assert_equals(e.data, "opened", "data");
+              break;
+
+            case 1:
+              assert_true(reconnected, "have reconnected");
+              assert_equals(e.data, "reconnected", "data");
+              break;
+
+            default:
+              assert_unreached("Dunno what to do with message number " + count);
+          }
+
+          count++;
+        });
+
+      });
+
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-constructor-document-domain.htm b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-document-domain.htm
new file mode 100644
index 0000000..8fd7420
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-document-domain.htm
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: document.domain</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        document.domain = document.domain
+        source = new EventSource("resources/message.py")
+        source.onopen = function(e) {
+          test.step(function() {
+            assert_equals(source.readyState, source.OPEN)
+            assert_false(e.hasOwnProperty('data'))
+            assert_false(e.bubbles)
+            assert_false(e.cancelable)
+            this.close()
+          }, this)
+          test.done()
+        }
+      })
+    </script>
+    <!-- Apart from document.domain equivalent to the onopen test. -->
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-constructor-non-same-origin.htm b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-non-same-origin.htm
new file mode 100644
index 0000000..dd4ab84
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-non-same-origin.htm
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: constructor (act as if there is a network error)</title>
+    <meta name=timeout content=long>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      function fetchFail(url) {
+        var test = async_test(document.title + " (" + url + ")", { timeout: 20000 })
+        test.step(function() {
+          var source = new EventSource(url)
+          source.onerror = function(e) {
+            test.step(function() {
+              assert_equals(source.readyState, source.CLOSED)
+              assert_false(e.hasOwnProperty('data'))
+            })
+            test.done()
+          }
+        })
+      }
+      fetchFail("http://example.not/")
+      fetchFail("https://example.not/test")
+      fetchFail("ftp://example.not/")
+      fetchFail("about:blank")
+      fetchFail("mailto:whatwg@awesome.example")
+      fetchFail("javascript:alert('FAIL')")
+    </script>
+    <!-- This tests "fails the connection" as well as making sure a simple
+         event is dispatched and not a MessageEvent -->
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-constructor-stringify.htm b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-stringify.htm
new file mode 100644
index 0000000..162fa34
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-stringify.htm
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: stringify argument</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      async_test(function (test) {
+        test.step(function() {
+          var source = new EventSource({toString:function(){return "resources/message.py";}})
+          source.onopen = function(e) {
+            test.step(function() {
+              assert_false(e.hasOwnProperty('data'))
+              source.close()
+              test.done()
+            })
+          }
+        });
+      }, document.title + ', object');
+
+      test(function(){
+        var source = new EventSource(1);
+        assert_regexp_match(source.url, /\/1$/);
+      }, document.title + ', 1');
+      test(function(){
+        var source = new EventSource(null);
+        assert_regexp_match(source.url, /\/null$/);
+      }, document.title + ', null');
+      test(function(){
+        var source = new EventSource(undefined);
+        assert_regexp_match(source.url, /\/undefined$/);
+      }, document.title + ', undefined');
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-constructor-url-bogus.htm b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-url-bogus.htm
new file mode 100644
index 0000000..8e769ed
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-url-bogus.htm
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: constructor (invalid URL)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      test(function() {
+        assert_throws("SyntaxError", function() { new EventSource("http://this is invalid/") })
+      })
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-constructor-url-multi-window.htm b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-url-multi-window.htm
new file mode 100644
index 0000000..99fecb9
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-constructor-url-multi-window.htm
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: resolving URLs</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      function init() {
+        test.step(function() {
+          source = new self[0].EventSource("message.py")
+          source.onopen = function(e) {
+            test.step(function() {
+              assert_equals(source.readyState, source.OPEN)
+              assert_false(e.hasOwnProperty('data'))
+              assert_false(e.bubbles)
+              assert_false(e.cancelable)
+              this.close()
+              test.done()
+            }, this)
+          }
+          source.onerror = function(e) {
+            test.step(function() {
+              assert_unreached()
+              source.close()
+              test.done()
+            })
+          }
+        })
+      }
+    </script>
+    <iframe src="resources/init.htm"></iframe>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-cross-origin.htm b/src/third_party/web_platform_tests/eventsource/eventsource-cross-origin.htm
new file mode 100644
index 0000000..b753bad
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-cross-origin.htm
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>EventSource: cross-origin</title>
+    <meta name=author title="Odin Hørthe Omdal" href="mailto:odiho@opera.com">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var crossdomain = location.href
+                    .replace('://', '://www2.')
+                    .replace(/\/[^\/]*$/, '/')
+
+      function doCORS(url, title) {
+        async_test(document.title + " " + title).step(function() {
+          var source = new EventSource(url, { withCredentials: true })
+          source.onmessage = this.step_func(function(e) {
+            assert_equals(e.data, "data")
+            source.close()
+            this.done()
+          })
+        })
+      }
+
+      doCORS(crossdomain + "resources/cors.py?run=message",
+        "basic use")
+      doCORS(crossdomain + "resources/cors.py?run=redirect&location=/eventsource/resources/cors.py?run=message",
+        "redirect use")
+      doCORS(crossdomain + "resources/cors.py?run=status-reconnect&status=200",
+        "redirect use recon")
+
+      function failCORS(url, title) {
+        async_test(document.title + " " + title).step(function() {
+          var source = new EventSource(url)
+          source.onerror = this.step_func(function(e) {
+            assert_equals(source.readyState, source.CLOSED, 'readyState')
+            assert_false(e.hasOwnProperty('data'))
+            source.close()
+            this.done()
+          })
+
+          /* Shouldn't happen */
+          source.onmessage = this.step_func(function(e) {
+            assert_unreached("shouldn't fire message event")
+          })
+          source.onopen = this.step_func(function(e) {
+            assert_unreached("shouldn't fire open event")
+          })
+        })
+      }
+
+      failCORS(crossdomain + "resources/cors.py?run=message&origin=http://example.org",
+        "allow-origin: http://example.org should fail")
+      failCORS(crossdomain + "resources/cors.py?run=message&origin=",
+        "allow-origin:'' should fail")
+      failCORS(crossdomain + "resources/message.py",
+        "No allow-origin should fail")
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-eventtarget.htm b/src/third_party/web_platform_tests/eventsource/eventsource-eventtarget.htm
new file mode 100644
index 0000000..6e600fc
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-eventtarget.htm
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: addEventListener()</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py")
+        source.addEventListener("message", listener, false)
+      })
+      function listener(e) {
+        test.step(function() {
+          assert_equals("data", e.data)
+          this.close()
+        }, this)
+        test.done()
+      }
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-onmessage.htm b/src/third_party/web_platform_tests/eventsource/eventsource-onmessage.htm
new file mode 100644
index 0000000..b683ebc
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-onmessage.htm
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: onmessage</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals("data", e.data)
+            source.close()
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-onopen.htm b/src/third_party/web_platform_tests/eventsource/eventsource-onopen.htm
new file mode 100644
index 0000000..1c9bfe0
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-onopen.htm
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: onopen (announcing the connection)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        source = new EventSource("resources/message.py")
+        source.onopen = function(e) {
+          test.step(function() {
+            assert_equals(source.readyState, source.OPEN)
+            assert_false(e.hasOwnProperty('data'))
+            assert_false(e.bubbles)
+            assert_false(e.cancelable)
+            this.close()
+          }, this)
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-prototype.htm b/src/third_party/web_platform_tests/eventsource/eventsource-prototype.htm
new file mode 100644
index 0000000..38f63eb
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-prototype.htm
@@ -0,0 +1,21 @@
+<!DoCtYpE hTMl>
+<html>
+  <heAd>
+    <title>EventSource: prototype et al</tiTle>
+    <scrIpt src="/resources/testharness.js"></scripT>
+    <scriPt src="/resources/testharnessreport.js"></Script>
+  </heaD>
+  <boDy>
+    <diV iD="log"></Div>
+    <sCript>
+      test(function() {
+        EventSource.prototype.ReturnTrue = function() { return true }
+        var source = new EventSource("resources/message.py")
+        assert_true(source.ReturnTrue())
+        assert_exists(window, "EventSource")
+        source.close()
+      })
+    </scrIpt>
+  </bOdy>
+</htMl>
+
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-reconnect.htm b/src/third_party/web_platform_tests/eventsource/eventsource-reconnect.htm
new file mode 100644
index 0000000..a23885f
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-reconnect.htm
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: reconnection</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      function doReconn(url, title) {
+        var test = async_test(document.title + " " + title)
+        test.step(function() {
+          var source = new EventSource(url)
+          source.onmessage = test.step_func(function(e) {
+            assert_equals(e.data, "data")
+            source.close()
+            test.done()
+          })
+        })
+      }
+
+      doReconn("resources/status-reconnect.py?status=200",
+        "200")
+
+
+      var t = async_test(document.title + ", test reconnection events", { timeout: 9000 });
+      t.step(function() {
+        var opened = false, reconnected = false,
+            source = new EventSource("resources/status-reconnect.py?status=200&ok_first&id=2");
+
+        source.onerror = t.step_func(function(e) {
+          assert_equals(e.type, 'error');
+          assert_equals(source.readyState, source.CONNECTING, "readyState");
+          assert_true(opened, "connection is opened earlier");
+
+          reconnected = true;
+        });
+
+        source.onmessage = t.step_func(function(e) {
+          if (!opened) {
+            opened = true;
+            assert_false(reconnected, "have reconnected before first message");
+            assert_equals(e.data, "ok");
+          }
+          else {
+            assert_true(reconnected, "Got reconnection event");
+            assert_equals(e.data, "data");
+            source.close()
+            t.done()
+          }
+        });
+      });
+
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-request-cancellation.htm b/src/third_party/web_platform_tests/eventsource/eventsource-request-cancellation.htm
new file mode 100644
index 0000000..308e4d5
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-request-cancellation.htm
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: request cancellation</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var t = async_test();
+      onload = t.step_func(function() {
+        var url = "resources/message.py?sleep=1000&message=" + encodeURIComponent("retry:1000\ndata:abc\n\n");
+        var es = new EventSource(url);
+        es.onerror = t.step_func(function() {
+          assert_equals(es.readyState, EventSource.CLOSED)
+          setTimeout(t.step_func(function () {
+            assert_equals(es.readyState, EventSource.CLOSED,
+                          "After stopping the eventsource readyState should be CLOSED")
+            t.done();
+          }), 1000);
+        });
+
+        setTimeout(t.step_func(function() {
+          window.stop()
+          es.onopen = t.unreached_func("Got open event");
+          es.onmessage = t.unreached_func("Got message after closing source");
+        }), 0);
+      });
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/eventsource-url.htm b/src/third_party/web_platform_tests/eventsource/eventsource-url.htm
new file mode 100644
index 0000000..8b9262b
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/eventsource-url.htm
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: url</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      test(function() {
+        var url = "resources/message.py",
+            source = new EventSource(url)
+        assert_equals(source.url.substr(-(url.length)), url)
+        source.close()
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-bom-2.htm b/src/third_party/web_platform_tests/eventsource/format-bom-2.htm
new file mode 100644
index 0000000..6f267a0
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-bom-2.htm
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: Double BOM</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test(),
+          hasbeenone = false,
+          hasbeentwo = false
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=%EF%BB%BF%EF%BB%BFdata%3A1%0A%0Adata%3A2%0A%0Adata%3A3")
+        source.addEventListener("message", listener, false)
+      })
+      function listener(e) {
+        test.step(function() {
+          if(e.data == "1")
+            hasbeenone = true
+          if(e.data == "2")
+            hasbeentwo = true
+          if(e.data == "3") {
+            assert_false(hasbeenone)
+            assert_true(hasbeentwo)
+            this.close()
+            test.done()
+          }
+        }, this)
+      }
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-bom.htm b/src/third_party/web_platform_tests/eventsource/format-bom.htm
new file mode 100644
index 0000000..9216022
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-bom.htm
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: BOM</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test(),
+          hasbeenone = false,
+          hasbeentwo = false
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=%EF%BB%BFdata%3A1%0A%0A%EF%BB%BFdata%3A2%0A%0Adata%3A3")
+        source.addEventListener("message", listener, false)
+      })
+      function listener(e) {
+        test.step(function() {
+          if(e.data == "1")
+            hasbeenone = true
+          if(e.data == "2")
+            hasbeentwo = true
+          if(e.data == "3") {
+            assert_true(hasbeenone)
+            assert_false(hasbeentwo)
+            this.close()
+            test.done()
+          }
+        }, this)
+      }
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-comments.htm b/src/third_party/web_platform_tests/eventsource/format-comments.htm
new file mode 100644
index 0000000..fde360d
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-comments.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: comment fest</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var longstring = (new Array(2*1024+1)).join("x"), // cannot make the string too long; causes timeout
+            message = encodeURI("data:1\r:\0\n:\r\ndata:2\n:" + longstring + "\rdata:3\n:data:fail\r:" + longstring + "\ndata:4\n"),
+            source = new EventSource("resources/message.py?message=" + message + "&newline=none")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals("1\n2\n3\n4", e.data)
+            source.close()
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-data-before-final-empty-line.htm b/src/third_party/web_platform_tests/eventsource/format-data-before-final-empty-line.htm
new file mode 100644
index 0000000..e429d7f
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-data-before-final-empty-line.htm
@@ -0,0 +1,29 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: a data before final empty line</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?newline=none&message=" + encodeURIComponent("retry:1000\ndata:test1\n\nid:test\ndata:test2"))
+        var count = 0;
+        source.onmessage = function(e) {
+          if (++count === 2) {
+            test.step(function() {
+              assert_equals(e.lastEventId, "", "lastEventId")
+              assert_equals(e.data, "test1", "data")
+              source.close()
+            })
+            test.done()
+          }
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-data.htm b/src/third_party/web_platform_tests/eventsource/format-field-data.htm
new file mode 100644
index 0000000..a731355
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-data.htm
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: data field parsing</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=data%3A%0A%0Adata%0Adata%0A%0Adata%3Atest"),
+        counter = 0
+        source.onmessage = function(e) {
+          test.step(function() {
+            if(counter == 0) {
+              assert_equals("", e.data)
+            } else if(counter == 1) {
+              assert_equals("\n", e.data)
+            } else if(counter == 2) {
+              assert_equals("test", e.data)
+              source.close()
+              test.done()
+            } else {
+              assert_unreached()
+            }
+            counter++
+          })
+        }
+      })
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-event-empty.htm b/src/third_party/web_platform_tests/eventsource/format-field-event-empty.htm
new file mode 100644
index 0000000..20a6d6d
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-event-empty.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: empty "event" field</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=event%3A%20%0Adata%3Adata")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals("data", e.data)
+            this.close()
+          }, this)
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-event.htm b/src/third_party/web_platform_tests/eventsource/format-field-event.htm
new file mode 100644
index 0000000..3c3267f
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-event.htm
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: custom event name</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test(),
+          dispatchedtest = false
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=event%3Atest%0Adata%3Ax%0A%0Adata%3Ax")
+        source.addEventListener("test", function() { test.step(function() { dispatchedtest = true }) }, false)
+        source.onmessage = function() {
+          test.step(function() {
+            assert_true(dispatchedtest)
+            this.close()
+          }, this)
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-id-2.htm b/src/third_party/web_platform_tests/eventsource/format-field-id-2.htm
new file mode 100644
index 0000000..ac521fc
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-id-2.htm
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>EventSource: Last-Event-ID (2)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/last-event-id.py"),
+            counter = 0
+        source.onmessage = function(e) {
+          test.step(function() {
+            if(e.data == "hello" && counter == 0) {
+              counter++
+              assert_equals(e.lastEventId, "…")
+            } else if(counter == 1) {
+              counter++
+              assert_equals("…", e.data)
+              assert_equals("…", e.lastEventId)
+            } else if(counter == 2) {
+              counter++
+              assert_equals("…", e.data)
+              assert_equals("…", e.lastEventId)
+              source.close()
+              test.done()
+            } else
+              assert_unreached()
+          })
+        }
+      })
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-id.htm b/src/third_party/web_platform_tests/eventsource/format-field-id.htm
new file mode 100644
index 0000000..19ada95
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-id.htm
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>EventSource: Last-Event-ID</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/last-event-id.py"),
+            seenhello = false
+        source.onmessage = function(e) {
+          test.step(function() {
+            if(e.data == "hello" && !seenhello) {
+              seenhello = true
+              assert_equals(e.lastEventId, "…")
+            } else if(seenhello) {
+              assert_equals("…", e.data)
+              assert_equals("…", e.lastEventId)
+              source.close()
+              test.done()
+            } else
+              assert_unreached()
+          })
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-parsing.htm b/src/third_party/web_platform_tests/eventsource/format-field-parsing.htm
new file mode 100644
index 0000000..da22176
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-parsing.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: field parsing</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var message = encodeURI("data:\0\ndata:  2\rData:1\ndata\0:2\ndata:1\r\0data:4\nda-ta:3\rdata_5\ndata:3\rdata:\r\n data:32\ndata:4\n"),
+            source = new EventSource("resources/message.py?message=" + message + "&newline=none")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals(e.data, "\0\n 2\n1\n3\n\n4")
+            source.close()
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-retry-bogus.htm b/src/third_party/web_platform_tests/eventsource/format-field-retry-bogus.htm
new file mode 100644
index 0000000..0cdf9b4
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-retry-bogus.htm
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: "retry" field (bogus)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test(document.title)
+      test.step(function() {
+        var timeoutms = 3000,
+            source = new EventSource("resources/message.py?message=retry%3A3000%0Aretry%3A1000x%0Adata%3Ax"),
+            opened = 0
+        source.onopen = function() {
+          test.step(function() {
+            if(opened == 0)
+              opened = new Date().getTime()
+            else {
+              var diff = (new Date().getTime()) - opened
+              assert_true(Math.abs(1 - diff / timeoutms) < 0.25) // allow 25% difference
+              this.close();
+              test.done()
+            }
+          }, this)
+        }
+      })
+    </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-retry-empty.htm b/src/third_party/web_platform_tests/eventsource/format-field-retry-empty.htm
new file mode 100644
index 0000000..2757486
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-retry-empty.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: empty retry field</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=retry%0Adata%3Atest")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals("test", e.data)
+            source.close()
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-retry.htm b/src/third_party/web_platform_tests/eventsource/format-field-retry.htm
new file mode 100644
index 0000000..133794f
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-retry.htm
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: "retry" field</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test(document.title);
+      test.step(function() {
+        var timeoutms = 3000,
+            timeoutstr = "03000", // 1536 in octal, but should be 3000
+            source = new EventSource("resources/message.py?message=retry%3A" + timeoutstr + "%0Adata%3Ax"),
+            opened = 0
+        source.onopen = function() {
+          test.step(function() {
+            if(opened == 0)
+              opened = new Date().getTime()
+            else {
+              var diff = (new Date().getTime()) - opened
+              assert_true(Math.abs(1 - diff / timeoutms) < 0.25) // allow 25% difference
+              this.close();
+              test.done()
+            }
+          }, this)
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-field-unknown.htm b/src/third_party/web_platform_tests/eventsource/format-field-unknown.htm
new file mode 100644
index 0000000..3b6efd54
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-field-unknown.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: unknown fields and parsing fun</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=data%3Atest%0A%20data%0Adata%0Afoobar%3Axxx%0Ajustsometext%0A%3Athisisacommentyay%0Adata%3Atest")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals("test\n\ntest", e.data)
+            source.close()
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-leading-space.htm b/src/third_party/web_platform_tests/eventsource/format-leading-space.htm
new file mode 100644
index 0000000..b70ba89
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-leading-space.htm
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: leading space</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=data%3A%09test%0Ddata%3A%20%0Adata%3Atest")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals("\ttest\n\ntest", e.data)
+            source.close()
+          })
+          test.done()
+        }
+      })
+    </script>
+    <!-- also used a CR as newline once -->
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-mime-bogus.htm b/src/third_party/web_platform_tests/eventsource/format-mime-bogus.htm
new file mode 100644
index 0000000..caf9cb4
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-mime-bogus.htm
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: bogus MIME type</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?mime=x%20bogus")
+        source.onmessage = function() {
+          test.step(function() {
+            assert_unreached()
+            source.close()
+          })
+          test.done()
+        }
+        source.onerror = function(e) {
+          test.step(function() {
+            assert_equals(this.readyState, this.CLOSED)
+            assert_false(e.hasOwnProperty('data'))
+            assert_false(e.bubbles)
+            assert_false(e.cancelable)
+            this.close()
+          }, this)
+          test.done()
+        }
+      })
+    </script>
+    <!-- This tests "fails the connection" as well as making sure a simple
+         event is dispatched and not a MessageEvent -->
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-mime-trailing-semicolon.htm b/src/third_party/web_platform_tests/eventsource/format-mime-trailing-semicolon.htm
new file mode 100644
index 0000000..6bcac83
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-mime-trailing-semicolon.htm
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: MIME type with trailing ;</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?mime=text/event-stream%3B")
+        source.onopen = function() {
+          test.step(function() {
+            assert_equals(source.readyState, source.OPEN)
+            source.close()
+          })
+          test.done()
+        }
+        source.onerror = function() {
+          test.step(function() {
+            assert_unreached()
+            source.close()
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-mime-valid-bogus.htm b/src/third_party/web_platform_tests/eventsource/format-mime-valid-bogus.htm
new file mode 100644
index 0000000..211f841
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-mime-valid-bogus.htm
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: incorrect valid MIME type</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?mime=text/x-bogus")
+        source.onmessage = function() {
+          test.step(function() {
+            assert_unreached()
+            source.close()
+          })
+          test.done()
+        }
+        source.onerror = function(e) {
+          test.step(function() {
+            assert_equals(source.readyState, source.CLOSED)
+            assert_false(e.hasOwnProperty('data'))
+            assert_false(e.bubbles)
+            assert_false(e.cancelable)
+          })
+          test.done()
+        }
+      })
+    </script>
+    <!-- This tests "fails the connection" as well as making sure a simple
+         event is dispatched and not a MessageEvent -->
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-newlines.htm b/src/third_party/web_platform_tests/eventsource/format-newlines.htm
new file mode 100644
index 0000000..87d6a56
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-newlines.htm
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+  <head>
+    <title>EventSource: newline fest</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=data%3Atest%0D%0Adata%0Adata%3Atest%0D%0A%0D&newline=none")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals("test\n\ntest", e.data)
+            source.close()
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-null-character.html b/src/third_party/web_platform_tests/eventsource/format-null-character.html
new file mode 100644
index 0000000..0640530
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-null-character.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>EventSource: null character in response</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/message.py?message=data%3A%00%0A%0A")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals("\x00", e.data)
+            source.close()
+          }, this)
+          test.done()
+        }
+        source.onerror = function() {
+          test.step(function() { assert_unreached() })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/format-utf-8.htm b/src/third_party/web_platform_tests/eventsource/format-utf-8.htm
new file mode 100644
index 0000000..d7858a1
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/format-utf-8.htm
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>EventSource: always UTF-8</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      async_test().step(function() {
+        var source = new EventSource("resources/message.py?mime=text/event-stream;charset=windows-1252&message=data%3Aok%E2%80%A6")
+        source.onmessage = this.step_func(function(e) {
+          assert_equals('ok…', e.data, 'decoded data')
+          source.close()
+          this.done()
+        })
+        source.onerror = this.step_func(function() {
+          assert_unreached("Got error event")
+        })
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/interfaces.html b/src/third_party/web_platform_tests/eventsource/interfaces.html
new file mode 100644
index 0000000..8c3cc90
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/interfaces.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<title>EventSource IDL tests</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/WebIDLParser.js></script>
+<script src=/resources/idlharness.js></script>
+
+<h1>EventSource IDL tests</h1>
+<div id=log></div>
+
+<script type=text/plain>
+[Constructor(DOMString url, optional EventSourceInit eventSourceInitDict)]
+interface EventSource : EventTarget {
+  readonly attribute DOMString url;
+  readonly attribute boolean withCredentials;
+
+  // ready state
+  const unsigned short CONNECTING = 0;
+  const unsigned short OPEN = 1;
+  const unsigned short CLOSED = 2;
+  readonly attribute unsigned short readyState;
+
+  // networking
+           attribute EventHandler onopen;
+           attribute EventHandler onmessage;
+           attribute EventHandler onerror;
+  void close();
+};
+
+dictionary EventSourceInit {
+  boolean withCredentials = false;
+};
+
+[TreatNonCallableAsNull]
+callback EventHandlerNonNull = any (Event event);
+typedef EventHandlerNonNull? EventHandler;
+</script>
+<script>
+"use strict";
+var idlArray;
+setup(function() {
+  idlArray = new IdlArray();
+  [].forEach.call(document.querySelectorAll("script[type=text\\/plain]"), function(node) {
+    if (node.className == "untested") {
+      idlArray.add_untested_idls(node.textContent);
+    } else {
+      idlArray.add_idls(node.textContent);
+    }
+  });
+}, {explicit_done:true});
+window.onload = function() {
+  idlArray.add_objects({
+    EventSource: ['new EventSource("http://foo")'],
+  });
+  idlArray.test();
+  done();
+};
+</script>
diff --git a/src/third_party/web_platform_tests/eventsource/request-accept.htm b/src/third_party/web_platform_tests/eventsource/request-accept.htm
new file mode 100644
index 0000000..6032cb6
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/request-accept.htm
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: Accept header</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var source = new EventSource("resources/accept.event_stream?pipe=sub")
+        source.onmessage = function(e) {
+          test.step(function() {
+            assert_equals(e.data, "text/event-stream")
+            this.close()
+          }, this)
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/request-cache-control.htm b/src/third_party/web_platform_tests/eventsource/request-cache-control.htm
new file mode 100644
index 0000000..b396592
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/request-cache-control.htm
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: Cache-Control</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var crossdomain = location.href
+                    .replace('://', '://www2.')
+                    .replace(/\/[^\/]*$/, '/')
+
+      // running it twice to check whether it stays consistent
+      function cacheTest(runAgain, url) {
+        var test = async_test()
+        test.step(function() {
+          var source = new EventSource(url)
+          source.onmessage = function(e) {
+            test.step(function() {
+              assert_equals(e.data, "no-cache")
+              this.close()
+              if(runAgain)
+                cacheTest(false, url) // this nests tests
+            }, this)
+            test.done()
+          }
+        })
+      }
+
+      cacheTest(true, "resources/cache-control.event_stream?pipe=sub")
+      cacheTest(true, crossdomain + "resources/cors.py?run=cache-control")
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/request-credentials.htm b/src/third_party/web_platform_tests/eventsource/request-credentials.htm
new file mode 100644
index 0000000..c3c178a
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/request-credentials.htm
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: credentials</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var crossdomain = location.href
+                    .replace('://', '://www2.')
+                    .replace(/\/[^\/]*$/, '/')
+
+      function testCookie(desc, success, props, id) {
+        var test = async_test(document.title + ': credentials ' + desc)
+        test.step(function() {
+          var source = new EventSource(crossdomain + "resources/cors-cookie.py?ident=" + id, props)
+
+          source.onmessage = test.step_func(function(e) {
+            if(e.data.indexOf("first") == 0) {
+              assert_equals(e.data, "first NO_COOKIE", "cookie status")
+            }
+            else if(e.data.indexOf("second") == 0) {
+              if (success)
+                assert_equals(e.data, "second COOKIE", "cookie status")
+              else
+                assert_equals(e.data, "second NO_COOKIE", "cookie status")
+
+              source.close()
+              test.done()
+            }
+            else {
+              assert_unreached("unrecognized data returned: " + e.data)
+              source.close()
+              test.done()
+            }
+          })
+        })
+      }
+
+      testCookie('enabled',  true,  { withCredentials: true  }, '1_' + new Date().getTime())
+      testCookie('disabled', false, { withCredentials: false }, '2_' + new Date().getTime())
+      testCookie('default',  false, { },                        '3_' + new Date().getTime())
+
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/request-redirect.htm b/src/third_party/web_platform_tests/eventsource/request-redirect.htm
new file mode 100644
index 0000000..794c878
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/request-redirect.htm
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: redirect</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      function redirectTest(status) {
+        var test = async_test(document.title + " (" + status +")")
+        test.step(function() {
+          var source = new EventSource("/common/redirect.py?location=/eventsource/resources/message.py&status=" + status)
+          source.onopen = function() {
+            test.step(function() {
+              assert_equals(this.readyState, this.OPEN)
+              this.close()
+            }, this)
+            test.done()
+          }
+          source.onerror = function() {
+            test.step(function() { assert_unreached() })
+            test.done()
+          }
+        })
+      }
+
+      redirectTest("301")
+      redirectTest("302")
+      redirectTest("303")
+      redirectTest("307")
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/request-status-error.htm b/src/third_party/web_platform_tests/eventsource/request-status-error.htm
new file mode 100644
index 0000000..d881a4d
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/request-status-error.htm
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>EventSource: incorrect HTTP status code</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      function statusTest(status) {
+        var test = async_test(document.title + " (" + status +")")
+        test.step(function() {
+          var source = new EventSource("resources/status-error.py?status=" + status)
+          source.onmessage = function() {
+            test.step(function() {
+              assert_unreached()
+            })
+            test.done()
+          }
+          source.onerror = function() {
+            test.step(function() {
+              assert_equals(this.readyState, this.CLOSED)
+            }, this)
+            test.done()
+          }
+        })
+      }
+      statusTest("204")
+      statusTest("205")
+      statusTest("210")
+      statusTest("299")
+      statusTest("404")
+      statusTest("410")
+      statusTest("503")
+    </script>
+  </body>
+</html>
+
diff --git a/src/third_party/web_platform_tests/eventsource/resources/accept.event_stream b/src/third_party/web_platform_tests/eventsource/resources/accept.event_stream
new file mode 100644
index 0000000..24da548
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/accept.event_stream
@@ -0,0 +1,2 @@
+data: {{headers[accept]}}
+
diff --git a/src/third_party/web_platform_tests/eventsource/resources/cache-control.event_stream b/src/third_party/web_platform_tests/eventsource/resources/cache-control.event_stream
new file mode 100644
index 0000000..aa9f2d6
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/cache-control.event_stream
@@ -0,0 +1,2 @@
+data: {{headers[cache-control]}}
+
diff --git a/src/third_party/web_platform_tests/eventsource/resources/cors-cookie.py b/src/third_party/web_platform_tests/eventsource/resources/cors-cookie.py
new file mode 100644
index 0000000..7deaff4
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/cors-cookie.py
@@ -0,0 +1,31 @@
+from datetime import datetime
+
+def main(request, response):
+    last_event_id = request.headers.get("Last-Event-Id", "")
+    ident = request.GET.first('ident', "test")
+    cookie = "COOKIE" if ident in request.cookies else "NO_COOKIE"
+    origin = request.GET.first('origin', request.headers["origin"])
+    credentials = request.GET.first('credentials', 'true')
+
+    headers = []
+
+    if origin != 'none':
+        headers.append(("Access-Control-Allow-Origin", origin));
+
+    if credentials != 'none':
+        headers.append(("Access-Control-Allow-Credentials", credentials));
+
+    if last_event_id == '':
+        headers.append(("Content-Type", "text/event-stream"))
+        response.set_cookie(ident, "COOKIE")
+        data = "id: 1\nretry: 200\ndata: first %s\n\n" % cookie
+    elif last_event_id == '1':
+        headers.append(("Content-Type", "text/event-stream"))
+        long_long_time_ago = datetime.now().replace(year=2001, month=7, day=27)
+        response.set_cookie(ident, "COOKIE", expires=long_long_time_ago)
+        data = "id: 2\ndata: second %s\n\n" % cookie
+    else:
+        headers.append(("Content-Type", "stop"))
+        data = "data: " + last_event_id + cookie + "\n\n";
+
+    return headers, data
diff --git a/src/third_party/web_platform_tests/eventsource/resources/cors.py b/src/third_party/web_platform_tests/eventsource/resources/cors.py
new file mode 100644
index 0000000..8be8052
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/cors.py
@@ -0,0 +1,34 @@
+import os
+from wptserve import pipes
+
+def run_other(request, response, path):
+    #This is a terrible hack
+    environ = {"__file__": path}
+    execfile(path, environ, environ)
+    rv = environ["main"](request, response)
+    return rv
+
+def main(request, response):
+    origin = request.GET.first("origin", request.headers["origin"])
+    credentials = request.GET.first("credentials", "true")
+
+    response.headers.update([("Access-Control-Allow-Origin", origin),
+                             ("Access-Control-Allow-Credentials", credentials)])
+
+    handler = request.GET.first('run')
+    if handler in ["status-reconnect",
+                   "message",
+                   "redirect",
+                   "cache-control"]:
+        if handler == "cache-control":
+            response.headers.set("Content-Type", "text/event-stream")
+            rv = open(os.path.join(request.doc_root, "eventsource", "resources", "cache-control.event_stream")).read()
+            response.content = rv
+            pipes.sub(request, response)
+            return
+        elif handler == "redirect":
+            return run_other(request, response, os.path.join(request.doc_root, "common", "redirect.py"))
+        else:
+            return run_other(request, response, os.path.join(os.path.split(__file__)[0], handler + ".py"))
+    else:
+        return
diff --git a/src/third_party/web_platform_tests/eventsource/resources/init.htm b/src/third_party/web_platform_tests/eventsource/resources/init.htm
new file mode 100644
index 0000000..7c56d88
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/init.htm
@@ -0,0 +1,9 @@
+<!doctype html>
+<html>
+  <head>
+    <title>support init file</title>
+  </head>
+  <body>
+    <script> parent.init() </script>
+  </body>
+</html>
diff --git a/src/third_party/web_platform_tests/eventsource/resources/last-event-id.py b/src/third_party/web_platform_tests/eventsource/resources/last-event-id.py
new file mode 100644
index 0000000..4306fba
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/last-event-id.py
@@ -0,0 +1,11 @@
+ # -*- coding: utf-8 -*-
+
+def main(request, response):
+  response.headers.set("Content-Type", "text/event-stream")
+  last_event_id = request.headers.get('Last-Event-ID', None)
+
+  if(last_event_id):
+      return "data: " + last_event_id + "\n\n"
+  else:
+    return "id: …\nretry: 200\ndata: hello\n\n"
+
diff --git a/src/third_party/web_platform_tests/eventsource/resources/message.py b/src/third_party/web_platform_tests/eventsource/resources/message.py
new file mode 100644
index 0000000..6d04b1f
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/message.py
@@ -0,0 +1,14 @@
+import time
+
+def main(request, response):
+    mime = request.GET.first("mime", "text/event-stream")
+    message = request.GET.first("message", "data: data");
+    newline = "" if request.GET.first("newline", None) == "none" else "\n\n";
+    sleep = int(request.GET.first("sleep", "0"))
+
+    headers = [("Content-Type", mime)]
+    body = message + newline + "\n"
+    if sleep != 0:
+        time.sleep(sleep/1000)
+
+    return headers, body
diff --git a/src/third_party/web_platform_tests/eventsource/resources/message2.py b/src/third_party/web_platform_tests/eventsource/resources/message2.py
new file mode 100644
index 0000000..ce339d9
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/message2.py
@@ -0,0 +1,35 @@
+import time
+
+def main(request, response):
+    response.headers.set('Content-Type', 'text/event-stream')
+    response.headers.set('Cache-Control', 'no-cache')
+
+    response.explicit_flush = True
+    response.write_status_headers()
+
+    while True:
+        response.writer.write("data:msg")
+        response.writer.write("\n")
+        response.writer.write("data: msg")
+        response.writer.write("\n\n")
+
+        response.writer.write(":")
+        response.writer.write("\n")
+
+        response.writer.write("falsefield:msg")
+        response.writer.write("\n\n")
+
+        response.writer.write("falsefield:msg")
+        response.writer.write("\n")
+
+        response.writer.write("Data:data")
+        response.writer.write("\n\n")
+
+        response.writer.write("data")
+        response.writer.write("\n\n")
+
+        response.writer.write("data:end")
+        response.writer.write("\n\n")
+
+        response.writer.flush()
+        time.sleep(2)
diff --git a/src/third_party/web_platform_tests/eventsource/resources/reconnect-fail.py b/src/third_party/web_platform_tests/eventsource/resources/reconnect-fail.py
new file mode 100644
index 0000000..80a247d
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/reconnect-fail.py
@@ -0,0 +1,24 @@
+def main(request, response):
+    name = "recon_fail_" + request.GET.first("id")
+
+    headers = [("Content-Type", "text/event-stream")]
+    cookie = request.cookies.first(name, None)
+    state = cookie.value if cookie is not None else None
+
+    if state == 'opened':
+        status = (200, "RECONNECT")
+        response.set_cookie(name, "reconnected");
+        body = "data: reconnected\n\n";
+
+    elif state == 'reconnected':
+        status = (204, "NO CONTENT (CLOSE)")
+        response.delete_cookie(name);
+        body = "data: closed\n\n" # Will never get through
+
+    else:
+        status = (200, "OPEN");
+        response.set_cookie(name, "opened");
+        body = "retry: 2\ndata: opened\n\n";
+
+    return status, headers, body
+
diff --git a/src/third_party/web_platform_tests/eventsource/resources/status-error.py b/src/third_party/web_platform_tests/eventsource/resources/status-error.py
new file mode 100644
index 0000000..8aa230c
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/status-error.py
@@ -0,0 +1,4 @@
+def main(request, response):
+  status = (request.GET.first("status", "404"), "HAHAHAHA")
+  headers = [("Content-Type", "text/event-stream")]
+  return status, headers, "data: data\n\n"
diff --git a/src/third_party/web_platform_tests/eventsource/resources/status-reconnect.py b/src/third_party/web_platform_tests/eventsource/resources/status-reconnect.py
new file mode 100644
index 0000000..16c6502
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/resources/status-reconnect.py
@@ -0,0 +1,21 @@
+def main(request, response):
+    status_code = request.GET.first("status", "204")
+    name = request.GET.first("id", status_code)
+
+    headers = [("Content-Type", "text/event-stream")]
+
+    cookie_name = "request" + name
+
+    if request.cookies.first(cookie_name, "") == status_code:
+        status = 200
+        response.delete_cookie(cookie_name)
+        body = "data: data\n\n"
+    else:
+        response.set_cookie(cookie_name, status_code);
+        status = (int(status_code), "TEST")
+        body = "retry: 2\n"
+        if "ok_first" in request.GET:
+            body += "data: ok\n\n"
+
+    return status, headers, body
+
diff --git a/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-close.htm b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-close.htm
new file mode 100644
index 0000000..0a0bdc7
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-close.htm
@@ -0,0 +1,39 @@
+<!--
+onconnect = function(e) {
+try {
+  var port = e.ports[0]
+  var source = new EventSource("../resources/message.py")
+  source.onopen = function(e) {
+    this.close()
+    port.postMessage([true, this.readyState])
+  }
+} catch(e) {
+  port.postMessage([false, String(e)])
+}
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>shared worker - EventSource: close()</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test();
+      test.step(function() {
+        var worker = new SharedWorker('#')
+        worker.port.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], EventSource.CLOSED, 'this.readyState')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.htm b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.htm
new file mode 100644
index 0000000..277fbd4
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-constructor-non-same-origin.htm
@@ -0,0 +1,52 @@
+<!--
+onconnect = function(e) {
+try {
+  var port = e.ports[0]
+  var url = decodeURIComponent(location.hash.substr(1))
+  var source = new EventSource(url)
+  source.onerror = function(e) {
+    port.postMessage([true, this.readyState, 'data' in e])
+    this.close();
+  }
+} catch(e) {
+  port.postMessage([false, String(e)])
+}
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>shared worker - EventSource: constructor (act as if there is a network error)</title>
+    <meta name=timeout content=long>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      function fetchFail(url) {
+        var test = async_test(document.title + " (" + url + ")", { timeout: 20000 })
+        test.step(function() {
+          var worker = new SharedWorker('#'+encodeURIComponent(url))
+          worker.port.onmessage = function(e) {
+            test.step(function() {
+              assert_true(e.data[0], e.data[1])
+              assert_equals(e.data[1], EventSource.CLOSED, 'source.readyState')
+              assert_false(e.data[2], "'data' in e");
+            })
+            test.done()
+          }
+        })
+      }
+      fetchFail("http://example.not")
+      fetchFail("https://example.not/test")
+      fetchFail("ftp://example.not")
+      fetchFail("about:blank")
+      fetchFail("mailto:whatwg@awesome.example")
+      fetchFail("javascript:alert('FAIL')")
+    </script>
+    <!-- This tests "fails the connection" as well as making sure a simple
+         event is dispatched and not a MessageEvent -->
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-constructor-url-bogus.htm b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-constructor-url-bogus.htm
new file mode 100644
index 0000000..88fa21e
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-constructor-url-bogus.htm
@@ -0,0 +1,37 @@
+<!--
+onconnect = function(e) {
+try {
+  var port = e.ports[0]
+  var source = new EventSource("http://this is invalid/")
+  port.postMessage([false, 'no exception thrown'])
+  source.close()
+} catch(e) {
+  port.postMessage([true, e.code])
+}
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>shared worker - EventSource: constructor (invalid URL)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var worker = new SharedWorker('#')
+        worker.port.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], DOMException.SYNTAX_ERR, 'e.code')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
\ No newline at end of file
diff --git a/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-eventtarget.htm b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-eventtarget.htm
new file mode 100644
index 0000000..f5f9439
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-eventtarget.htm
@@ -0,0 +1,40 @@
+<!--
+onconnect = function(e) {
+try {
+  var port = e.ports[0]
+  var source = new EventSource("../resources/message.py")
+  source.addEventListener("message", listener, false)
+  function listener(e) {
+    port.postMessage([true, e.data])
+    this.close()
+  }
+} catch(e) {
+  port.postMessage([false, String(e)])
+}
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>shared worker - EventSource: addEventListener()</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var worker = new SharedWorker('#')
+        worker.port.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], 'data', 'e.data')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-onmesage.htm b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-onmesage.htm
new file mode 100644
index 0000000..82c3ce7
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-onmesage.htm
@@ -0,0 +1,39 @@
+<!--
+onconnect = function(e) {
+try {
+  var port = e.ports[0]
+  var source = new EventSource("../resources/message.py")
+  source.onmessage = function(e) {
+    port.postMessage([true, e.data])
+    this.close()
+  }
+} catch(e) {
+  port.postMessage([false, String(e)])
+}
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>shared worker - EventSource: onmessage</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var worker = new SharedWorker('#')
+        worker.port.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], "data", 'e.data')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-onopen.htm b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-onopen.htm
new file mode 100644
index 0000000..2546781
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-onopen.htm
@@ -0,0 +1,42 @@
+<!--
+onconnect = function(e) {
+try {
+  var port = e.ports[0]
+  var source = new EventSource("../resources/message.py")
+  source.onopen = function(e) {
+    port.postMessage([true, source.readyState, 'data' in e, e.bubbles, e.cancelable])
+    this.close()
+  }
+} catch(e) {
+  port.postMessage([false, String(e)])
+}
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>shared worker - EventSource: onopen (announcing the connection)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test()
+      test.step(function() {
+        var worker = new SharedWorker('#')
+        worker.port.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_equals(e.data[1], EventSource.OPEN, 'source.readyState')
+            assert_false(e.data[2], "'data' in e")
+            assert_false(e.data[3], 'e.bubbles')
+            assert_false(e.data[4], 'e.calcelable')
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-prototype.htm b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-prototype.htm
new file mode 100644
index 0000000..27d51a8
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-prototype.htm
@@ -0,0 +1,39 @@
+<!--
+onconnect = function(e) {
+try {
+  var port = e.ports[0]
+  EventSource.prototype.ReturnTrue = function() { return true }
+  var source = new EventSource("../resources/message.py")
+  port.postMessage([true, source.ReturnTrue(), 'EventSource' in self])
+  source.close()
+} catch(e) {
+  port.postMessage([false, String(e)])
+}
+}
+/*-->
+<!DoCtYpE hTMl>
+<html>
+  <heAd>
+    <title>shared worker - EventSource: prototype et al</tiTle>
+    <scrIpt src="/resources/testharness.js"></scripT>
+    <scriPt src="/resources/testharnessreport.js"></Script>
+  </heaD>
+  <boDy>
+    <diV iD="log"></Div>
+    <sCript>
+      var test = async_test();
+      test.step(function() {
+        var worker = new SharedWorker('#')
+        worker.port.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1])
+            assert_true(e.data[1], 'source.ReturnTrue()')
+            assert_true(e.data[2], "'EventSource' in self")
+          })
+          test.done()
+        }
+      })
+    </scrIpt>
+  </bOdy>
+</htMl>
+<!--*/ //-->
diff --git a/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-url.htm b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-url.htm
new file mode 100644
index 0000000..0491085
--- /dev/null
+++ b/src/third_party/web_platform_tests/eventsource/shared-worker/eventsource-url.htm
@@ -0,0 +1,38 @@
+<!--
+onconnect = function(e) {
+try {
+  var port = e.ports[0]
+  var source = new EventSource("../resources/message.py")
+  port.postMessage([true, source.url])
+  source.close()
+} catch(e) {
+  port.postMessage([false, String(e)])
+}
+}
+/*-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>shared worker - EventSource: url</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script>
+      var test = async_test();
+      test.step(function() {
+        var url = "resources/message.py"
+        var worker = new SharedWorker('#')
+        worker.port.onmessage = function(e) {
+          test.step(function() {
+            assert_true(e.data[0], e.data[1]);
+            assert_equals(e.data[1].substr(-(url.length)), url)
+          })
+          test.done()
+        }
+      })
+    </script>
+  </body>
+</html>
+<!--*/ //-->