diff --git a/docs/userGuide/cliCommands.md b/docs/userGuide/cliCommands.md index d6031208e6..0e00d6c909 100644 --- a/docs/userGuide/cliCommands.md +++ b/docs/userGuide/cliCommands.md @@ -77,7 +77,7 @@ Usage: markbind **Description:** Does the following steps: 1. Builds the site and puts the generated files in a directory named `_site`. -1. Starts a web server instance locally and makes the site available at `http://127.0.0.1:8080`. +1. Starts a web server instance locally and makes the site available at `http://127.0.0.1:8080` by default. 1. Opens a live preview of the website. @@ -124,9 +124,11 @@ The caveat is that not building all pages during the initial process, or not reb * `-f`, `--force-reload`
Force live reload to process all files in the site, instead of just the relevant files. This option is useful when you are modifying a file that is not a file type monitored by the live preview feature. -* `-p `, `--port `
- Serve the website in the specified port. +* `-a
`, `--address
`
+ Specify the server address/host (Default is 127.0.0.1). +* `-p `, `--port `
+ Serve the website in the specified port (Default is 8080). {{ icon_examples }} * `markbind serve` : Serves the site from the current working directory. diff --git a/packages/cli/index.js b/packages/cli/index.js index d155004d0c..12b3f6bcb3 100755 --- a/packages/cli/index.js +++ b/packages/cli/index.js @@ -56,6 +56,7 @@ program .option('-p, --port ', 'port for server to listen on (Default is 8080)') .option('-s, --site-config ', 'specify the site config file (default: site.json)') .option('-d, --dev', 'development mode, enabling live & hot reload for frontend source files.') + .option('-a, --address
', 'specify the server address/host (Default is 127.0.0.1)') .description('build then serve a website from a directory') .action((userSpecifiedRoot, options) => { serve(userSpecifiedRoot, options); diff --git a/packages/cli/src/cmd/serve.js b/packages/cli/src/cmd/serve.js index cd85c89773..a43f33187e 100755 --- a/packages/cli/src/cmd/serve.js +++ b/packages/cli/src/cmd/serve.js @@ -1,5 +1,6 @@ const chokidar = require('chokidar'); const path = require('path'); +const readline = require('readline'); const { Site } = require('@markbind/core').Site; const { pageVueServerRenderer } = require('@markbind/core/src/Page/PageVueServerRenderer'); @@ -17,6 +18,23 @@ const { removeHandler, } = require('../util/serveUtil'); +function isIPAddressZero(address) { + const patternForZero = /^0(\.0)*$/; + + return patternForZero.test(address); +} + +function questionAsync(question) { + const readlineInterface = readline.createInterface({ input: process.stdin, output: process.stdout }); + + return new Promise((resolve) => { + readlineInterface.question(question, (response) => { + readlineInterface.close(); + resolve(response); + }); + }); +} + function serve(userSpecifiedRoot, options) { if (options.dev) { logger.useDebugConsole(); @@ -63,6 +81,7 @@ function serve(userSpecifiedRoot, options) { logLevel: 0, root: outputFolder, port: options.port || 8080, + host: options.address || '127.0.0.1', middleware: [], mount: [], }; @@ -70,6 +89,19 @@ function serve(userSpecifiedRoot, options) { site .readSiteConfig() .then(async (config) => { + if (isIPAddressZero(serverConfig.host)) { + const response = await questionAsync( + 'WARNING: Using the address \'0.0.0.0\' could potentially expose your server to the internet, ' + + 'which may pose security risks. \n' + + 'Proceed with caution? [y/N] '); + if (response.toLowerCase() === 'y') { + logger.info('Proceeding to generate website'); + } else { + logger.info('Website generation is cancelled.'); + process.exit(); + } + } + serverConfig.mount.push([config.baseUrl || '/', outputFolder]); if (options.dev) { @@ -111,8 +143,9 @@ function serve(userSpecifiedRoot, options) { const server = liveServer.start(serverConfig); server.addListener('listening', () => { const address = server.address(); - const serveHost = address.address === '0.0.0.0' ? '127.0.0.1' : address.address; - const serveURL = `http://${serveHost}:${address.port}`; + const serveHost = address.address; + const servePort = address.port; + const serveURL = `http://${serveHost}:${servePort}`; logger.info(`Serving "${outputFolder}" at ${serveURL}`); logger.info('Press CTRL+C to stop ...'); }); diff --git a/packages/cli/src/lib/live-server/index.js b/packages/cli/src/lib/live-server/index.js index 35a269f067..eabb31de8b 100644 --- a/packages/cli/src/lib/live-server/index.js +++ b/packages/cli/src/lib/live-server/index.js @@ -141,7 +141,7 @@ function entryPoint(staticHandler, file) { /** * Start a live server with parameters given as an object - * @param host {string} Address to bind to (default: 0.0.0.0) + * @param host {string} Address to bind to (default: 127.0.0.1) * @param port {number} Port number (default: 8080) * @param root {string} Path to root directory (default: cwd) * @param watch {array} Paths to exclusively watch for changes @@ -158,8 +158,8 @@ function entryPoint(staticHandler, file) { */ LiveServer.start = function(options) { options = options || {}; - var host = options.host || '0.0.0.0'; - var port = options.port !== undefined ? options.port : 8080; // 0 means random + var host = options.host ?? '127.0.0.1'; + var port = options.port ?? 8080; // 0 means random var root = options.root || process.cwd(); var mount = options.mount || []; var watchPaths = options.watch || [root]; @@ -281,7 +281,13 @@ LiveServer.start = function(options) { setTimeout(function() { server.listen(0, host); }, 1000); - } else { + } else if (e.code === 'EADDRNOTAVAIL') { + console.log('%s is not available. Trying another address'.yellow, host); + setTimeout(function() { + server.listen(port, '127.0.0.1'); + }, 1000); + } + else { console.error(e.toString().red); LiveServer.shutdown(); } @@ -292,8 +298,8 @@ LiveServer.start = function(options) { LiveServer.server = server; var address = server.address(); - var serveHost = address.address === "0.0.0.0" ? "127.0.0.1" : address.address; - var openHost = host === "0.0.0.0" ? "127.0.0.1" : host; + var serveHost = address.address; + var openHost = host; var serveURL = protocol + '://' + serveHost + ':' + address.port; var openURL = protocol + '://' + openHost + ':' + address.port;