mirror of
				https://github.com/therootcompany/greenlock.js.git
				synced 2024-11-16 17:29:00 +00:00 
			
		
		
		
	updates
This commit is contained in:
		
							parent
							
								
									82b10eda4c
								
							
						
					
					
						commit
						145dbad411
					
				
							
								
								
									
										190
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										190
									
								
								README.md
									
									
									
									
									
								
							| @ -3,11 +3,195 @@ letsencrypt | ||||
| 
 | ||||
| Let's Encrypt for node.js | ||||
| 
 | ||||
| ### Update: Fri, Dec 11 | ||||
| This allows you to get Free SSL Certificates for Automatic HTTPS. | ||||
| 
 | ||||
| Committing some stub code. | ||||
| NOT YET PUBLISHED | ||||
| ============ | ||||
| 
 | ||||
| Expect something workable by Tuesday or Wednesday. | ||||
| Dec 12 2015: almost done | ||||
| 
 | ||||
| Install | ||||
| ======= | ||||
| 
 | ||||
| ```bash | ||||
| npm install --save letsencrypt | ||||
| ``` | ||||
| 
 | ||||
| Right now this uses [`letsencrypt-python`](https://github.com/Daplie/node-letsencrypt-python), | ||||
| but it's built to be able to use a pure javasript version. | ||||
| 
 | ||||
| ```bash | ||||
| # install the python client (takes 2 minutes normally, 20 on a rasberry pi) | ||||
| git clone https://github.com/letsencrypt/letsencrypt | ||||
| pushd letsencrypt | ||||
| 
 | ||||
| ./letsencrypt-auto | ||||
| ``` | ||||
| 
 | ||||
| Usage | ||||
| ===== | ||||
| 
 | ||||
| ```javascript | ||||
| var leBinPath = '/home/user/.local/share/letsencrypt/bin/letsencrypt'; | ||||
| var lep = require('letsencrypt-python').create(leBinPath); | ||||
| 
 | ||||
| // backend-specific defaults | ||||
| // Note: For legal reasons you should NOT set email or agreeTos as a default | ||||
| var bkDefaults = { | ||||
|   webroot: true | ||||
| , webrootPath: __dirname, '/acme-challenge' | ||||
| , fullchainTpl: '/live/:hostname/fullchain.pem' | ||||
| , privkeyTpl: '/live/:hostname/fullchain.pem' | ||||
| , configDir: '/etc/letsencrypt' | ||||
| , logsDir: '/var/log/letsencrypt' | ||||
| , workDir: '/var/lib/letsencrypt' | ||||
| , text: true | ||||
| }; | ||||
| var leConfig = { | ||||
| , webrootPath: __dirname, '/acme-challenge' | ||||
| , configDir: '/etc/letsencrypt' | ||||
| }; | ||||
| var le = require('letsencrypt').create(le, bkDefaults, leConfig); | ||||
| 
 | ||||
| var localCerts = require('localhost.daplie.com-certificates'); | ||||
| var express = require('express'); | ||||
| var app = express(); | ||||
| 
 | ||||
| app.use(le.middleware); | ||||
| 
 | ||||
| server = require('http').createServer(); | ||||
| server.on('request', app); | ||||
| server.listen(80, function () { | ||||
|   console.log('Listening http', server.address()); | ||||
| }); | ||||
| 
 | ||||
| tlsServer = require('https').createServer({ | ||||
|   key: localCerts.key | ||||
| , cert: localCerts.cert | ||||
| , SNICallback: le.SNICallback | ||||
| }); | ||||
| tlsServer.on('request', app); | ||||
| tlsServer.listen(443, function () { | ||||
|   console.log('Listening http', server.address()); | ||||
| }); | ||||
| 
 | ||||
| le.register('certonly', { | ||||
| , domains: ['example.com'] | ||||
| , agreeTos: true | ||||
| , email: 'user@example.com' | ||||
| }).then(function () { | ||||
|   server.close(); | ||||
|   tlsServer.close(); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ``` | ||||
| lep.register('certonly', { | ||||
| , domains: ['example.com'] | ||||
| , agreeTos: true | ||||
| , email: 'user@example.com' | ||||
| 
 | ||||
| , configDir: '/etc/letsencrypt' | ||||
| , logsDir: '/var/log/letsencrypt' | ||||
| , workDir: '/var/lib/letsencrypt' | ||||
| , text: true | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ``` | ||||
| // if you would like to register new domains on-the-fly | ||||
| // you can use this function to return the user to which | ||||
| // it should be registered (or null if none) | ||||
| , needsRegistration: function (hostname, cb) { | ||||
|     cb(null, { | ||||
|       agreeTos: true | ||||
|     , email:  'user@example.com' | ||||
|     }); | ||||
|   } | ||||
| ``` | ||||
| 
 | ||||
| Backends | ||||
| -------- | ||||
| 
 | ||||
| * [`letsencrypt-python`](https://github.com/Daplie/node-letsencrypt-python) (complete) | ||||
| * [`lejs`](https://github.com/Daplie/node-lejs) (in progress) | ||||
| 
 | ||||
| #### How to write a backend | ||||
| 
 | ||||
| A backend must implement (or be wrapped to implement) this API: | ||||
| 
 | ||||
| * fetch(hostname, cb) will cb(err, certs) will get registered certs or null unless there is an error | ||||
| * register(args, challengeCb, done) will register and or renew a cert | ||||
|   * args = `{ domains, email, agreeTos }` MUST check that agreeTos === true | ||||
|   * challengeCb = `function (challenge, cb) { }` handle challenge as needed, call cb() | ||||
| 
 | ||||
| This is what `args` looks like: | ||||
| 
 | ||||
| ```javascript | ||||
| { domains: ['example.com', 'www.example.com'] | ||||
| , email: 'user@email.com' | ||||
| , agreeTos: true | ||||
| , configDir: '/etc/letsencrypt' | ||||
| , fullchainTpl: '/live/:hostname/fullchain.pem'  // :hostname will be replaced with the domainname | ||||
| , privkeyTpl: '/live/:hostname/privkey.pem'    // :hostname | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| This is what the implementation should look like: | ||||
| 
 | ||||
| (it's expected that the client will follow the same conventions as | ||||
| the python client, but it's not necessary) | ||||
| 
 | ||||
| ```javascript | ||||
| return { | ||||
|   fetch: function (args, cb) { | ||||
|     // NOTE: should return an error if args.domains cannot be satisfied with a single cert | ||||
|     // (usually example.com and www.example.com will be handled on the same cert, for example) | ||||
|     if (errorHappens) { | ||||
|       // return an error if there is an actual error (db, etc) | ||||
|       cb(err); | ||||
|       return; | ||||
|     } | ||||
|     // return null if there is no error, nor a certificate | ||||
|     else if (!cert) { | ||||
|       cb(null, null); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     // NOTE: if the certificate is available but expired it should be | ||||
|     // returned and the calling application will decide to renew when | ||||
|     // it is convenient | ||||
| 
 | ||||
|     // NOTE: the application should handle caching, not the library | ||||
| 
 | ||||
|     // return the cert with metadata | ||||
|     cb(null, { | ||||
|       cert: "/*contcatonated certs in pem format: cert + intermediate*/" | ||||
|     , key: "/*private keypair in pem format*/" | ||||
|     , renewedAt: new Date()       // fs.stat cert.pem should also work | ||||
|     , expiresIn: 90 * 60          // assumes 90-days unless specified | ||||
|     }); | ||||
|   } | ||||
| , register: function (args, challengeCallback, completeCallback) { | ||||
|     // **MUST** reject if args.agreeTos is not true | ||||
| 
 | ||||
|     // once you're ready for the caller to know the challenge | ||||
|     if (challengeCallback) { | ||||
|       challengeCallback(challenge, function () { | ||||
|         continueRegistration(); | ||||
|       }) | ||||
|     } else { | ||||
|       continueRegistration(); | ||||
|     } | ||||
| 
 | ||||
|     function continueRegistration() { | ||||
|       // it is not neccessary to to return the certificates here | ||||
|       // the client will call fetch() when it needs them | ||||
|       completeCallback(err); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| LICENSE | ||||
|  | ||||
							
								
								
									
										59
									
								
								bin/standalone.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								bin/standalone.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| var homedir = require('homedir'); | ||||
| var leBinPath = homedir() + '/.local/share/letsencrypt/bin/letsencrypt'; | ||||
| var lep = require('letsencrypt-python').create(leBinPath); | ||||
| var conf = { | ||||
|   domains: process.argv[2] | ||||
| , email: process.argv[3] | ||||
| , agree: process.argv[4] | ||||
| }; | ||||
| 
 | ||||
| // backend-specific defaults
 | ||||
| // Note: For legal reasons you should NOT set email or agreeTos as a default
 | ||||
| var bkDefaults = { | ||||
|   webroot: true | ||||
| , webrootPath: __dirname + '/acme-challenge' | ||||
| , fullchainTpl: '/live/:hostname/fullchain.pem' | ||||
| , privkeyTpl: '/live/:hostname/fullchain.pem' | ||||
| , configDir: '/etc/letsencrypt' | ||||
| , logsDir: '/var/log/letsencrypt' | ||||
| , workDir: '/var/lib/letsencrypt' | ||||
| , text: true | ||||
| }; | ||||
| var le = require('letsencrypt').create(lep, bkDefaults); | ||||
| 
 | ||||
| var localCerts = require('localhost.daplie.com-certificates'); | ||||
| var express = require('express'); | ||||
| var app = express(); | ||||
| 
 | ||||
| app.use(le.middleware); | ||||
| 
 | ||||
| var server = require('http').createServer(); | ||||
| server.on('request', app); | ||||
| server.listen(80, function () { | ||||
|   console.log('Listening http', server.address()); | ||||
| }); | ||||
| 
 | ||||
| var tlsServer = require('https').createServer({ | ||||
|   key: localCerts.key | ||||
| , cert: localCerts.cert | ||||
| , SNICallback: le.SNICallback | ||||
| }); | ||||
| tlsServer.on('request', app); | ||||
| tlsServer.listen(443, function () { | ||||
|   console.log('Listening http', tlsServer.address()); | ||||
| }); | ||||
| 
 | ||||
| le.register('certonly', { | ||||
|   agreeTos: 'agree' === conf.agree | ||||
| , domains: conf.domains.split(',') | ||||
| , email: conf.email | ||||
| }).then(function () { | ||||
|   console.log('success'); | ||||
| }, function (err) { | ||||
|   console.error(err.stack); | ||||
| }).then(function () { | ||||
|   server.close(); | ||||
|   tlsServer.close(); | ||||
| }); | ||||
| @ -1,131 +0,0 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| var PromiseA = require('bluebird'); | ||||
| var spawn = require('child_process').spawn; | ||||
| 
 | ||||
| var letsencrypt = module.exports; | ||||
| 
 | ||||
| letsencrypt.parseOptions = function (text) { | ||||
|   var options = {}; | ||||
|   var re = /--([a-z0-9\-]+)/g; | ||||
|   var m; | ||||
| 
 | ||||
|   function uc(match, c) { | ||||
|     return c.toUpperCase(); | ||||
|   } | ||||
| 
 | ||||
|   while ((m = re.exec(text))) { | ||||
|     var key = m[1].replace(/-([a-z0-9])/g, uc); | ||||
| 
 | ||||
|     options[key] = true; | ||||
|   } | ||||
| 
 | ||||
|   return options; | ||||
| }; | ||||
| 
 | ||||
| letsencrypt.opts = function (lebinpath, cb) { | ||||
|   letsencrypt.exec(lebinpath, ['--help', 'all'], function (err, text) { | ||||
|     if (err) { | ||||
|       cb(err); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     cb(null, Object.keys(letsencrypt.parseOptions(text))); | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| letsencrypt.exec = function (lebinpath, args, opts, cb) { | ||||
|   // TODO create and watch the directory for challenge callback
 | ||||
|   if (opts.challengeCallback) { | ||||
|     return PromiseA.reject({ | ||||
|       message: "challengeCallback not yet supported" | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   var le = spawn(lebinpath, args, { stdio: ['ignore', 'pipe', 'pipe'] }); | ||||
|   var text = ''; | ||||
|   var errtext = ''; | ||||
|   var err; | ||||
| 
 | ||||
|   le.on('error', function (error) { | ||||
|     err = error; | ||||
|   }); | ||||
| 
 | ||||
|   le.stdout.on('data', function (chunk) { | ||||
|     text += chunk.toString('ascii'); | ||||
|   }); | ||||
| 
 | ||||
|   le.stderr.on('data', function (chunk) { | ||||
|     errtext += chunk.toString('ascii'); | ||||
|   }); | ||||
| 
 | ||||
|   le.on('close', function (code, signal) { | ||||
|     if (err) { | ||||
|       cb(err); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     if (errtext) { | ||||
|       err = new Error(errtext); | ||||
|       err.code = code; | ||||
|       err.signal = signal; | ||||
|       cb(err); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     if (0 !== code) { | ||||
|       err = new Error("exited with code '" + code + "'"); | ||||
|       err.code = code; | ||||
|       err.signal = signal; | ||||
|       cb(err); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     cb(null, text); | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| letsencrypt.objToArr = function (params, opts) { | ||||
|   var args = {}; | ||||
|   var arr = []; | ||||
| 
 | ||||
|   Object.keys(opts).forEach(function (key) { | ||||
|     var val = opts[key]; | ||||
| 
 | ||||
|     if (!val && 0 !== val) { | ||||
|       // non-zero value which is false, null, or otherwise falsey
 | ||||
|       // falsey values should not be passed
 | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     if (!params.indexOf(key)) { | ||||
|       // key is not recognized by the python client
 | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     if (Array.isArray(val)) { | ||||
|       args[key] = opts[key].join(','); | ||||
|     } else { | ||||
|       args[key] = opts[key]; | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   Object.keys(args).forEach(function (key) { | ||||
|     if ('tlsSni01Port' === key) { | ||||
|       arr.push('--tls-sni-01-port'); | ||||
|     } | ||||
|     else if ('http01Port' === key) { | ||||
|       arr.push('--http-01-port'); | ||||
|     } | ||||
|     else { | ||||
|       arr.push('--' + key.replace(/([A-Z])/g, '-$1').toLowerCase()); | ||||
|     } | ||||
| 
 | ||||
|     if (true !== opts[key]) { | ||||
|       // value is truthy, but not true (and falsies were weeded out above)
 | ||||
|       arr.push(opts[key]); | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   return arr; | ||||
| }; | ||||
| @ -1,40 +0,0 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| cacheIpAddresses | ||||
| 
 | ||||
| var https = require('https'); | ||||
| var http = require('http'); | ||||
| var letsencrypt = require('letsencrypt'); | ||||
| var localCerts = require('localhost.daplie.com-certificates'); | ||||
| var insecureServer; | ||||
| var server; | ||||
| 
 | ||||
| letsencrypt.create( | ||||
|   '/home/user/.local/share/letsencrypt/bin/letsencrypt' | ||||
|   // set some defaults
 | ||||
| , { "": "" | ||||
|   } | ||||
| ).then(function (le) { | ||||
| 
 | ||||
|   var express = require('express'); | ||||
|   var app = express(); | ||||
|   var getSecureContext = require('./le-standalone').getSecureContext; | ||||
| 
 | ||||
|   insecureServer = http.createServer(); | ||||
|   localCerts.sniCallback = function (hostname, cb) { | ||||
|     getSecureContext(le, hostname, cb); | ||||
|   }; | ||||
|   server = https.createServer(localCerts); | ||||
| 
 | ||||
|   insecureServer.on('request', app); | ||||
| 
 | ||||
|   server.on('request', app); | ||||
| }); | ||||
| 
 | ||||
| insecureServer.listen(80, function () { | ||||
|   console.log('http server listening', insecureServer.address()); | ||||
| }); | ||||
| 
 | ||||
| server.listen(443, function () { | ||||
|   console.log('https server listening', server.address()); | ||||
| }); | ||||
| @ -32,5 +32,8 @@ | ||||
|   "devDependencies": { | ||||
|     "express": "^4.13.3", | ||||
|     "localhost.daplie.com-certificates": "^1.1.2" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "letsencrypt-python": "^1.0.3" | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -9,5 +9,5 @@ module.exports = { | ||||
| , webrootPath: path.join(__dirname, "acme-challenge") | ||||
| , configDir: path.join(__dirname, "letsencrypt.config") | ||||
| , workDir: path.join(__dirname, "letsencrypt.work") | ||||
| , logDir: path.join(__dirname, "letsencrypt.log") | ||||
| , logsDir: path.join(__dirname, "letsencrypt.logs") | ||||
| }; | ||||
|  | ||||
| @ -7,87 +7,84 @@ var http = require('http'); | ||||
| var express = require('express'); | ||||
| var app = express(); | ||||
| 
 | ||||
| var config = require('./config'); | ||||
| module.exports.create = function (opts) { | ||||
|   function getSecureContext(domainname, opts, cb) { | ||||
| 
 | ||||
|     if (!opts) { opts = {}; } | ||||
| 
 | ||||
|     opts.key = fs.readFileSync(path.join(opts.configDir, 'live', domainname, 'privkey.pem')); | ||||
|     opts.cert = fs.readFileSync(path.join(opts.configDir, 'live', domainname, 'cert.pem')); | ||||
|     opts.ca = fs.readFileSync(path.join(opts.configDir, 'live', domainname, 'chain.pem'), 'ascii') | ||||
|       .split('-----END CERTIFICATE-----') | ||||
|       .filter(function (ca) { | ||||
|         return ca.trim(); | ||||
|       }).map(function (ca) { | ||||
|         return (ca + '-----END CERTIFICATE-----').trim(); | ||||
|       }); | ||||
| 
 | ||||
|     cb(null, require('tls').createSecureContext(opts)); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| function getSecureContext(domainname, opts, cb) { | ||||
|   var letsetc = '/etc/letsencrypt/live/'; | ||||
|   // log the requests
 | ||||
|   app.use('/', function (req, res, next) { | ||||
|     console.log('[' + req.ip + ']', req.method + ' ' + req.headers.host, req.protocol + req.url); | ||||
|     next(); | ||||
|   }); | ||||
|   // handle static requests to /.well-known/acme-challenge
 | ||||
|   app.use( | ||||
|     '/.well-known/acme-challenge' | ||||
|   , express.static(opts.webrootPath, { dotfiles: undefined }) | ||||
|   ); | ||||
| 
 | ||||
|   if (!opts) { opts = {}; } | ||||
|   function serveHttps() { | ||||
|     //
 | ||||
|     // SSL Certificates
 | ||||
|     //
 | ||||
|     var server; | ||||
|     var localCerts = require('localhost.daplie.com-certificates'); | ||||
|     var options = { | ||||
|       requestCert: false | ||||
|     , rejectUnauthorized: true | ||||
| 
 | ||||
|   opts.key = fs.readFileSync(path.join(letsetc, domainname, 'privkey.pem')); | ||||
|   opts.cert = fs.readFileSync(path.join(letsetc, domainname, 'cert.pem')); | ||||
|   opts.ca = fs.readFileSync(path.join(letsetc, domainname, 'chain.pem'), 'ascii') | ||||
|     .split('-----END CERTIFICATE-----') | ||||
|     .filter(function (ca) { | ||||
|       return ca.trim(); | ||||
|     }).map(function (ca) { | ||||
|       return (ca + '-----END CERTIFICATE-----').trim(); | ||||
|       // If you need to use SNICallback you should be using io.js >= 1.x (possibly node >= 0.12)
 | ||||
|     , SNICallback: function (domainname, cb) { | ||||
|         var secureContext = getSecureContext(domainname); | ||||
|         cb(null, secureContext); | ||||
|       } | ||||
|       // If you need to support HTTP2 this is what you need to work with
 | ||||
|     //, NPNProtocols: ['http/2.0', 'http/1.1', 'http/1.0']
 | ||||
|     //, NPNProtocols: ['http/1.1']
 | ||||
|     , key: localCerts.key | ||||
|     , cert: localCerts.cert | ||||
|     //, ca: null
 | ||||
|     }; | ||||
| 
 | ||||
|     // Start the tls sni server4
 | ||||
|     server = https.createServer(options); | ||||
|     server.on('error', function (err) { | ||||
|       console.error(err); | ||||
|     }); | ||||
|     server.on('request', app); | ||||
|     server.listen(opts.tlsSni01Port, function () { | ||||
|       console.log('[https] Listening', server.address()); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   cb(null, require('tls').createSecureContext(opts)); | ||||
| } | ||||
|   function serveHttp() { | ||||
|     // Start the http server4
 | ||||
|     var insecureServer = http.createServer(); | ||||
|     insecureServer.on('error', function (err) { | ||||
|       console.error(err); | ||||
|     }); | ||||
|     // note that request handler must be attached *before* and handle comes in
 | ||||
|     insecureServer.on('request', app); | ||||
|     insecureServer.listen(opts.http01Port, function () { | ||||
|       console.log('[http] Listening', insecureServer.address()); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| // log the requests
 | ||||
| app.use('/', function (req, res, next) { | ||||
|   console.log('[' + req.ip + ']', req.method + ' ' + req.headers.host, req.protocol + req.url); | ||||
|   next(); | ||||
| }); | ||||
| // handle static requests to /.well-known/acme-challenge
 | ||||
| app.use( | ||||
|   '/.well-known/acme-challenge' | ||||
| , express.static(config.webrootPath, { dotfiles: undefined }) | ||||
| ); | ||||
| 
 | ||||
| 
 | ||||
| function serveHttps() { | ||||
|   //
 | ||||
|   // SSL Certificates
 | ||||
|   //
 | ||||
|   var server; | ||||
|   var localCerts = require('localhost.daplie.com-certificates'); | ||||
|   var options = { | ||||
|     requestCert: false | ||||
|   , rejectUnauthorized: true | ||||
| 
 | ||||
|     // If you need to use SNICallback you should be using io.js >= 1.x (possibly node >= 0.12)
 | ||||
|   , SNICallback: function (domainname, cb) { | ||||
|       var secureContext = getSecureContext(domainname); | ||||
|       cb(null, secureContext); | ||||
|     } | ||||
|     // If you need to support HTTP2 this is what you need to work with
 | ||||
|   //, NPNProtocols: ['http/2.0', 'http/1.1', 'http/1.0']
 | ||||
|   //, NPNProtocols: ['http/1.1']
 | ||||
|   , key: localCerts.key | ||||
|   , cert: localCerts.cert | ||||
|   //, ca: null
 | ||||
|   }; | ||||
| 
 | ||||
|   // Start the tls sni server4
 | ||||
|   server = https.createServer(options); | ||||
|   server.on('error', function (err) { | ||||
|     console.error(err); | ||||
|   }); | ||||
|   server.on('request', app); | ||||
|   server.listen(config.tlsSni01Port, function () { | ||||
|     console.log('[https] Listening', server.address()); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| function serveHttp() { | ||||
|   // Start the http server4
 | ||||
|   var insecureServer = http.createServer(); | ||||
|   insecureServer.on('error', function (err) { | ||||
|     console.error(err); | ||||
|   }); | ||||
|   // note that request handler must be attached *before* and handle comes in
 | ||||
|   insecureServer.on('request', app); | ||||
|   insecureServer.listen(config.http01Port, function () { | ||||
|     console.log('[http] Listening', insecureServer.address()); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| serveHttps(); | ||||
| serveHttp(); | ||||
|   serveHttps(); | ||||
|   serveHttp(); | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user