mirror of
https://github.com/kataras/iris.git
synced 2026-01-10 05:25:58 +00:00
Update to version 8.5.6 | Read HISTORY.md
Former-commit-id: 3c1fb7ad47d54133f68ee0ee8ebe4c3835fe4ce0
This commit is contained in:
@@ -263,7 +263,7 @@ You can serve [quicktemplate](https://github.com/valyala/quicktemplate) files to
|
||||
|
||||
- [Basic Authentication](authentication/basicauth/main.go)
|
||||
- [OAUth2](authentication/oauth2/main.go)
|
||||
- [JWT](https://github.com/iris-contrib/middleware/blob/master/jwt/_example/main.go)
|
||||
- [JWT](experimental-handlers/jwt/main.go)
|
||||
- [Sessions](#sessions)
|
||||
|
||||
### File Server
|
||||
@@ -307,6 +307,18 @@ You can serve [quicktemplate](https://github.com/valyala/quicktemplate) files to
|
||||
- [Internal Application File Logger](miscellaneous/file-logger/main.go)
|
||||
- [Google reCAPTCHA](miscellaneous/recaptcha/main.go)
|
||||
|
||||
### Experimental Handlers
|
||||
|
||||
* [Casbin wrapper](experimental-handlers/casbin/wrapper/main.go)
|
||||
* [Casbin middleware](experimental-handlers/casbin/middleware/main.go)
|
||||
* [Cloudwatch](experimental-handlers/cloudwatch/simple/main.go)
|
||||
* [CORS](experimental-handlers/cors/simple/main.go)
|
||||
* [JWT](experimental-handlers/jwt/main.go)
|
||||
* [Newrelic](experimental-handlers/newrelic/simple/main.go)
|
||||
* [Prometheus](experimental-handlers/prometheus/simple/main.go)
|
||||
* [Secure](experimental-handlers/secure/simple/main.go)
|
||||
* [Tollboothic](experimental-handlers/tollboothic/limit-handler/main.go)
|
||||
|
||||
#### More
|
||||
|
||||
https://github.com/kataras/iris/tree/master/middleware#third-party-handlers
|
||||
|
||||
@@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/context"
|
||||
|
||||
"github.com/betacraft/yaag/irisyaag"
|
||||
"github.com/betacraft/yaag/yaag"
|
||||
@@ -27,21 +26,21 @@ func main() {
|
||||
})
|
||||
app.Use(irisyaag.New()) // <- IMPORTANT, register the middleware.
|
||||
|
||||
app.Get("/json", func(ctx context.Context) {
|
||||
ctx.JSON(context.Map{"result": "Hello World!"})
|
||||
app.Get("/json", func(ctx iris.Context) {
|
||||
ctx.JSON(iris.Map{"result": "Hello World!"})
|
||||
})
|
||||
|
||||
app.Get("/plain", func(ctx context.Context) {
|
||||
app.Get("/plain", func(ctx iris.Context) {
|
||||
ctx.Text("Hello World!")
|
||||
})
|
||||
|
||||
app.Get("/xml", func(ctx context.Context) {
|
||||
app.Get("/xml", func(ctx iris.Context) {
|
||||
ctx.XML(myXML{Result: "Hello World!"})
|
||||
})
|
||||
|
||||
app.Get("/complex", func(ctx context.Context) {
|
||||
app.Get("/complex", func(ctx iris.Context) {
|
||||
value := ctx.URLParam("key")
|
||||
ctx.JSON(context.Map{"value": value})
|
||||
ctx.JSON(iris.Map{"value": value})
|
||||
})
|
||||
|
||||
// Run our HTTP Server.
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
- [Basic Authentication](basicauth/main.go)
|
||||
- [OAUth2](oauth2/main.go)
|
||||
- [JWT](https://github.com/iris-contrib/middleware/blob/master/jwt/_example/main.go)
|
||||
- [JWT](https://github.com/kataras/iris/blob/master/_examples/experimental-handlers/jwt/main.go)
|
||||
- [Sessions](https://github.com/kataras/iris/tree/master/_examples/#sessions)
|
||||
5
_examples/experimental-handlers/README.md
Normal file
5
_examples/experimental-handlers/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Install iris-contrib/middleware
|
||||
|
||||
```sh
|
||||
$ go get -u github.com/iris-contrib/middleware/...
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
[request_definition]
|
||||
r = sub, obj, act
|
||||
|
||||
[policy_definition]
|
||||
p = sub, obj, act
|
||||
|
||||
[role_definition]
|
||||
g = _, _
|
||||
|
||||
[policy_effect]
|
||||
e = some(where (p.eft == allow))
|
||||
|
||||
[matchers]
|
||||
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
|
||||
@@ -0,0 +1,5 @@
|
||||
p, alice, /dataset1/*, GET
|
||||
p, alice, /dataset1/resource1, POST
|
||||
p, bob, /dataset2/resource1, *
|
||||
p, bob, /dataset2/resource2, GET
|
||||
p, bob, /dataset2/folder1/*, POST
|
||||
|
43
_examples/experimental-handlers/casbin/middleware/main.go
Normal file
43
_examples/experimental-handlers/casbin/middleware/main.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/casbin/casbin"
|
||||
cm "github.com/iris-contrib/middleware/casbin"
|
||||
)
|
||||
|
||||
// $ go get github.com/casbin/casbin
|
||||
// $ go run main.go
|
||||
|
||||
// Enforcer maps the model and the policy for the casbin service, we use this variable on the main_test too.
|
||||
var Enforcer = casbin.NewEnforcer("casbinmodel.conf", "casbinpolicy.csv")
|
||||
|
||||
func newApp() *iris.Application {
|
||||
casbinMiddleware := cm.New(Enforcer)
|
||||
|
||||
app := iris.New()
|
||||
app.Use(casbinMiddleware.ServeHTTP)
|
||||
|
||||
app.Get("/", hi)
|
||||
|
||||
app.Get("/dataset1/{p:path}", hi) // p, alice, /dataset1/*, GET
|
||||
|
||||
app.Post("/dataset1/resource1", hi)
|
||||
|
||||
app.Get("/dataset2/resource2", hi)
|
||||
app.Post("/dataset2/folder1/{p:path}", hi)
|
||||
|
||||
app.Any("/dataset2/resource1", hi)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
|
||||
func hi(ctx iris.Context) {
|
||||
ctx.Writef("Hello %s", cm.Username(ctx.Request()))
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/iris-contrib/httpexpect"
|
||||
"github.com/kataras/iris/httptest"
|
||||
)
|
||||
|
||||
func TestCasbinMiddleware(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app, httptest.Debug(true))
|
||||
|
||||
type ttcasbin struct {
|
||||
username string
|
||||
path string
|
||||
method string
|
||||
status int
|
||||
}
|
||||
|
||||
tt := []ttcasbin{
|
||||
{"alice", "/dataset1/resource1", "GET", 200},
|
||||
{"alice", "/dataset1/resource1", "POST", 200},
|
||||
{"alice", "/dataset1/resource2", "GET", 200},
|
||||
{"alice", "/dataset1/resource2", "POST", 404},
|
||||
|
||||
{"bob", "/dataset2/resource1", "GET", 200},
|
||||
{"bob", "/dataset2/resource1", "POST", 200},
|
||||
{"bob", "/dataset2/resource1", "DELETE", 200},
|
||||
{"bob", "/dataset2/resource2", "GET", 200},
|
||||
{"bob", "/dataset2/resource2", "POST", 404},
|
||||
{"bob", "/dataset2/resource2", "DELETE", 404},
|
||||
|
||||
{"bob", "/dataset2/folder1/item1", "GET", 404},
|
||||
{"bob", "/dataset2/folder1/item1", "POST", 200},
|
||||
{"bob", "/dataset2/folder1/item1", "DELETE", 404},
|
||||
{"bob", "/dataset2/folder1/item2", "GET", 404},
|
||||
{"bob", "/dataset2/folder1/item2", "POST", 200},
|
||||
{"bob", "/dataset2/folder1/item2", "DELETE", 404},
|
||||
}
|
||||
|
||||
for _, tt := range tt {
|
||||
check(e, tt.method, tt.path, tt.username, tt.status)
|
||||
}
|
||||
}
|
||||
|
||||
func check(e *httpexpect.Expect, method, path, username string, status int) {
|
||||
e.Request(method, path).WithBasicAuth(username, "password").Expect().Status(status)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
[request_definition]
|
||||
r = sub, obj, act
|
||||
|
||||
[policy_definition]
|
||||
p = sub, obj, act
|
||||
|
||||
[role_definition]
|
||||
g = _, _
|
||||
|
||||
[policy_effect]
|
||||
e = some(where (p.eft == allow))
|
||||
|
||||
[matchers]
|
||||
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
|
||||
@@ -0,0 +1,7 @@
|
||||
p, alice, /dataset1/*, GET
|
||||
p, alice, /dataset1/resource1, POST
|
||||
p, bob, /dataset2/resource1, *
|
||||
p, bob, /dataset2/resource2, GET
|
||||
p, bob, /dataset2/folder1/*, POST
|
||||
p, dataset1_admin, /dataset1/*, *
|
||||
g, cathrin, dataset1_admin
|
||||
|
43
_examples/experimental-handlers/casbin/wrapper/main.go
Normal file
43
_examples/experimental-handlers/casbin/wrapper/main.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/casbin/casbin"
|
||||
cm "github.com/iris-contrib/middleware/casbin"
|
||||
)
|
||||
|
||||
// $ go get github.com/casbin/casbin
|
||||
// $ go run main.go
|
||||
|
||||
// Enforcer maps the model and the policy for the casbin service, we use this variable on the main_test too.
|
||||
var Enforcer = casbin.NewEnforcer("casbinmodel.conf", "casbinpolicy.csv")
|
||||
|
||||
func newApp() *iris.Application {
|
||||
casbinMiddleware := cm.New(Enforcer)
|
||||
|
||||
app := iris.New()
|
||||
app.WrapRouter(casbinMiddleware.Wrapper())
|
||||
|
||||
app.Get("/", hi)
|
||||
|
||||
app.Any("/dataset1/{p:path}", hi) // p, dataset1_admin, /dataset1/*, * && p, alice, /dataset1/*, GET
|
||||
|
||||
app.Post("/dataset1/resource1", hi)
|
||||
|
||||
app.Get("/dataset2/resource2", hi)
|
||||
app.Post("/dataset2/folder1/{p:path}", hi)
|
||||
|
||||
app.Any("/dataset2/resource1", hi)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
|
||||
func hi(ctx iris.Context) {
|
||||
ctx.Writef("Hello %s", cm.Username(ctx.Request()))
|
||||
}
|
||||
80
_examples/experimental-handlers/casbin/wrapper/main_test.go
Normal file
80
_examples/experimental-handlers/casbin/wrapper/main_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/iris-contrib/httpexpect"
|
||||
"github.com/kataras/iris/httptest"
|
||||
)
|
||||
|
||||
func TestCasbinWrapper(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app, httptest.Debug(true))
|
||||
|
||||
type ttcasbin struct {
|
||||
username string
|
||||
path string
|
||||
method string
|
||||
status int
|
||||
}
|
||||
|
||||
tt := []ttcasbin{
|
||||
{"alice", "/dataset1/resource1", "GET", 200},
|
||||
{"alice", "/dataset1/resource1", "POST", 200},
|
||||
{"alice", "/dataset1/resource2", "GET", 200},
|
||||
{"alice", "/dataset1/resource2", "POST", 403},
|
||||
|
||||
{"bob", "/dataset2/resource1", "GET", 200},
|
||||
{"bob", "/dataset2/resource1", "POST", 200},
|
||||
{"bob", "/dataset2/resource1", "DELETE", 200},
|
||||
{"bob", "/dataset2/resource2", "GET", 200},
|
||||
{"bob", "/dataset2/resource2", "POST", 403},
|
||||
{"bob", "/dataset2/resource2", "DELETE", 403},
|
||||
|
||||
{"bob", "/dataset2/folder1/item1", "GET", 403},
|
||||
{"bob", "/dataset2/folder1/item1", "POST", 200},
|
||||
{"bob", "/dataset2/folder1/item1", "DELETE", 403},
|
||||
{"bob", "/dataset2/folder1/item2", "GET", 403},
|
||||
{"bob", "/dataset2/folder1/item2", "POST", 200},
|
||||
{"bob", "/dataset2/folder1/item2", "DELETE", 403},
|
||||
}
|
||||
|
||||
for _, tt := range tt {
|
||||
check(e, tt.method, tt.path, tt.username, tt.status)
|
||||
}
|
||||
|
||||
println("ADMIN ROLES")
|
||||
ttAdmin := []ttcasbin{
|
||||
{"cathrin", "/dataset1/item", "GET", 200},
|
||||
{"cathrin", "/dataset1/item", "POST", 200},
|
||||
{"cathrin", "/dataset1/item", "DELETE", 200},
|
||||
{"cathrin", "/dataset2/item", "GET", 403},
|
||||
{"cathrin", "/dataset2/item", "POST", 403},
|
||||
{"cathrin", "/dataset2/item", "DELETE", 403},
|
||||
}
|
||||
|
||||
for _, tt := range ttAdmin {
|
||||
check(e, tt.method, tt.path, tt.username, tt.status)
|
||||
}
|
||||
|
||||
println("ADMIN ROLE FOR cathrin DELETED")
|
||||
Enforcer.DeleteRolesForUser("cathrin")
|
||||
|
||||
ttAdminDeleted := []ttcasbin{
|
||||
{"cathrin", "/dataset1/item", "GET", 403},
|
||||
{"cathrin", "/dataset1/item", "POST", 403},
|
||||
{"cathrin", "/dataset1/item", "DELETE", 403},
|
||||
{"cathrin", "/dataset2/item", "GET", 403},
|
||||
{"cathrin", "/dataset2/item", "POST", 403},
|
||||
{"cathrin", "/dataset2/item", "DELETE", 403},
|
||||
}
|
||||
|
||||
for _, tt := range ttAdminDeleted {
|
||||
check(e, tt.method, tt.path, tt.username, tt.status)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func check(e *httpexpect.Expect, method, path, username string, status int) {
|
||||
e.Request(method, path).WithBasicAuth(username, "password").Expect().Status(status)
|
||||
}
|
||||
50
_examples/experimental-handlers/cloudwatch/simple/main.go
Normal file
50
_examples/experimental-handlers/cloudwatch/simple/main.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
cw "github.com/iris-contrib/middleware/cloudwatch"
|
||||
)
|
||||
|
||||
// $ go get github.com/aws/aws-sdk-go/...
|
||||
// $ go run main.go
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Use(cw.New("us-east-1", "test").ServeHTTP)
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
put := cw.GetPutFunc(ctx)
|
||||
|
||||
put([]*cloudwatch.MetricDatum{
|
||||
{
|
||||
MetricName: aws.String("MyMetric"),
|
||||
Dimensions: []*cloudwatch.Dimension{
|
||||
{
|
||||
Name: aws.String("ThingOne"),
|
||||
Value: aws.String("something"),
|
||||
},
|
||||
{
|
||||
Name: aws.String("ThingTwo"),
|
||||
Value: aws.String("other"),
|
||||
},
|
||||
},
|
||||
Timestamp: aws.Time(time.Now()),
|
||||
Unit: aws.String("Count"),
|
||||
Value: aws.Float64(42),
|
||||
},
|
||||
})
|
||||
|
||||
ctx.StatusCode(iris.StatusOK)
|
||||
ctx.Text("success!\n")
|
||||
})
|
||||
|
||||
// http://localhost:8080
|
||||
// should give: NoCredentialProviders
|
||||
// which is correct, you have to authorize your aws, we asumme that you know how to.
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
43
_examples/experimental-handlers/cors/simple/main.go
Normal file
43
_examples/experimental-handlers/cors/simple/main.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
// $ go get github.com/rs/cors
|
||||
// $ go run main.go
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/iris-contrib/middleware/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
app := iris.New()
|
||||
crs := cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"*"}, // allows everything, use that to change the hosts.
|
||||
AllowCredentials: true,
|
||||
})
|
||||
|
||||
v1 := app.Party("/api/v1")
|
||||
v1.Use(crs)
|
||||
{
|
||||
v1.Get("/home", func(ctx iris.Context) {
|
||||
ctx.WriteString("Hello from /home")
|
||||
})
|
||||
v1.Get("/about", func(ctx iris.Context) {
|
||||
ctx.WriteString("Hello from /about")
|
||||
})
|
||||
v1.Post("/send", func(ctx iris.Context) {
|
||||
ctx.WriteString("sent")
|
||||
})
|
||||
}
|
||||
|
||||
// or use that to wrap the entire router
|
||||
// even before the path and method matching
|
||||
// this should work better and with all cors' features.
|
||||
// Use that instead, if suits you.
|
||||
// app.WrapRouter(cors.WrapNext(cors.Options{
|
||||
// AllowedOrigins: []string{"*"},
|
||||
// AllowCredentials: true,
|
||||
// }))
|
||||
app.Run(iris.Addr("localhost:8080"))
|
||||
}
|
||||
46
_examples/experimental-handlers/jwt/main.go
Normal file
46
_examples/experimental-handlers/jwt/main.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// iris provides some basic middleware, most for your learning courve.
|
||||
// You can use any net/http compatible middleware with iris.FromStd wrapper.
|
||||
//
|
||||
// JWT net/http video tutorial for golang newcomers: https://www.youtube.com/watch?v=dgJFeqeXVKw
|
||||
//
|
||||
// This middleware is the only one cloned from external source: https://github.com/auth0/go-jwt-middleware
|
||||
// (because it used "context" to define the user but we don't need that so a simple iris.FromStd wouldn't work as expected.)
|
||||
package main
|
||||
|
||||
// $ go get -u github.com/dgrijalva/jwt-go
|
||||
// $ go run main.go
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
jwtmiddleware "github.com/iris-contrib/middleware/jwt"
|
||||
)
|
||||
|
||||
func myHandler(ctx iris.Context) {
|
||||
user := ctx.Values().Get("jwt").(*jwt.Token)
|
||||
|
||||
ctx.Writef("This is an authenticated request\n")
|
||||
ctx.Writef("Claim content:\n")
|
||||
|
||||
ctx.Writef("%s", user.Signature)
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
jwtHandler := jwtmiddleware.New(jwtmiddleware.Config{
|
||||
ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte("My Secret"), nil
|
||||
},
|
||||
// When set, the middleware verifies that tokens are signed with the specific signing algorithm
|
||||
// If the signing method is not constant the ValidationKeyGetter callback can be used to implement additional checks
|
||||
// Important to avoid security issues described here: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
|
||||
SigningMethod: jwt.SigningMethodHS256,
|
||||
})
|
||||
|
||||
app.Use(jwtHandler.Serve)
|
||||
|
||||
app.Get("/ping", myHandler)
|
||||
app.Run(iris.Addr("localhost:3001"))
|
||||
} // don't forget to look ../jwt_test.go to seee how to set your own custom claims
|
||||
24
_examples/experimental-handlers/newrelic/simple/main.go
Normal file
24
_examples/experimental-handlers/newrelic/simple/main.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/iris-contrib/middleware/newrelic"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
config := newrelic.Config("APP_SERVER_NAME", "NEWRELIC_LICENSE_KEY")
|
||||
config.Enabled = true
|
||||
m, err := newrelic.New(config)
|
||||
if err != nil {
|
||||
app.Logger().Fatal(err)
|
||||
}
|
||||
app.Use(m.ServeHTTP)
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("success!\n")
|
||||
})
|
||||
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
40
_examples/experimental-handlers/prometheus/simple/main.go
Normal file
40
_examples/experimental-handlers/prometheus/simple/main.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
|
||||
prometheusMiddleware "github.com/iris-contrib/middleware/prometheus"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
m := prometheusMiddleware.New("serviceName", 300, 1200, 5000)
|
||||
|
||||
app.Use(m.ServeHTTP)
|
||||
|
||||
app.OnErrorCode(iris.StatusNotFound, func(ctx iris.Context) {
|
||||
// error code handlers are not sharing the same middleware as other routes, so we have
|
||||
// to call them inside their body.
|
||||
m.ServeHTTP(ctx)
|
||||
|
||||
ctx.Writef("Not Found")
|
||||
})
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
sleep := rand.Intn(4999) + 1
|
||||
time.Sleep(time.Duration(sleep) * time.Millisecond)
|
||||
ctx.Writef("Slept for %d milliseconds", sleep)
|
||||
})
|
||||
|
||||
app.Get("/metrics", iris.FromStd(prometheus.Handler()))
|
||||
|
||||
// http://localhost:8080/
|
||||
// http://localhost:8080/anotfound
|
||||
// http://localhost:8080/metrics
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
38
_examples/experimental-handlers/secure/simple/main.go
Normal file
38
_examples/experimental-handlers/secure/simple/main.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/iris-contrib/middleware/secure"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := secure.New(secure.Options{
|
||||
AllowedHosts: []string{"ssl.example.com"}, // AllowedHosts is a list of fully qualified domain names that are allowed. Default is empty list, which allows any and all host names.
|
||||
SSLRedirect: true, // If SSLRedirect is set to true, then only allow HTTPS requests. Default is false.
|
||||
SSLTemporaryRedirect: false, // If SSLTemporaryRedirect is true, the a 302 will be used while redirecting. Default is false (301).
|
||||
SSLHost: "ssl.example.com", // SSLHost is the host name that is used to redirect HTTP requests to HTTPS. Default is "", which indicates to use the same host.
|
||||
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"}, // SSLProxyHeaders is set of header keys with associated values that would indicate a valid HTTPS request. Useful when using Nginx: `map[string]string{"X-Forwarded-Proto": "https"}`. Default is blank map.
|
||||
STSSeconds: 315360000, // STSSeconds is the max-age of the Strict-Transport-Security header. Default is 0, which would NOT include the header.
|
||||
STSIncludeSubdomains: true, // If STSIncludeSubdomains is set to true, the `includeSubdomains` will be appended to the Strict-Transport-Security header. Default is false.
|
||||
STSPreload: true, // If STSPreload is set to true, the `preload` flag will be appended to the Strict-Transport-Security header. Default is false.
|
||||
ForceSTSHeader: false, // STS header is only included when the connection is HTTPS. If you want to force it to always be added, set to true. `IsDevelopment` still overrides this. Default is false.
|
||||
FrameDeny: true, // If FrameDeny is set to true, adds the X-Frame-Options header with the value of `DENY`. Default is false.
|
||||
CustomFrameOptionsValue: "SAMEORIGIN", // CustomFrameOptionsValue allows the X-Frame-Options header value to be set with a custom value. This overrides the FrameDeny option.
|
||||
ContentTypeNosniff: true, // If ContentTypeNosniff is true, adds the X-Content-Type-Options header with the value `nosniff`. Default is false.
|
||||
BrowserXSSFilter: true, // If BrowserXssFilter is true, adds the X-XSS-Protection header with the value `1; mode=block`. Default is false.
|
||||
ContentSecurityPolicy: "default-src 'self'", // ContentSecurityPolicy allows the Content-Security-Policy header value to be set with a custom value. Default is "".
|
||||
PublicKey: `pin-sha256="base64+primary=="; pin-sha256="base64+backup=="; max-age=5184000; includeSubdomains; report-uri="https://www.example.com/hpkp-report"`, // PublicKey implements HPKP to prevent MITM attacks with forged certificates. Default is "".
|
||||
|
||||
IsDevelopment: true, // This will cause the AllowedHosts, SSLRedirect, and STSSeconds/STSIncludeSubdomains options to be ignored during development. When deploying to production, be sure to set this to false.
|
||||
})
|
||||
|
||||
app := iris.New()
|
||||
app.Use(s.Serve)
|
||||
|
||||
app.Get("/home", func(ctx iris.Context) {
|
||||
ctx.Writef("Hello from /home")
|
||||
})
|
||||
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/didip/tollbooth"
|
||||
"github.com/iris-contrib/middleware/tollboothic"
|
||||
)
|
||||
|
||||
// $ go get github.com/didip/tollbooth
|
||||
// $ go run main.go
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
limiter := tollbooth.NewLimiter(1, nil)
|
||||
//
|
||||
// or create a limiter with expirable token buckets
|
||||
// This setting means:
|
||||
// create a 1 request/second limiter and
|
||||
// every token bucket in it will expire 1 hour after it was initially set.
|
||||
// limiter := tollbooth.NewLimiter(1, &limiter.ExpirableOptions{DefaultExpirationTTL: time.Hour})
|
||||
|
||||
app.Get("/", tollboothic.LimitHandler(limiter), func(ctx iris.Context) {
|
||||
ctx.HTML("<b>Hello, world!</b>")
|
||||
})
|
||||
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
|
||||
// Read more at: https://github.com/didip/tollbooth
|
||||
@@ -1,128 +0,0 @@
|
||||
// This file is automatically generated by qtc from "base.qtpl".
|
||||
// See https://github.com/valyala/quicktemplate for details.
|
||||
|
||||
// This is our templates' base implementation.
|
||||
//
|
||||
|
||||
//line base.qtpl:3
|
||||
package templates
|
||||
|
||||
//line base.qtpl:3
|
||||
import (
|
||||
qtio422016 "io"
|
||||
|
||||
qt422016 "github.com/valyala/quicktemplate"
|
||||
)
|
||||
|
||||
//line base.qtpl:3
|
||||
var (
|
||||
_ = qtio422016.Copy
|
||||
_ = qt422016.AcquireByteBuffer
|
||||
)
|
||||
|
||||
//line base.qtpl:4
|
||||
type Partial interface {
|
||||
//line base.qtpl:4
|
||||
Body() string
|
||||
//line base.qtpl:4
|
||||
StreamBody(qw422016 *qt422016.Writer)
|
||||
//line base.qtpl:4
|
||||
WriteBody(qq422016 qtio422016.Writer)
|
||||
//line base.qtpl:4
|
||||
}
|
||||
|
||||
// Template writes a template implementing the Partial interface.
|
||||
|
||||
//line base.qtpl:11
|
||||
func StreamTemplate(qw422016 *qt422016.Writer, p Partial) {
|
||||
//line base.qtpl:11
|
||||
qw422016.N().S(`
|
||||
<html>
|
||||
<head>
|
||||
<title>Quicktemplate integration with Iris</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
Header contents here...
|
||||
</div>
|
||||
|
||||
<div style="margin:10px;">
|
||||
`)
|
||||
//line base.qtpl:22
|
||||
p.StreamBody(qw422016)
|
||||
//line base.qtpl:22
|
||||
qw422016.N().S(`
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<footer>
|
||||
Footer contents here...
|
||||
</footer>
|
||||
</html>
|
||||
`)
|
||||
//line base.qtpl:30
|
||||
}
|
||||
|
||||
//line base.qtpl:30
|
||||
func WriteTemplate(qq422016 qtio422016.Writer, p Partial) {
|
||||
//line base.qtpl:30
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line base.qtpl:30
|
||||
StreamTemplate(qw422016, p)
|
||||
//line base.qtpl:30
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line base.qtpl:30
|
||||
}
|
||||
|
||||
//line base.qtpl:30
|
||||
func Template(p Partial) string {
|
||||
//line base.qtpl:30
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line base.qtpl:30
|
||||
WriteTemplate(qb422016, p)
|
||||
//line base.qtpl:30
|
||||
qs422016 := string(qb422016.B)
|
||||
//line base.qtpl:30
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line base.qtpl:30
|
||||
return qs422016
|
||||
//line base.qtpl:30
|
||||
}
|
||||
|
||||
// Base template implementation. Other pages may inherit from it if they need
|
||||
// overriding only certain Partial methods.
|
||||
|
||||
//line base.qtpl:35
|
||||
type Base struct{}
|
||||
|
||||
//line base.qtpl:36
|
||||
func (b *Base) StreamBody(qw422016 *qt422016.Writer) {
|
||||
//line base.qtpl:36
|
||||
qw422016.N().S(`This is the base body`) }
|
||||
|
||||
//line base.qtpl:36
|
||||
//line base.qtpl:36
|
||||
func (b *Base) WriteBody(qq422016 qtio422016.Writer) {
|
||||
//line base.qtpl:36
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line base.qtpl:36
|
||||
b.StreamBody(qw422016)
|
||||
//line base.qtpl:36
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line base.qtpl:36
|
||||
}
|
||||
|
||||
//line base.qtpl:36
|
||||
func (b *Base) Body() string {
|
||||
//line base.qtpl:36
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line base.qtpl:36
|
||||
b.WriteBody(qb422016)
|
||||
//line base.qtpl:36
|
||||
qs422016 := string(qb422016.B)
|
||||
//line base.qtpl:36
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line base.qtpl:36
|
||||
return qs422016
|
||||
//line base.qtpl:36
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// This file is automatically generated by qtc from "hello.qtpl".
|
||||
// See https://github.com/valyala/quicktemplate for details.
|
||||
|
||||
// Hello template, implements the Partial's methods.
|
||||
//
|
||||
|
||||
//line hello.qtpl:3
|
||||
package templates
|
||||
|
||||
//line hello.qtpl:3
|
||||
import (
|
||||
qtio422016 "io"
|
||||
|
||||
qt422016 "github.com/valyala/quicktemplate"
|
||||
)
|
||||
|
||||
//line hello.qtpl:3
|
||||
var (
|
||||
_ = qtio422016.Copy
|
||||
_ = qt422016.AcquireByteBuffer
|
||||
)
|
||||
|
||||
//line hello.qtpl:4
|
||||
type Hello struct {
|
||||
Vars map[string]interface{}
|
||||
}
|
||||
|
||||
//line hello.qtpl:9
|
||||
func (h *Hello) StreamBody(qw422016 *qt422016.Writer) {
|
||||
//line hello.qtpl:9
|
||||
qw422016.N().S(`
|
||||
<h1>`)
|
||||
//line hello.qtpl:10
|
||||
qw422016.E().V(h.Vars["message"])
|
||||
//line hello.qtpl:10
|
||||
qw422016.N().S(`</h1>
|
||||
<div>
|
||||
Hello <b>`)
|
||||
//line hello.qtpl:12
|
||||
qw422016.E().V(h.Vars["name"])
|
||||
//line hello.qtpl:12
|
||||
qw422016.N().S(`!</b>
|
||||
</div>
|
||||
`)
|
||||
//line hello.qtpl:14
|
||||
}
|
||||
|
||||
//line hello.qtpl:14
|
||||
func (h *Hello) WriteBody(qq422016 qtio422016.Writer) {
|
||||
//line hello.qtpl:14
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line hello.qtpl:14
|
||||
h.StreamBody(qw422016)
|
||||
//line hello.qtpl:14
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line hello.qtpl:14
|
||||
}
|
||||
|
||||
//line hello.qtpl:14
|
||||
func (h *Hello) Body() string {
|
||||
//line hello.qtpl:14
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line hello.qtpl:14
|
||||
h.WriteBody(qb422016)
|
||||
//line hello.qtpl:14
|
||||
qs422016 := string(qb422016.B)
|
||||
//line hello.qtpl:14
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line hello.qtpl:14
|
||||
return qs422016
|
||||
//line hello.qtpl:14
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// This file is automatically generated by qtc from "index.qtpl".
|
||||
// See https://github.com/valyala/quicktemplate for details.
|
||||
|
||||
// Index template, implements the Partial's methods.
|
||||
//
|
||||
|
||||
//line index.qtpl:3
|
||||
package templates
|
||||
|
||||
//line index.qtpl:3
|
||||
import (
|
||||
qtio422016 "io"
|
||||
|
||||
qt422016 "github.com/valyala/quicktemplate"
|
||||
)
|
||||
|
||||
//line index.qtpl:3
|
||||
var (
|
||||
_ = qtio422016.Copy
|
||||
_ = qt422016.AcquireByteBuffer
|
||||
)
|
||||
|
||||
//line index.qtpl:4
|
||||
type Index struct{}
|
||||
|
||||
//line index.qtpl:7
|
||||
func (i *Index) StreamBody(qw422016 *qt422016.Writer) {
|
||||
//line index.qtpl:7
|
||||
qw422016.N().S(`
|
||||
<h1>Index Page</h1>
|
||||
<div>
|
||||
This is our index page's body.
|
||||
</div>
|
||||
`)
|
||||
//line index.qtpl:12
|
||||
}
|
||||
|
||||
//line index.qtpl:12
|
||||
func (i *Index) WriteBody(qq422016 qtio422016.Writer) {
|
||||
//line index.qtpl:12
|
||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||
//line index.qtpl:12
|
||||
i.StreamBody(qw422016)
|
||||
//line index.qtpl:12
|
||||
qt422016.ReleaseWriter(qw422016)
|
||||
//line index.qtpl:12
|
||||
}
|
||||
|
||||
//line index.qtpl:12
|
||||
func (i *Index) Body() string {
|
||||
//line index.qtpl:12
|
||||
qb422016 := qt422016.AcquireByteBuffer()
|
||||
//line index.qtpl:12
|
||||
i.WriteBody(qb422016)
|
||||
//line index.qtpl:12
|
||||
qs422016 := string(qb422016.B)
|
||||
//line index.qtpl:12
|
||||
qt422016.ReleaseByteBuffer(qb422016)
|
||||
//line index.qtpl:12
|
||||
return qs422016
|
||||
//line index.qtpl:12
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
# Articles
|
||||
|
||||
- [How to build a file upload form using DropzoneJS and Go](https://dev.to/kataras/dropzonejs--go-series---part-1-474)
|
||||
- [How to display existing files on server using DropzoneJS and Go](https://dev.to/kataras/dropzonejs--go-series---part-2-4n1)
|
||||
* [How to build a file upload form using DropzoneJS and Go](https://hackernoon.com/how-to-build-a-file-upload-form-using-dropzonejs-and-go-8fb9f258a991)
|
||||
* [How to display existing files on server using DropzoneJS and Go](https://hackernoon.com/how-to-display-existing-files-on-server-using-dropzonejs-and-go-53e24b57ba19)
|
||||
|
||||
# Content
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Articles
|
||||
|
||||
- [How to build a file upload form using DropzoneJS and Go](https://dev.to/kataras/dropzonejs--go-series---part-1-474)
|
||||
- [How to display existing files on server using DropzoneJS and Go](https://dev.to/kataras/dropzonejs--go-series---part-2-4n1)
|
||||
* [How to build a file upload form using DropzoneJS and Go](https://hackernoon.com/how-to-build-a-file-upload-form-using-dropzonejs-and-go-8fb9f258a991)
|
||||
* [How to display existing files on server using DropzoneJS and Go](https://hackernoon.com/how-to-display-existing-files-on-server-using-dropzonejs-and-go-53e24b57ba19)
|
||||
|
||||
# Content
|
||||
|
||||
|
||||
8
_examples/tutorial/dropzonejs/meta.yml
Normal file
8
_examples/tutorial/dropzonejs/meta.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
Name: DropzoneJS
|
||||
Articles:
|
||||
- Title: How to build a file upload form using DropzoneJS and Go
|
||||
Source: https://hackernoon.com/how-to-build-a-file-upload-form-using-dropzonejs-and-go-8fb9f258a991
|
||||
Author: https://twitter.com/@kataras
|
||||
- Title: How to display existing files on server using DropzoneJS and Go
|
||||
Source: https://hackernoon.com/how-to-display-existing-files-on-server-using-dropzonejs-and-go-53e24b57ba19
|
||||
Author: https://twitter.com/@kataras
|
||||
@@ -1 +0,0 @@
|
||||
3c9dbd9acb1d553cc63940c72f212a880e8a8073
|
||||
Reference in New Issue
Block a user