Skip to content

Commit

Permalink
add new ':email' path parameter and revert the jsoniter removal
Browse files Browse the repository at this point in the history
  • Loading branch information
kataras committed Oct 13, 2021
1 parent a9b97e0 commit bf54d33
Show file tree
Hide file tree
Showing 15 changed files with 179 additions and 101 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ If applicable, add screenshots to help explain your problem.
- OS: [e.g. ubuntu, windows]

**iris.Version**
- e.g. v12.2.0-alpha or master
- e.g. v12.2.0-alpha3 or master

Please make sure the bug is reproducible over the `master` branch:

Expand Down
28 changes: 28 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,34 @@ The codebase for Dependency Injection, Internationalization and localization and

## Fixes and Improvements

- New `email` builtin path parameter type. Example:

```go
// +------------------------+
// | {param:email} |
// +------------------------+
// Email + mx look up path parameter validation. Use it on production.

// http://localhost:8080/user/kataras2006@hotmail.com -> OK
// http://localhost:8080/user/b-c@invalid_domain -> NOT FOUND
app.Get("/user/{user_email:email}", func(ctx iris.Context) {
email := ctx.Params().Get("user_email")
ctx.WriteString(email)
})

// +------------------------+
// | {param:mail} |
// +------------------------+
// Simple email path parameter validation.

// http://localhost:8080/user/kataras2006@hotmail.com -> OK
// http://localhost:8080/user/b-c@invalid_domainxxx1.com -> NOT FOUND
app.Get("/user/{local_email:mail}", func(ctx iris.Context) {
email := ctx.Params().Get("local_email")
ctx.WriteString(email)
})
```

- New `iris.IsErrEmptyJSON(err) bool` which reports whether the given "err" is caused by a
`Context.ReadJSON` call when the request body didn't start with { (or it was totally empty).

