Nothing special here, read HISTORY.md

This commit is contained in:
Gerasimos (Makis) Maropoulos 2017-01-10 15:03:02 +02:00
parent 053588babd
commit e4ab993760
12 changed files with 109 additions and 137 deletions

View File

@ -375,7 +375,7 @@ Downloads the [basic](https://github.com/iris-contrib/examples/tree/master/AIO_
**outline**
```go
// StaticEmbedded used when files are distrubuted inside the app executable, using go-bindata mostly
// StaticEmbedded used when files are distributed inside the app executable, using go-bindata mostly
// First parameter is the request path, the path which the files in the vdir(second parameter) will be served to, for example "/static"
// Second parameter is the (virtual) directory path, for example "./assets"
// Third parameter is the Asset function
@ -832,7 +832,7 @@ iris.Set(iris.OptionDisableBanner(true))
**List** of all available options:
```go
// OptionDisablePathCorrection corrects and redirects the requested path to the registed path
// OptionDisablePathCorrection corrects and redirects the requested path to the registered path
// for example, if /home/ path is requested but no handler for this Route found,
// then the Router checks if /home handler exists, if yes,
// (permant)redirects the client to the correct path /home
@ -880,7 +880,7 @@ OptionTimeFormat(val string)
OptionCharset(val string)
// OptionGzip enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content
// If you don't want to enable it globaly, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true})
// If you don't want to enable it globally, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true})
// Default is false
OptionGzip(val bool)
@ -1124,7 +1124,7 @@ Notes: if you compare it with previous releases (13+ versions before v3 stable),
If you're **willing to donate** click [here](DONATIONS.md)!
- `iris.Config.Gzip`, enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content. If you don't want to enable it globaly, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true}). It defaults to false
- `iris.Config.Gzip`, enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content. If you don't want to enable it globally, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true}). It defaults to false
- **Added** `config.Server.Name` as requested
@ -1551,7 +1551,7 @@ OnDisconnect(func(){})
We have some base-config's changed, these configs which are defaulted to true renamed to 'Disable+$oldName'
```go
// DisablePathCorrection corrects and redirects the requested path to the registed path
// DisablePathCorrection corrects and redirects the requested path to the registered path
// for example, if /home/ path is requested but no handler for this Route found,
// then the Router checks if /home handler exists, if yes,
// (permant)redirects the client to the correct path /home

View File

@ -378,7 +378,7 @@ Serve files or directories, use the correct for your case, if you don't know whi
// you can declare your own path if you have more than one favicon (desktop, mobile and so on)
//
// this func will add a route for you which will static serve the /yuorpath/yourfile.ico to the /yourfile.ico (nothing special that you can't handle by yourself)
// Note that you have to call it on every favicon you have to serve automatically (dekstop, mobile and so on)
// Note that you have to call it on every favicon you have to serve automatically (desktop, mobile and so on)
//
// panics on error
Favicon(favPath string, requestPath ...string) RouteNameFunc
@ -393,7 +393,7 @@ StaticHandler(reqPath string, systemPath string, showList bool, enableGzip bool)
// second parameter is the system directory (string)
StaticWeb(reqPath string, systemPath string) RouteNameFunc
// StaticEmbedded used when files are distrubuted inside the app executable, using go-bindata mostly
// StaticEmbedded used when files are distributed inside the app executable, using go-bindata mostly
// First parameter is the request path, the path which the files in the vdir will be served to, for example "/static"
// Second parameter is the (virtual) directory path, for example "./assets"
// Third parameter is the Asset function

View File

@ -119,7 +119,7 @@ type Configuration struct {
// Default is false
CheckForUpdatesSync bool
// DisablePathCorrection corrects and redirects the requested path to the registed path
// DisablePathCorrection corrects and redirects the requested path to the registered path
// for example, if /home/ path is requested but no handler for this Route found,
// then the Router checks if /home handler exists, if yes,
// (permant)redirects the client to the correct path /home
@ -177,7 +177,7 @@ type Configuration struct {
Charset string
// Gzip enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content
// If you don't want to enable it globaly, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true})
// If you don't want to enable it globally, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true})
// Defaults to false
Gzip bool
@ -312,7 +312,7 @@ var (
}
}
// OptionDisablePathCorrection corrects and redirects the requested path to the registed path
// OptionDisablePathCorrection corrects and redirects the requested path to the registered path
// for example, if /home/ path is requested but no handler for this Route found,
// then the Router checks if /home handler exists, if yes,
// (permant)redirects the client to the correct path /home
@ -401,7 +401,7 @@ var (
}
// OptionGzip enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content
// If you don't want to enable it globaly, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true})
// If you don't want to enable it globally, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true})
// Default is false
OptionGzip = func(val bool) OptionSet {
return func(c *Configuration) {

View File

@ -64,7 +64,7 @@ const (
// CacheControl "Cache-Control"
cacheControl = "Cache-Control"
// stopExecutionPosition used inside the Context, is the number which shows us that the context's middleware manualy stop the execution
// stopExecutionPosition used inside the Context, is the number which shows us that the context's middleware manually stop the execution
stopExecutionPosition = 255
)
@ -132,7 +132,7 @@ type (
Request *http.Request
values requestValues
framework *Framework
//keep track all registed middleware (handlers)
//keep track all registered middleware (handlers)
Middleware Middleware // exported because is useful for debugging
session sessions.Session
// Pos is the position number of the Context, look .Next to understand
@ -313,7 +313,7 @@ func (ctx *Context) URLParam(key string) string {
return ctx.Request.URL.Query().Get(key)
}
// URLParams returns a map of GET query parameters seperated by comma if more than one
// URLParams returns a map of GET query parameters separated by comma if more than one
// it returns an empty map if nothing founds
func (ctx *Context) URLParams() map[string]string {
values := map[string]string{}
@ -1192,7 +1192,7 @@ func (ctx *Context) RemoveCookie(name string) {
c.Expires = exp
c.MaxAge = -1
ctx.SetCookie(c)
// delete request's cookie also, which is temporarly available
// delete request's cookie also, which is temporary available
ctx.Request.Header.Set("Cookie", "")
}
@ -1292,7 +1292,7 @@ var errTransactionInterrupted = errors.New("Transaction Interrupted, recovery fr
// BeginTransaction starts a scoped transaction.
//
// Can't say a lot here because it will take more than 200 lines to write about.
// You can search third-party articles or books on how Business Transaction works (it's quite simple, especialy here).
// You can search third-party articles or books on how Business Transaction works (it's quite simple, especially here).
//
// Note that this is unique and new
// (=I haver never seen any other examples or code in Golang on this subject, so far, as with the most of iris features...)

View File

@ -684,7 +684,7 @@ func TestTransactions(t *testing.T) {
// OPTIONAl STEP:
// but useful if we want to post back an error message to the client if the transaction failed.
// if the reason is empty then the transaction completed succesfuly,
// if the reason is empty then the transaction completed successfully,
// otherwise we rollback the whole response body and cookies and everything lives inside the transaction.Request.
t.Complete(err)
}

View File

@ -697,7 +697,7 @@ type (
Path() string
// SetPath changes/sets the path for this route
SetPath(string)
// Middleware returns the slice of Handler([]Handler) registed to this route
// Middleware returns the slice of Handler([]Handler) registered to this route
Middleware() Middleware
// SetMiddleware changes/sets the middleware(handler(s)) for this route
SetMiddleware(Middleware)
@ -817,9 +817,9 @@ func (r *route) hasCors() bool {
}
const (
// subdomainIndicator where './' exists in a registed path then it contains subdomain
// subdomainIndicator where './' exists in a registered path then it contains subdomain
subdomainIndicator = "./"
// dynamicSubdomainIndicator where a registed path starts with '*.' then it contains a dynamic subdomain, if subdomain == "*." then its dynamic
// dynamicSubdomainIndicator where a registered path starts with '*.' then it contains a dynamic subdomain, if subdomain == "*." then its dynamic
dynamicSubdomainIndicator = "*."
)
@ -958,7 +958,7 @@ func (mux *serveMux) build() (methodEqual func(string, string) bool) {
tree = &muxTree{method: r.method, subdomain: r.subdomain, entry: &muxEntry{}}
mux.garden = append(mux.garden, tree)
}
// I decide that it's better to explicit give subdomain and a path to it than registedPath(mysubdomain./something) now its: subdomain: mysubdomain., path: /something
// I decide that it's better to explicit give subdomain and a path to it than registeredPath(mysubdomain./something) now its: subdomain: mysubdomain., path: /something
// we have different tree for each of subdomains, now you can use everything you can use with the normal paths ( before you couldn't set /any/*path)
if err := tree.entry.add(r.path, r.middleware); err != nil {
mux.logger.Panic(err)

View File

@ -293,7 +293,7 @@ type testRoute struct {
func TestMuxSimple(t *testing.T) {
testRoutes := []testRoute{
// FOUND - registed
// FOUND - registered
{"GET", "/test_get", "/test_get", "", "hello, get!", 200, true, nil, nil},
{"POST", "/test_post", "/test_post", "", "hello, post!", 200, true, nil, nil},
{"PUT", "/test_put", "/test_put", "", "hello, put!", 200, true, nil, nil},
@ -303,7 +303,7 @@ func TestMuxSimple(t *testing.T) {
{"CONNECT", "/test_connect", "/test_connect", "", "hello, connect!", 200, true, nil, nil},
{"PATCH", "/test_patch", "/test_patch", "", "hello, patch!", 200, true, nil, nil},
{"TRACE", "/test_trace", "/test_trace", "", "hello, trace!", 200, true, nil, nil},
// NOT FOUND - not registed
// NOT FOUND - not registered
{"GET", "/test_get_nofound", "/test_get_nofound", "", "Not Found", 404, false, nil, nil},
{"POST", "/test_post_nofound", "/test_post_nofound", "", "Not Found", 404, false, nil, nil},
{"PUT", "/test_put_nofound", "/test_put_nofound", "", "Not Found", 404, false, nil, nil},
@ -519,7 +519,7 @@ func TestMuxCustomErrors(t *testing.T) {
notFoundMessage = "Iris custom message for 404 not found"
internalServerMessage = "Iris custom message for 500 internal server error"
testRoutesCustomErrors = []testRoute{
// NOT FOUND CUSTOM ERRORS - not registed
// NOT FOUND CUSTOM ERRORS - not registered
{"GET", "/test_get_nofound_custom", "/test_get_nofound_custom", "", notFoundMessage, 404, false, nil, nil},
{"POST", "/test_post_nofound_custom", "/test_post_nofound_custom", "", notFoundMessage, 404, false, nil, nil},
{"PUT", "/test_put_nofound_custom", "/test_put_nofound_custom", "", notFoundMessage, 404, false, nil, nil},
@ -529,7 +529,7 @@ func TestMuxCustomErrors(t *testing.T) {
{"CONNECT", "/test_connect_nofound_custom", "/test_connect_nofound_custom", "", notFoundMessage, 404, false, nil, nil},
{"PATCH", "/test_patch_nofound_custom", "/test_patch_nofound_custom", "", notFoundMessage, 404, false, nil, nil},
{"TRACE", "/test_trace_nofound_custom", "/test_trace_nofound_custom", "", notFoundMessage, 404, false, nil, nil},
// SERVER INTERNAL ERROR 500 PANIC CUSTOM ERRORS - registed
// SERVER INTERNAL ERROR 500 PANIC CUSTOM ERRORS - registered
{"GET", "/test_get_panic_custom", "/test_get_panic_custom", "", internalServerMessage, 500, true, nil, nil},
{"POST", "/test_post_panic_custom", "/test_post_panic_custom", "", internalServerMessage, 500, true, nil, nil},
{"PUT", "/test_put_panic_custom", "/test_put_panic_custom", "", internalServerMessage, 500, true, nil, nil},
@ -618,7 +618,7 @@ func TestMuxAPI(t *testing.T) {
}}
iris.API("/users", testUserAPI{}, h...)
// test a simple .Party with compination of .API
// test a simple .Party with combination of .API
iris.Party("sites/:site").API("/users", testUserAPI{}, h...)
e := httptest.New(iris.Default, t)
@ -716,70 +716,6 @@ func TestMuxFireMethodNotAllowed(t *testing.T) {
iris.Close()
}
/*
var (
cacheDuration = 2 * time.Second
errCacheTestFailed = errors.New("Expected the main handler to be executed %d times instead of %d.")
)
// ~14secs
func runCacheTest(e *httpexpect.Expect, path string, counterPtr *uint32, expectedBodyStr, expectedContentType string) error {
e.GET(path).Expect().Status(iris.StatusOK).Body().Equal(expectedBodyStr)
time.Sleep(cacheDuration / 5) // lets wait for a while, cache should be saved and ready
e.GET(path).Expect().Status(iris.StatusOK).Body().Equal(expectedBodyStr)
counter := atomic.LoadUint32(counterPtr)
if counter > 1 {
// n should be 1 because it doesn't changed after the first call
return errCacheTestFailed.Format(1, counter)
}
time.Sleep(cacheDuration)
// cache should be cleared now
e.GET(path).Expect().Status(iris.StatusOK).ContentType(expectedContentType, "utf-8").Body().Equal(expectedBodyStr)
time.Sleep(cacheDuration / 5)
// let's call again , the cache should be saved
e.GET(path).Expect().Status(iris.StatusOK).ContentType(expectedContentType, "utf-8").Body().Equal(expectedBodyStr)
counter = atomic.LoadUint32(counterPtr)
if counter != 2 {
return errCacheTestFailed.Format(2, counter)
}
return nil
}
Inside github.com/geekypanda/httpcache are enough, no need to add 10+ seconds of testing here.
func TestCache(t *testing.T) {
iris.ResetDefault()
expectedBodyStr := "Imagine it as a big message to achieve x20 response performance!"
var textCounter, htmlCounter uint32
iris.Get("/text", iris.Cache(func(ctx *iris.Context) {
atomic.AddUint32(&textCounter, 1)
ctx.Text(iris.StatusOK, expectedBodyStr)
}, cacheDuration))
iris.Get("/html", iris.Cache(func(ctx *iris.Context) {
atomic.AddUint32(&htmlCounter, 1)
ctx.HTML(iris.StatusOK, expectedBodyStr)
}, cacheDuration))
e := httptest.New(iris.Default, t)
// test cache on text/plain
if err := runCacheTest(e, "/text", &textCounter, expectedBodyStr, "text/plain"); err != nil {
t.Fatal(err)
}
// text cache on text/html
if err := runCacheTest(e, "/html", &htmlCounter, expectedBodyStr, "text/html"); err != nil {
t.Fatal(err)
}
}
*/
func TestRedirectHTTPS(t *testing.T) {
api := iris.New(iris.OptionIsDevelopment(true))
@ -794,5 +730,4 @@ func TestRedirectHTTPS(t *testing.T) {
e := httptest.New(api, t)
e.GET("/redirect").Expect().Status(iris.StatusOK).Body().Equal(expectedBody)
}

75
iris.go
View File

@ -335,12 +335,12 @@ func (s *Framework) Set(setters ...OptionSetter) {
}
}
// Must panics on error, it panics on registed iris' logger
// Must panics on error, it panics on registered iris' logger
func Must(err error) {
Default.Must(err)
}
// Must panics on error, it panics on registed iris' logger
// Must panics on error, it panics on registered iris' logger
func (s *Framework) Must(err error) {
if err != nil {
// s.Logger.Panicf("%s. Trace:\n%s", err, debug.Stack())
@ -411,7 +411,7 @@ func (s *Framework) Build() {
s.mux.setFireMethodNotAllowed(s.Config.FireMethodNotAllowed)
// prepare the server's handler, we do that check because iris supports
// custom routers (you can take the routes registed by iris using iris.Lookups function)
// custom routers (you can take the routes registered by iris using iris.Lookups function)
if s.Router == nil {
// build and get the default mux' handler(*Context)
serve := s.mux.BuildHandler()
@ -437,6 +437,7 @@ func (s *Framework) Build() {
ConnState: s.Config.ConnState,
Handler: s.Router,
Addr: s.Config.VHost,
ErrorLog: s.Logger,
}
if s.Config.TLSNextProto != nil {
s.srv.TLSNextProto = s.Config.TLSNextProto
@ -973,17 +974,17 @@ func (s *Framework) UseGlobalFunc(handlersFn ...HandlerFunc) {
s.UseGlobal(convertToHandlers(handlersFn)...)
}
// Lookup returns a registed route by its name
// Lookup returns a registered route by its name
func Lookup(routeName string) Route {
return Default.Lookup(routeName)
}
// Lookups returns all registed routes
// Lookups returns all registered routes
func Lookups() []Route {
return Default.Lookups()
}
// Lookup returns a registed route by its name
// Lookup returns a registered route by its name
func (s *Framework) Lookup(routeName string) Route {
r := s.mux.lookup(routeName)
if nil == r {
@ -992,7 +993,7 @@ func (s *Framework) Lookup(routeName string) Route {
return r
}
// Lookups returns all registed routes
// Lookups returns all registered routes
func (s *Framework) Lookups() (routes []Route) {
// silly but...
for i := range s.mux.lookups {
@ -1411,27 +1412,27 @@ func (api *muxAPI) DoneFunc(handlersFn ...HandlerFunc) MuxAPI {
// Handle registers a route to the server's router
// if empty method is passed then registers handler(s) for all methods, same as .Any, but returns nil as result
func Handle(method string, registedPath string, handlers ...Handler) RouteNameFunc {
return Default.Handle(method, registedPath, handlers...)
func Handle(method string, registeredPath string, handlers ...Handler) RouteNameFunc {
return Default.Handle(method, registeredPath, handlers...)
}
// HandleFunc registers and returns a route with a method string, path string and a handler
// registedPath is the relative url path
func HandleFunc(method string, registedPath string, handlersFn ...HandlerFunc) RouteNameFunc {
return Default.HandleFunc(method, registedPath, handlersFn...)
// registeredPath is the relative url path
func HandleFunc(method string, registeredPath string, handlersFn ...HandlerFunc) RouteNameFunc {
return Default.HandleFunc(method, registeredPath, handlersFn...)
}
// Handle registers a route to the server's router
// if empty method is passed then registers handler(s) for all methods, same as .Any, but returns nil as result
func (api *muxAPI) Handle(method string, registedPath string, handlers ...Handler) RouteNameFunc {
func (api *muxAPI) Handle(method string, registeredPath string, handlers ...Handler) RouteNameFunc {
if method == "" { // then use like it was .Any
for _, k := range AllMethods {
api.Handle(k, registedPath, handlers...)
api.Handle(k, registeredPath, handlers...)
}
return nil
}
fullpath := api.relativePath + registedPath // for now, keep the last "/" if any, "/xyz/"
fullpath := api.relativePath + registeredPath // for now, keep the last "/" if any, "/xyz/"
middleware := joinMiddleware(api.middleware, handlers)
@ -1450,7 +1451,7 @@ func (api *muxAPI) Handle(method string, registedPath string, handlers ...Handle
//: /beta/ then should disable the path correction OR register it like: beta.Get("//")
// this is only for the party's roots in order to have expected paths,
// as we do with iris.Get("/") which is localhost:8080 as RFC points, not localhost:8080/
if api.mux.correctPath && registedPath == slash { // check the given relative path
if api.mux.correctPath && registeredPath == slash { // check the given relative path
// remove last "/" if any, "/xyz/"
if len(path) > 1 { // if it's the root, then keep it*
if path[len(path)-1] == slashByte {
@ -1473,9 +1474,9 @@ func (api *muxAPI) Handle(method string, registedPath string, handlers ...Handle
}
// HandleFunc registers and returns a route with a method string, path string and a handler
// registedPath is the relative url path
func (api *muxAPI) HandleFunc(method string, registedPath string, handlersFn ...HandlerFunc) RouteNameFunc {
return api.Handle(method, registedPath, convertToHandlers(handlersFn)...)
// registeredPath is the relative url path
func (api *muxAPI) HandleFunc(method string, registeredPath string, handlersFn ...HandlerFunc) RouteNameFunc {
return api.Handle(method, registeredPath, convertToHandlers(handlersFn)...)
}
// API converts & registers a custom struct to the router
@ -1484,7 +1485,7 @@ func (api *muxAPI) HandleFunc(method string, registedPath string, handlersFn ...
// second is the custom struct (interface{}) which can be anything that has a *iris.Context as field.
// third is the common middlewares, it's optional
//
// Note that API's routes have their default-name to the full registed path,
// Note that API's routes have their default-name to the full registered path,
// no need to give a special name for it, because it's not supposed to be used inside your templates.
//
// Recommend to use when you retrieve data from an external database,
@ -1501,7 +1502,7 @@ func API(path string, restAPI HandlerAPI, middleware ...HandlerFunc) {
// second is the custom struct (interface{}) which can be anything that has a *iris.Context as field.
// third is the common middleware, it's optional
//
// Note that API's routes have their default-name to the full registed path,
// Note that API's routes have their default-name to the full registered path,
// no need to give a special name for it, because it's not supposed to be used inside your templates.
//
// Recommend to use when you retrieve data from an external database,
@ -1509,7 +1510,7 @@ func API(path string, restAPI HandlerAPI, middleware ...HandlerFunc) {
//
// This is a slow method, if you care about router-performance use the Handle/HandleFunc/Get/Post/Put/Delete/Trace/Options... instead
func (api *muxAPI) API(path string, restAPI HandlerAPI, middleware ...HandlerFunc) {
// here we need to find the registed methods and convert them to handler funcs
// here we need to find the registered methods and convert them to handler funcs
// methods are collected by method naming: Get(),GetBy(...), Post(),PostBy(...), Put() and so on
if len(path) == 0 {
path = "/"
@ -1572,17 +1573,17 @@ func (api *muxAPI) API(path string, restAPI HandlerAPI, middleware ...HandlerFun
}
methodFuncType := methodFunc.Type()
numInLen := methodFuncType.NumIn() // how much data we should receive from the request
registedPath := path
registeredPath := path
for i := 1; i < numInLen; i++ { // from 1 because the first is the 'object'
if registedPath[len(registedPath)-1] == slashByte {
registedPath += ":" + string(paramPrefix) + strconv.Itoa(i)
if registeredPath[len(registeredPath)-1] == slashByte {
registeredPath += ":" + string(paramPrefix) + strconv.Itoa(i)
} else {
registedPath += "/:" + string(paramPrefix) + strconv.Itoa(i)
registeredPath += "/:" + string(paramPrefix) + strconv.Itoa(i)
}
}
func(registedPath string, typ reflect.Type, contextField reflect.StructField, methodFunc reflect.Value, paramsLen int, method string) {
func(registeredPath string, typ reflect.Type, contextField reflect.StructField, methodFunc reflect.Value, paramsLen int, method string) {
var handlersFn []HandlerFunc
handlersFn = append(handlersFn, middleware...)
@ -1604,8 +1605,8 @@ func (api *muxAPI) API(path string, restAPI HandlerAPI, middleware ...HandlerFun
methodFunc.Call(args)
})
// register route
api.HandleFunc(method, registedPath, handlersFn...)
}(registedPath, typ, contextField, methodFunc, numInLen-1, methodName)
api.HandleFunc(method, registeredPath, handlersFn...)
}(registeredPath, typ, contextField, methodFunc, numInLen-1, methodName)
}
@ -1659,8 +1660,8 @@ func Trace(path string, handlersFn ...HandlerFunc) RouteNameFunc {
}
// Any registers a route for ALL of the http methods (Get,Post,Put,Head,Patch,Options,Connect,Delete)
func Any(registedPath string, handlersFn ...HandlerFunc) {
Default.Any(registedPath, handlersFn...)
func Any(registeredPath string, handlersFn ...HandlerFunc) {
Default.Any(registeredPath, handlersFn...)
}
@ -1710,9 +1711,9 @@ func (api *muxAPI) Trace(path string, handlersFn ...HandlerFunc) RouteNameFunc {
}
// Any registers a route for ALL of the http methods (Get,Post,Put,Head,Patch,Options,Connect,Delete)
func (api *muxAPI) Any(registedPath string, handlersFn ...HandlerFunc) {
func (api *muxAPI) Any(registeredPath string, handlersFn ...HandlerFunc) {
for _, k := range AllMethods {
api.HandleFunc(k, registedPath, handlersFn...)
api.HandleFunc(k, registeredPath, handlersFn...)
}
}
@ -1790,7 +1791,7 @@ func (api *muxAPI) StaticContent(reqPath string, cType string, content []byte) R
return api.registerResourceRoute(reqPath, h)
}
// StaticEmbedded used when files are distrubuted inside the app executable, using go-bindata mostly
// StaticEmbedded used when files are distributed inside the app executable, using go-bindata mostly
// First parameter is the request path, the path which the files in the vdir(second parameter) will be served to, for example "/static"
// Second parameter is the (virtual) directory path, for example "./assets"
// Third parameter is the Asset function
@ -1802,7 +1803,7 @@ func StaticEmbedded(requestPath string, vdir string, assetFn func(name string) (
return Default.StaticEmbedded(requestPath, vdir, assetFn, namesFn)
}
// StaticEmbedded used when files are distrubuted inside the app executable, using go-bindata mostly
// StaticEmbedded used when files are distributed inside the app executable, using go-bindata mostly
// First parameter is the request path, the path which the files in the vdir will be served to, for example "/static"
// Second parameter is the (virtual) directory path, for example "./assets"
// Third parameter is the Asset function
@ -1899,7 +1900,7 @@ func (api *muxAPI) StaticEmbedded(requestPath string, vdir string, assetFn func(
// you can declare your own path if you have more than one favicon (desktop, mobile and so on)
//
// this func will add a route for you which will static serve the /yuorpath/yourfile.ico to the /yourfile.ico (nothing special that you can't handle by yourself)
// Note that you have to call it on every favicon you have to serve automatically (dekstop, mobile and so on)
// Note that you have to call it on every favicon you have to serve automatically (desktop, mobile and so on)
//
// panics on error
func Favicon(favPath string, requestPath ...string) RouteNameFunc {
@ -1913,7 +1914,7 @@ func Favicon(favPath string, requestPath ...string) RouteNameFunc {
// you can declare your own path if you have more than one favicon (desktop, mobile and so on)
//
// this func will add a route for you which will static serve the /yuorpath/yourfile.ico to the /yourfile.ico (nothing special that you can't handle by yourself)
// Note that you have to call it on every favicon you have to serve automatically (dekstop, mobile and so on)
// Note that you have to call it on every favicon you have to serve automatically (desktop, mobile and so on)
//
// panics on error
func (api *muxAPI) Favicon(favPath string, requestPath ...string) RouteNameFunc {

View File

@ -1,5 +1,7 @@
package iris
///TODO: Be ready for go v1.8 in order to accomplish my first idea.
import (
"log"
"sync"
@ -13,8 +15,8 @@ var (
errPluginAlreadyExists = errors.New("Cannot use the same plugin again, '%s[%s]' is already exists")
// errPluginActivate returns an error with message: 'While trying to activate plugin '+plugin name'. Trace: +specific error'
errPluginActivate = errors.New("While trying to activate plugin '%s'. Trace: %s")
// errPluginRemoveNoPlugins returns an error with message: 'No plugins are registed yet, you cannot remove a plugin from an empty list!'
errPluginRemoveNoPlugins = errors.New("No plugins are registed yet, you cannot remove a plugin from an empty list!")
// errPluginRemoveNoPlugins returns an error with message: 'No plugins are registered yet, you cannot remove a plugin from an empty list!'
errPluginRemoveNoPlugins = errors.New("No plugins are registered yet, you cannot remove a plugin from an empty list!")
// errPluginRemoveEmptyName returns an error with message: 'Plugin with an empty name cannot be removed'
errPluginRemoveEmptyName = errors.New("Plugin with an empty name cannot be removed")
// errPluginRemoveNotFound returns an error with message: 'Cannot remove a plugin which doesn't exists'
@ -248,7 +250,7 @@ func (d *pluginDownloadManager) Install(remoteFileZip string, targetDirectory st
return fs.Install(remoteFileZip, targetDirectory, true)
}
// pluginContainer is the base container of all Iris, registed plugins
// pluginContainer is the base container of all Iris, registered plugins
type pluginContainer struct {
activatedPlugins []Plugin
customEvents map[string][]func()
@ -379,7 +381,7 @@ func (p *pluginContainer) GetDownloader() PluginDownloadManager {
return p.downloader
}
// Printf sends plain text to any registed logger (future), some plugins maybe want use this method
// Printf sends plain text to any registered logger (future), some plugins maybe want use this method
// maybe at the future I change it, instead of sync even-driven to async channels...
func (p *pluginContainer) Printf(format string, a ...interface{}) {
if p.logger != nil {

View File

@ -125,7 +125,7 @@ func (t testPluginActivationType) Activate(p iris.PluginContainer) error {
// if an error happened then all of them are not activated/added to the plugin container
func AddPluginTo(t *testing.T, plugins iris.PluginContainer, plugin iris.Plugin, expectingCount int) {
plugins.Add(plugin)
if plugins.Len() != expectingCount { // 2 because it registeres a second plugin also
if plugins.Len() != expectingCount { // 2 because it registers a second plugin also
t.Fatalf("Expected activated plugins to be: %d but we got: %d", expectingCount, plugins.Len())
}
}
@ -165,7 +165,7 @@ func TestPluginEvents(t *testing.T) {
myplugin := &testPluginEx{}
plugins.Add(myplugin)
if plugins.Len() != 4 {
t.Fatalf("Expected: %d plugins to be registed but we got: %d", 4, plugins.Len())
t.Fatalf("Expected: %d plugins to be registered but we got: %d", 4, plugins.Len())
}
desc := plugins.GetDescription(myplugin)
if desc != testPluginExDescription {

View File

@ -1,9 +1,11 @@
package iris_test
import (
"fmt"
"testing"
"github.com/kataras/iris"
"github.com/kataras/iris/httptest"
"testing"
)
// most tests lives inside context_test.go:Transactions, there lives the response writer's full and coblex tests
@ -63,3 +65,35 @@ func TestResponseWriterToRecorderMiddleware(t *testing.T) {
e.GET("/").Expect().Status(iris.StatusForbidden).Body().Equal(beforeFlushBody)
}
func ExampleResponseWriter_WriteHeader() {
// func TestResponseWriterMultipleWriteHeader(t *testing.T) {
iris.ResetDefault()
iris.Default.Set(iris.OptionDisableBanner(true))
expectedOutput := "Hey"
iris.Get("/", func(ctx *iris.Context) {
// here
for i := 0; i < 10; i++ {
ctx.ResponseWriter.WriteHeader(iris.StatusOK)
}
ctx.Writef(expectedOutput)
// here
fmt.Println(expectedOutput)
// here
for i := 0; i < 10; i++ {
ctx.SetStatusCode(iris.StatusOK)
}
})
e := httptest.New(iris.Default, nil)
e.GET("/").Expect().Status(iris.StatusOK).Body().Equal(expectedOutput)
// here it shouldn't log an error that status code write multiple times (by the net/http package.)
// Output:
// Hey
}

View File

@ -124,7 +124,7 @@ func (tsf TransactionScopeFunc) EndTransaction(maybeErr TransactionErrResult, ct
return tsf(maybeErr, ctx)
}
// TransientTransactionScope explaination:
// TransientTransactionScope explanation:
//
// independent 'silent' scope, if transaction fails (if transaction.IsFailure() == true)
// then its response is not written to the real context no error is provided to the user.
@ -136,7 +136,7 @@ var TransientTransactionScope = TransactionScopeFunc(func(maybeErr TransactionEr
return true
})
// RequestTransactionScope explaination:
// RequestTransactionScope explanation:
//
// if scope fails (if transaction.IsFailure() == true)
// then the rest of the context's response (transaction or normal flow)