Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config.js -- one place to define protocol (http/https) #1002

Closed
buildbreakdo opened this issue Nov 29, 2016 · 2 comments
Closed

Config.js -- one place to define protocol (http/https) #1002

buildbreakdo opened this issue Nov 29, 2016 · 2 comments

Comments

@buildbreakdo
Copy link

buildbreakdo commented Nov 29, 2016

In the process of switching over from http to https and have come to agree with what @Strandedpirate suggested in #709 -- would be nice if there was one place to define which protocol (http || https) is to be used in the config.js.

@Strandedpirate
Copy link

Strandedpirate commented Dec 4, 2016

Sharing my config and findings thus far with this kit because you'll likely run into the same issues configuring browser-sync that I did when hooking things up to a configuration file.

Wasted a lot of time trying to fulfill browser-sync's configuration needs and seeing strange errors. Things were fragile for a while until I distilled what was going on. It boiled down to needing to serve up the port differently based on whether we are statically configuring the application vs actually making runtime calls. Anything under the tools folder calls into the config with true for the isStartup parameter to get the port, baseUrl, or localUrl so that the default port is returned. e.g. 4000 in this configuration. server.js also requires true for the isStartup parameter for any static configuration related stuff like the listen call. Everywhere else that is runtime will simply call in to the config without specifying the isStartup as it defaults to false and the port will be automatically incremented by one to match up with browser-sync's proxy server's port (this is in development only of course). e.g. 4001 in this example.

Anyway if someone wants to bake this config into the kit then its just a simply matter of keying off of config.url.scheme in a few places to easily switch between http vs https.

config.js

export default {
  get environment(){
    return process.env.NODE_ENV;
  },
  siteName: 'Foobar',
  get siteNameLower() {
    return this.siteName.toLowerCase();
  },
  /**
   * Returns the full base url. (scheme + authority)
   * @param isStartup set to true if calling during static configuration; false otherwise (during runtime).
   * @returns {string}
   */
  baseUrl(isStartup = false) {
    return `${this.url.scheme}://${this.url.authority(isStartup)}`;
  },
  /**
   * Returns an absolute path by combining the base url with the relative path.
   * @param relativePath the relative path.
   * @param isStartup set to true if calling during static configuration; false otherwise (during runtime).
   * @returns {string}
   */
  localUrl(relativePath, isStartup = false){
    const path = relativePath.startsWith('/') ? relativePath : `/${relativePath}`;
    return `${this.baseUrl(isStartup)}${path}`;
  },
  /**
   * The parts of a URL are defined as:
   *
   * foo://example.com:4235/test/there?name=jerald#star
   * \_/   \______________/\_________/ \_________/ \__/
   * |           |            |            |        |
   * scheme     authority       path        query   fragment
   *
   */
  url: {
    /**
     * The scheme. Either http or https
     */
    scheme: process.env.WEBSITE_SCHEME || `https`,
    /**
     * The domain name or IP address.
     */
    host: process.env.WEBSITE_HOST || 'dev.foobar.com',
    /**
     * Gets the port number.
     * @param isStartup set to true if calling during static configuration; false otherwise (during runtime).
     * @returns {*|number}
     */
    port(isStartup = false) {
      let port = process.env.WEBSITE_PORT || 4000;
      // increment the port to align with browser-sync's proxy server port
      if (isStartup === false && process.env.NODE_ENV === 'development') {
        port++;
      }
      return port;
    },
    /**
     * Returns a string comprising the host and port.
     * @param isStartup set to true if calling during static configuration; false otherwise (during runtime).
     * @returns {string}
     */
    authority(isStartup = false) {
      let portString = !this.port ? '' : (this.port === 80 || this.port == 443 ? '' : `:${this.port(isStartup)}`);
      return `${this.host}${portString}`;
    },
  },
  ssl: {
    key: 'src/sslcert/server.key',
    cert: 'src/sslcert/foobar_com.crt',
    ca: '',
  },
};

start.js

bs.init({
  ...(clientConfig.debug ? { notify: false } : { notify: false, ui: false }),
  scheme: config.url.scheme,
  port: config.url.port(true), // this should return the non-incremented port. e.g. 4000
  open: 'proxy',
  proxy: {
	target: config.baseUrl(true), // this should be the url with the non-incremented port. e.g. https://www.foobar.com:4000
	middleware: [wpMiddleware, hotMiddleware],
  },
  https: {
        key: config.ssl.key,
        cert: config.ssl.cert,
  },
  ...
}, resolve);

server.js

const credentials = {
  key: fs.readFileSync(config.ssl.key),
  cert: fs.readFileSync(config.ssl.cert),
};

app.use(async(req, res, next) => { 
  // if i need to get a port or url during runtime simply call into the config with no parameter
  console.log(`baseUrl is: ${config.baseUrl()}`); // this will be the url with the incremented port. e.g. https://www.foobar.com:4001
  next();
});

const httpsServer = https.createServer(credentials, app);
httpsServer.listen(config.url.port(true), () => { // this should return the non-incremented port. e.g. 4000
  console.log(`The server is running at ${config.baseUrl(true)}`); // this should be the url with the non-incremented port. e.g. https://www.foobar.com:4000
});

@buildbreakdo
Copy link
Author

buildbreakdo commented Dec 10, 2016

After using this config, which does work. Thank you! Decided to handle HTTPS at the load balancer instead of within the app itself. Believe if configuration can be offloaded to some other part of the app then we should do it (load balancer), basic premise is to keep config as much out of the app as possible.

Closing this for now as I don't believe it's actionable for most people and, in my opinion, is probably not the best route to go.

For those interested in the load balancer approach, Amazon gives you SSL certs for free if you use their load balancer. More on that here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants