Former-commit-id: 32af4dd8ef18a5fb2fa88aa8b87e71a594faa6f2
This commit is contained in:
Gerasimos (Makis) Maropoulos 2017-02-17 04:57:51 +02:00
parent 21a18d0990
commit 929b00a24b
5 changed files with 62 additions and 88 deletions

View File

@ -10,12 +10,14 @@
Users already notified for some breaking-changes, this section will help you Users already notified for some breaking-changes, this section will help you
to adapt the new changes to your application, it contains an overview of the new features too. to adapt the new changes to your application, it contains an overview of the new features too.
- Shutdown with `app.Shutdown(context.Context) error`, no need for any third-parties, with `EventPolicy.Interrupted` and Go's 1.8 Gracefully Shutdown feature you're ready to go!
- HTTP/2 Go 1.8 `context.Push(target string, opts *http.PushOptions) error` is supported
- Router (two lines to add, new features) - Router (two lines to add, new features)
- Template engines (two lines to add, same features as before, except their easier configuration) - Template engines (two lines to add, same features as before, except their easier configuration)
- Basic middleware, that have been written by me, are transfared to the main repository[/middleware](https://github.com/kataras/iris/tree/master/middleware) with a lot of improvements to the `recover middleware` (see the next) - Basic middleware, that have been written by me, are transfared to the main repository[/middleware](https://github.com/kataras/iris/tree/master/middleware) with a lot of improvements to the `recover middleware` (see the next)
- `func(http.ResponseWriter, r *http.Request, next http.HandlerFunc)` signature is fully compatible using `iris.ToHandler` helper wrapper func, without any need of custom boilerplate code. So all net/http middleware out there are supported, no need to re-invert the world here, search to the internet and you'll find a suitable to your case. - `func(http.ResponseWriter, r *http.Request, next http.HandlerFunc)` signature is fully compatible using `iris.ToHandler` helper wrapper func, without any need of custom boilerplate code. So all net/http middleware out there are supported, no need to re-invert the world here, search to the internet and you'll find a suitable to your case.
- Developers can use a `yaml` files for the configuration using the `iris.YAML` function: `app := iris.New(iris.YAML("myconfiguration.yaml"))` - Developers can use a `yaml` files for the configuration using the `iris.YAML` function: `app := iris.New(iris.YAML("myconfiguration.yaml"))`
- Shutdown with `app.Shutdown(context.Context) error`, no need for any third-parties, with `EventPolicy.Interrupted` and Go's 1.8 Gracefully Shutdown feature you're ready to go!
Fixes: Fixes:

View File

@ -113,7 +113,6 @@ func TestConfigurationYAML(t *testing.T) {
EnablePathEscape: false EnablePathEscape: false
FireMethodNotAllowed: true FireMethodNotAllowed: true
DisableBodyConsumptionOnUnmarshal: true DisableBodyConsumptionOnUnmarshal: true
DisableBodyConsumptionOnUnmarshal: true
TimeFormat: Mon, 01 Jan 2006 15:04:05 GMT TimeFormat: Mon, 01 Jan 2006 15:04:05 GMT
Charset: UTF-8 Charset: UTF-8
Gzip: true Gzip: true
@ -165,11 +164,6 @@ func TestConfigurationYAML(t *testing.T) {
t.Fatalf("error on TestConfigurationYAML: Expected DisableBodyConsumptionOnUnmarshal %v but got %v", expected, c.DisableBodyConsumptionOnUnmarshal) t.Fatalf("error on TestConfigurationYAML: Expected DisableBodyConsumptionOnUnmarshal %v but got %v", expected, c.DisableBodyConsumptionOnUnmarshal)
} }
if expected := true; c.DisableBodyConsumptionOnUnmarshal != expected {
t.Fatalf("error on TestConfigurationYAML: Expected DisableBodyConsumptionOnUnmarshal %v but got %v",
expected, c.DisableBodyConsumptionOnUnmarshal)
}
if expected := "Mon, 01 Jan 2006 15:04:05 GMT"; c.TimeFormat != expected { if expected := "Mon, 01 Jan 2006 15:04:05 GMT"; c.TimeFormat != expected {
t.Fatalf("error on TestConfigurationYAML: Expected TimeFormat %s but got %s", expected, c.TimeFormat) t.Fatalf("error on TestConfigurationYAML: Expected TimeFormat %s but got %s", expected, c.TimeFormat)
} }

View File

@ -443,8 +443,9 @@ func (s *Framework) Serve(ln net.Listener) error {
if s.ln != nil { if s.ln != nil {
return errors.New("server is already started and listening") return errors.New("server is already started and listening")
} }
// maybe a 'race' here but user should not call .Serve more than one time especially in more than one go routines...
s.ln = ln s.ln = ln
s.closedManually = false
s.Boot() s.Boot()
// post any panics to the user defined logger. // post any panics to the user defined logger.

View File

@ -159,44 +159,35 @@ func (w *ResponseRecorder) Flush() {
w.ResetBody() w.ResetBody()
} }
// NOTE: Users: Uncomment the below code if you are already using Go from master branch. // Push initiates an HTTP/2 server push. This constructs a synthetic
// HTTP/2 Go 1.8 Push feature, // request using the given target and options, serializes that request
// as described in the source code(master): // into a PUSH_PROMISE frame, then dispatches that request using the
// https://github.com/golang/go/blob/master/src/net/http/http.go#L119 . // server's request handler. If opts is nil, default options are used.
// I have already tested the feature on my machine, but
// in order to avoid breaking the users' workspace:
// Uncomment these when 1.8 released (I guess in the middle of February)
// TODO:
// //
// // Push initiates an HTTP/2 server push. This constructs a synthetic // The target must either be an absolute path (like "/path") or an absolute
// // request using the given target and options, serializes that request // URL that contains a valid host and the same scheme as the parent request.
// // into a PUSH_PROMISE frame, then dispatches that request using the // If the target is a path, it will inherit the scheme and host of the
// // server's request handler. If opts is nil, default options are used. // parent request.
// //
// // The target must either be an absolute path (like "/path") or an absolute
// // URL that contains a valid host and the same scheme as the parent request.
// // If the target is a path, it will inherit the scheme and host of the
// // parent request.
// //
// // The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
// // Push may or may not detect these invalid pushes; however, invalid
// // pushes will be detected and canceled by conforming clients.
// //
// // Handlers that wish to push URL X should call Push before sending any
// // data that may trigger a request for URL X. This avoids a race where the
// // client issues requests for X before receiving the PUSH_PROMISE for X.
// //
// // Push returns ErrNotSupported if the client has disabled push or if push
// // is not supported on the underlying connection.
// func (w *ResponseRecorder) Push(target string, opts *http.PushOptions) error {
// w.flushResponse()
// err := w.responseWriter.Push(target, opts)
// // NOTE: we have to reset them even if the push failed.
// w.ResetBody()
// w.ResetHeaders()
// //
// return err // The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
// } // Push may or may not detect these invalid pushes; however, invalid
// pushes will be detected and canceled by conforming clients.
//
// Handlers that wish to push URL X should call Push before sending any
// data that may trigger a request for URL X. This avoids a race where the
// client issues requests for X before receiving the PUSH_PROMISE for X.
//
// Push returns ErrPushNotSupported if the client has disabled push or if push
// is not supported on the underlying connection.
func (w *ResponseRecorder) Push(target string, opts *http.PushOptions) error {
w.flushResponse()
err := w.responseWriter.Push(target, opts)
// NOTE: we have to reset them even if the push failed.
w.ResetBody()
w.ResetHeaders()
return err
}
// clone returns a clone of this response writer // clone returns a clone of this response writer
// it copies the header, status code, headers and the beforeFlush finally returns a new ResponseRecorder // it copies the header, status code, headers and the beforeFlush finally returns a new ResponseRecorder

View File

@ -61,16 +61,7 @@ type ResponseWriter interface {
http.Flusher http.Flusher
http.Hijacker http.Hijacker
http.CloseNotifier http.CloseNotifier
// NOTE: Users: Uncomment the below code if you are already using Go from master branch. http.Pusher
// HTTP/2 Go 1.8 Push feature,
// as described in the source code(master):
// https://github.com/golang/go/blob/master/src/net/http/http.go#L119 .
// I have already tested the feature on my machine, but
// in order to avoid breaking the users' workspace:
// Uncomment these when 1.8 released (I guess in the middle of February)
// TODO:
//
// http.Pusher
Writef(format string, a ...interface{}) (n int, err error) Writef(format string, a ...interface{}) (n int, err error)
WriteString(s string) (n int, err error) WriteString(s string) (n int, err error)
@ -223,44 +214,39 @@ func (w *responseWriter) Flush() {
} }
} }
// NOTE: Users: Uncomment the below code if you are already using Go from master branch. // ErrPushNotSupported is returned by the Push method to
// HTTP/2 Go 1.8 Push feature, // indicate that HTTP/2 Push support is not available.
// as described in the source code(master): var ErrPushNotSupported = errors.New("push feature is not supported by this ResponseWriter")
// https://github.com/golang/go/blob/master/src/net/http/http.go#L119 .
// I have already tested the feature on my machine, but // Push initiates an HTTP/2 server push. This constructs a synthetic
// in order to avoid breaking the users' workspace: // request using the given target and options, serializes that request
// Uncomment these when 1.8 released (I guess in the middle of February) // into a PUSH_PROMISE frame, then dispatches that request using the
// TODO: // server's request handler. If opts is nil, default options are used.
// //
// The target must either be an absolute path (like "/path") or an absolute
// URL that contains a valid host and the same scheme as the parent request.
// If the target is a path, it will inherit the scheme and host of the
// parent request.
// //
// // Push initiates an HTTP/2 server push. This constructs a synthetic // The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
// // request using the given target and options, serializes that request // Push may or may not detect these invalid pushes; however, invalid
// // into a PUSH_PROMISE frame, then dispatches that request using the // pushes will be detected and canceled by conforming clients.
// // server's request handler. If opts is nil, default options are used.
// //
// // The target must either be an absolute path (like "/path") or an absolute
// // URL that contains a valid host and the same scheme as the parent request.
// // If the target is a path, it will inherit the scheme and host of the
// // parent request.
// //
// // The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
// // Push may or may not detect these invalid pushes; however, invalid
// // pushes will be detected and canceled by conforming clients.
// //
// // Handlers that wish to push URL X should call Push before sending any
// // data that may trigger a request for URL X. This avoids a race where the
// // client issues requests for X before receiving the PUSH_PROMISE for X.
// //
// // Push returns ErrNotSupported if the client has disabled push or if push
// // is not supported on the underlying connection.
// func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
// //
// if pusher, isPusher := w.ResponseWriter.(http.Pusher); isPusher { // Handlers that wish to push URL X should call Push before sending any
// return pusher.Push(target, opts) // data that may trigger a request for URL X. This avoids a race where the
// } // client issues requests for X before receiving the PUSH_PROMISE for X.
// //
// return errors.New("HTTP/2 Push feature is not supported, yet.") // Push returns ErrPushNotSupported if the client has disabled push or if push
// } // is not supported on the underlying connection.
func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
if pusher, isPusher := w.ResponseWriter.(http.Pusher); isPusher {
err := pusher.Push(target, opts)
if err != nil && err.Error() == http.ErrNotSupported.ErrorString {
return ErrPushNotSupported
}
}
return ErrPushNotSupported
}
// CloseNotify returns a channel that receives at most a // CloseNotify returns a channel that receives at most a
// single value (true) when the client connection has gone // single value (true) when the client connection has gone