1
0
mirror of https://github.com/kataras/iris.git synced 2026-02-28 05:26:00 +00:00

create the new FileServer and HandleDir, deprecate the rest APIBuilder/Party static methods and more

relative: https://github.com/kataras/iris/issues/1283 and removing pongo2 from vendor: https://github.com/kataras/iris/issues/1284

Former-commit-id: 3ec57b349f99faca2b8e36d9f7252db0b6ea080d
This commit is contained in:
Gerasimos (Makis) Maropoulos
2019-06-21 19:43:25 +03:00
parent 7f9e33cabb
commit d0104defa8
72 changed files with 1585 additions and 1826 deletions

View File

@@ -209,6 +209,12 @@ type Context interface {
Proceed(Handler) bool
// HandlerName returns the current handler's name, helpful for debugging.
HandlerName() string
// HandlerFileLine returns the current running handler's function source file and line information.
// Useful mostly when debugging.
HandlerFileLine() (file string, line int)
// RouteName returns the route name that this handler is running on.
// Note that it will return empty on not found handlers.
RouteName() string
// Next calls all the next handler from the handlers chain,
// it should be used inside a middleware.
//
@@ -626,7 +632,7 @@ type Context interface {
// Note that it has nothing to do with server-side caching.
// It does those checks by checking if the "If-Modified-Since" request header
// sent by client or a previous server response header
// (e.g with WriteWithExpiration or StaticEmbedded or Favicon etc.)
// (e.g with WriteWithExpiration or HandleDir or Favicon etc.)
// is a valid one and it's before the "modtime".
//
// A check for !modtime && err == nil is necessary to make sure that
@@ -775,7 +781,7 @@ type Context interface {
// You can define your own "Content-Type" with `context#ContentType`, before this function call.
//
// This function doesn't support resuming (by range),
// use ctx.SendFile or router's `StaticWeb` instead.
// use ctx.SendFile or router's `HandleDir` instead.
ServeContent(content io.ReadSeeker, filename string, modtime time.Time, gzipCompression bool) error
// ServeFile serves a file (to send a file, a zip for example to the client you should use the `SendFile` instead)
// receives two parameters
@@ -785,7 +791,7 @@ type Context interface {
// You can define your own "Content-Type" with `context#ContentType`, before this function call.
//
// This function doesn't support resuming (by range),
// use ctx.SendFile or router's `StaticWeb` instead.
// use ctx.SendFile or router's `HandleDir` instead.
//
// Use it when you want to serve dynamic files to the client.
ServeFile(filename string, gzipCompression bool) error
@@ -1208,12 +1214,21 @@ func (ctx *context) Proceed(h Handler) bool {
// HandlerName returns the current handler's name, helpful for debugging.
func (ctx *context) HandlerName() string {
if name := ctx.currentRouteName; name != "" {
return name
}
return HandlerName(ctx.handlers[ctx.currentHandlerIndex])
}
// HandlerFileLine returns the current running handler's function source file and line information.
// Useful mostly when debugging.
func (ctx *context) HandlerFileLine() (file string, line int) {
return HandlerFileLine(ctx.handlers[ctx.currentHandlerIndex])
}
// RouteName returns the route name that this handler is running on.
// Note that it will return empty on not found handlers.
func (ctx *context) RouteName() string {
return ctx.currentRouteName
}
// Next is the function that executed when `ctx.Next()` is called.
// It can be changed to a customized one if needed (very advanced usage).
//
@@ -2476,7 +2491,7 @@ func (ctx *context) SetLastModified(modtime time.Time) {
// Note that it has nothing to do with server-side caching.
// It does those checks by checking if the "If-Modified-Since" request header
// sent by client or a previous server response header
// (e.g with WriteWithExpiration or StaticEmbedded or Favicon etc.)
// (e.g with WriteWithExpiration or HandleDir or Favicon etc.)
// is a valid one and it's before the "modtime".
//
// A check for !modtime && err == nil is necessary to make sure that
@@ -3122,7 +3137,10 @@ func (ctx *context) ServeContent(content io.ReadSeeker, filename string, modtime
return nil
}
ctx.ContentType(filename)
if ctx.GetContentType() == "" {
ctx.ContentType(filename)
}
ctx.SetLastModified(modtime)
var out io.Writer
if gzipCompression && ctx.ClientSupportsGzip() {
@@ -3150,7 +3168,7 @@ func (ctx *context) ServeContent(content io.ReadSeeker, filename string, modtime
func (ctx *context) ServeFile(filename string, gzipCompression bool) error {
f, err := os.Open(filename)
if err != nil {
return fmt.Errorf("%d", 404)
return fmt.Errorf("%d", http.StatusNotFound)
}
defer f.Close()
fi, _ := f.Stat()

View File

@@ -3,6 +3,7 @@ package context
import (
"reflect"
"runtime"
"strings"
)
// A Handler responds to an HTTP request.
@@ -26,15 +27,35 @@ type Handler func(Context)
// See `Handler` for more.
type Handlers []Handler
// HandlerName returns the name, the handler function informations.
// Same as `context.HandlerName`.
// HandlerName returns the handler's function name.
// See `context.HandlerName` to get function name of the current running handler in the chain.
func HandlerName(h Handler) string {
pc := reflect.ValueOf(h).Pointer()
// l, n := runtime.FuncForPC(pc).FileLine(pc)
// return fmt.Sprintf("%s:%d", l, n)
return runtime.FuncForPC(pc).Name()
}
// HandlerFileLine returns the handler's file and line information.
// See `context.HandlerFileLine` to get the file, line of the current running handler in the chain.
func HandlerFileLine(h Handler) (file string, line int) {
pc := reflect.ValueOf(h).Pointer()
return runtime.FuncForPC(pc).FileLine(pc)
}
// MainHandlerName tries to find the main handler than end-developer
// registered on the provided chain of handlers and returns its function name.
func MainHandlerName(handlers Handlers) (name string) {
for i := 0; i < len(handlers); i++ {
name = HandlerName(handlers[i])
if !strings.HasPrefix(name, "github.com/kataras/iris") ||
strings.HasPrefix(name, "github.com/kataras/iris/core/router.StripPrefix") ||
strings.HasPrefix(name, "github.com/kataras/iris/core/router.FileServer") {
break
}
}
return
}
// Filter is just a type of func(Handler) bool which reports whether an action must be performed
// based on the incoming request.
//

View File

@@ -60,7 +60,7 @@ type ResponseWriter interface {
// Written should returns the total length of bytes that were being written to the client.
// In addition iris provides some variables to help low-level actions:
// NoWritten, means that nothing were written yet and the response writer is still live.
// StatusCodeWritten, means that status code were written but no other bytes are written to the client, response writer may closed.
// StatusCodeWritten, means that status code was written but no other bytes are written to the client, response writer may closed.
// > 0 means that the reply was written and it's the total number of bytes were written.
Written() int

View File

@@ -1,6 +1,13 @@
package context
import "github.com/kataras/iris/macro"
import (
"os"
"path"
"path/filepath"
"strings"
"github.com/kataras/iris/macro"
)
// RouteReadOnly allows decoupled access to the current route
// inside the context.
@@ -42,4 +49,59 @@ type RouteReadOnly interface {
// MainHandlerName returns the first registered handler for the route.
MainHandlerName() string
// StaticSites if not empty, refers to the system (or virtual if embedded) directory
// and sub directories that this "GET" route was registered to serve files and folders
// that contain index.html (a site). The index handler may registered by other
// route, manually or automatic by the framework,
// get the route by `Application#GetRouteByPath(staticSite.RequestPath)`.
StaticSites() []StaticSite
}
// StaticSite is a structure which is used as field on the `Route`
// and route registration on the `APIBuilder#HandleDir`.
// See `GetStaticSites` and `APIBuilder#HandleDir`.
type StaticSite struct {
Dir string `json:"dir"`
RequestPath string `json:"requestPath"`
}
// GetStaticSites search for a relative filename of "indexName" in "rootDir" and all its subdirectories
// and returns a list of structures which contains the directory found an "indexName" and the request path
// that a route should be registered to handle this "indexName".
// The request path is given by the directory which an index exists on.
func GetStaticSites(rootDir, rootRequestPath, indexName string) (sites []StaticSite) {
f, err := os.Open(rootDir)
if err != nil {
return nil
}
list, err := f.Readdir(-1)
f.Close()
if err != nil {
return nil
}
if len(list) == 0 {
return nil
}
for _, l := range list {
dir := filepath.Join(rootDir, l.Name())
if l.IsDir() {
sites = append(sites, GetStaticSites(dir, path.Join(rootRequestPath, l.Name()), indexName)...)
continue
}
if l.Name() == strings.TrimPrefix(indexName, "/") {
sites = append(sites, StaticSite{
Dir: filepath.FromSlash(rootDir),
RequestPath: rootRequestPath,
})
continue
}
}
return
}