test_simple_stream.js (5882B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // keep eslint happy until it knows about WebTransport 6 /* global WebTransport:false */ 7 /* global TextDecoderStream:false */ 8 9 // Using multiple files to reduce racing 10 // This file tests reading/writing to incoming/outgoing streams (uni & bidi) 11 // 12 "use strict"; 13 14 var h3Port; 15 var host; 16 17 registerCleanupFunction(async () => { 18 Services.prefs.clearUserPref("network.dns.localDomains"); 19 Services.prefs.clearUserPref("network.webtransport.enabled"); 20 Services.prefs.clearUserPref("network.webtransport.redirect.enabled"); 21 }); 22 23 var { NetUtil } = ChromeUtils.importESModule( 24 "resource://gre/modules/NetUtil.sys.mjs" 25 ); 26 27 function readFile(file) { 28 let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( 29 Ci.nsIFileInputStream 30 ); 31 fstream.init(file, -1, 0, 0); 32 let data = NetUtil.readInputStreamToString(fstream, fstream.available()); 33 fstream.close(); 34 return data; 35 } 36 37 function addCertFromFile(certdb, filename, trustString) { 38 let certFile = do_get_file(filename, false); 39 let pem = readFile(certFile) 40 .replace(/-----BEGIN CERTIFICATE-----/, "") 41 .replace(/-----END CERTIFICATE-----/, "") 42 .replace(/[\r\n]/g, ""); 43 certdb.addCertFromBase64(pem, trustString); 44 } 45 46 add_setup(async function setup() { 47 Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com"); 48 Services.prefs.setBoolPref("network.webtransport.enabled", true); 49 Services.prefs.setBoolPref("network.webtransport.redirect.enabled", true); 50 51 h3Port = Services.env.get("MOZHTTP3_PORT"); 52 Assert.notEqual(h3Port, null); 53 Assert.notEqual(h3Port, ""); 54 host = "foo.example.com:" + h3Port; 55 do_get_profile(); 56 57 let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( 58 Ci.nsIX509CertDB 59 ); 60 // `../unit/` so that unit_ipc tests can use as well 61 addCertFromFile( 62 certdb, 63 "../../../../netwerk/test/unit/http2-ca.pem", 64 "CTu,u,u" 65 ); 66 }); 67 68 // Read all chunks from |readable_stream|, decode chunks to a utf-8 string, then 69 // return the string. (borrowed from wpt tests) 70 async function read_stream_as_string(readable_stream) { 71 const decoder = new TextDecoderStream(); 72 const decode_stream = readable_stream.pipeThrough(decoder); 73 const reader = decode_stream.getReader(); 74 75 let chunks = ""; 76 while (true) { 77 const { value: chunk, done } = await reader.read(); 78 if (done) { 79 break; 80 } 81 chunks += chunk; 82 } 83 reader.releaseLock(); 84 return chunks; 85 } 86 87 add_task(async function test_wt_incoming_unidi_stream() { 88 // trigger stream creation server side and default echo 89 let wt = new WebTransport( 90 "https://" + host + "/create_unidi_stream_and_hello" 91 ); 92 await wt.ready; 93 94 const streams = await wt.incomingUnidirectionalStreams; 95 const stream_reader = streams.getReader(); 96 const { value: recv_stream } = await stream_reader.read(); 97 let str = await read_stream_as_string(recv_stream); 98 stream_reader.releaseLock(); 99 Assert.equal(str, "qwerty"); 100 101 wt.close(); 102 }); 103 104 add_task(async function test_wt_incoming_and_outgoing_unidi_stream() { 105 // create the client's incoming stream from the server side 106 // we need it to listen to the echo back 107 let wt = new WebTransport("https://" + host + "/create_unidi_stream"); 108 await wt.ready; 109 110 // send hello to server 111 let expected = "uni_hello"; 112 let writableStream = await wt.createUnidirectionalStream(); // only triggers NewStream OnWrite 113 let wsDefaultWriter = writableStream.getWriter(); 114 await wsDefaultWriter.ready; 115 let data = new TextEncoder().encode(expected); 116 await wsDefaultWriter.write(data); // triggers Http3ServerEvent::Data 117 await wsDefaultWriter.close(); 118 wsDefaultWriter.releaseLock(); 119 120 // read the echo 121 const streams = await wt.incomingUnidirectionalStreams; 122 const stream_reader = streams.getReader(); 123 const { value: recv_stream } = await stream_reader.read(); 124 let str = await read_stream_as_string(recv_stream); 125 Assert.equal(str, expected); 126 stream_reader.releaseLock(); 127 await recv_stream.closed; 128 129 wt.close(); 130 }); 131 132 add_task(async function test_wt_outgoing_bidi_stream() { 133 let wt = new WebTransport("https://" + host + "/success"); 134 await wt.ready; 135 136 // write to server 137 let wtbds = await wt.createBidirectionalStream(); 138 let writableStream = wtbds.writable; 139 let wsDefaultWriter = writableStream.getWriter(); 140 await wsDefaultWriter.ready; 141 let expected = "xyzhello"; 142 let data = new TextEncoder().encode(expected); 143 await wsDefaultWriter.write(data); 144 await wsDefaultWriter.close(); 145 wsDefaultWriter.releaseLock(); 146 147 // string goes through server and is echoed back here 148 const str = await read_stream_as_string(wtbds.readable); 149 Assert.equal(str, expected); 150 151 wt.close(); 152 }); 153 154 add_task(async function test_wt_incoming_bidi_stream() { 155 let wt = new WebTransport( 156 "https://" + host + "/create_bidi_stream_and_hello" 157 ); 158 // await wt.ready; // causes occasional hang on release --verify 159 160 const stream_reader = wt.incomingBidirectionalStreams.getReader(); 161 const { value: bidi_stream } = await stream_reader.read(); 162 stream_reader.releaseLock(); 163 164 const str = await read_stream_as_string(bidi_stream.readable); 165 Assert.equal(str, "asdfg"); 166 167 wt.close(); 168 }); 169 170 add_task(async function test_wt_incoming_bidi_stream_huge_data() { 171 let wt = new WebTransport( 172 "https://" + host + "/create_bidi_stream_and_large_data" 173 ); 174 // await wt.ready; // causes occasional hang on release --verify 175 176 const stream_reader = wt.incomingBidirectionalStreams.getReader(); 177 const { value: bidi_stream } = await stream_reader.read(); 178 stream_reader.releaseLock(); 179 180 const str = await read_stream_as_string(bidi_stream.readable); 181 Assert.equal(str.length, 32 * 1024 * 1024); 182 wt.close(); 183 });