From 878484204e29df53aadc9f21e99624f87d95175a Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Sat, 20 Jun 2020 09:39:42 +0300 Subject: [PATCH] minor: versioning: Match: store the matched version and revert the last change Former-commit-id: e7aa04671d3f54650bb194a97300b6a89e1b0d2b --- HISTORY.md | 1 - configuration.go | 2 +- context/context.go | 9 --------- versioning/version.go | 13 ++++++++++++- versioning/version_test.go | 2 +- versioning/versioning.go | 26 +++++++++++++++++++++----- 6 files changed, 35 insertions(+), 18 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 113a5b3f..6750362d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -430,7 +430,6 @@ New Context Methods: - `Context.GetDomain() string` returns the domain. - `Context.AddCookieOptions(...CookieOption)` adds options for `SetCookie`, `SetCookieKV, UpsertCookie` and `RemoveCookie` methods for the current request. - `Context.ClearCookieOptions()` clears any cookie options registered through `AddCookieOptions`. -- `Context.SetVersion(constraint string)` force-sets an [API Version](https://github.com/kataras/iris/wiki/API-versioning) - `Context.SetLanguage(langCode string)` force-sets a language code from inside a middleare, similar to the `app.I18n.ExtractFunc` - `Context.ServeContentWithRate`, `ServeFileWithRate` and `SendFileWithRate` methods to throttle the "download" speed of the client - `Context.IsHTTP2() bool` reports whether the protocol version for incoming request was HTTP/2 diff --git a/configuration.go b/configuration.go index 925a457c..2f890c30 100644 --- a/configuration.go +++ b/configuration.go @@ -944,7 +944,7 @@ type Configuration struct { // Defaults to "iris.locale.language". LanguageContextKey string `json:"languageContextKey,omitempty" yaml:"LanguageContextKey" toml:"LanguageContextKey"` // VersionContextKey is the context key which an API Version can be modified - // via a middleware through `SetVersion` method, e.g. `ctx.SetVersion("1.0, 1.1")`. + // via a middleware through `SetVersion` method, e.g. `versioning.SetVersion(ctx, "1.0, 1.1")`. // Defaults to "iris.api.version". VersionContextKey string `json:"versionContextKey" yaml:"VersionContextKey" toml:"VersionContextKey"` // GetViewLayoutContextKey is the key of the context's user values' key diff --git a/context/context.go b/context/context.go index e29059ec..663241a8 100644 --- a/context/context.go +++ b/context/context.go @@ -429,9 +429,6 @@ type Context interface { // See `GetLocale` too. // Example: https://github.com/kataras/iris/tree/master/_examples/i18n Tr(format string, args ...interface{}) string - // SetVersion force-sets the API Version integrated with the "iris/versioning" subpackage. - // It can be used inside a middleare. - SetVersion(constraint string) // +------------------------------------------------------------+ // | Headers helpers | // +------------------------------------------------------------+ @@ -2145,12 +2142,6 @@ func (ctx *context) Tr(format string, args ...interface{}) string { // other nam return fmt.Sprintf(format, args...) } -// SetVersion force-sets the API Version integrated with the "iris/versioning" subpackage. -// It can be used inside a middleare. -func (ctx *context) SetVersion(constraint string) { - ctx.values.Set(ctx.app.ConfigurationReadOnly().GetVersionContextKey(), constraint) -} - // +------------------------------------------------------------+ // | Response Headers helpers | // +------------------------------------------------------------+ diff --git a/versioning/version.go b/versioning/version.go index a72d6de9..ae3d30ee 100644 --- a/versioning/version.go +++ b/versioning/version.go @@ -22,7 +22,9 @@ const ( // ctx.Next() // } // - // DEPRECATED: May 06 2020: Use `ctx.SetVersion(ctx.URLParamDefault("version", "1"))` instead. + // DEPRECATED: Use: + // version := ctx.URLParamDefault("version", "1") + // versioning.SetVersion(ctx, version) instead. Key = "iris.api.version" // NotFound is the key that can be used inside a `Map` or inside `ctx.SetVersion(versioning.NotFound)` // to tell that a version wasn't found, therefore the not found handler should handle the request instead. @@ -56,6 +58,8 @@ var NotFoundHandler = func(ctx context.Context) { // // However, the end developer can also set a custom version for a handler via a middleware by using the context's store key // for versions (see `Key` for further details on that). +// +// See `SetVersion` too. func GetVersion(ctx context.Context) string { // firstly by context store, if manually set by a middleware. version := ctx.Values().GetString(ctx.Application().ConfigurationReadOnly().GetVersionContextKey()) @@ -96,3 +100,10 @@ func GetVersion(ctx context.Context) string { return "" } + +// SetVersion force-sets the API Version. +// It can be used inside a middleware. +// See `GetVersion` too. +func SetVersion(ctx context.Context, constraint string) { + ctx.Values().Set(ctx.Application().ConfigurationReadOnly().GetVersionContextKey(), constraint) +} diff --git a/versioning/version_test.go b/versioning/version_test.go index e5aef53f..eab10ea9 100644 --- a/versioning/version_test.go +++ b/versioning/version_test.go @@ -17,7 +17,7 @@ func TestGetVersion(t *testing.T) { app.Get("/", writeVesion) app.Get("/manual", func(ctx iris.Context) { - ctx.SetVersion("11.0.5") + versioning.SetVersion(ctx, "11.0.5") ctx.Next() }, writeVesion) diff --git a/versioning/versioning.go b/versioning/versioning.go index 36f52ea8..886b7666 100644 --- a/versioning/versioning.go +++ b/versioning/versioning.go @@ -9,23 +9,39 @@ import ( // If reports whether the "version" is matching to the "is". // the "is" can be a constraint like ">= 1, < 3". func If(v string, is string) bool { + _, ok := check(v, is) + return ok +} + +func check(v string, is string) (string, bool) { ver, err := version.NewVersion(v) if err != nil { - return false + return "", false } constraints, err := version.NewConstraint(is) if err != nil { - return false + return "", false } - return constraints.Check(ver) + // return the extracted version from request, even if not matched. + return ver.String(), constraints.Check(ver) } // Match acts exactly the same as `If` does but instead it accepts // a Context, so it can be called by a handler to determinate the requested version. +// +// If matched then it sets the "X-API-Version" response header and +// stores the matched version into Context (see `GetVersion` too). func Match(ctx context.Context, expectedVersion string) bool { - return If(GetVersion(ctx), expectedVersion) + versionString, matched := check(GetVersion(ctx), expectedVersion) + if !matched { + return false + } + + SetVersion(ctx, versionString) + ctx.Header("X-API-Version", versionString) + return true } // Map is a map of versions targets to a handlers, @@ -63,7 +79,7 @@ func NewMatcher(versions Map) context.Handler { } // pass the not matched version so the not found handler can have knowedge about it. - // ctx.SetVersion(versionString) + // SetVersion(ctx, versionString) // or let a manual cal of GetVersion(ctx) do that instead. notFoundHandler(ctx) }