mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
move sessions and websocket examples, gofmt, fix misspells and experimental optimizations 🍐
Former-commit-id: cae4f94bbd404d26ab13dade02b52f81feaddf24
This commit is contained in:
parent
90b8c1af44
commit
9a0b18acbf
12
.travis.yml
12
.travis.yml
|
@ -15,18 +15,6 @@ after_script:
|
|||
- cd ./_examples
|
||||
- go get ./...
|
||||
- go test -v -cover ./...
|
||||
# cache examples
|
||||
- cd ../cache/_examples
|
||||
- go get ./...
|
||||
- go test -v -cover ./...
|
||||
# sessions examples
|
||||
- cd ../../sessions/_examples
|
||||
- go get ./...
|
||||
- go test -v -cover ./...
|
||||
# websocket examples
|
||||
- cd ../../websocket/_examples
|
||||
- go get ./...
|
||||
- go test -v -cover ./...
|
||||
# typescript examples
|
||||
- cd ../../typescript/_examples
|
||||
- go get ./...
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
|
||||
## 🔥 Reborn
|
||||
|
||||
As you may have heard I have huge responsibilities on my new position at Dubai nowdays, therefore I don't have the needed time to work on this project anymore.
|
||||
As you may have heard I have huge responsibilities on my new position at Dubai nowadays, therefore I don't have the needed time to work on this project anymore.
|
||||
|
||||
After almost a month of negotiations and searching I succeed to find a decent software engineer to continue my work on the open source community.
|
||||
|
||||
The leadership of this, open-source, repository was transfered to [hiveminded](https://github.com/hiveminded).
|
||||
The leadership of this, open-source, repository was transferred to [hiveminded](https://github.com/hiveminded).
|
||||
|
||||
These types of projects need heart and sacrifices to continue offer the best developer experience like a paid software, please do support him as you did with me!
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ No API Changes.
|
|||
|
||||
### Django view engine
|
||||
|
||||
@corebreaker pushed a [PR](https://github.com/kataras/iris/pull/682) to solve the [Problem for {%extends%} in Django Engine with embedded files](dhttps://github.com/kataras/iris/issues/681).
|
||||
@corebreaker pushed a [PR](https://github.com/kataras/iris/pull/682) to solve the [Problem for {%extends%} in Django Engine with embedded files](https://github.com/kataras/iris/issues/681).
|
||||
|
||||
### Logger
|
||||
|
||||
|
@ -248,11 +248,11 @@ Despite the deflamations, the clickbait articles, the removed posts of mine at r
|
|||
|
||||
## 🔥 Reborn
|
||||
|
||||
As you may have heard I have huge responsibilities on my new position at Dubai nowdays, therefore I don't have the needed time to work on this project anymore.
|
||||
As you may have heard I have huge responsibilities on my new position at Dubai nowadays, therefore I don't have the needed time to work on this project anymore.
|
||||
|
||||
After a month of negotiations and searching I succeed to find a decent software engineer to continue my work on the open source community.
|
||||
|
||||
The leadership of this, open-source, repository was transfered to [hiveminded](https://github.com/hiveminded), the author of iris-based [get-ion/ion](https://github.com/get-ion/ion), he actually did an excellent job on the framework, he kept the code as minimal as possible and at the same time added more features, examples and middleware(s).
|
||||
The leadership of this, open-source, repository was transferred to [hiveminded](https://github.com/hiveminded), the author of iris-based [get-ion/ion](https://github.com/get-ion/ion), he actually did an excellent job on the framework, he kept the code as minimal as possible and at the same time added more features, examples and middleware(s).
|
||||
|
||||
These types of projects need heart and sacrifices to continue offer the best developer experience like a paid software, please do support him as you did with me!
|
||||
|
||||
|
|
|
@ -61,11 +61,11 @@ Iris is a fast, simple and efficient micro web framework for Go. It provides a b
|
|||
|
||||
### 🔥 Reborn
|
||||
|
||||
As you may have heard I have huge responsibilities on my new position at Dubai nowdays, therefore I don't have the needed time to work on this project anymore.
|
||||
As you may have heard I have huge responsibilities on my new position at Dubai nowadays, therefore I don't have the needed time to work on this project anymore.
|
||||
|
||||
After almost a month of negotiations and searching I succeed to find a decent software engineer to continue my work on the open source community.
|
||||
|
||||
The leadership of this, open-source, repository was transfered to [hiveminded](https://github.com/hiveminded).
|
||||
The leadership of this, open-source, repository was transferred to [hiveminded](https://github.com/hiveminded).
|
||||
|
||||
These types of projects need heart and sacrifices to continue offer the best developer experience like a paid software, please do support him as you did with me!
|
||||
|
||||
|
@ -158,7 +158,7 @@ We expect Go version 1.9 to be released in August, however you can install Go 1.
|
|||
### Installing Go 1.9beta2
|
||||
|
||||
1. Go to https://golang.org/dl/#go1.9beta2
|
||||
2. Download a compatible, with your OS, archieve, i.e `go1.9beta2.windows-amd64.zip`
|
||||
2. Download a compatible, with your OS, archive, i.e `go1.9beta2.windows-amd64.zip`
|
||||
3. Unzip the contents of `go1.9beta2.windows-amd64.zip/go` folder to your $GOROOT, i.e `C:\Go`
|
||||
4. Open a terminal and execute `go version`, it should output the go1.9beta2 version, i.e:
|
||||
```sh
|
||||
|
@ -282,7 +282,7 @@ Compared to the rest open source projects, this one is very active and you get a
|
|||
* JWT
|
||||
- Server
|
||||
* Automatically install and serve certificates from https://letsencrypt.org when serving via TLS
|
||||
* Gracefuly shutdown by-default
|
||||
* Gracefully shutdown by-default
|
||||
* Register on shutdown, error or interrupt events
|
||||
* Attach more than one server, fully compatible with `net/http#Server`
|
||||
- View system: supporting 5 template engines. Fully compatible with `html/template`
|
||||
|
|
|
@ -179,17 +179,32 @@ The `httptest` package is your way for end-to-end HTTP testing, it uses the http
|
|||
|
||||
### Caching
|
||||
|
||||
iris cache library lives on its own package: [https://github.com/kataras/iris/tree/master/cache](https://github.com/kataras/iris/tree/master/cache) **it contains examples**
|
||||
iris cache library lives on its own [package](https://github.com/kataras/iris/tree/master/cache).
|
||||
|
||||
- [Simple](cache/simple/main.go)
|
||||
|
||||
> You're free to use your own favourite caching package if you'd like so.
|
||||
|
||||
### Sessions
|
||||
iris session manager lives on its own [package](https://github.com/kataras/iris/tree/master/sessions).
|
||||
|
||||
iris session manager lives on its own package: [https://github.com/kataras/iris/tree/master/sessions](https://github.com/kataras/iris/tree/master/sessions) **it contains examples**
|
||||
- [Overview](sessions/overview/main.go)
|
||||
- [Standalone](sessions/standalone/main.go)
|
||||
- [Secure Cookie](sessions/securecookie/main.go)
|
||||
- [Flash Messages](sessions/flash-messages/main.go)
|
||||
- [Database](sessions/database/main.go)
|
||||
|
||||
> You're free to use your own favourite sessions package if you'd like so.
|
||||
|
||||
### Websockets
|
||||
|
||||
iris websocket library lives on its own package: [https://github.com/kataras/iris/tree/master/websocket](https://github.com/kataras/iris/tree/master/websocket) **it contains examples**
|
||||
iris websocket library lives on its own [package](https://github.com/kataras/iris/tree/master/websocket).
|
||||
|
||||
- [Chat](websocket/chat/main.go)
|
||||
- [Native Messages](websocket/native-messages/main.go)
|
||||
- [Connection List](websocket/connectionlist/main.go)
|
||||
- [TLS Enabled](websocket/secure/main.go)
|
||||
- [Custom Raw Go Client](websocket/custom-go-client/main.go)
|
||||
|
||||
> You're free to use your own favourite websockets package if you'd like so.
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ func main() {
|
|||
Age: 25,
|
||||
}
|
||||
|
||||
ctx.StatusCode(iris.StatusOK)
|
||||
// Manually setting a content type: ctx.ContentType("application/javascript")
|
||||
ctx.JSON(peter)
|
||||
})
|
||||
|
@ -83,5 +82,13 @@ func main() {
|
|||
// http://localhost:8080/jsonp
|
||||
// http://localhost:8080/xml
|
||||
// http://localhost:8080/markdown
|
||||
app.Run(iris.Addr(":8080"))
|
||||
//
|
||||
// `iris.WithOptimizations` is an optional configurator,
|
||||
// if passed to the `Run` then it will ensure that the application
|
||||
// response to the client as fast as possible.
|
||||
//
|
||||
//
|
||||
// `iris.WithoutServerError` is an optional configurator,
|
||||
// if passed to the `Run` then it will not print its passed error as an actual server error.
|
||||
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed), iris.WithOptimizations)
|
||||
}
|
||||
|
|
7
cache/README.md
vendored
7
cache/README.md
vendored
|
@ -1,7 +0,0 @@
|
|||
# Cache
|
||||
|
||||
Fast HTTP Cache support for the [iris](https://github.com/kataras/iris) web framework.
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Simple](_examples/simple/main.go)
|
|
@ -15,9 +15,9 @@ var errConfigurationDecode = errors.New("error while trying to decode configurat
|
|||
|
||||
// YAML reads Configuration from a configuration.yml file.
|
||||
//
|
||||
// Accepts the absolute path of the configuration.yml.
|
||||
// Accepts the absolute path of the cfg.yml.
|
||||
// An error will be shown to the user via panic with the error message.
|
||||
// Error may occur when the configuration.yml doesn't exists or is not formatted correctly.
|
||||
// Error may occur when the cfg.yml doesn't exists or is not formatted correctly.
|
||||
//
|
||||
// Usage:
|
||||
// app := iris.Run(iris.Addr(":8080"), iris.WithConfiguration(iris.YAML("myconfig.yml")))
|
||||
|
@ -138,42 +138,49 @@ var WithoutInterruptHandler = func(app *Application) {
|
|||
|
||||
// WithoutPathCorrection disables the PathCorrection setting.
|
||||
//
|
||||
// See` Configuration`.
|
||||
// See `Configuration`.
|
||||
var WithoutPathCorrection = func(app *Application) {
|
||||
app.config.DisablePathCorrection = true
|
||||
}
|
||||
|
||||
// WithoutBodyConsumptionOnUnmarshal disables BodyConsumptionOnUnmarshal setting.
|
||||
//
|
||||
// See` Configuration`.
|
||||
// See `Configuration`.
|
||||
var WithoutBodyConsumptionOnUnmarshal = func(app *Application) {
|
||||
app.config.DisableBodyConsumptionOnUnmarshal = true
|
||||
}
|
||||
|
||||
// WithoutAutoFireStatusCode disables the AutoFireStatusCode setting.
|
||||
//
|
||||
// See` Configuration`.
|
||||
// See `Configuration`.
|
||||
var WithoutAutoFireStatusCode = func(app *Application) {
|
||||
app.config.DisableAutoFireStatusCode = true
|
||||
}
|
||||
|
||||
// WithPathEscape enanbles the PathEscape setting.
|
||||
//
|
||||
// See` Configuration`.
|
||||
// See `Configuration`.
|
||||
var WithPathEscape = func(app *Application) {
|
||||
app.config.EnablePathEscape = true
|
||||
}
|
||||
|
||||
// WithOptimizations can force the application to optimize for the best performance where is possible.
|
||||
//
|
||||
// See `Configuration`.
|
||||
var WithOptimizations = func(app *Application) {
|
||||
app.config.EnableOptimizations = true
|
||||
}
|
||||
|
||||
// WithFireMethodNotAllowed enanbles the FireMethodNotAllowed setting.
|
||||
//
|
||||
// See` Configuration`.
|
||||
// See `Configuration`.
|
||||
var WithFireMethodNotAllowed = func(app *Application) {
|
||||
app.config.FireMethodNotAllowed = true
|
||||
}
|
||||
|
||||
// WithTimeFormat sets the TimeFormat setting.
|
||||
//
|
||||
// See` Configuration`.
|
||||
// See `Configuration`.
|
||||
func WithTimeFormat(timeformat string) Configurator {
|
||||
return func(app *Application) {
|
||||
app.config.TimeFormat = timeformat
|
||||
|
@ -182,7 +189,7 @@ func WithTimeFormat(timeformat string) Configurator {
|
|||
|
||||
// WithCharset sets the Charset setting.
|
||||
//
|
||||
// See` Configuration`.
|
||||
// See `Configuration`.
|
||||
func WithCharset(charset string) Configurator {
|
||||
return func(app *Application) {
|
||||
app.config.Charset = charset
|
||||
|
@ -227,7 +234,7 @@ func WithoutRemoteAddrHeader(headerName string) Configurator {
|
|||
|
||||
// WithOtherValue adds a value based on a key to the Other setting.
|
||||
//
|
||||
// See` Configuration`.
|
||||
// See `Configuration`.
|
||||
func WithOtherValue(key string, val interface{}) Configurator {
|
||||
return func(app *Application) {
|
||||
if app.config.Other == nil {
|
||||
|
@ -290,6 +297,11 @@ type Configuration struct {
|
|||
// Defaults to false.
|
||||
EnablePathEscape bool `yaml:"EnablePathEscape" toml:"EnablePathEscape"`
|
||||
|
||||
// EnableOptimization when this field is true
|
||||
// then the application tries to optimize for the best performance where is possible.
|
||||
//
|
||||
// Defaults to false.
|
||||
EnableOptimizations bool `yaml:"EnableOptimizations" toml:"EnableOptimizations"`
|
||||
// FireMethodNotAllowed if it's true router checks for StatusMethodNotAllowed(405) and
|
||||
// fires the 405 error instead of 404
|
||||
// Defaults to false.
|
||||
|
@ -366,10 +378,11 @@ type Configuration struct {
|
|||
//
|
||||
// Look `context.RemoteAddr()` for more.
|
||||
RemoteAddrHeaders map[string]bool `yaml:"RemoteAddrHeaders" toml:"RemoteAddrHeaders"`
|
||||
|
||||
// Other are the custom, dynamic options, can be empty.
|
||||
// This field used only by you to set any app's options you want
|
||||
// or by custom adaptors, it's a way to simple communicate between your adaptors (if any)
|
||||
// Defaults to a non-nil empty map
|
||||
// Defaults to a non-nil empty map.
|
||||
Other map[string]interface{} `yaml:"Other" toml:"Other"`
|
||||
}
|
||||
|
||||
|
@ -384,7 +397,7 @@ func (c Configuration) GetVHost() string {
|
|||
return c.vhost
|
||||
}
|
||||
|
||||
// GetDisablePathCorrection returns the configuration.DisablePathCorrection,
|
||||
// GetDisablePathCorrection returns the Configuration#DisablePathCorrection,
|
||||
// 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,
|
||||
|
@ -393,18 +406,24 @@ func (c Configuration) GetDisablePathCorrection() bool {
|
|||
return c.DisablePathCorrection
|
||||
}
|
||||
|
||||
// GetEnablePathEscape is the configuration.EnablePathEscape,
|
||||
// GetEnablePathEscape is the Configuration#EnablePathEscape,
|
||||
// returns true when its escapes the path, the named parameters (if any).
|
||||
func (c Configuration) GetEnablePathEscape() bool {
|
||||
return c.EnablePathEscape
|
||||
}
|
||||
|
||||
// GetFireMethodNotAllowed returns the configuration.FireMethodNotAllowed.
|
||||
// GetEnableOptimizations returns whether
|
||||
// the application has performance optimizations enabled.
|
||||
func (c Configuration) GetEnableOptimizations() bool {
|
||||
return c.EnableOptimizations
|
||||
}
|
||||
|
||||
// GetFireMethodNotAllowed returns the Configuration#FireMethodNotAllowed.
|
||||
func (c Configuration) GetFireMethodNotAllowed() bool {
|
||||
return c.FireMethodNotAllowed
|
||||
}
|
||||
|
||||
// GetDisableBodyConsumptionOnUnmarshal returns the configuration.GetDisableBodyConsumptionOnUnmarshal,
|
||||
// GetDisableBodyConsumptionOnUnmarshal returns the Configuration#GetDisableBodyConsumptionOnUnmarshal,
|
||||
// manages the reading behavior of the context's body readers/binders.
|
||||
// If returns true then the body consumption by the `context.UnmarshalBody/ReadJSON/ReadXML`
|
||||
// is disabled.
|
||||
|
@ -417,19 +436,19 @@ func (c Configuration) GetDisableBodyConsumptionOnUnmarshal() bool {
|
|||
return c.DisableBodyConsumptionOnUnmarshal
|
||||
}
|
||||
|
||||
// GetDisableAutoFireStatusCode returns the configuration.DisableAutoFireStatusCode.
|
||||
// GetDisableAutoFireStatusCode returns the Configuration#DisableAutoFireStatusCode.
|
||||
// Returns true when the http error status code handler automatic execution turned off.
|
||||
func (c Configuration) GetDisableAutoFireStatusCode() bool {
|
||||
return c.DisableAutoFireStatusCode
|
||||
}
|
||||
|
||||
// GetTimeFormat returns the configuration.TimeFormat,
|
||||
// GetTimeFormat returns the Configuration#TimeFormat,
|
||||
// format for any kind of datetime parsing.
|
||||
func (c Configuration) GetTimeFormat() string {
|
||||
return c.TimeFormat
|
||||
}
|
||||
|
||||
// GetCharset returns the configuration.Charset,
|
||||
// GetCharset returns the Configuration#Charset,
|
||||
// the character encoding for various rendering
|
||||
// used for templates and the rest of the responses.
|
||||
func (c Configuration) GetCharset() string {
|
||||
|
@ -476,7 +495,7 @@ func (c Configuration) GetRemoteAddrHeaders() map[string]bool {
|
|||
return c.RemoteAddrHeaders
|
||||
}
|
||||
|
||||
// GetOther returns the configuration.Other map.
|
||||
// GetOther returns the Configuration#Other map.
|
||||
func (c Configuration) GetOther() map[string]interface{} {
|
||||
return c.Other
|
||||
}
|
||||
|
@ -513,6 +532,10 @@ func WithConfiguration(c Configuration) Configurator {
|
|||
main.EnablePathEscape = v
|
||||
}
|
||||
|
||||
if v := c.EnableOptimizations; v {
|
||||
main.EnableOptimizations = v
|
||||
}
|
||||
|
||||
if v := c.FireMethodNotAllowed; v {
|
||||
main.FireMethodNotAllowed = v
|
||||
}
|
||||
|
@ -590,6 +613,7 @@ func DefaultConfiguration() Configuration {
|
|||
"X-Forwarded-For": false,
|
||||
"CF-Connecting-IP": false,
|
||||
},
|
||||
Other: make(map[string]interface{}, 0),
|
||||
EnableOptimizations: false,
|
||||
Other: make(map[string]interface{}, 0),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@ type ConfigurationReadOnly interface {
|
|||
// returns true when its escapes the path, the named parameters (if any).
|
||||
GetEnablePathEscape() bool
|
||||
|
||||
// GetEnableOptimizations returns whether
|
||||
// the application has performance optimizations enabled.
|
||||
GetEnableOptimizations() bool
|
||||
|
||||
// GetFireMethodNotAllowed returns the configuration.FireMethodNotAllowed.
|
||||
GetFireMethodNotAllowed() bool
|
||||
// GetDisableBodyConsumptionOnUnmarshal returns the configuration.GetDisableBodyConsumptionOnUnmarshal,
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"github.com/json-iterator/go"
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
"github.com/monoculum/formam"
|
||||
"github.com/russross/blackfriday"
|
||||
|
@ -1344,16 +1345,22 @@ func (ctx *context) UnmarshalBody(v interface{}, unmarshaler Unmarshaler) error
|
|||
return unmarshaler.Unmarshal(rawData, &v)
|
||||
}
|
||||
|
||||
func (ctx *context) shouldOptimize() bool {
|
||||
return ctx.Application().ConfigurationReadOnly().GetEnableOptimizations()
|
||||
}
|
||||
|
||||
// ReadJSON reads JSON from request's body and binds it to a value of any json-valid type.
|
||||
func (ctx *context) ReadJSON(jsonObject interface{}) error {
|
||||
return ctx.UnmarshalBody(jsonObject, UnmarshalerFunc(json.Unmarshal))
|
||||
|
||||
var unmarshaler = json.Unmarshal
|
||||
if ctx.shouldOptimize() {
|
||||
unmarshaler = jsoniter.Unmarshal
|
||||
}
|
||||
return ctx.UnmarshalBody(jsonObject, UnmarshalerFunc(unmarshaler))
|
||||
}
|
||||
|
||||
// ReadXML reads XML from request's body and binds it to a value of any xml-valid type.
|
||||
func (ctx *context) ReadXML(xmlObject interface{}) error {
|
||||
return ctx.UnmarshalBody(xmlObject, UnmarshalerFunc(xml.Unmarshal))
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -1780,15 +1787,28 @@ var (
|
|||
|
||||
// WriteJSON marshals the given interface object and writes the JSON response to the 'writer'.
|
||||
// Ignores StatusCode, Gzip, StreamingJSON options.
|
||||
func WriteJSON(writer io.Writer, v interface{}, options JSON) (int, error) {
|
||||
var result []byte
|
||||
var err error
|
||||
func WriteJSON(writer io.Writer, v interface{}, options JSON, enableOptimization ...bool) (int, error) {
|
||||
var (
|
||||
result []byte
|
||||
err error
|
||||
optimize = len(enableOptimization) > 0 && enableOptimization[0]
|
||||
)
|
||||
|
||||
if indent := options.Indent; indent != "" {
|
||||
result, err = json.MarshalIndent(v, "", indent)
|
||||
marshalIndent := json.MarshalIndent
|
||||
if optimize {
|
||||
marshalIndent = jsoniter.ConfigCompatibleWithStandardLibrary.MarshalIndent
|
||||
}
|
||||
|
||||
result, err = marshalIndent(v, "", indent)
|
||||
result = append(result, newLineB...)
|
||||
} else {
|
||||
result, err = json.Marshal(v)
|
||||
marshal := json.Marshal
|
||||
if optimize {
|
||||
marshal = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal
|
||||
}
|
||||
|
||||
result, err = marshal(v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -1811,20 +1831,32 @@ func WriteJSON(writer io.Writer, v interface{}, options JSON) (int, error) {
|
|||
var defaultJSONOptions = JSON{}
|
||||
|
||||
// JSON marshals the given interface object and writes the JSON response to the client.
|
||||
func (ctx *context) JSON(v interface{}, opts ...JSON) (int, error) {
|
||||
func (ctx *context) JSON(v interface{}, opts ...JSON) (n int, err error) {
|
||||
options := defaultJSONOptions
|
||||
|
||||
if len(opts) > 0 {
|
||||
options = opts[0]
|
||||
}
|
||||
|
||||
optimize := ctx.shouldOptimize()
|
||||
|
||||
ctx.ContentType(contentJSONHeaderValue)
|
||||
|
||||
if options.StreamingJSON {
|
||||
enc := json.NewEncoder(ctx.writer)
|
||||
enc.SetEscapeHTML(!options.UnescapeHTML)
|
||||
enc.SetIndent(options.Prefix, options.Indent)
|
||||
err := enc.Encode(v)
|
||||
if optimize {
|
||||
var jsoniterConfig = jsoniter.Config{
|
||||
EscapeHTML: !options.UnescapeHTML,
|
||||
IndentionStep: 4,
|
||||
}.Froze()
|
||||
enc := jsoniterConfig.NewEncoder(ctx.writer)
|
||||
err = enc.Encode(v)
|
||||
} else {
|
||||
enc := json.NewEncoder(ctx.writer)
|
||||
enc.SetEscapeHTML(!options.UnescapeHTML)
|
||||
enc.SetIndent(options.Prefix, options.Indent)
|
||||
err = enc.Encode(v)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ctx.StatusCode(http.StatusInternalServerError) // it handles the fallback to normal mode here which also removes the gzip headers.
|
||||
return 0, err
|
||||
|
@ -1832,7 +1864,7 @@ func (ctx *context) JSON(v interface{}, opts ...JSON) (int, error) {
|
|||
return ctx.writer.Written(), err
|
||||
}
|
||||
|
||||
n, err := WriteJSON(ctx.writer, v, options)
|
||||
n, err = WriteJSON(ctx.writer, v, options, optimize)
|
||||
if err != nil {
|
||||
ctx.StatusCode(http.StatusInternalServerError)
|
||||
return 0, err
|
||||
|
@ -1846,14 +1878,21 @@ var (
|
|||
)
|
||||
|
||||
// WriteJSONP marshals the given interface object and writes the JSON response to the writer.
|
||||
func WriteJSONP(writer io.Writer, v interface{}, options JSONP) (int, error) {
|
||||
func WriteJSONP(writer io.Writer, v interface{}, options JSONP, enableOptimization ...bool) (int, error) {
|
||||
if callback := options.Callback; callback != "" {
|
||||
writer.Write([]byte(callback + "("))
|
||||
defer writer.Write(finishCallbackB)
|
||||
}
|
||||
|
||||
optimize := len(enableOptimization) > 0 && enableOptimization[0]
|
||||
|
||||
if indent := options.Indent; indent != "" {
|
||||
result, err := json.MarshalIndent(v, "", indent)
|
||||
marshalIndent := json.MarshalIndent
|
||||
if optimize {
|
||||
marshalIndent = jsoniter.ConfigCompatibleWithStandardLibrary.MarshalIndent
|
||||
}
|
||||
|
||||
result, err := marshalIndent(v, "", indent)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -1861,7 +1900,12 @@ func WriteJSONP(writer io.Writer, v interface{}, options JSONP) (int, error) {
|
|||
return writer.Write(result)
|
||||
}
|
||||
|
||||
result, err := json.Marshal(v)
|
||||
marshal := json.Marshal
|
||||
if optimize {
|
||||
marshal = jsoniter.ConfigCompatibleWithStandardLibrary.Marshal
|
||||
}
|
||||
|
||||
result, err := marshal(v)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -1880,7 +1924,7 @@ func (ctx *context) JSONP(v interface{}, opts ...JSONP) (int, error) {
|
|||
|
||||
ctx.ContentType(contentJavascriptHeaderValue)
|
||||
|
||||
n, err := WriteJSONP(ctx.writer, v, options)
|
||||
n, err := WriteJSONP(ctx.writer, v, options, ctx.shouldOptimize())
|
||||
if err != nil {
|
||||
ctx.StatusCode(http.StatusInternalServerError)
|
||||
return 0, err
|
||||
|
|
|
@ -105,7 +105,7 @@ func (su *Supervisor) newListener() (net.Listener, error) {
|
|||
return l, nil
|
||||
}
|
||||
|
||||
// RegisterOnError registers a function to call when errors occured by the underline http server.
|
||||
// RegisterOnError registers a function to call when errors occurred by the underline http server.
|
||||
func (su *Supervisor) RegisterOnError(cb func(error)) {
|
||||
su.mu.Lock()
|
||||
su.onErr = append(su.onErr, cb)
|
||||
|
|
|
@ -33,7 +33,7 @@ func WriteStartupLogOnServe(w io.Writer) func(TaskHost) {
|
|||
}
|
||||
|
||||
// ShutdownOnInterrupt terminates the supervisor and its underline server when CMD+C/CTRL+C pressed.
|
||||
// This function should be registerd on Interrupt.
|
||||
// This function should be registered on Interrupt.
|
||||
func ShutdownOnInterrupt(su *Supervisor, shutdownTimeout time.Duration) func() {
|
||||
return func() {
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), shutdownTimeout)
|
||||
|
|
|
@ -301,6 +301,11 @@ func (nodes Nodes) findChild(path string, params []string) (*node, []string) {
|
|||
if n.rootWildcard {
|
||||
// println("return from n.rootWildcard")
|
||||
// single root wildcard
|
||||
if len(path) < 2 {
|
||||
// do not remove that, it seems useless but it's not,
|
||||
// we had an error while production, this fixes that.
|
||||
path = "/" + path
|
||||
}
|
||||
return n, append(params, path[1:])
|
||||
}
|
||||
|
||||
|
|
2
doc.go
2
doc.go
|
@ -261,7 +261,7 @@ Example code:
|
|||
|
||||
That's all with listening, you have the full control when you need it.
|
||||
|
||||
Let's continue by learning how to catch CONTROL+C/COMMAND+C or unix kill command and shutdown the server gracefuly.
|
||||
Let's continue by learning how to catch CONTROL+C/COMMAND+C or unix kill command and shutdown the server gracefully.
|
||||
|
||||
Gracefully Shutdown on CONTROL+C/COMMAND+C or when kill command sent is ENABLED BY-DEFAULT.
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ type Config struct {
|
|||
|
||||
// Columns will display the logs as well formatted columns (bool).
|
||||
// If custom `LogFunc` has been provided then this field is useless and users should
|
||||
// use the `Columinize` function of the logger to get the ouput result as columns.
|
||||
// use the `Columinize` function of the logger to get the output result as columns.
|
||||
//
|
||||
// Defaults to true.
|
||||
Columns bool
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# Sessions
|
||||
|
||||
Fast HTTP Sessions for the [iris](https://github.com/kataras/iris) web framework.
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Overview](_examples/overview/main.go)
|
||||
* [Standalone](_examples/standalone/main.go)
|
||||
* [Secure Cookie](_examples/securecookie/main.go)
|
||||
* [Flash Messages](_examples/flash-messages/main.go)
|
||||
* [Database](_examples/database/main.go)
|
|
@ -1,11 +0,0 @@
|
|||
# Websocket
|
||||
|
||||
Rich websocket support for the [iris](https://github.com/kataras/iris) web framework.
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Chat](_examples/chat/main.go)
|
||||
* [Native Messages](_examples/native-messages/main.go)
|
||||
* [Connection List](_examples/connectionlist/main.go)
|
||||
* [TLS Enabled](_examples/secure/main.go)
|
||||
* [Custom Raw Go Client](_examples/custom-go-client/main.go)
|
Loading…
Reference in New Issue
Block a user