From d76b73427bfc5c7f04b6ec8f4ca446450a28ed01 Mon Sep 17 00:00:00 2001 From: Makis Maropoulos Date: Tue, 5 Jul 2016 15:26:47 +0200 Subject: [PATCH] New: ListenVirtual and ListenTo specific configs - server_test fixed --- config/iris.go | 8 ----- initiatory.go | 29 +++++------------ iris.go | 85 +++++++++++++++++++++++++++++++----------------- plugin_test.go | 3 +- server_test.go | 27 +++------------ sessions_test.go | 2 +- 6 files changed, 71 insertions(+), 83 deletions(-) diff --git a/config/iris.go b/config/iris.go index c7d7310b..930b0883 100644 --- a/config/iris.go +++ b/config/iris.go @@ -103,13 +103,6 @@ type ( // Websocket contains the configs for Websocket's server integration Websocket *Websocket - // Server contains the configs for the http server - // Server configs are the only one which are setted inside base Iris package (from Listen, ListenTLS, ListenUNIX) NO from users - // - // this field is useful only when you need to READ which is the server's address, certfile & keyfile or unix's mode. - // - Server Server - // Tester contains the configs for the test framework, so far we have only one because all test framework's configs are setted by the iris itself Tester Tester } @@ -148,7 +141,6 @@ func Default() Iris { Sessions: DefaultSessions(), Render: DefaultRender(), Websocket: DefaultWebsocket(), - Server: DefaultServer(), Tester: Tester{Debug: false}, } } diff --git a/initiatory.go b/initiatory.go index 2c6fa358..111861c2 100644 --- a/initiatory.go +++ b/initiatory.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "sync" - "testing" "time" "github.com/gavv/httpexpect" @@ -29,7 +28,7 @@ var ( HTTPServer *Server // Available is a channel type of bool, fired to true when the server is opened and all plugins ran // never fires false, if the .Close called then the channel is re-allocating. - // the channel is always oepen until you close it when you don't need this. + // the channel is closed only when .ListenVirtual is used, otherwise it remains open until you close it. // // Note: it is a simple channel and decided to put it here and no inside HTTPServer, doesn't have statuses just true and false, simple as possible // Where to use that? @@ -119,8 +118,9 @@ func New(cfg ...config.Iris) *Framework { mux := newServeMux(sync.Pool{New: func() interface{} { return &Context{framework: s} }}, s.Logger) // set the public router API (and party) s.muxAPI = &muxAPI{mux: mux, relativePath: "/"} - // set the server - s.HTTPServer = newServer(&s.Config.Server) + // set the server with the default configuration, which is changed on Listen functions + defaultServerCfg := config.DefaultServer() + s.HTTPServer = newServer(&defaultServerCfg) } return s @@ -187,15 +187,12 @@ func (s *Framework) openServer() (err error) { s.HTTPServer.Host())) } s.Plugins.DoPostListen(s) - go func() { - s.Available <- true - }() - if !s.Config.Server.Virtual { - ch := make(chan os.Signal) - <-ch - s.Close() - } + go func() { s.Available <- true }() + + ch := make(chan os.Signal) + <-ch + s.Close() } return @@ -207,11 +204,3 @@ func (s *Framework) closeServer() error { s.Available = make(chan bool) return s.HTTPServer.Close() } - -// tester returns the test framework -func (s *Framework) tester(t *testing.T) *httpexpect.Expect { - if s.testFramework == nil { - s.testFramework = NewTester(s, t) - } - return s.testFramework -} diff --git a/iris.go b/iris.go index f4d783c1..42f419ab 100644 --- a/iris.go +++ b/iris.go @@ -86,6 +86,7 @@ type ( FrameworkAPI interface { MuxAPI Must(error) + ListenTo(config.Server) error ListenWithErr(string) error Listen(string) ListenTLSWithErr(string, string, string) error @@ -93,8 +94,8 @@ type ( ListenUNIXWithErr(string, os.FileMode) error ListenUNIX(string, os.FileMode) SecondaryListen(config.Server) *Server + ListenVirtual(...string) *Server NoListen(...string) *Server - ListenVirtual(cfg ...config.Server) *Server Close() // global middleware prepending, registers to all subdomains, to all parties, you can call it at the last also MustUse(...Handler) @@ -171,6 +172,19 @@ func (s *Framework) Must(err error) { } } +// ListenTo listens to a server but receives the full server's configuration +// it's a blocking func +func ListenTo(cfg config.Server) error { + return Default.ListenTo(cfg) +} + +// ListenTo listens to a server but receives the full server's configuration +// it's a blocking func +func (s *Framework) ListenTo(cfg config.Server) error { + s.HTTPServer.Config = &cfg + return s.openServer() +} + // ListenWithErr starts the standalone http server // which listens to the addr parameter which as the form of // host:port @@ -200,8 +214,12 @@ func Listen(addr string) { // if you need a func to panic on error use the Listen // ex: log.Fatal(iris.ListenWithErr(":8080")) func (s *Framework) ListenWithErr(addr string) error { - s.Config.Server.ListeningAddr = addr - return s.openServer() + cfg := config.DefaultServer() + if len(addr) > 0 { + cfg.ListeningAddr = addr + } + + return s.ListenTo(cfg) } // Listen starts the standalone http server @@ -249,13 +267,14 @@ func ListenTLS(addr string, certFile string, keyFile string) { // if you need a func to panic on error use the ListenTLS // ex: log.Fatal(iris.ListenTLSWithErr(":8080","yourfile.cert","yourfile.key")) func (s *Framework) ListenTLSWithErr(addr string, certFile string, keyFile string) error { + cfg := config.DefaultServer() if certFile == "" || keyFile == "" { return fmt.Errorf("You should provide certFile and keyFile for TLS/SSL") } - s.Config.Server.ListeningAddr = addr - s.Config.Server.CertFile = certFile - s.Config.Server.KeyFile = keyFile - return s.openServer() + cfg.ListeningAddr = addr + cfg.CertFile = certFile + cfg.KeyFile = keyFile + return s.ListenTo(cfg) } // ListenTLS Starts a https server with certificates, @@ -285,9 +304,10 @@ func ListenUNIX(addr string, mode os.FileMode) { // ListenUNIXWithErr starts the process of listening to the new requests using a 'socket file', this works only on unix // returns an error if something bad happens when trying to listen to func (s *Framework) ListenUNIXWithErr(addr string, mode os.FileMode) error { - s.Config.Server.ListeningAddr = addr - s.Config.Server.Mode = mode - return s.openServer() + cfg := config.DefaultServer() + cfg.ListeningAddr = addr + cfg.Mode = mode + return s.ListenTo(cfg) } // ListenUNIX starts the process of listening to the new requests using a 'socket file', this works only on unix @@ -342,37 +362,44 @@ func (s *Framework) SecondaryListen(cfg config.Server) *Server { } // NoListen is useful only when you want to test Iris, it doesn't starts the server but it configures and returns it +// initializes the whole framework but server doesn't listens to a specific net.Listener +// it is not blocking the app +// same as ListenVirtual func NoListen(optionalAddr ...string) *Server { return Default.NoListen(optionalAddr...) } // NoListen is useful only when you want to test Iris, it doesn't starts the server but it configures and returns it // initializes the whole framework but server doesn't listens to a specific net.Listener +// it is not blocking the app +// same as ListenVirtual func (s *Framework) NoListen(optionalAddr ...string) *Server { - if len(optionalAddr) > 0 { - s.Config.Server.ListeningAddr = optionalAddr[0] - } - return s.ListenVirtual() + return s.ListenVirtual(optionalAddr...) } // ListenVirtual is useful only when you want to test Iris, it doesn't starts the server but it configures and returns it // initializes the whole framework but server doesn't listens to a specific net.Listener -// same as NoListen -func ListenVirtual(cfg ...config.Server) *Server { - return Default.ListenVirtual(cfg...) +// it is not blocking the app +func ListenVirtual(optionalAddr ...string) *Server { + return Default.ListenVirtual(optionalAddr...) } // ListenVirtual is useful only when you want to test Iris, it doesn't starts the server but it configures and returns it // initializes the whole framework but server doesn't listens to a specific net.Listener -// same as NoListen -func (s *Framework) ListenVirtual(cfg ...config.Server) *Server { - if len(cfg) > 0 { - s.Config.Server = cfg[0] - } +// it is not blocking the app +func (s *Framework) ListenVirtual(optionalAddr ...string) *Server { s.Config.DisableBanner = true - s.Config.Server.Virtual = true + cfg := config.DefaultServer() - s.Must(s.openServer()) + if len(optionalAddr) > 0 { + cfg.ListeningAddr = optionalAddr[0] + } + cfg.Virtual = true + go s.ListenTo(cfg) + if ok := <-s.Available; !ok { + s.Logger.Panic("Unexpected error:Virtual server cannot start, please report this as bug!!") + } + close(s.Available) return s.HTTPServer } @@ -634,13 +661,8 @@ func (s *Framework) TemplateString(templateFile string, pageContext interface{}, // NewTester Prepares and returns a new test framework based on the api // is useful when you need to have more than one test framework for the same iris insttance, otherwise you can use the iris.Tester(t *testing.T)/variable.Tester(t *testing.T) func NewTester(api *Framework, t *testing.T) *httpexpect.Expect { - api.Config.DisableBanner = true if !api.HTTPServer.IsListening() { // maybe the user called this after .Listen/ListenTLS/ListenUNIX, the tester can be used as standalone (with no running iris instance) or inside a running instance/app api.ListenVirtual() - if ok := <-api.Available; !ok { - t.Fatal("Unexpected error: server cannot start, please report this as bug!!") - } - close(api.Available) } handler := api.HTTPServer.Handler @@ -670,7 +692,10 @@ func Tester(t *testing.T) *httpexpect.Expect { // Tester returns the test framework for this iris insance func (s *Framework) Tester(t *testing.T) *httpexpect.Expect { - return s.tester(t) + if s.testFramework == nil { + s.testFramework = NewTester(s, t) + } + return s.testFramework } // ------------------------------------------------------------------------------------- diff --git a/plugin_test.go b/plugin_test.go index 9b1c2f63..4f072426 100644 --- a/plugin_test.go +++ b/plugin_test.go @@ -50,7 +50,6 @@ func (t *testPluginEx) PreClose(*Framework) { func ExamplePlugins_Add() { initDefault() - Plugins.Add(PreListenFunc(func(*Framework) { fmt.Println("PreListen Func") })) @@ -68,7 +67,7 @@ func ExamplePlugins_Add() { desc := Plugins.GetDescription(myplugin) fmt.Println(desc) - NoListen() + ListenVirtual() CloseWithErr() // Output: diff --git a/server_test.go b/server_test.go index e4276769..1e457862 100644 --- a/server_test.go +++ b/server_test.go @@ -1,19 +1,5 @@ package iris -/* -Linux: /etc/hosts -Windows: $Drive:/windows/system32/drivers/etc/hosts - -127.0.0.1 mydomain.com -127.0.0.1 mysubdomain.mydomain.com - -Windows: - go test -v -Linux: - $ su - $ go test -v -*/ - import ( "io/ioutil" "net/http" @@ -23,7 +9,6 @@ import ( "github.com/gavv/httpexpect" "github.com/kataras/iris/config" - "github.com/kataras/iris/utils" ) const ( @@ -75,9 +60,6 @@ const ( MlobQSunSDKx/CCJhWkbytCyh1bngAtwSAYLXavYIlJbAzx6FvtAIw4= -----END RSA PRIVATE KEY----- ` - - testCertFilename = "mycert.cert" - testKeyFilename = "mykey.key" ) // Contains the server test for multi running servers @@ -86,13 +68,13 @@ func TestMultiRunningServers(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) // create the key and cert files on the fly, and delete them when this test finished - certFile, ferr := ioutil.TempFile(utils.AssetsDirectory, "_iris") + certFile, ferr := ioutil.TempFile("", "cert") if ferr != nil { t.Fatal(ferr.Error()) } - keyFile, ferr := ioutil.TempFile(utils.AssetsDirectory, "_iris") + keyFile, ferr := ioutil.TempFile("", "key") if ferr != nil { t.Fatal(ferr.Error()) } @@ -117,9 +99,10 @@ func TestMultiRunningServers(t *testing.T) { ctx.Write("Hello from %s", ctx.HostString()) }) - secondary := SecondaryListen(config.Server{ListeningAddr: ":80", RedirectTo: "https://" + host, Virtual: true}) // start one secondary server + // start the secondary server + secondary := SecondaryListen(config.Server{ListeningAddr: ":80", RedirectTo: "https://" + host, Virtual: true}) // start the main server - go ListenVirtual(config.Server{ListeningAddr: host, CertFile: certFile.Name(), KeyFile: keyFile.Name()}) + go ListenTo(config.Server{ListeningAddr: host, CertFile: certFile.Name(), KeyFile: keyFile.Name(), Virtual: true}) defer func() { go secondary.Close() diff --git a/sessions_test.go b/sessions_test.go index f9488b2e..88cbac36 100644 --- a/sessions_test.go +++ b/sessions_test.go @@ -15,7 +15,7 @@ func TestSessions(t *testing.T) { } initDefault() - Config.Server.ListeningAddr = "127.0.0.1:8080" // in order to test the sessions + HTTPServer.Config.ListeningAddr = "127.0.0.1:8080" // in order to test the sessions Config.Sessions.Cookie = "mycustomsessionid" writeValues := func(ctx *Context) {