Parse server's addr before use it

This commit is contained in:
Makis Maropoulos 2016-07-07 17:17:34 +02:00
parent 981fef9ecf
commit e3b2c68085
5 changed files with 100 additions and 56 deletions

View File

@ -3,6 +3,7 @@ package config
import (
"os"
"strconv"
"strings"
"github.com/imdario/mergo"
"github.com/kataras/fasthttp"
@ -51,6 +52,37 @@ type Server struct {
Virtual bool
}
// ServerParseAddr parses the listening addr and returns this
func ServerParseAddr(listeningAddr string) string {
// check if addr has :port, if not do it +:80 ,we need the hostname for many cases
a := listeningAddr
if a == "" {
// check for os environments
if oshost := os.Getenv("HOST"); oshost != "" {
a = oshost
} else if oshost := os.Getenv("ADDR"); oshost != "" {
a = oshost
} else if osport := os.Getenv("PORT"); osport != "" {
a = ":" + osport
}
if a == "" {
a = DefaultServerAddr
}
}
if portIdx := strings.IndexByte(a, ':'); portIdx == 0 {
// if contains only :port ,then the : is the first letter, so we dont have setted a hostname, lets set it
a = DefaultServerHostname + a
}
if portIdx := strings.IndexByte(a, ':'); portIdx < 0 {
// missing port part, add it
a = a + ":80"
}
return a
}
// DefaultServer returns the default configs for the server
func DefaultServer() Server {
return Server{ListeningAddr: DefaultServerAddr,

View File

@ -220,7 +220,7 @@ func (ctx *Context) HostString() string {
func (ctx *Context) VirtualHostname() string {
realhost := ctx.HostString()
hostname := realhost
virtualhost := ctx.framework.Servers.Main().VirtualHostname()
virtualhost := ctx.framework.Servers.Main().Hostname()
if portIdx := strings.IndexByte(hostname, ':'); portIdx > 0 {
hostname = hostname[0:portIdx]

70
http.go
View File

@ -230,7 +230,6 @@ func StatusText(code int) string {
var (
errServerPortAlreadyUsed = errors.New("Server can't run, port is already used")
errServerAlreadyStarted = errors.New("Server is already started and listening")
errServerConfigMissing = errors.New("Empty Config for server")
errServerHandlerMissing = errors.New("Handler is missing from server, can't start without handler")
errServerIsClosed = errors.New("Can't close the server, propably is already closed or never started")
errServerRemoveUnix = errors.New("Unexpected error when trying to remove unix socket file. Addr: %s | Trace: %s")
@ -256,9 +255,15 @@ type (
// newServer returns a pointer to a Server object, and set it's options if any, nothing more
func newServer(cfg config.Server) *Server {
s := &Server{Server: &fasthttp.Server{Name: config.ServerName}, Config: cfg}
s.prepare()
return s
}
// prepare just prepares the listening addr
func (s *Server) prepare() {
s.Config.ListeningAddr = config.ServerParseAddr(s.Config.ListeningAddr)
}
// IsListening returns true if server is listening/started, otherwise false
func (s *Server) IsListening() bool {
if s == nil {
@ -288,43 +293,28 @@ func (s *Server) Listener() net.Listener {
return s.listener
}
// Host returns the Listener().Addr().String(), if server is not listening it returns the config.ListeningAddr
// Host returns the registered host for the server
func (s *Server) Host() (host string) {
if s.IsListening() {
return s.Listener().Addr().String()
}
return s.Config.ListeningAddr
}
// Port returns the port which server listening for
// if no port given with the ListeningAddr, it returns 80
func (s *Server) Port() (port int) {
a := s.Config.ListeningAddr
if portIdx := strings.IndexByte(a, ':'); portIdx == 0 {
if portIdx := strings.IndexByte(a, ':'); portIdx != -1 {
p, err := strconv.Atoi(a[portIdx+1:])
if err != nil {
port = 80
} else {
port = p
}
} else {
port = 80
}
return
}
// VirtualHost returns the s.Config.ListeningAddr
//
func (s *Server) VirtualHost() (host string) {
// check the addr if :8080 do it 0.0.0.0:8080 ,we need the hostname for many cases
a := s.Config.ListeningAddr
//check if contains hostname, we need the full host, :8080 should be : 127.0.0.1:8080
if portIdx := strings.IndexByte(a, ':'); portIdx == 0 {
// then the : is the first letter, so we dont have setted a hostname, lets set it
s.Config.ListeningAddr = config.DefaultServerHostname + a
}
return s.Config.ListeningAddr
}
// FullHost returns the scheme+host
func (s *Server) FullHost() string {
scheme := "http://"
@ -332,30 +322,12 @@ func (s *Server) FullHost() string {
if s.IsSecure() || (s.Config.CertFile != "" && s.Config.KeyFile != "") {
scheme = "https://"
}
return scheme + s.VirtualHost()
return scheme + s.Host()
}
// Hostname returns the hostname part only, if host == localhost:8080 it will return the localhost
// if server is not listening it returns the config.ListeningAddr's hostname part
func (s *Server) Hostname() (hostname string) {
if s.IsListening() {
fullhost := s.Listener().Addr().String()
hostname = fullhost[0:strings.IndexByte(fullhost, ':')] // no the port
} else {
hostname = s.VirtualHostname()
}
return
}
// VirtualHostname returns the hostname that user registers, host path maybe differs from the real which is HostString, which taken from a net.listener
func (s *Server) VirtualHostname() (hostname string) {
hostname = s.Config.ListeningAddr
if idx := strings.IndexByte(hostname, ':'); idx > 1 { // at least after second char
hostname = hostname[0:idx]
} else {
hostname = config.DefaultServerHostname
}
return
// Hostname returns the hostname part of the host (host expect port)
func (s *Server) Hostname() string {
return s.Host()[0:strings.IndexByte(s.Host(), ':')] // no the port
}
func (s *Server) listen() error {
@ -420,17 +392,7 @@ func (s *Server) Open(h fasthttp.RequestHandler) error {
return errServerAlreadyStarted.Return()
}
if s.Config.ListeningAddr == "" {
return errServerConfigMissing.Return()
}
// check the addr if :8080 do it 0.0.0.0:8080 ,we need the hostname for many cases
a := s.Config.ListeningAddr
//check if contains hostname, we need the full host, :8080 should be : 127.0.0.1:8080
if portIdx := strings.IndexByte(a, ':'); portIdx == 0 {
// then the : is the first letter, so we dont have setted a hostname, lets set it
s.Config.ListeningAddr = config.DefaultServerHostname + a
}
s.prepare() // do it again for any case
if s.Config.MaxRequestBodySize > config.DefaultMaxRequestBodySize {
s.Server.MaxRequestBodySize = int(s.Config.MaxRequestBodySize)
@ -570,7 +532,7 @@ func (s *ServerList) OpenAll() error {
break
}
if i == l {
s.mux.setHostname(s.servers[i].VirtualHostname())
s.mux.setHostname(s.servers[i].Hostname())
}
}

View File

@ -69,6 +69,56 @@ const (
`
)
func TestServerHost(t *testing.T) {
var server1, server2, server3 Server
var expectedHost1 = "mydomain.com:1993"
var expectedHost2 = "mydomain.com:80"
var expectedHost3 = "127.0.0.1:9090"
server1.Config.ListeningAddr = expectedHost1
server2.Config.ListeningAddr = "mydomain.com"
server3.Config.ListeningAddr = ":9090"
server1.prepare()
server2.prepare()
server3.prepare()
if server1.Host() != expectedHost1 {
t.Fatalf("Expecting server 1's host to be %s but we got %s", expectedHost1, server1.Host())
}
if server2.Host() != expectedHost2 {
t.Fatalf("Expecting server 2's host to be %s but we got %s", expectedHost2, server2.Host())
}
if server3.Host() != expectedHost3 {
t.Fatalf("Expecting server 3's host to be %s but we got %s", expectedHost3, server3.Host())
}
}
func TestServerHostname(t *testing.T) {
var server Server
var expectedHostname = "mydomain.com"
server.Config.ListeningAddr = expectedHostname + ":1993"
server.prepare()
if server.Hostname() != expectedHostname {
t.Fatalf("Expecting server's hostname to be %s but we got %s", expectedHostname, server.Hostname())
}
}
func TestServerPort(t *testing.T) {
var server1, server2 Server
expectedPort1 := 8080
expectedPort2 := 80
server1.Config.ListeningAddr = "mydomain.com:8080"
server2.Config.ListeningAddr = "mydomain.com"
server1.prepare()
server2.prepare()
if server1.Port() != expectedPort1 {
t.Fatalf("Expecting server 1's port to be %d but we got %d", expectedPort1, server1.Port())
}
if server2.Port() != expectedPort2 {
t.Fatalf("Expecting server 2's port to be %d but we got %d", expectedPort2, server2.Port())
}
}
// Contains the server test for multi running servers
func TestMultiRunningServers_v1(t *testing.T) {
host := "mydomain.com:443" // you have to add it to your hosts file( for windows, as 127.0.0.1 mydomain.com)

View File

@ -656,7 +656,7 @@ func (s *Framework) URL(routeName string, args ...interface{}) (url string) {
scheme = "https://"
}
host := srv.VirtualHost()
host := srv.Host()
arguments := args[0:]
// join arrays as arguments