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