From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- testing/xpcshell/moz-http2/http2-cert.pem | 79 +++ testing/xpcshell/moz-http2/http2-key.pem | 28 ++ testing/xpcshell/moz-http2/moz-http2.js | 786 ++++++++++++++++++++++++++++++ 3 files changed, 893 insertions(+) create mode 100644 testing/xpcshell/moz-http2/http2-cert.pem create mode 100644 testing/xpcshell/moz-http2/http2-key.pem create mode 100644 testing/xpcshell/moz-http2/moz-http2.js (limited to 'testing/xpcshell/moz-http2') diff --git a/testing/xpcshell/moz-http2/http2-cert.pem b/testing/xpcshell/moz-http2/http2-cert.pem new file mode 100644 index 000000000..d5944e531 --- /dev/null +++ b/testing/xpcshell/moz-http2/http2-cert.pem @@ -0,0 +1,79 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=Maine, O=CA Example + Validity + Not Before: Apr 29 05:29:19 2015 GMT + Not After : Apr 26 05:29:19 2025 GMT + Subject: C=US, ST=Maine, O=Example Com, CN=foo.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:cf:ff:c0:27:3b:a3:11:b5:7f:5d:4f:22:f9:75: + 48:47:d9:3a:ce:9b:66:82:4e:e4:ae:ab:78:d3:4c: + 3a:9a:5c:37:97:b2:7b:4e:2a:54:77:16:2a:3e:6f: + 52:ee:4b:49:46:1d:6b:18:9a:ed:b1:ad:64:9f:8b: + e5:fa:e4:60:7b:39:0e:db:e8:b4:2d:4b:e8:ab:37: + e8:90:ec:eb:0f:3e:6b:40:7a:d1:da:e6:68:b3:f4: + f6:68:54:5b:27:90:6d:c2:c3:04:de:85:23:2b:3c: + 66:4e:06:79:58:93:a1:71:d7:ec:74:55:a4:84:9d: + 41:22:2a:7a:76:ae:56:b1:6f:15:2d:f2:f5:9c:64: + 3e:4f:0f:6e:8f:b6:28:66:e9:89:04:5d:1d:21:77: + f8:03:d3:89:ed:7c:f4:3b:42:02:c8:8d:de:47:74: + 1f:4a:5d:fe:8d:d1:57:37:08:54:bf:89:d8:f7:27: + 22:a7:2a:5d:aa:d5:b0:61:22:9b:96:75:ee:ab:09: + ca:a9:cb:2b:1e:88:7c:5a:53:7e:5f:88:c4:43:ea: + e8:a7:db:35:6c:b2:89:ad:98:e0:96:c9:83:c4:c1: + e7:2a:5c:f8:99:5c:9e:01:9c:e6:99:bd:18:5c:69: + d4:10:f1:46:88:37:0b:4e:76:5f:6a:1a:21:c2:a4: + 16:d1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 76:BC:13:90:F7:85:1B:1C:24:A1:CC:65:8A:4F:4C:0C:7F:10:D3:F5 + X509v3 Authority Key Identifier: + keyid:F7:FC:76:AF:C5:1A:E9:C9:42:6C:38:DF:8B:07:9E:2B:2C:E5:8E:20 + + X509v3 Basic Constraints: + CA:FALSE + X509v3 Key Usage: + Digital Signature, Key Encipherment + Signature Algorithm: sha256WithRSAEncryption + 03:ab:2a:9e:e5:cd:5c:88:5a:6c:f7:4b:7a:7c:ef:85:2c:31: + df:03:79:31:a6:c5:c8:2b:c6:21:a5:33:2b:a0:4b:e2:7e:0a: + 86:9b:72:25:b6:75:43:41:7c:30:9f:15:b4:9f:34:50:57:eb: + 87:f9:1e:9f:b6:cd:81:36:92:61:66:d5:fe:e2:c5:ed:de:f1: + ce:85:0b:f9:6a:2b:32:4d:29:f1:a9:94:57:a3:0f:74:93:12: + c9:0a:28:5e:72:9f:4f:0f:78:f5:84:11:5a:9f:d7:1c:4c:fd: + 13:d8:3d:4c:f8:dd:4c:c6:1c:fd:63:ee:f5:d5:96:f5:00:2c: + e6:bb:c9:4c:d8:6a:19:59:58:2b:d4:05:ab:57:47:1c:49:d6: + c5:56:1a:e3:64:10:19:9b:44:3e:74:8b:19:73:28:86:96:b4: + d1:2a:49:23:07:25:97:64:8f:1b:1c:64:76:12:e0:df:e3:cf: + 55:d5:7c:e9:77:d4:69:2f:c7:9a:fd:ce:1a:29:ab:d7:88:68: + 93:de:75:e4:d6:85:29:e2:b6:b7:59:20:e3:b5:20:b7:e8:0b: + 23:9b:4c:b4:e8:d9:90:cf:e9:2f:9e:a8:22:a2:ef:6a:68:65: + f6:c4:81:ed:75:77:88:01:f2:47:03:1a:de:1f:44:38:47:fa: + aa:69:f2:98 +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIBATANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJVUzEO +MAwGA1UECAwFTWFpbmUxEzARBgNVBAoMCkNBIEV4YW1wbGUwHhcNMTUwNDI5MDUy +OTE5WhcNMjUwNDI2MDUyOTE5WjBNMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFTWFp +bmUxFDASBgNVBAoMC0V4YW1wbGUgQ29tMRgwFgYDVQQDDA9mb28uZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDP/8AnO6MRtX9dTyL5 +dUhH2TrOm2aCTuSuq3jTTDqaXDeXsntOKlR3Fio+b1LuS0lGHWsYmu2xrWSfi+X6 +5GB7OQ7b6LQtS+irN+iQ7OsPPmtAetHa5miz9PZoVFsnkG3CwwTehSMrPGZOBnlY +k6Fx1+x0VaSEnUEiKnp2rlaxbxUt8vWcZD5PD26Ptihm6YkEXR0hd/gD04ntfPQ7 +QgLIjd5HdB9KXf6N0Vc3CFS/idj3JyKnKl2q1bBhIpuWde6rCcqpyyseiHxaU35f +iMRD6uin2zVssomtmOCWyYPEwecqXPiZXJ4BnOaZvRhcadQQ8UaINwtOdl9qGiHC +pBbRAgMBAAGjWjBYMB0GA1UdDgQWBBR2vBOQ94UbHCShzGWKT0wMfxDT9TAfBgNV +HSMEGDAWgBT3/HavxRrpyUJsON+LB54rLOWOIDAJBgNVHRMEAjAAMAsGA1UdDwQE +AwIFoDANBgkqhkiG9w0BAQsFAAOCAQEAA6sqnuXNXIhabPdLenzvhSwx3wN5MabF +yCvGIaUzK6BL4n4KhptyJbZ1Q0F8MJ8VtJ80UFfrh/ken7bNgTaSYWbV/uLF7d7x +zoUL+WorMk0p8amUV6MPdJMSyQooXnKfTw949YQRWp/XHEz9E9g9TPjdTMYc/WPu +9dWW9QAs5rvJTNhqGVlYK9QFq1dHHEnWxVYa42QQGZtEPnSLGXMohpa00SpJIwcl +l2SPGxxkdhLg3+PPVdV86XfUaS/Hmv3OGimr14hok9515NaFKeK2t1kg47Ugt+gL +I5tMtOjZkM/pL56oIqLvamhl9sSB7XV3iAHyRwMa3h9EOEf6qmnymA== +-----END CERTIFICATE----- diff --git a/testing/xpcshell/moz-http2/http2-key.pem b/testing/xpcshell/moz-http2/http2-key.pem new file mode 100644 index 000000000..387449ddc --- /dev/null +++ b/testing/xpcshell/moz-http2/http2-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDP/8AnO6MRtX9d +TyL5dUhH2TrOm2aCTuSuq3jTTDqaXDeXsntOKlR3Fio+b1LuS0lGHWsYmu2xrWSf +i+X65GB7OQ7b6LQtS+irN+iQ7OsPPmtAetHa5miz9PZoVFsnkG3CwwTehSMrPGZO +BnlYk6Fx1+x0VaSEnUEiKnp2rlaxbxUt8vWcZD5PD26Ptihm6YkEXR0hd/gD04nt +fPQ7QgLIjd5HdB9KXf6N0Vc3CFS/idj3JyKnKl2q1bBhIpuWde6rCcqpyyseiHxa +U35fiMRD6uin2zVssomtmOCWyYPEwecqXPiZXJ4BnOaZvRhcadQQ8UaINwtOdl9q +GiHCpBbRAgMBAAECggEBAKqcsQQ9cdQr2S4zpI+UuVZeBFPGun32srPn6TMA2y0U +qXEgMO574E7SepI+BHt8e70sklVbd89/WANa4Kk8vTs2IU8XAPwKwO347SY7f9BA +Nf9s/0gcKRQ7wgbv8tlwKehQyWSxNpjXcV9dBho29n2ITOdb/Jfe2bdpuowxEuF0 +rugkKh7P7LJTG1SAw01UTIszoOGIqHU2XlmYQOws4EvRov/BRTn9axBHH33top+m +dX+96ntgWxdHOJjTcoXLGhTu1c0ZlJgtgEaH03jjy0f+3Qc+jIgbaZ4WLZkF/oZh +hscL56XhsT3hR2Sdtxccw2zZ0exLO+qV1RykIAlUXkECgYEA7U+ljowyPxbREHnf +SRTauIZfJNP6IHT60MkslltlYn7jABvx+u2xCC/QhZxCJi/iAs6iNvkbXR6uK/MH +NrXwdk67SDUXaDZ9LM3rXPqjuwmvkc+e7P5an6KRtyzQD8K8mjbze1NfxbcGgKti +A+8GL8H3V29EQ6xp2+UxIF/3UNkCgYEA4GEm9NLbu4neP+A+1NpUS4tUgMCdTkPm +fiOECd4jjTizPZjjrk+zTin9aP+eBRYHharIGrDP2Uj98uv4kQ8u0rQbcjPwitog +8DgccMQ92E6DYGDGECh5Hg2Zu71+zQQNzOEJTyrFLx4Gf5SkBzLlbDZDpNhbuQc9 +zvRYBc11urkCgYBOu2Dy9SJqefhsnfJtfaS/GZ2RS16tzAG2qTfIvpPZZL2NOLhE +hv13+N0WpuvvXW1/fuykjmr8rwQcAqo/BYe8yIwr/alBYuqOpdbTZzhRAnqkRpy0 +hgKs+bOccRqqT/Jgu6B2JwgcQYe/wpxnL7L+vzx/XqPoS9hnIxf0ZMJZqQKBgQDa +KJuf3oQWS23z3Sw5+C2NZeK7bIuF1S795bozffBDFqXvdf+pM4S6ssjYlfAmMc0O +gYYdrVvpf7apwhTjtUdpRgSJfUabOopcBbJhUexvq6bAxlbMzw0z0zVt/EiVPSPN +198dQhCGR0M6OGNjPHEkTX5ngJVtyUSnO5t5yNJ2wQKBgQDheEUJYgo2UjLNsdTs +b4og5gHkyoKS3paWV64itJQbVBuri4HWeIExM9ayBB6nSJ2VvpZPyE6XfiYYGNhR +jOc394qlnrx+oi2KdSmIWfQU0I+rW3bMqpoyWPYxP/hN6w4LAwjnJOSOIMCACm5J +d8IebWjY2B3Zc6FFVzbmhXtlig== +-----END PRIVATE KEY----- diff --git a/testing/xpcshell/moz-http2/moz-http2.js b/testing/xpcshell/moz-http2/moz-http2.js new file mode 100644 index 000000000..760fef1ef --- /dev/null +++ b/testing/xpcshell/moz-http2/moz-http2.js @@ -0,0 +1,786 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This module is the stateful server side of test_http2.js and is meant +// to have node be restarted in between each invocation + +var node_http2_root = '../node-http2'; +if (process.env.NODE_HTTP2_ROOT) { + node_http2_root = process.env.NODE_HTTP2_ROOT; +} +var http2 = require(node_http2_root); +var fs = require('fs'); +var url = require('url'); +var crypto = require('crypto'); + +// Hook into the decompression code to log the decompressed name-value pairs +var compression_module = node_http2_root + "/lib/protocol/compressor"; +var http2_compression = require(compression_module); +var HeaderSetDecompressor = http2_compression.HeaderSetDecompressor; +var originalRead = HeaderSetDecompressor.prototype.read; +var lastDecompressor; +var decompressedPairs; +HeaderSetDecompressor.prototype.read = function() { + if (this != lastDecompressor) { + lastDecompressor = this; + decompressedPairs = []; + } + var pair = originalRead.apply(this, arguments); + if (pair) { + decompressedPairs.push(pair); + } + return pair; +} + +var connection_module = node_http2_root + "/lib/protocol/connection"; +var http2_connection = require(connection_module); +var Connection = http2_connection.Connection; +var originalClose = Connection.prototype.close; +Connection.prototype.close = function (error, lastId) { + if (lastId !== undefined) { + this._lastIncomingStream = lastId; + } + + originalClose.apply(this, arguments); +} + +var framer_module = node_http2_root + "/lib/protocol/framer"; +var http2_framer = require(framer_module); +var Serializer = http2_framer.Serializer; +var originalTransform = Serializer.prototype._transform; +var newTransform = function (frame, encoding, done) { + if (frame.type == 'DATA') { + // Insert our empty DATA frame + emptyFrame = {}; + emptyFrame.type = 'DATA'; + emptyFrame.data = new Buffer(0); + emptyFrame.flags = []; + emptyFrame.stream = frame.stream; + var buffers = []; + Serializer['DATA'](emptyFrame, buffers); + Serializer.commonHeader(emptyFrame, buffers); + for (var i = 0; i < buffers.length; i++) { + this.push(buffers[i]); + } + + // Reset to the original version for later uses + Serializer.prototype._transform = originalTransform; + } + originalTransform.apply(this, arguments); +}; + +function getHttpContent(path) { + var content = '' + + '' + + 'HOORAY!' + + 'You Win! (by requesting' + path + ')' + + ''; + return content; +} + +function generateContent(size) { + var content = ''; + for (var i = 0; i < size; i++) { + content += '0'; + } + return content; +} + +/* This takes care of responding to the multiplexed request for us */ +var m = { + mp1res: null, + mp2res: null, + buf: null, + mp1start: 0, + mp2start: 0, + + checkReady: function() { + if (this.mp1res != null && this.mp2res != null) { + this.buf = generateContent(30*1024); + this.mp1start = 0; + this.mp2start = 0; + this.send(this.mp1res, 0); + setTimeout(this.send.bind(this, this.mp2res, 0), 5); + } + }, + + send: function(res, start) { + var end = Math.min(start + 1024, this.buf.length); + var content = this.buf.substring(start, end); + res.write(content); + if (end < this.buf.length) { + setTimeout(this.send.bind(this, res, end), 10); + } else { + res.end(); + } + } +}; + +var runlater = function() {}; +runlater.prototype = { + req : null, + resp : null, + + onTimeout : function onTimeout() { + this.resp.writeHead(200); + this.resp.end("It's all good 750ms."); + } +}; + +var moreData = function() {}; +moreData.prototype = { + req : null, + resp : null, + iter: 3, + + onTimeout : function onTimeout() { + // 1mb of data + content = generateContent(1024*1024); + this.resp.write(content); // 1mb chunk + this.iter--; + if (!this.iter) { + this.resp.end(); + } else { + setTimeout(executeRunLater, 1, this); + } + } +}; + +function executeRunLater(arg) { + arg.onTimeout(); +} + +var Compressor = http2_compression.Compressor; +var HeaderSetCompressor = http2_compression.HeaderSetCompressor; +var originalCompressHeaders = Compressor.prototype.compress; + +function insertSoftIllegalHpack(headers) { + var originalCompressed = originalCompressHeaders.apply(this, headers); + var illegalLiteral = new Buffer([ + 0x00, // Literal, no index + 0x08, // Name: not huffman encoded, 8 bytes long + 0x3a, 0x69, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, // :illegal + 0x10, // Value: not huffman encoded, 16 bytes long + // REALLY NOT LEGAL + 0x52, 0x45, 0x41, 0x4c, 0x4c, 0x59, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4c, 0x45, 0x47, 0x41, 0x4c + ]); + var newBufferLength = originalCompressed.length + illegalLiteral.length; + var concatenated = new Buffer(newBufferLength); + originalCompressed.copy(concatenated, 0); + illegalLiteral.copy(concatenated, originalCompressed.length); + return concatenated; +} + +function insertHardIllegalHpack(headers) { + var originalCompressed = originalCompressHeaders.apply(this, headers); + // Now we have to add an invalid header + var illegalIndexed = HeaderSetCompressor.integer(5000, 7); + // The above returns an array of buffers, but there's only one buffer, so + // get rid of the array. + illegalIndexed = illegalIndexed[0]; + // Set the first bit to 1 to signal this is an indexed representation + illegalIndexed[0] |= 0x80; + var newBufferLength = originalCompressed.length + illegalIndexed.length; + var concatenated = new Buffer(newBufferLength); + originalCompressed.copy(concatenated, 0); + illegalIndexed.copy(concatenated, originalCompressed.length); + return concatenated; +} + +var h11required_conn = null; +var h11required_header = "yes"; +var didRst = false; +var rstConnection = null; +var illegalheader_conn = null; + +function handleRequest(req, res) { + // We do this first to ensure nothing goes wonky in our tests that don't want + // the headers to have something illegal in them + Compressor.prototype.compress = originalCompressHeaders; + + var u = url.parse(req.url); + var content = getHttpContent(u.pathname); + var push, push1, push1a, push2, push3; + + // PushService tests. + var pushPushServer1, pushPushServer2, pushPushServer3, pushPushServer4; + + if (req.httpVersionMajor === 2) { + res.setHeader('X-Connection-Http2', 'yes'); + res.setHeader('X-Http2-StreamId', '' + req.stream.id); + } else { + res.setHeader('X-Connection-Http2', 'no'); + } + + if (u.pathname === '/exit') { + res.setHeader('Content-Type', 'text/plain'); + res.setHeader('Connection', 'close'); + res.writeHead(200); + res.end('ok'); + process.exit(); + } + + if (u.pathname === '/750ms') { + var rl = new runlater(); + rl.req = req; + rl.resp = res; + setTimeout(executeRunLater, 750, rl); + return; + } + + else if ((u.pathname === '/multiplex1') && (req.httpVersionMajor === 2)) { + res.setHeader('Content-Type', 'text/plain'); + res.writeHead(200); + m.mp1res = res; + m.checkReady(); + return; + } + + else if ((u.pathname === '/multiplex2') && (req.httpVersionMajor === 2)) { + res.setHeader('Content-Type', 'text/plain'); + res.writeHead(200); + m.mp2res = res; + m.checkReady(); + return; + } + + else if (u.pathname === "/header") { + var val = req.headers["x-test-header"]; + if (val) { + res.setHeader("X-Received-Test-Header", val); + } + } + + else if (u.pathname === "/doubleheader") { + res.setHeader('Content-Type', 'text/html'); + res.writeHead(200); + res.write(content); + res.writeHead(200); + res.end(); + return; + } + + else if (u.pathname === "/cookie_crumbling") { + res.setHeader("X-Received-Header-Pairs", JSON.stringify(decompressedPairs)); + } + + else if (u.pathname === "/push") { + push = res.push('/push.js'); + push.writeHead(200, { + 'content-type': 'application/javascript', + 'pushed' : 'yes', + 'content-length' : 11, + 'X-Connection-Http2': 'yes' + }); + push.end('// comments'); + content = '