Expand Down
2 changes: 1 addition & 1 deletion README_FA.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ Venkatt Guhesan" title="vguhesan" with="75" style="width:75px;max-width:75px;hei
$ mkdir myapp
$ cd myapp
$ go mod init myapp
$ go get github.com/kataras/iris/v12@master # or @v12.2.0-alpha2
$ go get github.com/kataras/iris/v12@master # or @v12.2.0-alpha3
```

<div dir="rtl">
Expand Down
10 changes: 3 additions & 7 deletions _examples/bootstrapper/go.mod
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
module github.com/kataras/iris/_examples/bootstrapper
module github.com/kataras/iris/v12/_examples/bootstrapper

go 1.16

require (
github.com/Joker/hpp v1.0.0 // indirect
github.com/gorilla/securecookie v1.1.1
github.com/kataras/iris/v12 v12.2.0-alpha2.0.20210717090056-b2cc3a287149
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/nats-io/nats-server/v2 v2.3.2 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/yudai/pp v2.0.1+incompatible // indirect
github.com/iris-contrib/httpexpect/v2 v2.0.5 // indirect
github.com/kataras/iris/v12 v12.2.0-alpha2.0.20210922114959-0011e0ca3aa6
)
130 changes: 42 additions & 88 deletions _examples/bootstrapper/go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions _examples/desktop/blink/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build windows
// +build windows

package main
Expand Down
7 changes: 6 additions & 1 deletion _examples/response-writer/write-rest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ func main() {
app.Post("/decode", func(ctx iris.Context) {
// Read https://github.com/kataras/iris/blob/master/_examples/request-body/read-json/main.go as well.
var user User
ctx.ReadJSON(&user)
err := ctx.ReadJSON(&user)
if err != nil {
ctx.StatusCode(iris.StatusBadRequest)
ctx.Writef("unable to read body: %s\nbody is empty: %v", err.Error(), iris.IsErrEmptyJSON(err))
return
}

ctx.Writef("%s %s is %d years old and comes from %s!", user.Firstname, user.Lastname, user.Age, user.City)
})
Expand Down
13 changes: 13 additions & 0 deletions _examples/routing/dynamic-path/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,19 @@ func main() {
ctx.WriteString(id)
})

// +------------------------+
// | {param:email} |
// +------------------------+
// Email + mx look uppath parameter validation.
// Note that, you can also use the simplier ":mail" to accept any domain email.

// http://localhost:8080/user/email/kataras2006@hotmail.com -> OK
// http://localhost:8080/user/email/b-c@ -> NOT FOUND
app.Get("/user/email/{user_email:email}", func(ctx iris.Context) {
email := ctx.Params().Get("user_email")
ctx.WriteString(email)
})

// you can use the "string" type which is valid for a single path parameter that can be anything.
app.Get("/username/{name}", func(ctx iris.Context) {
ctx.Writef("Hello %s", ctx.Params().Get("name"))
Expand Down
1 change: 1 addition & 0 deletions _examples/webassembly/client/hello_go116.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build js
// +build js

package main
Expand Down
4 changes: 4 additions & 0 deletions context/request_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ func (r *RequestParams) Get(key string) string {
return v // it should always be string here on :string parameter.
}

if v, ok := kv.ValueRaw.(fmt.Stringer); ok {
return v.String()
}

return fmt.Sprintf("%s", kv.ValueRaw)
}
}
Expand Down
1 change: 1 addition & 0 deletions core/netutil/tcp_soreuse_control_unix.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !windows && !wasm
// +build !windows,!wasm

package netutil
Expand Down
1 change: 1 addition & 0 deletions core/netutil/tcp_soreuse_control_wasm.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build wasm
// +build wasm

package netutil
Expand Down
36 changes: 36 additions & 0 deletions macro/macro_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,42 @@ func TestUUIDEvaluatorRaw(t *testing.T) {
}
}

func TestMailEvaluatorRaw(t *testing.T) {
tests := []struct {
pass bool
input string
}{
{true, "kataras2006@hotmail.com"}, // 0
{true, "iris-go@outlook.com"}, // 1
{true, "iris-go@mail"}, // 2
{true, "kataras@k.c"}, // 3
{false, "www.kataras@"}, // 4
{false, "name"}, // 5
{false, "b-c@"}, // 6
}
for i, tt := range tests {
testEvaluatorRaw(t, Mail, tt.input, reflect.String, tt.pass, i)
}
}

func TestEmailEvaluatorRaw(t *testing.T) {
tests := []struct {
pass bool
input string
}{
{true, "kataras2006@hotmail.com"}, // 0
{true, "iris-go@outlook.com"}, // 1
{false, "iris-go@mail"}, // 2
{false, "kataras@k.c"}, // 3
{false, "www.kataras@"}, // 4
{false, "name"}, // 5
{false, "b-c@"}, // 6
}
for i, tt := range tests {
testEvaluatorRaw(t, Email, tt.input, reflect.String, tt.pass, i)
}
}

func TestConvertBuilderFunc(t *testing.T) {
fn := func(min uint64, slice []string) func(string) bool {
return func(paramValue string) bool {
Expand Down
42 changes: 40 additions & 2 deletions macro/macros.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package macro
import (
"errors"
"fmt"
"net"
"net/mail"
"strconv"
"strings"

Expand Down Expand Up @@ -384,8 +386,8 @@ var (
// Should be living in the latest path segment of a route path.
Path = NewMacro("path", "", false, true, nil)

// UUID string type for validating a uuidv4 (and v1) path parameter
// Read more at: https://tools.ietf.org/html/rfc4122
// UUID string type for validating a uuidv4 (and v1) path parameter.
// Read more at: https://tools.ietf.org/html/rfc4122.
UUID = NewMacro("uuid", "uuidv4", false, false, func(paramValue string) (interface{}, bool) {
_, err := uuid.Parse(paramValue) // this is x10+ times faster than regexp.
if err != nil {
Expand All @@ -394,6 +396,41 @@ var (

return paramValue, true
})

// Email string type for validating an e-mail path parameter. It returns the address as string, instead of an *mail.Address.
// Read more at go std mail.ParseAddress method. See the ':email' path parameter for a more strictly version of validation.
Mail = NewMacro("mail", "", false, false, func(paramValue string) (interface{}, bool) {
_, err := mail.ParseAddress(paramValue)
if err != nil {
return fmt.Errorf("%s: %w", paramValue, err), false
}

return paramValue, true
})

// Email string type for validating an e-mail path parameter. It returns the address as string, instead of an *mail.Address.
// It is a combined validation using mail.ParseAddress and net.LookupMX so only valid domains can be passed.
// It's a more strictly version of the ':mail' path parameter.
Email = NewMacro("email", "", false, false, func(paramValue string) (interface{}, bool) {
_, err := mail.ParseAddress(paramValue)
if err != nil {
return fmt.Errorf("%s: %w", paramValue, err), false
}

domainPart := strings.Split(paramValue, "@")[1]

mx, err := net.LookupMX(domainPart)
if err != nil {
return fmt.Errorf("%s: %w", paramValue, err), false
}

if len(mx) == 0 {
return fmt.Errorf("%s: mx is empty", paramValue), false
}

return paramValue, true
})

// Defaults contains the defaults macro and parameters types for the router.
//
// Read https://github.com/kataras/iris/tree/master/_examples/routing/macros for more details.
Expand All @@ -414,6 +451,7 @@ var (
File,
Path,
UUID,
Email,
}
)

Expand Down
2 changes: 1 addition & 1 deletion middleware/rewrite/rewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (e *Engine) Rewrite(w http.ResponseWriter, r *http.Request, routeHandler ht
hostport := context.GetHost(r)
root := context.GetDomain(hostport)

e.initDebugf("Begin request: full host: %s and root domain: %s", hostport, root)
e.initDebugf("Begin request: full host: %s and root domain: %s\n", hostport, root)
// Note:
// localhost and 127.0.0.1 are not supported for subdomain rewrite, by purpose,
// use a virtual host instead.
Expand Down

0 comments on commit bf54d33

Please sign in to comment.