diff --git a/gin.go b/gin.go index c9d38d6..21fc89f 100644 --- a/gin.go +++ b/gin.go @@ -228,11 +228,12 @@ func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo { // Run attaches the router to a http.Server and starts listening and serving HTTP requests. // It is a shortcut for http.ListenAndServe(addr, router) // Note: this method will block the calling goroutine undefinitelly unless an error happens. -func (engine *Engine) Run(addr string) (err error) { - debugPrint("Listening and serving HTTP on %s\n", addr) +func (engine *Engine) Run(addr ...string) (err error) { defer func() { debugPrintError(err) }() - err = http.ListenAndServe(addr, engine) + address := resolveAddress(addr) + debugPrint("Listening and serving HTTP on %s\n", address) + err = http.ListenAndServe(address, engine) return } diff --git a/gin_integration_test.go b/gin_integration_test.go index f7ae075..0665a61 100644 --- a/gin_integration_test.go +++ b/gin_integration_test.go @@ -2,49 +2,86 @@ package gin import ( "bufio" - "bytes" "fmt" "io/ioutil" "net" "net/http" + "os" "testing" "time" "github.com/stretchr/testify/assert" ) -func TestRun(t *testing.T) { - buffer := new(bytes.Buffer) +func testRequest(t *testing.T, url string) { + resp, err := http.Get(url) + defer resp.Body.Close() + assert.NoError(t, err) + + body, ioerr := ioutil.ReadAll(resp.Body) + assert.NoError(t, ioerr) + assert.Equal(t, "it worked", string(body), "resp body should match") + assert.Equal(t, "200 OK", resp.Status, "should get a 200") +} + +func TestRunEmpty(t *testing.T) { + SetMode(DebugMode) + os.Setenv("PORT", "") router := New() go func() { - router.Use(LoggerWithWriter(buffer)) router.GET("/example", func(c *Context) { c.String(http.StatusOK, "it worked") }) - router.Run(":5150") + assert.NoError(t, router.Run()) + }() + // have to wait for the goroutine to start and run the server + // otherwise the main thread will complete + time.Sleep(5 * time.Millisecond) + + assert.Error(t, router.Run(":8080")) + testRequest(t, "http://localhost:8080/example") +} + +func TestRunEmptyWithEnv(t *testing.T) { + os.Setenv("PORT", "3123") + router := New() + go func() { + router.GET("/example", func(c *Context) { c.String(http.StatusOK, "it worked") }) + assert.NoError(t, router.Run()) + }() + // have to wait for the goroutine to start and run the server + // otherwise the main thread will complete + time.Sleep(5 * time.Millisecond) + + assert.Error(t, router.Run(":3123")) + testRequest(t, "http://localhost:3123/example") +} + +func TestRunTooMuchParams(t *testing.T) { + router := New() + assert.Panics(t, func() { + router.Run("2", "2") + }) +} + +func TestRunWithPort(t *testing.T) { + router := New() + go func() { + router.GET("/example", func(c *Context) { c.String(http.StatusOK, "it worked") }) + assert.NoError(t, router.Run(":5150")) }() // have to wait for the goroutine to start and run the server // otherwise the main thread will complete time.Sleep(5 * time.Millisecond) assert.Error(t, router.Run(":5150")) - - resp, err := http.Get("http://localhost:5150/example") - defer resp.Body.Close() - assert.NoError(t, err) - - body, ioerr := ioutil.ReadAll(resp.Body) - assert.NoError(t, ioerr) - assert.Equal(t, "it worked", string(body[:]), "resp body should match") - assert.Equal(t, "200 OK", resp.Status, "should get a 200") + testRequest(t, "http://localhost:5150/example") } func TestUnixSocket(t *testing.T) { - buffer := new(bytes.Buffer) router := New() go func() { - router.Use(LoggerWithWriter(buffer)) router.GET("/example", func(c *Context) { c.String(http.StatusOK, "it worked") }) - router.RunUnix("/tmp/unix_unit_test") + assert.NoError(t, router.RunUnix("/tmp/unix_unit_test")) }() // have to wait for the goroutine to start and run the server // otherwise the main thread will complete diff --git a/utils.go b/utils.go index 7e64687..533888d 100644 --- a/utils.go +++ b/utils.go @@ -7,6 +7,7 @@ package gin import ( "encoding/xml" "net/http" + "os" "path" "reflect" "runtime" @@ -129,3 +130,20 @@ func joinPaths(absolutePath, relativePath string) string { } return finalPath } + +func resolveAddress(addr []string) string { + switch len(addr) { + case 0: + if port := os.Getenv("PORT"); len(port) > 0 { + debugPrint("Environment variable PORT=\"%s\"", port) + return ":" + port + } else { + debugPrint("Environment variable PORT is undefined. Using port :8080 by default") + return ":8080" + } + case 1: + return addr[0] + default: + panic("too much parameters") + } +}