The preview server can now serve over HTTPS using the --https flag. It will use an automatic self-signed cert which can be overridden using --ssl_certificate and --ssl_private_key. These settings can also be set in config.rb.

This commit is contained in:
Ben Hollis 2015-05-02 20:54:58 -07:00
parent d1211cc089
commit f8e4f6f059
4 changed files with 54 additions and 2 deletions

View file

@ -33,3 +33,4 @@ master
* Remove deprecated `request` instance * Remove deprecated `request` instance
* Remove old module-style extension support * Remove old module-style extension support
* Placed all `config.rb` evaluation inside the `ConfigContext` class * Placed all `config.rb` evaluation inside the `ConfigContext` class
* The preview server can now serve over HTTPS using the `--https` flag. It will use an automatic self-signed cert which can be overridden using `--ssl_certificate` and `--ssl_private_key`. These settings can also be set in `config.rb`

View file

@ -89,6 +89,18 @@ module Middleman
# @return [Fixnum] # @return [Fixnum]
config.define_setting :port, 4567, 'The preview server port' config.define_setting :port, 4567, 'The preview server port'
# Whether to serve the preview server over HTTPS.
# @return [Boolean]
config.define_setting :https, false, 'Serve the preview server over SSL/TLS'
# The (optional) path to the SSL cert to use for the preview server.
# @return [String]
config.define_setting :ssl_certificate, nil, 'Path to an X.509 certificate to use for the preview server'
# The (optional) private key for the certificate in :ssl_certificate.
# @return [String]
config.define_setting :ssl_private_key, nil, "Path to an RSA private key for the preview server's certificate"
# Name of the source directory # Name of the source directory
# @return [String] # @return [String]
config.define_setting :source, 'source', 'Name of the source directory' config.define_setting :source, 'source', 'Name of the source directory'

View file

@ -18,6 +18,13 @@ module Middleman::Cli
method_option :port, method_option :port,
aliases: '-p', aliases: '-p',
desc: 'The port Middleman will listen on' desc: 'The port Middleman will listen on'
method_option :https,
type: :boolean,
desc: 'Serve the preview server over SSL/TLS'
method_option :ssl_certificate,
desc: 'Path to an X.509 certificate to use for the preview server'
method_option :ssl_private_key,
desc: "Path to an RSA private key for the preview server's certificate"
method_option :verbose, method_option :verbose,
type: :boolean, type: :boolean,
default: false, default: false,
@ -63,6 +70,9 @@ module Middleman::Cli
params = { params = {
port: options['port'], port: options['port'],
host: options['host'], host: options['host'],
https: options['https'],
ssl_certificate: options['ssl_certificate'],
ssl_private_key: options['ssl_private_key'],
environment: options['environment'], environment: options['environment'],
debug: options['verbose'], debug: options['verbose'],
instrumenting: options['instrument'], instrumenting: options['instrument'],

View file

@ -1,4 +1,6 @@
require 'webrick' require 'webrick'
require 'webrick/https'
require 'openssl'
require 'middleman-core/meta_pages' require 'middleman-core/meta_pages'
require 'middleman-core/logger' require 'middleman-core/logger'
require 'middleman-core/rack' require 'middleman-core/rack'
@ -9,9 +11,13 @@ module Middleman
class << self class << self
extend Forwardable extend Forwardable
attr_reader :app, :host, :port attr_reader :app, :host, :port, :ssl_certificate, :ssl_private_key
def_delegator :app, :logger def_delegator :app, :logger
def https?
@https
end
# Start an instance of Middleman::Application # Start an instance of Middleman::Application
# @return [void] # @return [void]
def start(opts={}) def start(opts={})
@ -105,6 +111,8 @@ module Middleman
config[:host] = opts[:host] if opts[:host] config[:host] = opts[:host] if opts[:host]
config[:port] = opts[:port] if opts[:port] config[:port] = opts[:port] if opts[:port]
config[:ssl_certificate] = opts[:ssl_certificate] if opts[:ssl_certificate]
config[:ssl_private_key] = opts[:ssl_private_key] if opts[:ssl_private_key]
ready do ready do
match_against = [ match_against = [
@ -123,6 +131,10 @@ module Middleman
@host = app.config[:host] @host = app.config[:host]
@port = app.config[:port] @port = app.config[:port]
@https = @app.config[:https]
@ssl_certificate = @app.config[:ssl_certificate]
@ssl_private_key = @app.config[:ssl_private_key]
app.files.on_change :reload do app.files.on_change :reload do
$mm_reload = true $mm_reload = true
@ -163,6 +175,22 @@ module Middleman
DoNotReverseLookup: true DoNotReverseLookup: true
} }
if https?
http_opts[:SSLEnable] = true
if ssl_certificate || ssl_private_key
raise "You must provide both :ssl_certificate and :ssl_private_key" unless ssl_private_key && ssl_certificate
http_opts[:SSLCertificate] = OpenSSL::X509::Certificate.new File.read ssl_certificate
http_opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new File.read ssl_private_key
else
# use a generated self-signed cert
http_opts[:SSLCertName] = [
%w(CN localhost),
%w(CN #{host})
].uniq
end
end
if is_logging if is_logging
http_opts[:Logger] = FilteredWebrickLog.new http_opts[:Logger] = FilteredWebrickLog.new
else else
@ -203,7 +231,8 @@ module Middleman
# @return [URI] # @return [URI]
def uri def uri
host = (@host == '0.0.0.0') ? 'localhost' : @host host = (@host == '0.0.0.0') ? 'localhost' : @host
URI("http://#{host}:#{@port}") scheme = https? ? 'https' : 'http'
URI("#{scheme}://#{host}:#{@port}")
end end
end end