test_bhttp.js (6498B)
1 /* Any copyright is dedicated to the Public Domain. 2 * https://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Unit tests for the binary http bindings. 7 // Tests basic encoding and decoding of requests and responses. 8 9 function BinaryHttpRequest( 10 method, 11 scheme, 12 authority, 13 path, 14 headerNames, 15 headerValues, 16 content 17 ) { 18 this.method = method; 19 this.scheme = scheme; 20 this.authority = authority; 21 this.path = path; 22 this.headerNames = headerNames; 23 this.headerValues = headerValues; 24 this.content = content; 25 } 26 27 BinaryHttpRequest.prototype = { 28 QueryInterface: ChromeUtils.generateQI(["nsIBinaryHttpRequest"]), 29 }; 30 31 function test_encode_request() { 32 let bhttp = Cc["@mozilla.org/network/binary-http;1"].getService( 33 Ci.nsIBinaryHttp 34 ); 35 let request = new BinaryHttpRequest( 36 "GET", 37 "https", 38 "", 39 "/hello.txt", 40 ["user-agent", "host", "accept-language"], 41 [ 42 "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3", 43 "www.example.com", 44 "en, mi", 45 ], 46 [] 47 ); 48 let encoded = bhttp.encodeRequest(request); 49 // This example is from RFC 9292. 50 let expected = hexStringToBytes( 51 "0003474554056874747073000a2f6865" + 52 "6c6c6f2e747874406c0a757365722d61" + 53 "67656e74346375726c2f372e31362e33" + 54 "206c69626375726c2f372e31362e3320" + 55 "4f70656e53534c2f302e392e376c207a" + 56 "6c69622f312e322e3304686f73740f77" + 57 "77772e6578616d706c652e636f6d0f61" + 58 "63636570742d6c616e67756167650665" + 59 "6e2c206d690000" 60 ); 61 deepEqual(encoded, expected); 62 63 let mismatchedHeaders = new BinaryHttpRequest( 64 "GET", 65 "https", 66 "", 67 "", 68 ["whoops-only-one-header-name"], 69 ["some-header-value", "some-other-header-value"], 70 [] 71 ); 72 // The implementation uses "NS_ERROR_INVALID_ARG", because that's an 73 // appropriate description for the error. However, that is an alias to 74 // "NS_ERROR_ILLEGAL_VALUE", which is what the actual exception uses, so 75 // that's what is tested for here. 76 Assert.throws( 77 () => bhttp.encodeRequest(mismatchedHeaders), 78 /NS_ERROR_ILLEGAL_VALUE/ 79 ); 80 } 81 82 function test_decode_request() { 83 let bhttp = Cc["@mozilla.org/network/binary-http;1"].getService( 84 Ci.nsIBinaryHttp 85 ); 86 87 // From RFC 9292. 88 let encoded = hexStringToBytes( 89 "0003474554056874747073000a2f6865" + 90 "6c6c6f2e747874406c0a757365722d61" + 91 "67656e74346375726c2f372e31362e33" + 92 "206c69626375726c2f372e31362e3320" + 93 "4f70656e53534c2f302e392e376c207a" + 94 "6c69622f312e322e3304686f73740f77" + 95 "77772e6578616d706c652e636f6d0f61" + 96 "63636570742d6c616e67756167650665" + 97 "6e2c206d690000" 98 ); 99 let request = bhttp.decodeRequest(encoded); 100 equal(request.method, "GET"); 101 equal(request.scheme, "https"); 102 equal(request.authority, ""); 103 equal(request.path, "/hello.txt"); 104 let expectedHeaderNames = ["user-agent", "host", "accept-language"]; 105 deepEqual(request.headerNames, expectedHeaderNames); 106 let expectedHeaderValues = [ 107 "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3", 108 "www.example.com", 109 "en, mi", 110 ]; 111 deepEqual(request.headerValues, expectedHeaderValues); 112 deepEqual(request.content, []); 113 114 let garbage = hexStringToBytes("115f00ab64c0fa783fe4cb723eaa87fa78900a0b00"); 115 Assert.throws(() => bhttp.decodeRequest(garbage), /NS_ERROR_UNEXPECTED/); 116 } 117 118 function test_decode_response() { 119 let bhttp = Cc["@mozilla.org/network/binary-http;1"].getService( 120 Ci.nsIBinaryHttp 121 ); 122 // From RFC 9292. 123 let encoded = hexStringToBytes( 124 "0340660772756e6e696e670a22736c65" + 125 "657020313522004067046c696e6b233c" + 126 "2f7374796c652e6373733e3b2072656c" + 127 "3d7072656c6f61643b2061733d737479" + 128 "6c65046c696e6b243c2f736372697074" + 129 "2e6a733e3b2072656c3d7072656c6f61" + 130 "643b2061733d7363726970740040c804" + 131 "646174651d4d6f6e2c203237204a756c" + 132 "20323030392031323a32383a35332047" + 133 "4d540673657276657206417061636865" + 134 "0d6c6173742d6d6f6469666965641d57" + 135 "65642c203232204a756c203230303920" + 136 "31393a31353a353620474d5404657461" + 137 "671422333461613338372d642d313536" + 138 "3865623030220d6163636570742d7261" + 139 "6e6765730562797465730e636f6e7465" + 140 "6e742d6c656e67746802353104766172" + 141 "790f4163636570742d456e636f64696e" + 142 "670c636f6e74656e742d747970650a74" + 143 "6578742f706c61696e003348656c6c6f" + 144 "20576f726c6421204d7920636f6e7465" + 145 "6e7420696e636c756465732061207472" + 146 "61696c696e672043524c462e0d0a0000" 147 ); 148 let response = bhttp.decodeResponse(encoded); 149 equal(response.status, 200); 150 deepEqual( 151 response.content, 152 stringToBytes("Hello World! My content includes a trailing CRLF.\r\n") 153 ); 154 let expectedHeaderNames = [ 155 "date", 156 "server", 157 "last-modified", 158 "etag", 159 "accept-ranges", 160 "content-length", 161 "vary", 162 "content-type", 163 ]; 164 deepEqual(response.headerNames, expectedHeaderNames); 165 let expectedHeaderValues = [ 166 "Mon, 27 Jul 2009 12:28:53 GMT", 167 "Apache", 168 "Wed, 22 Jul 2009 19:15:56 GMT", 169 '"34aa387-d-1568eb00"', 170 "bytes", 171 "51", 172 "Accept-Encoding", 173 "text/plain", 174 ]; 175 deepEqual(response.headerValues, expectedHeaderValues); 176 177 let garbage = hexStringToBytes( 178 "0367890084cb0ab03115fa0b4c2ea0fa783f7a87fa00" 179 ); 180 Assert.throws(() => bhttp.decodeResponse(garbage), /NS_ERROR_UNEXPECTED/); 181 } 182 183 function test_encode_response() { 184 let response = new BinaryHttpResponse( 185 418, 186 ["content-type"], 187 ["text/plain"], 188 stringToBytes("I'm a teapot") 189 ); 190 let bhttp = Cc["@mozilla.org/network/binary-http;1"].getService( 191 Ci.nsIBinaryHttp 192 ); 193 let encoded = bhttp.encodeResponse(response); 194 let expected = hexStringToBytes( 195 "0141a2180c636f6e74656e742d747970650a746578742f706c61696e0c49276d206120746561706f7400" 196 ); 197 deepEqual(encoded, expected); 198 199 let mismatchedHeaders = new BinaryHttpResponse( 200 500, 201 ["some-header", "some-other-header"], 202 ["whoops-only-one-header-value"], 203 [] 204 ); 205 // The implementation uses "NS_ERROR_INVALID_ARG", because that's an 206 // appropriate description for the error. However, that is an alias to 207 // "NS_ERROR_ILLEGAL_VALUE", which is what the actual exception uses, so 208 // that's what is tested for here. 209 Assert.throws( 210 () => bhttp.encodeResponse(mismatchedHeaders), 211 /NS_ERROR_ILLEGAL_VALUE/ 212 ); 213 } 214 215 function run_test() { 216 test_encode_request(); 217 test_decode_request(); 218 test_encode_response(); 219 test_decode_response(); 220 }