mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
parent
3574816e1d
commit
c8ed26ee51
|
@ -438,6 +438,7 @@ New Package-level Variables:
|
||||||
|
|
||||||
New Context Methods:
|
New Context Methods:
|
||||||
|
|
||||||
|
- `Context.SetErr(error)` and `Context.GetErr() error` helpers
|
||||||
- `Context.Compress(bool) error` and `Context.CompressReader(bool) error`
|
- `Context.Compress(bool) error` and `Context.CompressReader(bool) error`
|
||||||
- `Context.Clone() Context` returns a copy of the Context.
|
- `Context.Clone() Context` returns a copy of the Context.
|
||||||
- `Context.IsCanceled() bool` reports whether the request has been canceled by the client.
|
- `Context.IsCanceled() bool` reports whether the request has been canceled by the client.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
2
cli.go
2
cli.go
|
@ -2,7 +2,7 @@ package iris
|
||||||
|
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
// | Bridge code between iris-cli and iris web application |
|
// | Bridge code between iris-cli and iris web application |
|
||||||
// | https://github.com/kataras/iris-cli |
|
// | https://github.com/kataras/iris-cli |
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/andybalholm/brotli"
|
"github.com/andybalholm/brotli"
|
||||||
"github.com/klauspost/compress/flate"
|
"github.com/klauspost/compress/flate"
|
||||||
"github.com/klauspost/compress/gzip"
|
"github.com/klauspost/compress/gzip"
|
||||||
"github.com/klauspost/compress/s2"
|
"github.com/klauspost/compress/s2" // snappy output but likely faster decompression.
|
||||||
"github.com/klauspost/compress/snappy"
|
"github.com/klauspost/compress/snappy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -184,11 +184,10 @@ func AcquireCompressResponseWriter(w ResponseWriter, r *http.Request, level int)
|
||||||
return nil, ErrResponseNotCompressed
|
return nil, ErrResponseNotCompressed
|
||||||
}
|
}
|
||||||
|
|
||||||
encoding := negotiateAcceptHeader(acceptEncoding, []string{"gzip", "deflate", "br", "snappy", "s2"}, "")
|
encoding := negotiateAcceptHeader(acceptEncoding, []string{GZIP, DEFLATE, BROTLI, SNAPPY, S2}, IDENTITY)
|
||||||
if encoding == "" {
|
if encoding == "" {
|
||||||
return nil, fmt.Errorf("%w: %s", ErrNotSupportedCompression, encoding)
|
return nil, fmt.Errorf("%w: %s", ErrNotSupportedCompression, encoding)
|
||||||
}
|
}
|
||||||
AddCompressHeaders(w.Header(), encoding)
|
|
||||||
|
|
||||||
v := compressWritersPool.Get().(*CompressResponseWriter)
|
v := compressWritersPool.Get().(*CompressResponseWriter)
|
||||||
v.ResponseWriter = w
|
v.ResponseWriter = w
|
||||||
|
@ -212,6 +211,8 @@ func AcquireCompressResponseWriter(w ResponseWriter, r *http.Request, level int)
|
||||||
}
|
}
|
||||||
|
|
||||||
v.CompressWriter = encWriter
|
v.CompressWriter = encWriter
|
||||||
|
|
||||||
|
AddCompressHeaders(w.Header(), encoding)
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4505,6 +4505,32 @@ func (ctx *Context) Application() Application {
|
||||||
return ctx.app
|
return ctx.app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const errorContextKey = "iris.context.error"
|
||||||
|
|
||||||
|
// SetErr is just a helper that sets an error value
|
||||||
|
// as a context value, it does nothing more.
|
||||||
|
// Also, by-default this error's value is written to the client
|
||||||
|
// on failures when no registered error handler is available (see `Party.On(Any)ErrorCode`).
|
||||||
|
// See `GetError` to retrieve it back.
|
||||||
|
//
|
||||||
|
// Note that, if you want to stop the chain
|
||||||
|
// with an error see the `StopWithError` instead.
|
||||||
|
func (ctx *Context) SetErr(err error) {
|
||||||
|
ctx.Values().Set(errorContextKey, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetErr is a helper which retrieves
|
||||||
|
// the error value stored by `SetErr`.
|
||||||
|
func (ctx *Context) GetErr() error {
|
||||||
|
if v := ctx.Values().Get(errorContextKey); v != nil {
|
||||||
|
if err, ok := v.(error); ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
const idContextKey = "iris.context.id"
|
const idContextKey = "iris.context.id"
|
||||||
|
|
||||||
// SetID sets an ID, any value, to the Request Context.
|
// SetID sets an ID, any value, to the Request Context.
|
||||||
|
|
|
@ -548,8 +548,14 @@ func (h *routerHandler) FireErrorCode(ctx *context.Context) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// not error handler found, write a default message.
|
// not error handler found,
|
||||||
ctx.WriteString(context.StatusText(statusCode))
|
// see if failed with a stored error, and if so
|
||||||
|
// then render it, otherwise write a default message.
|
||||||
|
if err := ctx.GetErr(); err != nil {
|
||||||
|
ctx.WriteString(err.Error())
|
||||||
|
} else {
|
||||||
|
ctx.WriteString(context.StatusText(statusCode))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *routerHandler) subdomainAndPathAndMethodExists(ctx *context.Context, t *trie, method, path string) bool {
|
func (h *routerHandler) subdomainAndPathAndMethodExists(ctx *context.Context, t *trie, method, path string) bool {
|
||||||
|
|
|
@ -114,14 +114,23 @@ type compatibleErr interface {
|
||||||
Error() string
|
Error() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispatchErr writes the error to the response.
|
// dispatchErr sets the error status code
|
||||||
|
// and the error value to the context.
|
||||||
|
// The APIBuilder's On(Any)ErrorCode is responsible to render this error code.
|
||||||
func dispatchErr(ctx *context.Context, status int, err error) bool {
|
func dispatchErr(ctx *context.Context, status int, err error) bool {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StatusCode(status)
|
if err != ErrStopExecution {
|
||||||
DefaultErrorHandler.HandleError(ctx, err)
|
if status == 0 || !context.StatusCodeNotSuccessful(status) {
|
||||||
|
status = DefaultErrStatusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.StatusCode(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.SetErr(err)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,3 +258,24 @@ func TestPreflightResult(t *testing.T) {
|
||||||
e.POST("/alternative").WithJSON(testInput{expected4.Name}).
|
e.POST("/alternative").WithJSON(testInput{expected4.Name}).
|
||||||
Expect().Status(httptest.StatusAccepted).JSON().Equal(expected4)
|
Expect().Status(httptest.StatusAccepted).JSON().Equal(expected4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResponseErr(t *testing.T) {
|
||||||
|
app := iris.New()
|
||||||
|
var expectedErr = errors.New("response error")
|
||||||
|
|
||||||
|
app.OnAnyErrorCode(func(ctx iris.Context) {
|
||||||
|
err := ctx.GetErr()
|
||||||
|
if err != expectedErr {
|
||||||
|
t.Fatalf("expected error value does not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.WriteString(err.Error())
|
||||||
|
})
|
||||||
|
|
||||||
|
app.ConfigureContainer().Get("/", func() Response {
|
||||||
|
return Response{Code: iris.StatusBadGateway, Err: expectedErr}
|
||||||
|
})
|
||||||
|
|
||||||
|
e := httptest.New(t, app)
|
||||||
|
e.GET("/").Expect().Status(iris.StatusBadGateway).Body().Equal("response error")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user