diff --git a/glide.lock b/glide.lock index 1ba41546..253ab23e 100644 --- a/glide.lock +++ b/glide.lock @@ -1,18 +1,20 @@ -hash: c9f84c389c3133ad9adf26b374f5b7970f26f3d185ec13e1d6824254478beb76 -updated: 2016-02-18T14:02:34.556933487-08:00 +hash: f220137e9ccd9aaf3051be33c3c23ea8abd2c40df6cf96175c3994d482b5e007 +updated: 2016-02-18T22:26:06.777493855-08:00 imports: - name: github.com/klauspost/compress version: 3dcfad3351d86b2c07406ac93e92f03edd98c707 - repo: https://github.com/klauspost/compress + subpackages: + - flate + - gzip + - zlib - name: github.com/klauspost/cpuid version: 349c675778172472f5e8f3a3e0fe187e302e5a10 - repo: https://github.com/klauspost/cpuid - name: github.com/klauspost/crc32 version: 81ac41837f877bc6a7f81321c2c29d88d69c108a - name: github.com/labstack/gommon version: bfff5bf04688a4048a5cb4dd3b3f0697caaad19c subpackages: - - /color + - color - log - name: github.com/mattn/go-colorable version: 9fdad7c47650b7d2e1da50644c1f4ba7f172f252 @@ -20,13 +22,9 @@ imports: version: 56b76bdf51f7708750eac80fa38b952bb9f32639 - name: github.com/valyala/fasthttp version: 14b2ff3d2b38a596b037541c94f43718d9da215f -- name: golang.org/x/crypto - version: 1f22c0103821b9390939b6776727195525381532 - name: golang.org/x/net version: b6d7b1396ec874c3b00f6c84cd4301a17c56c8ed subpackages: - - /context + - context - websocket -- name: golang.org/x/text - version: 07b9a78963006a15c538ec5175243979025fa7a8 devImports: [] diff --git a/handler/static.go b/handler/static.go deleted file mode 100644 index 5bb9302c..00000000 --- a/handler/static.go +++ /dev/null @@ -1,95 +0,0 @@ -package handler - -import ( - "fmt" - "io" - "net/http" - "path" - - "github.com/labstack/echo" -) - -type ( - StaticOptions struct { - Root string `json:"root"` - Index string `json:"index"` - Browse bool `json:"browse"` - } -) - -func Static(root string, options ...*StaticOptions) echo.HandlerFunc { - // Default options - opts := &StaticOptions{Index: "index.html"} - if len(options) > 0 { - opts = options[0] - } - - return func(c echo.Context) error { - fs := http.Dir(root) - file := c.P(0) - f, err := fs.Open(file) - if err != nil { - return echo.ErrNotFound - } - defer f.Close() - - fi, err := f.Stat() - if err != nil { - return err - } - - if fi.IsDir() { - /* NOTE: - Not checking the Last-Modified header as it caches the response `304` when - changing differnt directories for the same path. - */ - d := f - - // Index file - file = path.Join(file, opts.Index) - f, err = fs.Open(file) - if err != nil { - if opts.Browse { - dirs, err := d.Readdir(-1) - if err != nil { - return err - } - - // Create a directory index - res := c.Response() - res.Header().Set(echo.ContentType, echo.TextHTMLCharsetUTF8) - if _, err = fmt.Fprintf(res, "
\n"); err != nil {
-						return err
-					}
-					for _, d := range dirs {
-						name := d.Name()
-						color := "#212121"
-						if d.IsDir() {
-							color = "#e91e63"
-							name += "/"
-						}
-						if _, err = fmt.Fprintf(res, "%s\n", name, color, name); err != nil {
-							return err
-						}
-					}
-					_, err = fmt.Fprintf(res, "
\n") - return err - } - return echo.ErrNotFound - } - fi, _ = f.Stat() // Index file stat - } - c.Response().WriteHeader(http.StatusOK) - io.Copy(c.Response(), f) - return nil - // TODO: - // http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), f) - } -} - -// Favicon serves the default favicon - GET /favicon.ico. -func Favicon() echo.HandlerFunc { - return func(c echo.Context) error { - return nil - } -} diff --git a/middleware/auth.go b/middleware/auth.go index c788c246..cfe51c73 100644 --- a/middleware/auth.go +++ b/middleware/auth.go @@ -23,7 +23,7 @@ const ( // For valid credentials it calls the next handler. // For invalid credentials, it sends "401 - Unauthorized" response. func BasicAuth(fn BasicAuthFunc, options ...*BasicAuthOptions) echo.MiddlewareFunc { - return func(h echo.Handler) echo.Handler { + return func(next echo.Handler) echo.Handler { return echo.HandlerFunc(func(c echo.Context) error { // Skip WebSocket if (c.Request().Header().Get(echo.Upgrade)) == echo.WebSocket { diff --git a/middleware/compress.go b/middleware/compress.go index c04ce80d..31975e82 100644 --- a/middleware/compress.go +++ b/middleware/compress.go @@ -28,7 +28,7 @@ type ( // Gzip returns a middleware which compresses HTTP response using gzip compression // scheme. func Gzip(options ...*GzipOptions) echo.MiddlewareFunc { - return func(h echo.Handler) echo.Handler { + return func(next echo.Handler) echo.Handler { scheme := "gzip" return echo.HandlerFunc(func(c echo.Context) error { c.Response().Header().Add(echo.Vary, echo.AcceptEncoding) @@ -43,7 +43,7 @@ func Gzip(options ...*GzipOptions) echo.MiddlewareFunc { c.Response().Header().Set(echo.ContentEncoding, scheme) c.Response().SetWriter(gw) } - if err := h.Handle(c); err != nil { + if err := next.Handle(c); err != nil { c.Error(err) } return nil diff --git a/middleware/log_test.go b/middleware/log_test.go index 1f5b7360..f243eba1 100644 --- a/middleware/log_test.go +++ b/middleware/log_test.go @@ -12,13 +12,13 @@ import ( "github.com/stretchr/testify/assert" ) -func TestLog(t *testing.T) { +func TestLogger(t *testing.T) { // Note: Just for the test coverage, not a real test. e := echo.New() req := test.NewRequest(echo.GET, "/", nil) rec := test.NewResponseRecorder() c := echo.NewContext(req, rec, e) - h := Log()(echo.HandlerFunc(func(c echo.Context) error { + h := Logger()(echo.HandlerFunc(func(c echo.Context) error { return c.String(http.StatusOK, "test") })) @@ -28,7 +28,7 @@ func TestLog(t *testing.T) { // Status 3xx rec = test.NewResponseRecorder() c = echo.NewContext(req, rec, e) - h = Log()(echo.HandlerFunc(func(c echo.Context) error { + h = Logger()(echo.HandlerFunc(func(c echo.Context) error { return c.String(http.StatusTemporaryRedirect, "test") })) h.Handle(c) @@ -36,7 +36,7 @@ func TestLog(t *testing.T) { // Status 4xx rec = test.NewResponseRecorder() c = echo.NewContext(req, rec, e) - h = Log()(echo.HandlerFunc(func(c echo.Context) error { + h = Logger()(echo.HandlerFunc(func(c echo.Context) error { return c.String(http.StatusNotFound, "test") })) h.Handle(c) @@ -45,13 +45,13 @@ func TestLog(t *testing.T) { req = test.NewRequest(echo.GET, "", nil) rec = test.NewResponseRecorder() c = echo.NewContext(req, rec, e) - h = Log()(echo.HandlerFunc(func(c echo.Context) error { + h = Logger()(echo.HandlerFunc(func(c echo.Context) error { return errors.New("error") })) h.Handle(c) } -func TestLogIPAddress(t *testing.T) { +func TestLoggerIPAddress(t *testing.T) { e := echo.New() req := test.NewRequest(echo.GET, "/", nil) rec := test.NewResponseRecorder() @@ -59,7 +59,7 @@ func TestLogIPAddress(t *testing.T) { buf := new(bytes.Buffer) e.Logger().(*log.Logger).SetOutput(buf) ip := "127.0.0.1" - h := Log()(echo.HandlerFunc(func(c echo.Context) error { + h := Logger()(echo.HandlerFunc(func(c echo.Context) error { return c.String(http.StatusOK, "test") })) diff --git a/middleware/log.go b/middleware/logger.go similarity index 85% rename from middleware/log.go rename to middleware/logger.go index 73119cfc..e5d2e614 100644 --- a/middleware/log.go +++ b/middleware/logger.go @@ -9,12 +9,12 @@ import ( ) type ( - LogOptions struct { + LoggerOptions struct { } ) -func Log(options ...*LogOptions) echo.MiddlewareFunc { - return func(h echo.Handler) echo.Handler { +func Logger(options ...*LoggerOptions) echo.MiddlewareFunc { + return func(next echo.Handler) echo.Handler { return echo.HandlerFunc(func(c echo.Context) error { req := c.Request() res := c.Response() @@ -30,7 +30,7 @@ func Log(options ...*LogOptions) echo.MiddlewareFunc { } start := time.Now() - if err := h.Handle(c); err != nil { + if err := next.Handle(c); err != nil { c.Error(err) } stop := time.Now() diff --git a/middleware/recover.go b/middleware/recover.go index 2902a4c2..04f00212 100644 --- a/middleware/recover.go +++ b/middleware/recover.go @@ -16,7 +16,7 @@ type ( // Recover returns a middleware which recovers from panics anywhere in the chain // and handles the control to the centralized HTTPErrorHandler. func Recover(options ...*RecoverOptions) echo.MiddlewareFunc { - return func(h echo.Handler) echo.Handler { + return func(next echo.Handler) echo.Handler { // TODO: Provide better stack trace `https://github.com/go-errors/errors` `https://github.com/docker/libcontainer/tree/master/stacktrace` return echo.HandlerFunc(func(c echo.Context) error { defer func() { @@ -27,7 +27,7 @@ func Recover(options ...*RecoverOptions) echo.MiddlewareFunc { err, n, trace[:n])) } }() - return h.Handle(c) + return next.Handle(c) }) } } diff --git a/middleware/static.go b/middleware/static.go new file mode 100644 index 00000000..7a3ced04 --- /dev/null +++ b/middleware/static.go @@ -0,0 +1,97 @@ +package middleware + +import ( + "fmt" + "io" + "net/http" + "path" + + "github.com/labstack/echo" +) + +type ( + StaticOptions struct { + Root string `json:"root"` + Index string `json:"index"` + Browse bool `json:"browse"` + } +) + +func Static(root string, options ...*StaticOptions) echo.MiddlewareFunc { + return func(next echo.Handler) echo.Handler { + // Default options + opts := &StaticOptions{Index: "index.html"} + if len(options) > 0 { + opts = options[0] + } + + return echo.HandlerFunc(func(c echo.Context) error { + fs := http.Dir(root) + file := c.Request().URI() + f, err := fs.Open(file) + if err != nil { + return next.Handle(c) + } + defer f.Close() + + fi, err := f.Stat() + if err != nil { + return err + } + + if fi.IsDir() { + /* NOTE: + Not checking the Last-Modified header as it caches the response `304` when + changing differnt directories for the same path. + */ + d := f + + // Index file + file = path.Join(file, opts.Index) + f, err = fs.Open(file) + if err != nil { + if opts.Browse { + dirs, err := d.Readdir(-1) + if err != nil { + return err + } + + // Create a directory index + res := c.Response() + res.Header().Set(echo.ContentType, echo.TextHTMLCharsetUTF8) + if _, err = fmt.Fprintf(res, "
\n"); err != nil {
+							return err
+						}
+						for _, d := range dirs {
+							name := d.Name()
+							color := "#212121"
+							if d.IsDir() {
+								color = "#e91e63"
+								name += "/"
+							}
+							if _, err = fmt.Fprintf(res, "%s\n", name, color, name); err != nil {
+								return err
+							}
+						}
+						_, err = fmt.Fprintf(res, "
\n") + return err + } + return next.Handle(c) + } + fi, _ = f.Stat() // Index file stat + } + c.Response().WriteHeader(http.StatusOK) + io.Copy(c.Response(), f) + return nil + // TODO: + // http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), f) + }) + } +} + +// Favicon serves the default favicon - GET /favicon.ico. +func Favicon() echo.HandlerFunc { + return func(c echo.Context) error { + return nil + } +}