middleman/middleman-core/lib/middleman-core/preview_server/server_information.rb

154 lines
4.4 KiB
Ruby

require 'middleman-core/dns_resolver'
require 'middleman-core/preview_server/information'
require 'middleman-core/preview_server/network_interface_inventory'
require 'middleman-core/preview_server/tcp_port_prober'
require 'middleman-core/preview_server/server_information_validator'
module Middleman
class PreviewServer
# This class holds all information which the preview server needs to setup a listener
#
# * server name
# * bind address
# * port
#
# Furthermore it probes for a free tcp port, if the default one 4567 is not available.
class ServerInformation
private
attr_reader :resolver, :validator, :network_interface_inventory, :informations, :tcp_port_prober
public
attr_writer :https
def initialize(opts={})
@resolver = opts.fetch(:resolver, DnsResolver.new)
@validator = opts.fetch(:validator, ServerInformationValidator.new)
@network_interface_inventory = opts.fetch(:network_interface_inventory, NetworkInterfaceInventory.new)
@tcp_port_prober = opts.fetch(:tcp_port_prober, TcpPortProber.new)
@informations = []
@informations << AllInterfaces
@informations << AllIpv4Interfaces
@informations << AllIpv6Interfaces
@informations << ServerNameIsIpInformation
@informations << ServerNameInformation
@informations << BindAddressInformation
@informations << BindAddressAndServerNameInformation
@informations << DefaultInformation
end
# The information
#
# Is cached
def information
return @information if @information
# The `DefaultInformation`-class always returns `true`, so there's
# always a klass available and find will never return nil
listener_klass = informations.find { |l| l.matches? bind_address: @bind_address, server_name: @server_name }
@information = listener_klass.new(bind_address: @bind_address, server_name: @server_name)
@information.show_me_network_interfaces(network_interface_inventory)
@information.resolve_me(resolver)
@information.port = tcp_port_prober.port(@port)
@information.validate_me(validator)
@information
end
# Use a middleman configuration to get information
#
# @param [#[]] config
# The middleman config
def use(config)
@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[:https] = https?
end
# Make information of internal server class available to make debugging
# easier. This can be used to log the class which was used to determine
# the preview server settings
#
# @return [String]
# The name of the class
def handler
information.class.to_s
end
# Is the server information valid?
#
# This is used to output a helpful error message, which can be stored in
# `#reason`.
#
# @return [TrueClass, FalseClass]
# The result
def valid?
information.valid?
end
# The reason why the information is NOT valid
#
# @return [String]
# The reason why the information is not valid
def reason
information.reason
end
# The server name
#
# @return [String]
# The name of the server
def server_name
information.server_name
end
# The bind address of server
#
# @return [String]
# The bind address of the server
def bind_address
information.bind_address
end
# The port on which the server should listen
#
# @return [Integer]
# The port number
def port
information.port
end
# A list of site addresses
#
# @return [Array]
# A list of addresses which can be used to access the middleman preview
# server
def site_addresses
information.site_addresses
end
# A list of listeners
#
# @return [Array]
# A list of bind address where the
def listeners
information.listeners
end
# Is https enabled?
def https?
@https == true
end
end
end
end