diff --git a/middleman-core/features/cli/preview_server-hook.feature b/middleman-core/features/cli/preview_server-hook.feature
new file mode 100644
index 00000000..15f6cba0
--- /dev/null
+++ b/middleman-core/features/cli/preview_server-hook.feature
@@ -0,0 +1,17 @@
+Feature: Run preview server before hook
+
+ Scenario: When run
+ Given a fixture app "preview-server-hook-app"
+ And the default aruba timeout is 30 seconds
+ When I run `middleman server --server-name localhost --bind-address 127.0.0.1` interactively
+ And I stop middleman if the output contains:
+ """
+ ### END ###
+ """
+ Then the output should contain:
+ """
+ /// 127.0.0.1:4567 ///
+ /// 4567 ///
+ /// localhost ///
+ /// http://localhost:4567 ///
+ """
diff --git a/middleman-core/fixtures/preview-server-hook-app/config.rb b/middleman-core/fixtures/preview-server-hook-app/config.rb
new file mode 100644
index 00000000..9892009e
--- /dev/null
+++ b/middleman-core/fixtures/preview-server-hook-app/config.rb
@@ -0,0 +1,19 @@
+set :layout, false
+
+class MyFeature < Middleman::Extension
+ def initialize(app, options_hash = {}, &block)
+ super
+
+ app.before_server do |server_information|
+ puts "/// #{server_information.listeners.first} ///"
+ puts "/// #{server_information.port} ///"
+ puts "/// #{server_information.server_name} ///"
+ puts "/// #{server_information.site_addresses.first} ///"
+ puts "/// ### END ### ///"
+ end
+ end
+end
+
+::Middleman::Extensions.register(:my_feature, MyFeature)
+
+activate :my_feature
diff --git a/middleman-core/fixtures/preview-server-hook-app/source/index.html.erb b/middleman-core/fixtures/preview-server-hook-app/source/index.html.erb
new file mode 100644
index 00000000..ca390d46
--- /dev/null
+++ b/middleman-core/fixtures/preview-server-hook-app/source/index.html.erb
@@ -0,0 +1,9 @@
+
+
+
+ preview-server-hook-app
+
+
+ preview-server-hook-app
+
+
diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb
index 4e46ed82..cf5cfd66 100644
--- a/middleman-core/lib/middleman-core/application.rb
+++ b/middleman-core/lib/middleman-core/application.rb
@@ -216,7 +216,8 @@ module Middleman
:before_shutdown,
:before, # Before Rack requests
:before_render,
- :after_render
+ :after_render,
+ :before_server
])
@middleware = Set.new
diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb
index 40275df5..ffed7f21 100644
--- a/middleman-core/lib/middleman-core/preview_server.rb
+++ b/middleman-core/lib/middleman-core/preview_server.rb
@@ -6,6 +6,7 @@ require 'middleman-core/logger'
require 'middleman-core/rack'
require 'middleman-core/preview_server/server_information'
require 'middleman-core/preview_server/server_url'
+require 'middleman-core/preview_server/server_information_callback_proxy'
# rubocop:disable GlobalVars
module Middleman
@@ -15,10 +16,6 @@ module Middleman
attr_reader :app, :ssl_certificate, :ssl_private_key, :environment, :server_information
- def https?
- @https == true
- end
-
# Start an instance of Middleman::Application
# @return [void]
def start(opts={})
@@ -28,6 +25,7 @@ module Middleman
@options = opts
@server_information = ServerInformation.new
+ @server_information.https = (@options[:https] == true)
# New app evaluates the middleman configuration. Since this can be
# invalid as well, we need to evaluate the configuration BEFORE
@@ -44,9 +42,9 @@ module Middleman
app.logger.debug %(== Server information is provided by #{server_information.handler})
app.logger.debug %(== The Middleman is running in "#{environment}" environment)
- app.logger.debug format('== The Middleman preview server is bound to %s', ServerUrl.new(hosts: server_information.listeners, port: server_information.port, https: https?).to_bind_addresses.join(', '))
- app.logger.info format('== View your site at %s', ServerUrl.new(hosts: server_information.site_addresses, port: server_information.port, https: https?).to_urls.join(', '))
- app.logger.info format('== Inspect your site configuration at %s', ServerUrl.new(hosts: server_information.site_addresses, port: server_information.port, https: https?).to_config_urls.join(', '))
+ app.logger.debug format('== The Middleman preview server is bound to %s', ServerUrl.new(hosts: server_information.listeners, port: server_information.port, https: server_information.https?).to_bind_addresses.join(', '))
+ app.logger.info format('== View your site at %s', ServerUrl.new(hosts: server_information.site_addresses, port: server_information.port, https: server_information.https?).to_urls.join(', '))
+ app.logger.info format('== Inspect your site configuration at %s', ServerUrl.new(hosts: server_information.site_addresses, port: server_information.port, https: server_information.https?).to_config_urls.join(', '))
@initialized ||= false
return if @initialized
@@ -58,6 +56,8 @@ module Middleman
# reloading later on.
::Middleman::Profiling.report('server_start')
+ app.execute_callbacks(:before_server, [ServerInformationCallbackProxy.new(server_information)])
+
loop do
@webrick.start
@@ -170,7 +170,6 @@ module Middleman
app.logger.warn format('== The Middleman uses a different port "%s" then the configured one "%s" because some other server is listening on that port.', server_information.port, configured_port) unless app.config[:port] == configured_port
- @https = app.config[:https]
@environment = app.config[:environment]
@ssl_certificate = app.config[:ssl_certificate]
@@ -216,7 +215,7 @@ module Middleman
DoNotReverseLookup: true
}
- if https?
+ if server_information.https?
http_opts[:SSLEnable] = true
if ssl_certificate || ssl_private_key
diff --git a/middleman-core/lib/middleman-core/preview_server/server_information.rb b/middleman-core/lib/middleman-core/preview_server/server_information.rb
index 937efdd5..345da1c7 100644
--- a/middleman-core/lib/middleman-core/preview_server/server_information.rb
+++ b/middleman-core/lib/middleman-core/preview_server/server_information.rb
@@ -20,6 +20,8 @@ module Middleman
public
+ attr_writer :https
+
def initialize(opts={})
@resolver = opts.fetch(:resolver, DnsResolver.new)
@validator = opts.fetch(:validator, ServerInformationValidator.new)
@@ -64,10 +66,12 @@ module Middleman
@bind_address = config[:bind_address]
@port = config[:port]
@server_name = config[:server_name]
+ @https = config[:https]
config[:bind_address] = bind_address
- config[:port] = port
- config[:server_name] = server_name
+ config[:port] = port
+ config[:server_name] = server_name
+ config[:https] = https?
end
# Make information of internal server class avaible to make debugging
@@ -139,6 +143,11 @@ module Middleman
def listeners
information.listeners
end
+
+ # Is https enabled?
+ def https?
+ @https == true
+ end
end
end
end
diff --git a/middleman-core/lib/middleman-core/preview_server/server_information_callback_proxy.rb b/middleman-core/lib/middleman-core/preview_server/server_information_callback_proxy.rb
new file mode 100644
index 00000000..106abba0
--- /dev/null
+++ b/middleman-core/lib/middleman-core/preview_server/server_information_callback_proxy.rb
@@ -0,0 +1,35 @@
+module Middleman
+ class PreviewServer
+ # This class wraps server information to be used in call back
+ #
+ # * listeners
+ # * port
+ # * server name
+ # * site_addresses
+ #
+ # All information is "dupped" and the callback is not meant to be used to
+ # modify these information.
+ class ServerInformationCallbackProxy
+ attr_reader :server_name, :port, :site_addresses, :listeners
+
+ def initialize(server_information)
+ @listeners = ServerUrl.new(
+ hosts: server_information.listeners,
+ port: server_information.port,
+ https: server_information.https?,
+ format_output: false
+ ).to_bind_addresses
+
+ @port = server_information.port
+ @server_name = server_information.server_name.dup unless server_information.server_name == nil
+
+ @site_addresses = ServerUrl.new(
+ hosts: server_information.site_addresses,
+ port: server_information.port,
+ https: server_information.https?,
+ format_output: false
+ ).to_urls
+ end
+ end
+ end
+end
diff --git a/middleman-core/lib/middleman-core/preview_server/server_url.rb b/middleman-core/lib/middleman-core/preview_server/server_url.rb
index 9b7a5b29..bc18da55 100644
--- a/middleman-core/lib/middleman-core/preview_server/server_url.rb
+++ b/middleman-core/lib/middleman-core/preview_server/server_url.rb
@@ -6,7 +6,7 @@ module Middleman
class ServerUrl
private
- attr_reader :hosts, :port, :https
+ attr_reader :hosts, :port, :https, :format_output
public
@@ -14,6 +14,7 @@ module Middleman
@hosts = opts.fetch(:hosts)
@port = opts.fetch(:port)
@https = opts.fetch(:https, false)
+ @format_output = opts.fetch(:format_output, true)
end
# Return bind addresses
@@ -21,7 +22,11 @@ module Middleman
# @return [Array]
# List of bind addresses of format host:port
def to_bind_addresses
- hosts.map { |l| format('"%s:%s"', l.to_s, port) }
+ if format_output
+ hosts.map { |l| format('"%s:%s"', l.to_s, port) }
+ else
+ hosts.map { |l| format('%s:%s', l.to_s, port) }
+ end
end
# Return server urls
@@ -29,7 +34,11 @@ module Middleman
# @return [Array]
# List of urls of format http://host:port
def to_urls
- hosts.map { |l| format('"%s://%s:%s"', https? ? 'https' : 'http', l.to_browser, port) }
+ if format_output
+ hosts.map { |l| format('"%s://%s:%s"', https? ? 'https' : 'http', l.to_browser, port) }
+ else
+ hosts.map { |l| format('%s://%s:%s', https? ? 'https' : 'http', l.to_browser, port) }
+ end
end
# Return server config urls
@@ -37,7 +46,11 @@ module Middleman
# @return [Array]
# List of urls of format http://host:port/__middleman
def to_config_urls
- hosts.map { |l| format('"%s://%s:%s/__middleman"', https? ? 'https' : 'http', l.to_browser, port) }
+ if format_output
+ hosts.map { |l| format('"%s://%s:%s/__middleman"', https? ? 'https' : 'http', l.to_browser, port) }
+ else
+ hosts.map { |l| format('%s://%s:%s/__middleman', https? ? 'https' : 'http', l.to_browser, port) }
+ end
end
private