From e6964cfe1497bd1c9463ac96a4d36b35e8df226d Mon Sep 17 00:00:00 2001 From: Rafael Alfaro Date: Mon, 29 Feb 2016 14:35:25 -0600 Subject: [PATCH] Added options map to eventSourceInitDict object to setup http/https connection options (specifically for certificate configuration) --- lib/eventsource.js | 10 ++++++++ test/client_certs/cacert.crt | 13 +++++++++++ test/client_certs/client_cert.crt | 13 +++++++++++ test/client_certs/client_key.pem | 18 ++++++++++++++ test/client_certs/server_cert.crt | 13 +++++++++++ test/client_certs/server_key.pem | 18 ++++++++++++++ test/eventsource_test.js | 39 +++++++++++++++++++++++++++++++ 7 files changed, 124 insertions(+) create mode 100644 test/client_certs/cacert.crt create mode 100644 test/client_certs/client_cert.crt create mode 100644 test/client_certs/client_key.pem create mode 100644 test/client_certs/server_cert.crt create mode 100644 test/client_certs/server_key.pem diff --git a/lib/eventsource.js b/lib/eventsource.js index 7fb0a8b..4d594f2 100644 --- a/lib/eventsource.js +++ b/lib/eventsource.js @@ -93,6 +93,16 @@ function EventSource(url, eventSourceInitDict) { options.port = proxy.port; } + //If specify options, include all properties in the http/https request options + if (eventSourceInitDict && eventSourceInitDict.options && isPlainObject(eventSourceInitDict.options)){ + for (var optName in eventSourceInitDict.options){ + var option = eventSourceInitDict.options[optName]; + if (option !== undefined) { + options[optName] = option; + } + } + } + req = (isSecure ? https : http).request(options, function (res) { // Handle HTTP redirects if (res.statusCode == 301 || res.statusCode == 307) { diff --git a/test/client_certs/cacert.crt b/test/client_certs/cacert.crt new file mode 100644 index 0000000..a37a23e --- /dev/null +++ b/test/client_certs/cacert.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICBzCCAXACCQDe3kCVnwXlKTANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQGEwJV +UzELMAkGA1UECBMCVkExFDASBgNVBAoTC0V2ZW50U291cmNlMRYwFAYDVQQDEw1F +dmVudFNvdXJjZUNBMB4XDTE2MDIyOTIwMTMyNloXDTI2MDIyNjIwMTMyNlowSDEL +MAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRQwEgYDVQQKEwtFdmVudFNvdXJjZTEW +MBQGA1UEAxMNRXZlbnRTb3VyY2VDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAujWjBi18dawJfTPMd1vtozoE0VRD5aP32d2UU3kps8nDfKlwcWcaYcKtGhlT +KXYKn4zrXd6wa5J3RdWEwukN5aAkLYDPCJX12w8KacDOoqdYyHi635QXXq1N+7rK +nDKaDwtg015fPsOumLDqk6x4VBpFDbjrcblT0ILqsurd0OMCAwEAATANBgkqhkiG +9w0BAQUFAAOBgQABgZZnsnsDsGctScBD7vSoTM9+aOetlUlPZx6N52ADe1L77rP7 +0rPxL/+yD3VGVTAhAHrtC1JpJpo+JBssuC2EkwZ2RWFU/rkYQBO7wbgRFAoEWylT +j3PaeDzUZumSL5ZuVyQC94XNCodNeWBDK+WzQbjPa0BPd6vflUnAb/stwg== +-----END CERTIFICATE----- diff --git a/test/client_certs/client_cert.crt b/test/client_certs/client_cert.crt new file mode 100644 index 0000000..201218c --- /dev/null +++ b/test/client_certs/client_cert.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICAjCCAWsCCQDcY7oXL2AdXjANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQGEwJV +UzELMAkGA1UECBMCVkExFDASBgNVBAoTC0V2ZW50U291cmNlMRYwFAYDVQQDEw1F +dmVudFNvdXJjZUNBMB4XDTE2MDIyOTIwMTU0MVoXDTI2MDIyNjIwMTU0MVowQzEL +MAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRQwEgYDVQQKEwtFdmVudFNvdXJjZTER +MA8GA1UEAxMIdGVzdHVzZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPKw +mifd5tbJg5ZDkoabQsgqqu24MsNbJMtrbTkH/DtK12Qg6m5n8TR2aUt/CfpXBNkh +C40KzbFirkoTwLtLon39f6HFqaQCvdRZOb9e3SmHapm1W/ROx2M4L17DdKaVdkVn +7HA4zBL+kfZSI914dWTI4s0l9ohwJdVmBBBsmEO9AgMBAAEwDQYJKoZIhvcNAQEF +BQADgYEAdDfnGB9/n3Q2Hao4t8svM5s/Wyvy/sc8iZUn4R6PwFKSmeeuOS6NjkIy +rq59z3D4qHTES5RFoO7d8km884UcYCz6mq081hAm+Dlcd3uZhsWyboHCgkWlhVIS +XGEeNAUBir6aGvBkfU69HFdXfprTiTvHlt2NukwTPCYoqPQQH3w= +-----END CERTIFICATE----- diff --git a/test/client_certs/client_key.pem b/test/client_certs/client_key.pem new file mode 100644 index 0000000..bdaa171 --- /dev/null +++ b/test/client_certs/client_key.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,6040D9A5C438CD94 + +nIsbCSSu74WqCDkABopP4WfV1qt1Om0Se27KNWYQdPxBgD7APTcf2OBb3QZH5IpX +esGvGcCAfmE9VXmT9z3Kpwaloo1kZ3kdEEdYIH7QWc0mbIlMLghgvjfYy43LupoG +GD9Hlhvtpynhrc+VE+R3DKKboA8NnT//NuekPkiVdp5qVM7uKNLCiYrW2iKHZDiA +mRCbmWmLAC9YPou9mEu0wJxk+MULXjIjgls8IdCcNdcEJO6sRyzPOgBv/6WipGxq +15xYJViBUVl8W33JdkGWFTrlodJs49X7/AjHw55GqCixONrPzhzycsgFo8FOCROI +BqPHD5N/itGtMu61JGCmvBuXyhUYd9xiBrinalVOxJV+XUJWLGw7KurNQrPa/RwU +m9E0cSxwyYWEalpr0fTMpvo2NYcKmJLs30jj9G/Kpqs/7LWjrp7Tm/stHFSpa4Jm +Qt1nX7x8Vjt1cnMup0f/dK8eMsx4JsF0YqyklYObyJdJhe1akoz2YhSnD4CNE0T+ +oIoxrU74w6iK0PF33+w7sc2ZRODZdJcA09r9yZfh68yhGPkcp91koaZso+0uHlHw +sN204cy1jhS2s7EJ/J8abHdOnznEw1g/1YIPkhfgEh3ccpGCWPbpAHc12eth+fEl +SL5rmFrQtowic2lOYOabWbkP+ZDd5deSlTouOB/iYtsRZP7UINBlqcoYvThx40ba +yHKeFE1pitNB3oh3AVGGu8xbzObzjVC32s8caMZqr2QwIyk18oIGQPD4rhcbkRQ8 +WIeog03dLVEBa+qhgaOZX7zJrYX6eilRGBXmjZueV57VOl3pTQCnpg== +-----END RSA PRIVATE KEY----- diff --git a/test/client_certs/server_cert.crt b/test/client_certs/server_cert.crt new file mode 100644 index 0000000..45dd803 --- /dev/null +++ b/test/client_certs/server_cert.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICAzCCAWwCCQDcY7oXL2AdXTANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQGEwJV +UzELMAkGA1UECBMCVkExFDASBgNVBAoTC0V2ZW50U291cmNlMRYwFAYDVQQDEw1F +dmVudFNvdXJjZUNBMB4XDTE2MDIyOTIwMTQyMVoXDTI2MDIyNjIwMTQyMVowRDEL +MAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRQwEgYDVQQKEwtFdmVudFNvdXJjZTES +MBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJ +5BXHRbLlvlMGg19SQ1Bg4iDA8Tt9IJ4P/tocgwamQyCjFpngOi+uDmnXLZFf1x7P +ueXEtKVLLGlehcqM3LNS3Z4SUUc+OkcO2ztFZHjWell7FOuDTUuus3BjcFQDDNhd +GBNBKI79/oxRVjRFcDdMvTWG0r1UIALvlECTj8uwswIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAFqvIsJWnsV/drGNeuftEMG/zwD+5j8Xe9xCUIewMH5Er20/MXK0owLi +V3XI84LpVKi9hfUwJji91EW6Qi18Z4LKdA/bXvLdWwtZMCybYTTGKnLmUELhqIyn +VZbgEXyYpiUzRUnIotjbOwQIpP1aj+8Gys6DrHgBEbqrMuI6tiKF +-----END CERTIFICATE----- diff --git a/test/client_certs/server_key.pem b/test/client_certs/server_key.pem new file mode 100644 index 0000000..4818aae --- /dev/null +++ b/test/client_certs/server_key.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,5A4FE8B32AF89EBF + +Falz9rSy6LdpFlmXQKkmIGVzYqkmKJ8rA1E/xt5YFOGk7tO6kwCKm5/wOrWv3TrH +6v90CTNNJHerwFe7QinEAMiwKaLssR+YUxdNplJrYCbTTRrOo/DER0qVO8bw4yht +MawMDY1+pI1YyDpkwNt8QsVn80DFUBTqnXb2A+u0Pk+PaL/hji7t1piGD+yRkPsC +Fbx54F3IzZByFyhMQ2YoTzT8OHEyMDEzqxjla7DsWC9PGuFTtp7h6NWA4kT1FBb5 +kkEIYai/DuN/ng750+7eAVv6K3Fz+byb9t4VMpb3FHpreqk32D8StCVG1N1vUVK7 +gN8D3X1GBDRKmOEP/hSJOoDZj8W9UXq4SQ9GzRtyVGq2ARMr32P/e/EOq5L4tSy1 +WVJk0pBVIIUrY2Z0UO5tpK7+pkZvjOCWr68qnXIWcyEptyPqEiFZNqoztRbtaHyf +7m8FEDXSRBKQpFyi5p9AWut1hlaf6YyKbw3z8Gqfd1nqbzcqqH2jSN7WdZcJj0Ma +JWTMaFBT1wZYQ/mQleLk4TakQf+X/wlq/B9gfrEWR0Zkmc7tuXwDaMU8muQdXx6d +Olu73ICqrsajrmILX2tmJo2HsSvfNjxOXC/VORqVwD+Hp09p3UZnrxxNohCm8Qka +Dgghd+oU0o1RfdBa+c5ZL6l41ghk2a3zMi/GCGl+KprmMonlRIfUSkMc3tdRQiZV +GubJSwASXFxVDrIb64fDdyEryHFxKjyFeHOc9fFyP11TawLJgCKPaiqSnUivvvPr +PBei3pkaFiq9mpF3pF3GO7I6ENGpBmU0O/6rVh7hYtg= +-----END RSA PRIVATE KEY----- diff --git a/test/eventsource_test.js b/test/eventsource_test.js index 79f0709..d8fd8b1 100644 --- a/test/eventsource_test.js +++ b/test/eventsource_test.js @@ -27,6 +27,19 @@ function createHttpsServer(callback) { configureServer(server, 'https', _port++, callback); } +function createHttpsServerWithClientAuth(callback) { + var options = { + key: fs.readFileSync(__dirname + '/client_certs/server_key.pem'), + cert: fs.readFileSync(__dirname + '/client_certs/server_cert.crt'), + ca: fs.readFileSync(__dirname + '/client_certs/cacert.crt'), + passphrase:'test1234$', + requestCert: true, + rejectAuthorized:true + }; + var server = https.createServer(options); + configureServer(server, 'https', _port++, callback); +} + function configureServer(server, protocol, port, callback) { var responses = []; @@ -486,6 +499,32 @@ describe('HTTPS Support', function () { }); }); +describe('HTTPS Client Certificate Support', function () { + it('uses client certificate for https urls', function (done) { + this.timeout(1500000); + createHttpsServerWithClientAuth(function (err, server) { + if(err) return done(err); + + server.on('request', writeEvents(["data: hello\n\n"])); + var es = new EventSource(server.url, + { + options:{ + key: fs.readFileSync(__dirname + '/client_certs/client_key.pem'), + cert: fs.readFileSync(__dirname + '/client_certs/client_cert.crt'), + ca: fs.readFileSync(__dirname + '/client_certs/cacert.crt'), + passphrase:'test1234$', + rejectUnauthorized: true + } + } + ); + es.onmessage = function (m) { + assert.equal("hello", m.data); + server.close(done); + } + }); + }); +}); + describe('Reconnection', function () { it('is attempted when server is down', function (done) { var es = new EventSource('http://localhost:' + _port);