mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
parent
85fd5ead04
commit
29c8f44c93
|
@ -28,6 +28,8 @@ The codebase for Dependency Injection, Internationalization and localization and
|
||||||
|
|
||||||
## Fixes and Improvements
|
## Fixes and Improvements
|
||||||
|
|
||||||
|
- Add `iris.TrimParamFilePart` to handle cases like [#2024](https://github.com/kataras/iris/issues/2024) and improve the [_examples/routing/dynamic-path/main.go](_examples/routing/dynamic-path/main.go#L356) example to include that case as well.
|
||||||
|
|
||||||
- **Breaking-change**: HTML template functions `yield`, `part`, `partial`, `partial_r` and `render` now accept (and require for some cases) a second argument of the binding data context too. Convert: `{{ yield }}` to `{{ yield . }}`, `{{ render "templates/mytemplate.html" }}` to `{{ render "templates/mytemplate.html" . }}`, `{{ partial "partials/mypartial.html" }}` to `{{ partial "partials/mypartial.html" . }}` and so on.
|
- **Breaking-change**: HTML template functions `yield`, `part`, `partial`, `partial_r` and `render` now accept (and require for some cases) a second argument of the binding data context too. Convert: `{{ yield }}` to `{{ yield . }}`, `{{ render "templates/mytemplate.html" }}` to `{{ render "templates/mytemplate.html" . }}`, `{{ partial "partials/mypartial.html" }}` to `{{ partial "partials/mypartial.html" . }}` and so on.
|
||||||
|
|
||||||
- Add new `URLParamSeparator` to the configuration. Defaults to "," but can be set to an empty string to disable splitting query values on `Context.URLParamSlice` method.
|
- Add new `URLParamSeparator` to the configuration. Defaults to "," but can be set to an empty string to disable splitting query values on `Context.URLParamSlice` method.
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<!-- <a href="https://iris-go.com"> <img align="right" src="https://iris-go.com/images/logo-w169.png"></a> -->
|
<!-- <a href="https://iris-go.com"> <img align="right" src="https://iris-go.com/images/logo-w169.png"></a> -->
|
||||||
|
|
||||||
Iris is a fast, simple yet fully featured and very efficient web framework for Go. **With a personal promise of active lifetime maintenance, [unlike other](https://github.com/gorilla/.github/blob/master/profile/README.md) free software packages offered in Go ecosystem**.
|
Iris is a fast, simple yet fully featured and very efficient web framework for Go. **With the promise of active lifetime maintenance, unlike other free software packages offered in Go ecosystem**.
|
||||||
|
|
||||||
It provides a beautifully expressive and easy to use foundation for your next website or API.
|
It provides a beautifully expressive and easy to use foundation for your next website or API.
|
||||||
|
|
||||||
|
|
|
@ -352,6 +352,17 @@ func main() {
|
||||||
}) // for wildcard path (any number of path segments) without validation you can use:
|
}) // for wildcard path (any number of path segments) without validation you can use:
|
||||||
// /myfiles/*
|
// /myfiles/*
|
||||||
|
|
||||||
|
// http://localhost:8080/trimmed/42.html
|
||||||
|
app.Get("/trimmed/{uid:string regexp(^[0-9]{1,20}.html$)}", iris.TrimParamFilePart, func(ctx iris.Context) {
|
||||||
|
//
|
||||||
|
// The above line is useless now that we've registered the TrimParamFilePart middleware:
|
||||||
|
// uid := ctx.Params().GetTrimFileUint64("uid")
|
||||||
|
// TrimParamFilePart can be registered to a Party (group of routes) too.
|
||||||
|
|
||||||
|
uid := ctx.Params().GetUint64Default("uid", 0)
|
||||||
|
ctx.Writef("Param value: %d\n", uid)
|
||||||
|
})
|
||||||
|
|
||||||
// "{param}"'s performance is exactly the same of ":param"'s.
|
// "{param}"'s performance is exactly the same of ":param"'s.
|
||||||
|
|
||||||
// alternatives -> ":param" for single path parameter and "*" for wildcard path parameter.
|
// alternatives -> ":param" for single path parameter and "*" for wildcard path parameter.
|
||||||
|
|
|
@ -618,8 +618,13 @@ var (
|
||||||
// A shortcut for the `context#ErrPushNotSupported`.
|
// A shortcut for the `context#ErrPushNotSupported`.
|
||||||
ErrPushNotSupported = context.ErrPushNotSupported
|
ErrPushNotSupported = context.ErrPushNotSupported
|
||||||
// PrivateError accepts an error and returns a wrapped private one.
|
// PrivateError accepts an error and returns a wrapped private one.
|
||||||
// A shortcut for the `context#PrivateError`.
|
// A shortcut for the `context#PrivateError` function.
|
||||||
PrivateError = context.PrivateError
|
PrivateError = context.PrivateError
|
||||||
|
|
||||||
|
// TrimParamFilePart is a middleware which trims any last part after a dot (.) character
|
||||||
|
// of the current route's dynamic path parameters.
|
||||||
|
// A shortcut for the `context#TrimParamFilePart` function.
|
||||||
|
TrimParamFilePart Handler = context.TrimParamFilePart
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTP Methods copied from `net/http`.
|
// HTTP Methods copied from `net/http`.
|
||||||
|
|
|
@ -91,6 +91,113 @@ func (r *RequestParams) GetDecoded(key string) string {
|
||||||
return r.GetEscape(key)
|
return r.GetEscape(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TrimParamFilePart is a middleware which replaces all route dynamic path parameters
|
||||||
|
// with values that do not contain any part after the last dot (.) character.
|
||||||
|
//
|
||||||
|
// Example Code:
|
||||||
|
//
|
||||||
|
// package main
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "github.com/kataras/iris/v12"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func main() {
|
||||||
|
// app := iris.New()
|
||||||
|
// app.Get("/{uid:string regexp(^[0-9]{1,20}.html$)}", iris.TrimParamFilePart, handler)
|
||||||
|
// // TrimParamFilePart can be registered as a middleware to a Party (group of routes) as well.
|
||||||
|
// app.Listen(":8080")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func handler(ctx iris.Context) {
|
||||||
|
// //
|
||||||
|
// // The above line is useless now that we've registered the TrimParamFilePart middleware:
|
||||||
|
// // uid := ctx.Params().GetTrimFileUint64("uid")
|
||||||
|
// //
|
||||||
|
//
|
||||||
|
// uid := ctx.Params().GetUint64Default("uid", 0)
|
||||||
|
// ctx.Writef("Param value: %d\n", uid)
|
||||||
|
// }
|
||||||
|
func TrimParamFilePart(ctx *Context) { // See #2024.
|
||||||
|
params := ctx.Params()
|
||||||
|
|
||||||
|
for i, param := range params.Store {
|
||||||
|
if value, ok := param.ValueRaw.(string); ok {
|
||||||
|
if idx := strings.LastIndexByte(value, '.'); idx > 1 /* at least .h */ {
|
||||||
|
value = value[0:idx]
|
||||||
|
param.ValueRaw = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
params.Store[i] = param
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrimFile returns a parameter value but without the last ".ANYTHING_HERE" part.
|
||||||
|
func (r *RequestParams) GetTrimFile(key string) string {
|
||||||
|
value := r.Get(key)
|
||||||
|
|
||||||
|
if idx := strings.LastIndexByte(value, '.'); idx > 1 /* at least .h */ {
|
||||||
|
return value[0:idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrimFileInt same as GetTrimFile but it returns the value as int.
|
||||||
|
func (r *RequestParams) GetTrimFileInt(key string) int {
|
||||||
|
value := r.Get(key)
|
||||||
|
|
||||||
|
if idx := strings.LastIndexByte(value, '.'); idx > 1 /* at least .h */ {
|
||||||
|
value = value[0:idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
v, _ := strconv.Atoi(value)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrimFileUint64 same as GetTrimFile but it returns the value as uint64.
|
||||||
|
func (r *RequestParams) GetTrimFileUint64(key string) uint64 {
|
||||||
|
value := r.Get(key)
|
||||||
|
|
||||||
|
if idx := strings.LastIndexByte(value, '.'); idx > 1 /* at least .h */ {
|
||||||
|
value = value[0:idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := strconv.ParseUint(value, 10, strconv.IntSize)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrimFileUint64 same as GetTrimFile but it returns the value as uint.
|
||||||
|
func (r *RequestParams) GetTrimFileUint(key string) uint {
|
||||||
|
return uint(r.GetTrimFileUint64(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RequestParams) getRightTrimmed(key string, cutset string) string {
|
||||||
|
return strings.TrimRight(strings.ToLower(r.Get(key)), cutset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrimHTML returns a parameter value but without the last ".html" part.
|
||||||
|
func (r *RequestParams) GetTrimHTML(key string) string {
|
||||||
|
return r.getRightTrimmed(key, ".html")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrimJSON returns a parameter value but without the last ".json" part.
|
||||||
|
func (r *RequestParams) GetTrimJSON(key string) string {
|
||||||
|
return r.getRightTrimmed(key, ".json")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrimXML returns a parameter value but without the last ".xml" part.
|
||||||
|
func (r *RequestParams) GetTrimXML(key string) string {
|
||||||
|
return r.getRightTrimmed(key, ".xml")
|
||||||
|
}
|
||||||
|
|
||||||
// GetIntUnslashed same as Get but it removes the first slash if found.
|
// GetIntUnslashed same as Get but it removes the first slash if found.
|
||||||
// Usage: Get an id from a wildcard path.
|
// Usage: Get an id from a wildcard path.
|
||||||
//
|
//
|
||||||
|
|
|
@ -27,10 +27,26 @@ func Parse(fullpath string, paramTypes []ast.ParamType) ([]*ast.ParamStatement,
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it's not a named path parameter of the new syntax then continue to the next
|
// if it's not a named path parameter of the new syntax then continue to the next
|
||||||
if s[0] != lexer.Begin || s[len(s)-1] != lexer.End {
|
// if s[0] != lexer.Begin || s[len(s)-1] != lexer.End {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Modified to show an error on a certain invalid action.
|
||||||
|
if s[0] != lexer.Begin {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s[len(s)-1] != lexer.End {
|
||||||
|
if idx := strings.LastIndexByte(s, lexer.End); idx > 2 && idx < len(s)-1 /* at least {x}*/ {
|
||||||
|
// Do NOT allow something more than a dynamic path parameter in the same path segment,
|
||||||
|
// e.g. /{param}-other-static-part/. See #2024.
|
||||||
|
// this allows it but NO (see trie insert): s = s[0 : idx+1]
|
||||||
|
return nil, fmt.Errorf("%s: invalid path part: dynamic path parameter and other parameters or static parts are not allowed in the same exact request path part, use the {regexp} function alone instead", s)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p.Reset(s)
|
p.Reset(s)
|
||||||
stmt, err := p.Parse(paramTypes)
|
stmt, err := p.Parse(paramTypes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user