From 51cbd7c75eb523f75116e73c5058c40940f495d9 Mon Sep 17 00:00:00 2001 From: Keiji Yoshida Date: Sat, 26 Jul 2014 01:57:24 +0900 Subject: [PATCH 01/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6fa52d0b..b0d5f4b1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ #Gin Web Framework -[![GoDoc](https://godoc.org/github.com/gin-gonic/gin?status.png)](https://godoc.org/github.com/gin-gonic/gin) +[![GoDoc](https://godoc.org/github.com/gin-gonic/gin?status.svg)](https://godoc.org/github.com/gin-gonic/gin) [![Build Status](https://travis-ci.org/gin-gonic/gin.svg)](https://travis-ci.org/gin-gonic/gin) Gin is a web framework written in Golang. It features a martini-like API with much better performance, up to 40 times faster. If you need performance and good productivity, you will love Gin. From 2b486327db838703e7b2eddec24ee6d09c84b4a4 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Mon, 18 Aug 2014 20:55:33 +0200 Subject: [PATCH 02/13] Updates CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c399078..437b01bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ###Gin 0.4 (??) +- [NEW] Unit tests +- [NEW] Add Content.Redirect() +- [FIX] Deferring WriteHeader() +- [FIX] Improved documentation for model binding + ###Gin 0.3 (Jul 18, 2014) From 312e03296096d861900ca456551f3e74d380c23a Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Mon, 18 Aug 2014 21:01:54 +0200 Subject: [PATCH 03/13] Updates AUTHORS.md --- AUTHORS.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 67535a41..4a844091 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -22,10 +22,13 @@ People and companies, who have contributed, in alphabetical order. - Using template.Must to fix multiple return issue - ★ Added support for OPTIONS verb - ★ Setting response headers before calling WriteHeader +- Improved documentation for model binding +- ★ Added Content.Redirect() +- ★ Added tons of Unit tests **@austinheap (Austin Heap)** -- Adds travis CI integration +- Added travis CI integration **@bluele (Jun Kimura)** @@ -67,20 +70,23 @@ People and companies, who have contributed, in alphabetical order. **@mdigger (Dmitry Sedykh)** - Fixes Form binding when content-type is x-www-form-urlencoded - No repeat call c.Writer.Status() in gin.Logger -- Fixed Content-Type for json render +- Fixes Content-Type for json render **@mopemope (Yutaka Matsubara)** - ★ Adds Godep support (Dependencies Manager) - Fix variadic parameter in the flexible render API - Fix Corrupted plain render -- Fix variadic parameter in new flexible render API - + **@msemenistyi (Mykyta Semenistyi)** - update Readme.md. Add code to String method +**@msoedov (Sasha Myasoedov)** +- ★ Adds tons of unit tests. + + **@ngerakines (Nick Gerakines)** - ★ Improves API, c.GET() doesn't panic - Adds MustGet() method From 809eee8a72ac1bd65a4d5ca20c89ee0adb9101e6 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Tue, 19 Aug 2014 03:40:52 +0200 Subject: [PATCH 04/13] Adds debug mode (part 1) - Adds API to switch the gin's mode - Log listening port - Log routes --- gin.go | 12 ++++++++++++ mode.go | 38 ++++++++++++++++++++++++++++++++++++++ utils.go | 6 ++++++ 3 files changed, 56 insertions(+) create mode 100644 mode.go diff --git a/gin.go b/gin.go index 99c5cbce..c1adbb49 100644 --- a/gin.go +++ b/gin.go @@ -1,6 +1,7 @@ package gin import ( + "fmt" "github.com/gin-gonic/gin/render" "github.com/julienschmidt/httprouter" "html/template" @@ -113,12 +114,18 @@ func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { } func (engine *Engine) Run(addr string) { + if gin_mode == debugCode { + fmt.Println("[GIN-debug] Listening and serving HTTP on " + addr) + } if err := http.ListenAndServe(addr, engine); err != nil { panic(err) } } func (engine *Engine) RunTLS(addr string, cert string, key string) { + if gin_mode == debugCode { + fmt.Println("[GIN-debug] Listening and serving HTTPS on " + addr) + } if err := http.ListenAndServeTLS(addr, cert, key, engine); err != nil { panic(err) } @@ -168,6 +175,11 @@ func (group *RouterGroup) pathFor(p string) string { func (group *RouterGroup) Handle(method, p string, handlers []HandlerFunc) { p = group.pathFor(p) handlers = group.combineHandlers(handlers) + if gin_mode == debugCode { + nuHandlers := len(handlers) + name := funcName(handlers[nuHandlers-1]) + fmt.Printf("[GIN-debug] %-5s %-25s --> %s (%d handlers)\n", method, p, name, nuHandlers) + } group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { c := group.engine.createContext(w, req, params, handlers) c.Next() diff --git a/mode.go b/mode.go new file mode 100644 index 00000000..803a2ec4 --- /dev/null +++ b/mode.go @@ -0,0 +1,38 @@ +package gin + +import ( + "os" +) + +const GIN_MODE = "GIN_MODE" + +const ( + DebugMode string = "debug" + ReleaseMode string = "release" +) +const ( + debugCode = iota + releaseCode = iota +) + +var gin_mode int = debugCode + +func SetMode(value string) { + switch value { + case DebugMode: + gin_mode = debugCode + case ReleaseMode: + gin_mode = releaseCode + default: + panic("gin mode unknown, the allowed modes are: " + DebugMode + " and " + ReleaseMode) + } +} + +func init() { + value := os.Getenv(GIN_MODE) + if len(value) == 0 { + SetMode(DebugMode) + } else { + SetMode(value) + } +} diff --git a/utils.go b/utils.go index 90cca1be..6417efd9 100644 --- a/utils.go +++ b/utils.go @@ -2,6 +2,8 @@ package gin import ( "encoding/xml" + "reflect" + "runtime" ) type H map[string]interface{} @@ -38,3 +40,7 @@ func filterFlags(content string) string { } return content } + +func funcName(f interface{}) string { + return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name() +} From a0437ff9f2589629d2d8afbff68d4be6ffce6ab4 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Tue, 19 Aug 2014 03:41:05 +0200 Subject: [PATCH 05/13] Typo in AUTHORS --- AUTHORS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS.md b/AUTHORS.md index 4a844091..2a7c347f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -5,7 +5,7 @@ List of all the awesome people working to make Gin the best Web Framework in Go! ##gin 0.x series authors **Lead Developer:** Manu Martinez-Almeida (@manucorporat) -**Stuff:** +**Staff:** Javier Provecho (@javierprovecho) People and companies, who have contributed, in alphabetical order. From f39b692fc522849b3fc5a63213043b46193d1914 Mon Sep 17 00:00:00 2001 From: yuyabe Date: Tue, 19 Aug 2014 01:38:03 -0700 Subject: [PATCH 06/13] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6fa52d0b..af6b3a54 100644 --- a/README.md +++ b/README.md @@ -392,7 +392,7 @@ func main() { time.Sleep(5 * time.Second) // note than you are using the copied context "c_cp", IMPORTANT - log.Println("Done! in path " + c_cp.Req.URL.Path) + log.Println("Done! in path " + c_cp.Request.URL.Path) }() }) @@ -402,7 +402,7 @@ func main() { time.Sleep(5 * time.Second) // since we are NOT using a goroutine, we do not have to copy the context - log.Println("Done! in path " + c.Req.URL.Path) + log.Println("Done! in path " + c.Request.URL.Path) }) // Listen and server on 0.0.0.0:8080 From 378610b3b215bc8d07c4c4b6dc42c59a8fe20b1a Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Wed, 20 Aug 2014 18:14:10 +0200 Subject: [PATCH 07/13] HTML template debug mode. - theHTML templates are reloaded each time --- gin.go | 8 ++++++-- render/render.go | 33 ++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/gin.go b/gin.go index c1adbb49..8b6d17d5 100644 --- a/gin.go +++ b/gin.go @@ -92,8 +92,12 @@ func (engine *Engine) LoadHTMLFiles(files ...string) { } func (engine *Engine) SetHTMLTemplate(templ *template.Template) { - engine.HTMLRender = render.HTMLRender{ - Template: templ, + if gin_mode == debugCode { + engine.HTMLRender = render.HTMLDebug + } else { + engine.HTMLRender = render.HTMLRender{ + Template: templ, + } } } diff --git a/render/render.go b/render/render.go index 207e7a52..57a59fe1 100644 --- a/render/render.go +++ b/render/render.go @@ -25,6 +25,9 @@ type ( // Redirects redirectRender struct{} + // Redirects + htmlDebugRender struct{} + // form binding HTMLRender struct { Template *template.Template @@ -32,10 +35,11 @@ type ( ) var ( - JSON = jsonRender{} - XML = xmlRender{} - Plain = plainRender{} - Redirect = redirectRender{} + JSON = jsonRender{} + XML = xmlRender{} + Plain = plainRender{} + Redirect = redirectRender{} + HTMLDebug = htmlDebugRender{} ) func writeHeader(w http.ResponseWriter, code int, contentType string) { @@ -61,13 +65,6 @@ func (_ xmlRender) Render(w http.ResponseWriter, code int, data ...interface{}) return encoder.Encode(data[0]) } -func (html HTMLRender) Render(w http.ResponseWriter, code int, data ...interface{}) error { - writeHeader(w, code, "text/html") - file := data[0].(string) - obj := data[1] - return html.Template.ExecuteTemplate(w, file, obj) -} - func (_ plainRender) Render(w http.ResponseWriter, code int, data ...interface{}) error { writeHeader(w, code, "text/plain") format := data[0].(string) @@ -80,3 +77,17 @@ func (_ plainRender) Render(w http.ResponseWriter, code int, data ...interface{} } return err } + +func (_ htmlDebugRender) Render(w http.ResponseWriter, code int, data ...interface{}) error { + writeHeader(w, code, "text/html") + file := data[0].(string) + obj := data[1] + return template.New(file).Execute(w, obj) +} + +func (html HTMLRender) Render(w http.ResponseWriter, code int, data ...interface{}) error { + writeHeader(w, code, "text/html") + file := data[0].(string) + obj := data[1] + return html.Template.ExecuteTemplate(w, file, obj) +} From 0ed259ca34d5af4e91a9820dd1923b89f6bb58d5 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Thu, 21 Aug 2014 01:01:05 +0200 Subject: [PATCH 08/13] Adds TestMode --- mode.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mode.go b/mode.go index 803a2ec4..85f133b9 100644 --- a/mode.go +++ b/mode.go @@ -9,10 +9,12 @@ const GIN_MODE = "GIN_MODE" const ( DebugMode string = "debug" ReleaseMode string = "release" + TestMode string = "test" ) const ( debugCode = iota releaseCode = iota + testCode = iota ) var gin_mode int = debugCode @@ -23,6 +25,8 @@ func SetMode(value string) { gin_mode = debugCode case ReleaseMode: gin_mode = releaseCode + case TestMode: + gin_mode = testCode default: panic("gin mode unknown, the allowed modes are: " + DebugMode + " and " + ReleaseMode) } From 94f2f3f7eba02686e60f788d2766ee5003ab17a2 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Thu, 21 Aug 2014 01:01:42 +0200 Subject: [PATCH 09/13] Using test mode --- gin_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gin_test.go b/gin_test.go index 0cd5bf1b..7425cc21 100644 --- a/gin_test.go +++ b/gin_test.go @@ -10,6 +10,10 @@ import ( "testing" ) +func init() { + SetMode(TestMode) +} + func PerformRequest(r http.Handler, method, path string) *httptest.ResponseRecorder { req, _ := http.NewRequest(method, path, nil) w := httptest.NewRecorder() From 46225ea53a2c5f82ad2d02bff2e08d756eab9fc1 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Thu, 21 Aug 2014 01:04:35 +0200 Subject: [PATCH 10/13] Fixes html debug mode --- gin.go | 30 +++++++++++++++++------------- render/render.go | 6 +++++- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/gin.go b/gin.go index 8b6d17d5..0f4753e2 100644 --- a/gin.go +++ b/gin.go @@ -82,22 +82,26 @@ func Default() *Engine { } func (engine *Engine) LoadHTMLGlob(pattern string) { - templ := template.Must(template.ParseGlob(pattern)) - engine.SetHTMLTemplate(templ) -} - -func (engine *Engine) LoadHTMLFiles(files ...string) { - templ := template.Must(template.ParseFiles(files...)) - engine.SetHTMLTemplate(templ) -} - -func (engine *Engine) SetHTMLTemplate(templ *template.Template) { if gin_mode == debugCode { engine.HTMLRender = render.HTMLDebug } else { - engine.HTMLRender = render.HTMLRender{ - Template: templ, - } + templ := template.Must(template.ParseGlob(pattern)) + engine.SetHTMLTemplate(templ) + } +} + +func (engine *Engine) LoadHTMLFiles(files ...string) { + if gin_mode == debugCode { + engine.HTMLRender = render.HTMLDebug + } else { + templ := template.Must(template.ParseFiles(files...)) + engine.SetHTMLTemplate(templ) + } +} + +func (engine *Engine) SetHTMLTemplate(templ *template.Template) { + engine.HTMLRender = render.HTMLRender{ + Template: templ, } } diff --git a/render/render.go b/render/render.go index 57a59fe1..bc982a30 100644 --- a/render/render.go +++ b/render/render.go @@ -82,7 +82,11 @@ func (_ htmlDebugRender) Render(w http.ResponseWriter, code int, data ...interfa writeHeader(w, code, "text/html") file := data[0].(string) obj := data[1] - return template.New(file).Execute(w, obj) + t, err := template.ParseFiles(file) + if err != nil { + return err + } + return t.ExecuteTemplate(w, file, obj) } func (html HTMLRender) Render(w http.ResponseWriter, code int, data ...interface{}) error { From 2ec71baf2574058bbcd0c4414b4100965711f151 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Thu, 21 Aug 2014 01:13:37 +0200 Subject: [PATCH 11/13] Updates CHANGELOG and AUTHORS --- AUTHORS.md | 6 +++++- CHANGELOG.md | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 2a7c347f..c09e263f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -101,4 +101,8 @@ People and companies, who have contributed, in alphabetical order. **@SkuliOskarsson (Skuli Oskarsson)** -- Fixes some texts in README II \ No newline at end of file +- Fixes some texts in README II + + +**@yuyabee** +- Fixed README \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 437b01bf..5ec8c5ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ -##Changelog +#Changelog -###Gin 0.4 (??) +###Gin 0.4 (Aug 21, 2014) +- [NEW] Development mode - [NEW] Unit tests - [NEW] Add Content.Redirect() - [FIX] Deferring WriteHeader() From 5092886e997e42a4aa50e36f3d8d14defb2db2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=A6=E6=BA=AA=E7=AC=94=E8=B0=88?= Date: Thu, 21 Aug 2014 21:32:32 +0800 Subject: [PATCH 12/13] Update README.md Fix a typo in Redirects section. --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f150f433..c97164d4 100644 --- a/README.md +++ b/README.md @@ -324,12 +324,13 @@ func main() { Issuing a HTTP redirect is easy: -```r.GET("/test", func(c *gin.Context) { +```go +r.GET("/test", func(c *gin.Context) { c.Redirect(301, "http://www.google.com/") }) - -Both internal and external locations are supported. ``` +Both internal and external locations are supported. + #### Custom Middlewares From b3f322c5fc19d68e297ae0a175770b232eae0bc1 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Sun, 24 Aug 2014 04:35:11 +0200 Subject: [PATCH 13/13] Fixes bug when status code is negative --- response_writer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/response_writer.go b/response_writer.go index 2da8e336..91afe89b 100644 --- a/response_writer.go +++ b/response_writer.go @@ -27,7 +27,7 @@ func (w *responseWriter) reset(writer http.ResponseWriter) { } func (w *responseWriter) WriteHeader(code int) { - if code != 0 { + if code > 0 { w.status = code if w.written { log.Println("[GIN] WARNING. Headers were already written!")