summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/test_alt-data_stream.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/unit/test_alt-data_stream.js')
-rw-r--r--netwerk/test/unit/test_alt-data_stream.js161
1 files changed, 161 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_alt-data_stream.js b/netwerk/test/unit/test_alt-data_stream.js
new file mode 100644
index 0000000000..4b5b584188
--- /dev/null
+++ b/netwerk/test/unit/test_alt-data_stream.js
@@ -0,0 +1,161 @@
+/**
+ * Test for the "alternative data stream" stored withing a cache entry.
+ *
+ * - we load a URL with preference for an alt data (check what we get is the raw data,
+ * since there was nothing previously cached)
+ * - we write a big chunk of alt-data to the output stream
+ * - we load the URL again, expecting to get alt-data
+ * - we check that the alt-data is streamed. We should get the first chunk, then
+ * the rest of the alt-data is written, and we check that it is received in
+ * the proper order.
+ *
+ */
+
+"use strict";
+
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+
+XPCOMUtils.defineLazyGetter(this, "URL", function() {
+ return "http://localhost:" + httpServer.identity.primaryPort + "/content";
+});
+
+var httpServer = null;
+
+function make_channel(url) {
+ return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
+}
+
+const responseContent = "response body";
+// We need a large content in order to make sure that the IPDL stream is cut
+// into several different chunks.
+// We fill each chunk with a different character for easy debugging.
+const altContent =
+ "a".repeat(128 * 1024) +
+ "b".repeat(128 * 1024) +
+ "c".repeat(128 * 1024) +
+ "d".repeat(128 * 1024) +
+ "e".repeat(128 * 1024) +
+ "f".repeat(128 * 1024) +
+ "g".repeat(128 * 1024) +
+ "h".repeat(128 * 1024) +
+ "i".repeat(13); // Just so the chunk size doesn't match exactly.
+
+const firstChunkSize = Math.floor(altContent.length / 4);
+const altContentType = "text/binary";
+
+function contentHandler(metadata, response) {
+ response.setHeader("Content-Type", "text/plain");
+ response.setHeader("Cache-Control", "max-age=86400");
+
+ response.bodyOutputStream.write(responseContent, responseContent.length);
+}
+
+function run_test() {
+ do_get_profile();
+ httpServer = new HttpServer();
+ httpServer.registerPathHandler("/content", contentHandler);
+ httpServer.start(-1);
+
+ var chan = make_channel(URL);
+
+ var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
+ cc.preferAlternativeDataType(
+ altContentType,
+ "",
+ Ci.nsICacheInfoChannel.ASYNC
+ );
+
+ chan.asyncOpen(new ChannelListener(readServerContent, null));
+ do_test_pending();
+}
+
+// Output stream used to write alt-data to the cache entry.
+var os;
+
+function readServerContent(request, buffer) {
+ var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
+
+ Assert.equal(buffer, responseContent);
+ Assert.equal(cc.alternativeDataType, "");
+
+ executeSoon(() => {
+ os = cc.openAlternativeOutputStream(altContentType, altContent.length);
+ // Write a quarter of the alt data content
+ os.write(altContent, firstChunkSize);
+
+ executeSoon(openAltChannel);
+ });
+}
+
+function openAltChannel() {
+ var chan = make_channel(URL);
+ var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
+ cc.preferAlternativeDataType(
+ altContentType,
+ "",
+ Ci.nsICacheInfoChannel.ASYNC
+ );
+
+ chan.asyncOpen(altDataListener);
+}
+
+var altDataListener = {
+ buffer: "",
+ onStartRequest(request) {},
+ onDataAvailable(request, stream, offset, count) {
+ let string = NetUtil.readInputStreamToString(stream, count);
+ this.buffer += string;
+
+ // XXX: this condition might be a bit volatile. If this test times out,
+ // it probably means that for some reason, the listener didn't get all the
+ // data in the first chunk.
+ if (this.buffer.length == firstChunkSize) {
+ // write the rest of the content
+ os.write(
+ altContent.substring(firstChunkSize, altContent.length),
+ altContent.length - firstChunkSize
+ );
+ os.close();
+ }
+ },
+ onStopRequest(request, status) {
+ var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
+ Assert.equal(cc.alternativeDataType, altContentType);
+ Assert.equal(this.buffer.length, altContent.length);
+ Assert.equal(this.buffer, altContent);
+ openAltChannelWithOriginalContent();
+ },
+};
+
+function openAltChannelWithOriginalContent() {
+ var chan = make_channel(URL);
+ var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
+ cc.preferAlternativeDataType(
+ altContentType,
+ "",
+ Ci.nsICacheInfoChannel.SERIALIZE
+ );
+
+ chan.asyncOpen(originalListener);
+}
+
+var originalListener = {
+ buffer: "",
+ onStartRequest(request) {},
+ onDataAvailable(request, stream, offset, count) {
+ let string = NetUtil.readInputStreamToString(stream, count);
+ this.buffer += string;
+ },
+ onStopRequest(request, status) {
+ var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
+ Assert.equal(cc.alternativeDataType, altContentType);
+ Assert.equal(this.buffer.length, responseContent.length);
+ Assert.equal(this.buffer, responseContent);
+ testAltDataStream(cc);
+ },
+};
+
+function testAltDataStream(cc) {
+ Assert.ok(!!cc.alternativeDataInputStream);
+ httpServer.stop(do_test_finished);
+}