mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
New Context.FormFiles method
This commit is contained in:
parent
32291fa59e
commit
8f9140b705
|
@ -396,6 +396,7 @@ var dirOpts = iris.DirOptions{
|
||||||
|
|
||||||
## New Context Methods
|
## New Context Methods
|
||||||
|
|
||||||
|
- `Context.FormFiles(key string, before ...func(*Context, *multipart.FileHeader) bool) (files []multipart.File, headers []*multipart.FileHeader, err error)` method.
|
||||||
- `Context.ReadURL(ptr interface{}) error` shortcut of `ReadParams` and `ReadQuery`. Binds URL dynamic path parameters and URL query parameters to the given "ptr" pointer of a struct value.
|
- `Context.ReadURL(ptr interface{}) error` shortcut of `ReadParams` and `ReadQuery`. Binds URL dynamic path parameters and URL query parameters to the given "ptr" pointer of a struct value.
|
||||||
- `Context.SetUser(User)` and `Context.User() User` to store and retrieve an authenticated client. Read more [here](https://github.com/iris-contrib/middleware/issues/63).
|
- `Context.SetUser(User)` and `Context.User() User` to store and retrieve an authenticated client. Read more [here](https://github.com/iris-contrib/middleware/issues/63).
|
||||||
- `Context.SetLogoutFunc(fn interface{}, persistenceArgs ...interface{})` and `Logout(args ...interface{}) error` methods to allow different kind of auth middlewares to be able to set a "logout" a user/client feature with a single function, the route handler may not be aware of the implementation of the authentication used.
|
- `Context.SetLogoutFunc(fn interface{}, persistenceArgs ...interface{})` and `Logout(args ...interface{}) error` methods to allow different kind of auth middlewares to be able to set a "logout" a user/client feature with a single function, the route handler may not be aware of the implementation of the authentication used.
|
||||||
|
|
|
@ -1943,6 +1943,51 @@ func (ctx *Context) FormFile(key string) (multipart.File, *multipart.FileHeader,
|
||||||
return ctx.request.FormFile(key)
|
return ctx.request.FormFile(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FormFiles same as FormFile but may return multiple file inputs based on a key, e.g. "files[]".
|
||||||
|
func (ctx *Context) FormFiles(key string, before ...func(*Context, *multipart.FileHeader) bool) (files []multipart.File, headers []*multipart.FileHeader, err error) {
|
||||||
|
err = ctx.request.ParseMultipartForm(ctx.app.ConfigurationReadOnly().GetPostMaxMemory())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.request.MultipartForm != nil {
|
||||||
|
fhs := ctx.request.MultipartForm.File
|
||||||
|
if n := len(fhs); n > 0 {
|
||||||
|
files = make([]multipart.File, 0, n)
|
||||||
|
headers = make([]*multipart.FileHeader, 0, n)
|
||||||
|
|
||||||
|
innerLoop:
|
||||||
|
for _, header := range fhs[key] {
|
||||||
|
// Fix an issue that net/http has,
|
||||||
|
// an attacker can push a filename
|
||||||
|
// which could lead to override existing system files
|
||||||
|
// by ../../$header.
|
||||||
|
// Reported by Frank through security reports.
|
||||||
|
header.Filename = strings.ReplaceAll(header.Filename, "../", "")
|
||||||
|
header.Filename = strings.ReplaceAll(header.Filename, "..\\", "")
|
||||||
|
|
||||||
|
for _, b := range before {
|
||||||
|
if !b(ctx, header) {
|
||||||
|
continue innerLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file, fErr := header.Open()
|
||||||
|
if fErr != nil { // exit on first error but return the succeed.
|
||||||
|
return files, headers, fErr
|
||||||
|
}
|
||||||
|
|
||||||
|
files = append(files, file)
|
||||||
|
headers = append(headers, header)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, http.ErrMissingFile
|
||||||
|
}
|
||||||
|
|
||||||
// UploadFormFiles uploads any received file(s) from the client
|
// UploadFormFiles uploads any received file(s) from the client
|
||||||
// to the system physical location "destDirectory".
|
// to the system physical location "destDirectory".
|
||||||
//
|
//
|
||||||
|
@ -1967,7 +2012,7 @@ func (ctx *Context) FormFile(key string) (multipart.File, *multipart.FileHeader,
|
||||||
// the `WithPostMaxMemory` configurator or by `SetMaxRequestBodySize` or
|
// the `WithPostMaxMemory` configurator or by `SetMaxRequestBodySize` or
|
||||||
// by the `LimitRequestBodySize` middleware (depends the use case).
|
// by the `LimitRequestBodySize` middleware (depends the use case).
|
||||||
//
|
//
|
||||||
// See `FormFile` to a more controlled way to receive a file.
|
// See `FormFile` and `FormFiles` to a more controlled way to receive a file.
|
||||||
//
|
//
|
||||||
// Example: https://github.com/kataras/iris/tree/master/_examples/file-server/upload-files
|
// Example: https://github.com/kataras/iris/tree/master/_examples/file-server/upload-files
|
||||||
func (ctx *Context) UploadFormFiles(destDirectory string, before ...func(*Context, *multipart.FileHeader) bool) (uploaded []*multipart.FileHeader, n int64, err error) {
|
func (ctx *Context) UploadFormFiles(destDirectory string, before ...func(*Context, *multipart.FileHeader) bool) (uploaded []*multipart.FileHeader, n int64, err error) {
|
||||||
|
|
|
@ -98,6 +98,29 @@ var IsLoopbackHost = func(requestHost string) bool {
|
||||||
return valid
|
return valid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func isLoopbackHostGoVersion(host string) bool {
|
||||||
|
ip := net.ParseIP(host)
|
||||||
|
if ip != nil {
|
||||||
|
return ip.IsLoopback()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Host is not an ip, perform lookup.
|
||||||
|
addrs, err := net.LookupHost(host)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if !net.ParseIP(addr).IsLoopback() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// defaultServerHostname returns the default hostname which is "localhost"
|
// defaultServerHostname returns the default hostname which is "localhost"
|
||||||
defaultServerHostname = "localhost"
|
defaultServerHostname = "localhost"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user