remove 'WithoutVersionChecker', update and test the new versions of some of the dependencies, add a history entry with unknown release date

Former-commit-id: 399db6aac44d3b336648d6d61842f4d7a0266842
This commit is contained in:
Gerasimos (Makis) Maropoulos 2018-08-31 02:09:48 +03:00
parent 6cf48df5c0
commit f365be3c62
32 changed files with 143 additions and 300 deletions

18
Gopkg.lock generated
View File

@ -277,6 +277,24 @@
packages = ["."] packages = ["."]
revision = "aad8439df3bf67adb025382ee2e5f46a72fc9456" revision = "aad8439df3bf67adb025382ee2e5f46a72fc9456"
[[projects]]
branch = "master"
name = "github.com/dgraph-io/badger"
packages = ["."]
revision = "391b6d3b93e6014fe8c2971fcc0c1266e47dbbd9"
[[projects]]
branch = "master"
name = "github.com/etcd-io/bbolt"
packages = ["."]
revision = "acbc2c426a444a65e0cbfdcbb3573857bf18b465"
[[projects]]
branch = "master"
name = "github.com/gomodule/redigo"
packages = ["internal","redis"]
revision = "2cd21d9966bf7ff9ae091419744f0b3fb0fecace"
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1

View File

@ -81,3 +81,15 @@
[[constraint]] [[constraint]]
branch = "master" branch = "master"
name = "github.com/Shopify/goreferrer" name = "github.com/Shopify/goreferrer"
[[constraint]]
name = "github.com/dgraph-io/badger"
version = "1.5.3"
[[constraint]]
name = "github.com/etcd-io/bbolt"
version = "1.3.1-etcd.7"
[[constraint]]
branch = "master"
name = "github.com/gomodule/redigo"

View File

@ -17,6 +17,71 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
# Whenever | v11.0.0
## Breaking changes
- Remove the "Configurator" `WithoutVersionChecker` and the configuration field `DisableVersionChecker`
- `:int` (or its new alias `:number`) macro route path parameter type **can accept negative numbers now**. Recommendation: `:int` should be replaced with the more generic numeric parameter type `:number` if possible (although it will stay for backwards-compatibility)
## Routing
- `:number` parameter type as an alias to the old `:int` which can accept any numeric path segment now, both negative and positive numbers and without digits limitation
- Add `:int64` parameter type and `ctx.Params().GetInt64`
- Add `:uint8` parameter type and `ctx.Params().GetUint8`
- Add `:uint64` parameter type and `ctx.Params().GetUint64`
- `:bool` parameter type as an alias for `:boolean`
Here is the full list of the built'n parameter types that we support now, including their validations/path segment rules.
| Param Type | Go Type | Validation |
| -----------|---------|------------|
| `:string` | string | anything |
| `:number` | uint, uint8, uint16, uint32, uint64, int, int8, int32, int64 | positive or negative number, any number of digits |
| `:int64` | int64 | -9223372036854775808 to 9223372036854775807 |
| `:uint8` | uint8 | 0 to 255 |
| `:uint64` | uint64 | 0 to 18446744073709551615 |
| `:bool` | bool | "1" or "t" or "T" or "TRUE" or "true" or "True" or "0" or "f" or "F" or "FALSE" or "false" or "False" |
| `:alphabetical` | string | lowercase or uppercase letters |
| `:file` | string | lowercase or uppercase letters, numbers, underscore (_), dash (-), point (.) and no spaces or other special characters that are not valid for filenames |
| `:path` | string | anything, can be separated by slashes (path segments) but should be the last part of the route path |
**Usage**:
```go
app.Get("/users/{id:uint64}", func(ctx iris.Context){
id, _ := ctx.Params().GetUint64("id")
// [...]
})
```
| Built'n Func | Param Types |
| -----------|---------------|
| `regexp`(expr string) | :string |
| `prefix`(prefix string) | :string |
| `suffix`(suffix string) | :string |
| `contains`(s string) | :string |
| `min`(minValue int or int8 or int16 or int32 or int64 or uint8 or uint16 or uint32 or uint64 or float32 or float64) | :string(char length), :number, :int64, :uint8, :uint64 |
| `max`(maxValue int or int8 or int16 or int32 or int64 or uint8 or uint16 or uint32 or uint64 or float32 or float64) | :string(char length), :number, :int64, :uint8, :uint64 |
| `range`(minValue, maxValue int or int8 or int16 or int32 or int64 or uint8 or uint16 or uint32 or uint64 or float32 or float64) | :number, :int64, :uint8, :uint64 |
**Usage**:
```go
app.Get("/profile/{name:alphabetical max(255)}", func(ctx iris.Context){
name := ctx.Params().Get("name")
// len(name) <=255 otherwise this route will fire 404 Not Found
// and this handler will not be executed at all.
})
```
## Vendoring
- Rename the vendor `sessions/sessiondb/vendor/...bbolt` from `coreos/bbolt` to `etcd-io/bbolt` and update to v1.3.1, based on [that](https://github.com/etcd-io/bbolt/releases/tag/v1.3.1-etcd.7)
- Update the vendor `sessions/sessiondb/vendor/...badger` to v1.5.3
> More to come, maybe it will be removed eventually.
# Sat, 11 August 2018 | v10.7.0 # Sat, 11 August 2018 | v10.7.0
I am overjoyed to announce stage 1 of the the Iris Web framework **10.7 stable release is now available**. I am overjoyed to announce stage 1 of the the Iris Web framework **10.7 stable release is now available**.

View File

@ -588,7 +588,6 @@ func main() {
app.Run( app.Run(
iris.Addr(":8080"), iris.Addr(":8080"),
iris.WithoutBanner, iris.WithoutBanner,
iris.WithoutVersionChecker,
iris.WithoutServerError(iris.ErrServerClosed), iris.WithoutServerError(iris.ErrServerClosed),
) )
} }

View File

@ -24,7 +24,7 @@ func main() {
mvc.New(app).Handle(new(controllers.HomeController)) mvc.New(app).Handle(new(controllers.HomeController))
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker) app.Run(iris.Addr(":5000"))
} }
type err struct { type err struct {

View File

@ -16,7 +16,7 @@ func main() {
mvc.New(app.Party("/api/values/{id}")). mvc.New(app.Party("/api/values/{id}")).
Handle(new(controllers.ValuesController)) Handle(new(controllers.ValuesController))
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker) app.Run(iris.Addr(":5000"))
} }
// +2MB/s faster than the previous implementation, 0.4MB/s difference from the raw handlers. // +2MB/s faster than the previous implementation, 0.4MB/s difference from the raw handlers.

View File

@ -24,9 +24,7 @@ func main() {
app.Delete("/del", delHandler) app.Delete("/del", delHandler)
*/ */
// 24 August 2017: Iris has a built'n version updater but we don't need it app.Run(iris.Addr(":5000"))
// when benchmarking...
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
} }
// Set and Get // Set and Get

View File

@ -8,5 +8,5 @@ func main() {
ctx.WriteString("value") ctx.WriteString("value")
}) })
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker) app.Run(iris.Addr(":5000"))
} }

View File

@ -50,8 +50,6 @@ func main() {
app.Run( app.Run(
// Start the web server at localhost:8080 // Start the web server at localhost:8080
iris.Addr("localhost:8080"), iris.Addr("localhost:8080"),
// disables updates:
iris.WithoutVersionChecker,
// skip err server closed when CTRL/CMD+C pressed: // skip err server closed when CTRL/CMD+C pressed:
iris.WithoutServerError(iris.ErrServerClosed), iris.WithoutServerError(iris.ErrServerClosed),
// enables faster json serialization and more: // enables faster json serialization and more:

View File

@ -34,7 +34,6 @@ func main() {
app.Run( app.Run(
iris.Addr(":8080"), iris.Addr(":8080"),
iris.WithoutVersionChecker,
iris.WithoutServerError(iris.ErrServerClosed), iris.WithoutServerError(iris.ErrServerClosed),
) )
} }

View File

@ -25,5 +25,5 @@ func main() {
// http://localhost:8080?referer=https://twitter.com/Xinterio/status/1023566830974251008 // http://localhost:8080?referer=https://twitter.com/Xinterio/status/1023566830974251008
// http://localhost:8080?referer=https://www.google.com/search?q=Top+6+golang+web+frameworks&oq=Top+6+golang+web+frameworks // http://localhost:8080?referer=https://www.google.com/search?q=Top+6+golang+web+frameworks&oq=Top+6+golang+web+frameworks
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed), iris.WithoutVersionChecker) app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
} }

View File

@ -79,8 +79,6 @@ func main() {
app.Run( app.Run(
// Starts the web server at localhost:8080 // Starts the web server at localhost:8080
iris.Addr("localhost:8080"), iris.Addr("localhost:8080"),
// Disables the updater.
iris.WithoutVersionChecker,
// Ignores err server closed log when CTRL/CMD+C pressed. // Ignores err server closed log when CTRL/CMD+C pressed.
iris.WithoutServerError(iris.ErrServerClosed), iris.WithoutServerError(iris.ErrServerClosed),
// Enables faster json serialization and more. // Enables faster json serialization and more.

View File

@ -33,8 +33,6 @@ func main() {
app.Run( app.Run(
// Start the web server at localhost:8080 // Start the web server at localhost:8080
iris.Addr("localhost:8080"), iris.Addr("localhost:8080"),
// disables updates:
iris.WithoutVersionChecker,
// skip err server closed when CTRL/CMD+C pressed: // skip err server closed when CTRL/CMD+C pressed:
iris.WithoutServerError(iris.ErrServerClosed), iris.WithoutServerError(iris.ErrServerClosed),
// enables faster json serialization and more: // enables faster json serialization and more:

View File

@ -68,5 +68,5 @@ func main() {
// 3. refresh the page some times // 3. refresh the page some times
// 4. close the browser // 4. close the browser
// 5. re-open the browser and re-play 2. // 5. re-open the browser and re-play 2.
app.Run(iris.Addr(":8080"), iris.WithoutVersionChecker) app.Run(iris.Addr(":8080"))
} }

View File

@ -74,7 +74,7 @@ func main() {
} }
// Listen for incoming HTTP/1.x & HTTP/2 clients on localhost port 8080. // Listen for incoming HTTP/1.x & HTTP/2 clients on localhost port 8080.
app.Run(iris.Addr(":8080"), iris.WithCharset("UTF-8"), iris.WithoutVersionChecker) app.Run(iris.Addr(":8080"), iris.WithCharset("UTF-8"))
} }
func logThisMiddleware(ctx iris.Context) { func logThisMiddleware(ctx iris.Context) {

View File

@ -2,7 +2,7 @@
// //
// Article: https://medium.com/@kataras/a-url-shortener-service-using-go-iris-and-bolt-4182f0b00ae7 // Article: https://medium.com/@kataras/a-url-shortener-service-using-go-iris-and-bolt-4182f0b00ae7
// //
// $ go get github.com/coreos/bbolt // $ go get github.com/etcd-io/bbolt
// $ go get github.com/satori/go.uuid // $ go get github.com/satori/go.uuid
// $ cd $GOPATH/src/github.com/kataras/iris/_examples/tutorial/url-shortener // $ cd $GOPATH/src/github.com/kataras/iris/_examples/tutorial/url-shortener
// $ go build // $ go build

View File

@ -3,7 +3,7 @@ package main
import ( import (
"bytes" "bytes"
"github.com/coreos/bbolt" "github.com/etcd-io/bbolt"
) )
// Panic panics, change it if you don't want to panic on critical INITIALIZE-ONLY-ERRORS // Panic panics, change it if you don't want to panic on critical INITIALIZE-ONLY-ERRORS
@ -28,17 +28,17 @@ var (
// Only one table/bucket which contains the urls, so it's not a fully Database, // Only one table/bucket which contains the urls, so it's not a fully Database,
// it works only with single bucket because that all we need. // it works only with single bucket because that all we need.
type DB struct { type DB struct {
db *bolt.DB db *bbolt.DB
} }
var _ Store = &DB{} var _ Store = &DB{}
// openDatabase open a new database connection // openDatabase open a new database connection
// and returns its instance. // and returns its instance.
func openDatabase(stumb string) *bolt.DB { func openDatabase(stumb string) *bbolt.DB {
// Open the data(base) file in the current working directory. // Open the data(base) file in the current working directory.
// It will be created if it doesn't exist. // It will be created if it doesn't exist.
db, err := bolt.Open(stumb, 0600, nil) db, err := bbolt.Open(stumb, 0600, nil)
if err != nil { if err != nil {
Panic(err) Panic(err)
} }
@ -48,7 +48,7 @@ func openDatabase(stumb string) *bolt.DB {
tableURLs, tableURLs,
} }
db.Update(func(tx *bolt.Tx) (err error) { db.Update(func(tx *bbolt.Tx) (err error) {
for _, table := range tables { for _, table := range tables {
_, err = tx.CreateBucketIfNotExists(table) _, err = tx.CreateBucketIfNotExists(table)
if err != nil { if err != nil {
@ -73,7 +73,7 @@ func NewDB(stumb string) *DB {
// Set sets a shorten url and its key // Set sets a shorten url and its key
// Note: Caller is responsible to generate a key. // Note: Caller is responsible to generate a key.
func (d *DB) Set(key string, value string) error { func (d *DB) Set(key string, value string) error {
return d.db.Update(func(tx *bolt.Tx) error { return d.db.Update(func(tx *bbolt.Tx) error {
b, err := tx.CreateBucketIfNotExists(tableURLs) b, err := tx.CreateBucketIfNotExists(tableURLs)
// Generate ID for the url // Generate ID for the url
// Note: we could use that instead of a random string key // Note: we could use that instead of a random string key
@ -106,7 +106,7 @@ func (d *DB) Set(key string, value string) error {
// Clear clears all the database entries for the table urls. // Clear clears all the database entries for the table urls.
func (d *DB) Clear() error { func (d *DB) Clear() error {
return d.db.Update(func(tx *bolt.Tx) error { return d.db.Update(func(tx *bbolt.Tx) error {
return tx.DeleteBucket(tableURLs) return tx.DeleteBucket(tableURLs)
}) })
} }
@ -116,7 +116,7 @@ func (d *DB) Clear() error {
// Returns an empty string if not found. // Returns an empty string if not found.
func (d *DB) Get(key string) (value string) { func (d *DB) Get(key string) (value string) {
keyB := []byte(key) keyB := []byte(key)
d.db.Update(func(tx *bolt.Tx) error { d.db.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket(tableURLs) b := tx.Bucket(tableURLs)
if b == nil { if b == nil {
return nil return nil
@ -138,7 +138,7 @@ func (d *DB) Get(key string) (value string) {
// GetByValue returns all keys for a specific (original) url value. // GetByValue returns all keys for a specific (original) url value.
func (d *DB) GetByValue(value string) (keys []string) { func (d *DB) GetByValue(value string) (keys []string) {
valueB := []byte(value) valueB := []byte(value)
d.db.Update(func(tx *bolt.Tx) error { d.db.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket(tableURLs) b := tx.Bucket(tableURLs)
if b == nil { if b == nil {
return nil return nil
@ -159,7 +159,7 @@ func (d *DB) GetByValue(value string) (keys []string) {
// Len returns all the "shorted" urls length // Len returns all the "shorted" urls length
func (d *DB) Len() (num int) { func (d *DB) Len() (num int) {
d.db.View(func(tx *bolt.Tx) error { d.db.View(func(tx *bbolt.Tx) error {
// Assume bucket exists and has keys // Assume bucket exists and has keys
b := tx.Bucket(tableURLs) b := tx.Bucket(tableURLs)

View File

@ -530,7 +530,7 @@ func main() {
todosApp.Handle(new(controllers.TodoController)) todosApp.Handle(new(controllers.TodoController))
// start the web server at http://localhost:8080 // start the web server at http://localhost:8080
app.Run(iris.Addr(":8080"), iris.WithoutVersionChecker) app.Run(iris.Addr(":8080"))
} }
``` ```

View File

@ -51,5 +51,5 @@ func main() {
todosApp.Handle(new(controllers.TodoController)) todosApp.Handle(new(controllers.TodoController))
// start the web server at http://localhost:8080 // start the web server at http://localhost:8080
app.Run(iris.Addr(":8080"), iris.WithoutVersionChecker) app.Run(iris.Addr(":8080"))
} }

View File

@ -1,4 +1,4 @@
// +build go1.11beta3 // +build go1.11
package main package main
@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
// GOARCH=wasm GOOS=js /home/$yourusername/go1.11beta1/bin/go build -o hello.wasm hello_go11beta2.go // GOARCH=wasm GOOS=js /home/$yourusername/go1.11/bin/go build -o hello.wasm hello_go111.go
js.Global().Get("console").Call("log", "Hello WebAssemply!") js.Global().Get("console").Call("log", "Hello WebAssemply!")
message := fmt.Sprintf("Hello, the current time is: %s", time.Now().String()) message := fmt.Sprintf("Hello, the current time is: %s", time.Now().String())
js.Global().Get("document").Call("getElementById", "hello").Set("innerText", message) js.Global().Get("document").Call("getElementById", "hello").Set("innerText", message)

View File

@ -6,7 +6,7 @@ import (
/* /*
You need to build the hello.wasm first, download the go1.11 and execute the below command: You need to build the hello.wasm first, download the go1.11 and execute the below command:
$ cd client && GOARCH=wasm GOOS=js /home/$yourname/go1.11beta3/bin/go build -o hello.wasm hello_go11beta3.go $ cd client && GOARCH=wasm GOOS=js /home/$yourname/go1.11/bin/go build -o hello.wasm hello_go111.go
*/ */
func main() { func main() {

View File

@ -222,14 +222,6 @@ var WithoutInterruptHandler = func(app *Application) {
app.config.DisableInterruptHandler = true app.config.DisableInterruptHandler = true
} }
// WithoutVersionChecker will disable the version checker and updater.
// The Iris server will be not
// receive automatic updates if you pass this
// to the `Run` function. Use it only while you're ready for Production environment.
var WithoutVersionChecker = func(app *Application) {
app.config.DisableVersionChecker = true
}
// WithoutPathCorrection disables the PathCorrection setting. // WithoutPathCorrection disables the PathCorrection setting.
// //
// See `Configuration`. // See `Configuration`.
@ -388,11 +380,6 @@ type Configuration struct {
// Defaults to false. // Defaults to false.
DisableInterruptHandler bool `json:"disableInterruptHandler,omitempty" yaml:"DisableInterruptHandler" toml:"DisableInterruptHandler"` DisableInterruptHandler bool `json:"disableInterruptHandler,omitempty" yaml:"DisableInterruptHandler" toml:"DisableInterruptHandler"`
// DisableVersionChecker if true then process will be not be notified for any available updates.
//
// Defaults to false.
DisableVersionChecker bool `json:"disableVersionChecker,omitempty" yaml:"DisableVersionChecker" toml:"DisableVersionChecker"`
// DisablePathCorrection corrects and redirects the requested path to the registered 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, // for example, if /home/ path is requested but no handler for this Route found,
// then the Router checks if /home handler exists, if yes, // then the Router checks if /home handler exists, if yes,
@ -677,10 +664,6 @@ func WithConfiguration(c Configuration) Configurator {
main.DisableInterruptHandler = v main.DisableInterruptHandler = v
} }
if v := c.DisableVersionChecker; v {
main.DisableVersionChecker = v
}
if v := c.DisablePathCorrection; v { if v := c.DisablePathCorrection; v {
main.DisablePathCorrection = v main.DisablePathCorrection = v
} }
@ -758,7 +741,6 @@ func DefaultConfiguration() Configuration {
return Configuration{ return Configuration{
DisableStartupLog: false, DisableStartupLog: false,
DisableInterruptHandler: false, DisableInterruptHandler: false,
DisableVersionChecker: false,
DisablePathCorrection: false, DisablePathCorrection: false,
EnablePathEscape: false, EnablePathEscape: false,
FireMethodNotAllowed: false, FireMethodNotAllowed: false,

View File

@ -77,13 +77,12 @@ func TestConfigurationOptions(t *testing.T) {
func TestConfigurationOptionsDeep(t *testing.T) { func TestConfigurationOptionsDeep(t *testing.T) {
charset := "MYCHARSET" charset := "MYCHARSET"
app := New().Configure(WithCharset(charset), WithoutBodyConsumptionOnUnmarshal, WithoutBanner, WithoutVersionChecker) app := New().Configure(WithCharset(charset), WithoutBodyConsumptionOnUnmarshal, WithoutBanner)
expected := DefaultConfiguration() expected := DefaultConfiguration()
expected.Charset = charset expected.Charset = charset
expected.DisableBodyConsumptionOnUnmarshal = true expected.DisableBodyConsumptionOnUnmarshal = true
expected.DisableStartupLog = true expected.DisableStartupLog = true
expected.DisableVersionChecker = true
has := *app.config has := *app.config
@ -142,7 +141,6 @@ func TestConfigurationYAML(t *testing.T) {
}() }()
yamlConfigurationContents := ` yamlConfigurationContents := `
DisableVersionChecker: true
DisablePathCorrection: false DisablePathCorrection: false
EnablePathEscape: false EnablePathEscape: false
FireMethodNotAllowed: true FireMethodNotAllowed: true
@ -165,10 +163,6 @@ Other:
c := app.config c := app.config
if expected := true; c.DisableVersionChecker != expected {
t.Fatalf("error on TestConfigurationYAML: Expected DisableVersionChecker %v but got %v", expected, c.DisableVersionChecker)
}
if expected := false; c.DisablePathCorrection != expected { if expected := false; c.DisablePathCorrection != expected {
t.Fatalf("error on TestConfigurationYAML: Expected DisablePathCorrection %v but got %v", expected, c.DisablePathCorrection) t.Fatalf("error on TestConfigurationYAML: Expected DisablePathCorrection %v but got %v", expected, c.DisablePathCorrection)
} }
@ -241,7 +235,6 @@ func TestConfigurationTOML(t *testing.T) {
}() }()
tomlConfigurationContents := ` tomlConfigurationContents := `
DisableVersionChecker = true
EnablePathEscape = false EnablePathEscape = false
FireMethodNotAllowed = true FireMethodNotAllowed = true
EnableOptimizations = true EnableOptimizations = true
@ -265,10 +258,6 @@ Charset = "UTF-8"
c := app.config c := app.config
if expected := true; c.DisableVersionChecker != expected {
t.Fatalf("error on TestConfigurationTOML: Expected DisableVersionChecker %v but got %v", expected, c.DisableVersionChecker)
}
if expected := false; c.DisablePathCorrection != expected { if expected := false; c.DisablePathCorrection != expected {
t.Fatalf("error on TestConfigurationTOML: Expected DisablePathCorrection %v but got %v", expected, c.DisablePathCorrection) t.Fatalf("error on TestConfigurationTOML: Expected DisablePathCorrection %v but got %v", expected, c.DisablePathCorrection)
} }

View File

@ -60,7 +60,7 @@ func TestProxy(t *testing.T) {
t.Fatalf("%v while creating tcp4 listener for new tls local test listener", err) t.Fatalf("%v while creating tcp4 listener for new tls local test listener", err)
} }
// main server // main server
go app.Run(iris.Listener(httptest.NewLocalTLSListener(l)), iris.WithoutVersionChecker, iris.WithoutStartupLog) go app.Run(iris.Listener(httptest.NewLocalTLSListener(l)), iris.WithoutStartupLog)
e := httptest.NewInsecure(t, httptest.URL("http://"+listener.Addr().String())) e := httptest.NewInsecure(t, httptest.URL("http://"+listener.Addr().String()))
e.GET("/").Expect().Status(iris.StatusOK).Body().Equal(expectedIndex) e.GET("/").Expect().Status(iris.StatusOK).Body().Equal(expectedIndex)

View File

@ -1,6 +0,0 @@
package maintenance
// Start starts the maintenance process.
func Start() {
CheckForUpdates()
}

View File

@ -1,78 +0,0 @@
package maintenance
import (
"fmt"
"os"
"os/exec"
"github.com/kataras/iris/core/maintenance/version"
"github.com/kataras/golog"
"github.com/kataras/survey"
)
const (
// Version is the string representation of the current local Iris Web Framework version.
Version = "10.7.0"
)
// CheckForUpdates checks for any available updates
// and asks for the user if want to update now or not.
func CheckForUpdates() {
v := version.Acquire()
updateAvailale := v.Compare(Version) == version.Smaller
if updateAvailale {
if confirmUpdate(v) {
installVersion()
return
}
}
}
func confirmUpdate(v version.Version) bool {
// on help? when asking for installing the new update.
ignoreUpdatesMsg := "Would you like to ignore future updates? Disable the version checker via:\napp.Run(..., iris.WithoutVersionChecker)"
// if update available ask for update action.
shouldUpdateNowMsg :=
fmt.Sprintf("A new version is available online[%s > %s]. Type '?' for help.\nRelease notes: %s.\nUpdate now?",
v.String(), Version, v.ChangelogURL)
var confirmUpdate bool
survey.AskOne(&survey.Confirm{
Message: shouldUpdateNowMsg,
Help: ignoreUpdatesMsg,
}, &confirmUpdate, nil)
return confirmUpdate // it's true only when update was available and user typed "yes".
}
func installVersion() {
golog.Infof("Downloading...\n")
repo := "github.com/kataras/iris/..."
cmd := exec.Command("go", "get", "-u", "-v", repo)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
if err := cmd.Run(); err != nil {
golog.Warnf("unexpected message while trying to go get,\nif you edited the original source code then you've to remove the whole $GOPATH/src/github.com/kataras folder and execute `go get -u github.com/kataras/iris/...` manually\n%v", err)
return
}
golog.Infof("Update process finished.\nManual rebuild and restart is required to apply the changes...\n")
return
}
/* Author's note:
We could use github webhooks to automatic notify for updates
when a new update is pushed to the repository
even when server is already started and running but this would expose
a route which dev may don't know about, so let it for now but if
they ask it then I should add an optional configuration field
to "live/realtime update" and implement the idea (which is already implemented in the iris-go server).
*/
/* Author's note:
The old remote endpoint for version checker is still available on the server for backwards
compatibility with older clients, it will stay there for a long period of time.
*/

View File

@ -1,59 +0,0 @@
package version
import (
"io/ioutil"
"strings"
"time"
"github.com/hashicorp/go-version"
"github.com/kataras/golog"
"github.com/kataras/iris/core/netutil"
)
const (
versionURL = "https://raw.githubusercontent.com/kataras/iris/master/VERSION"
)
func fetch() (*version.Version, string) {
client := netutil.Client(time.Duration(30 * time.Second))
r, err := client.Get(versionURL)
if err != nil {
golog.Debugf("err: %v\n", err)
return nil, ""
}
defer r.Body.Close()
if r.StatusCode >= 400 {
golog.Debugf("Internet connection is missing, updater is unable to fetch the latest Iris version\n", err)
return nil, ""
}
b, err := ioutil.ReadAll(r.Body)
if len(b) == 0 || err != nil {
golog.Debugf("err: %v\n", err)
return nil, ""
}
var (
fetchedVersion = string(b)
changelogURL string
)
// Example output:
// Version(8.5.5)
// 8.5.5:https://github.com/kataras/iris/blob/master/HISTORY.md#tu-02-november-2017--v855
if idx := strings.IndexByte(fetchedVersion, ':'); idx > 0 {
changelogURL = fetchedVersion[idx+1:]
fetchedVersion = fetchedVersion[0:idx]
}
latestVersion, err := version.NewVersion(fetchedVersion)
if err != nil {
golog.Debugf("while fetching and parsing latest version from github: %v\n", err)
return nil, ""
}
return latestVersion, changelogURL
}

View File

@ -1,64 +0,0 @@
package version
import (
"time"
"github.com/hashicorp/go-version"
)
// Version is a version wrapper which
// contains some additional customized properties.
type Version struct {
version.Version
WrittenAt time.Time
ChangelogURL string
}
// Result is the compare result type.
// Available types are Invalid, Smaller, Equal or Larger.
type Result int32
const (
// Smaller when the compared version is smaller than the latest one.
Smaller Result = -1
// Equal when the compared version is equal with the latest one.
Equal Result = 0
// Larger when the compared version is larger than the latest one.
Larger Result = 1
// Invalid means that an error occurred when comparing the versions.
Invalid Result = -2
)
// Compare compares the "versionStr" with the latest Iris version,
// opossite to the version package
// it returns the result of the "versionStr" not the "v" itself.
func (v *Version) Compare(versionStr string) Result {
if len(v.Version.String()) == 0 {
// if version not refreshed, by an internet connection lose,
// then return Invalid.
return Invalid
}
other, err := version.NewVersion(versionStr)
if err != nil {
return Invalid
}
return Result(other.Compare(&v.Version))
}
// Acquire returns the latest version info wrapper.
// It calls the fetch.
func Acquire() (v Version) {
newVersion, changelogURL := fetch()
if newVersion == nil { // if github was down then don't panic, just set it as the smallest version.
newVersion, _ = version.NewVersion("0.0.1")
}
v = Version{
Version: *newVersion,
WrittenAt: time.Now(),
ChangelogURL: changelogURL,
}
return
}

View File

@ -105,7 +105,7 @@ func TestNumberEvaluatorRaw(t *testing.T) {
{true, "-18446744073709553213213213213213121615"}, // 5 {true, "-18446744073709553213213213213213121615"}, // 5
{false, "42 18446744073709551615"}, // 6 {false, "42 18446744073709551615"}, // 6
{false, "--42"}, // 7 {false, "--42"}, // 7
{false, "+42"}, // 9 {false, "+42"}, // 8
{false, "main.css"}, // 9 {false, "main.css"}, // 9
{false, "/assets/main.css"}, // 10 {false, "/assets/main.css"}, // 10
} }

View File

@ -84,8 +84,7 @@ func New(t *testing.T, app *iris.Application, setters ...OptionSetter) *httpexpe
setter.Set(conf) setter.Set(conf)
} }
// set the logger or disable it (default) and disable the updater (for any case). // set the logger or disable it (default).
app.Configure(iris.WithoutVersionChecker)
app.Logger().SetLevel(conf.LogLevel) app.Logger().SetLevel(conf.LogLevel)
if err := app.Build(); err != nil { if err := app.Build(); err != nil {

View File

@ -17,7 +17,6 @@ import (
// core packages, needed to build the application // core packages, needed to build the application
"github.com/kataras/iris/core/errors" "github.com/kataras/iris/core/errors"
"github.com/kataras/iris/core/host" "github.com/kataras/iris/core/host"
"github.com/kataras/iris/core/maintenance"
"github.com/kataras/iris/core/netutil" "github.com/kataras/iris/core/netutil"
"github.com/kataras/iris/core/router" "github.com/kataras/iris/core/router"
// handlerconv conversions // handlerconv conversions
@ -34,7 +33,7 @@ import (
var ( var (
// Version is the current version number of the Iris Web Framework. // Version is the current version number of the Iris Web Framework.
Version = maintenance.Version Version = "11.0.0"
) )
// HTTP status codes as registered with IANA. // HTTP status codes as registered with IANA.
@ -811,10 +810,6 @@ func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error {
app.Configure(withOrWithout...) app.Configure(withOrWithout...)
app.logger.Debugf("Application: running using %d host(s)", len(app.Hosts)+1) app.logger.Debugf("Application: running using %d host(s)", len(app.Hosts)+1)
if !app.config.DisableVersionChecker {
go maintenance.Start()
}
// this will block until an error(unless supervisor's DeferFlow called from a Task). // this will block until an error(unless supervisor's DeferFlow called from a Task).
err := serve(app) err := serve(app)
if err != nil { if err != nil {

View File

@ -6,7 +6,7 @@ import (
"runtime" "runtime"
"time" "time"
"github.com/coreos/bbolt" "github.com/etcd-io/bbolt"
"github.com/kataras/golog" "github.com/kataras/golog"
"github.com/kataras/iris/core/errors" "github.com/kataras/iris/core/errors"
"github.com/kataras/iris/sessions" "github.com/kataras/iris/sessions"
@ -25,7 +25,7 @@ type Database struct {
// Service is the underline BoltDB database connection, // Service is the underline BoltDB database connection,
// it's initialized at `New` or `NewFromDB`. // it's initialized at `New` or `NewFromDB`.
// Can be used to get stats. // Can be used to get stats.
Service *bolt.DB Service *bbolt.DB
} }
var errPathMissing = errors.New("path is required") var errPathMissing = errors.New("path is required")
@ -51,8 +51,8 @@ func New(path string, fileMode os.FileMode) (*Database, error) {
return nil, err return nil, err
} }
service, err := bolt.Open(path, fileMode, service, err := bbolt.Open(path, fileMode,
&bolt.Options{Timeout: 20 * time.Second}, &bbolt.Options{Timeout: 20 * time.Second},
) )
if err != nil { if err != nil {
@ -64,10 +64,10 @@ func New(path string, fileMode os.FileMode) (*Database, error) {
} }
// NewFromDB same as `New` but accepts an already-created custom boltdb connection instead. // NewFromDB same as `New` but accepts an already-created custom boltdb connection instead.
func NewFromDB(service *bolt.DB, bucketName string) (*Database, error) { func NewFromDB(service *bbolt.DB, bucketName string) (*Database, error) {
bucket := []byte(bucketName) bucket := []byte(bucketName)
service.Update(func(tx *bolt.Tx) (err error) { service.Update(func(tx *bbolt.Tx) (err error) {
_, err = tx.CreateBucketIfNotExists(bucket) _, err = tx.CreateBucketIfNotExists(bucket)
return return
}) })
@ -78,15 +78,15 @@ func NewFromDB(service *bolt.DB, bucketName string) (*Database, error) {
return db, db.cleanup() return db, db.cleanup()
} }
func (db *Database) getBucket(tx *bolt.Tx) *bolt.Bucket { func (db *Database) getBucket(tx *bbolt.Tx) *bbolt.Bucket {
return tx.Bucket(db.table) return tx.Bucket(db.table)
} }
func (db *Database) getBucketForSession(tx *bolt.Tx, sid string) *bolt.Bucket { func (db *Database) getBucketForSession(tx *bbolt.Tx, sid string) *bbolt.Bucket {
b := db.getBucket(tx).Bucket([]byte(sid)) b := db.getBucket(tx).Bucket([]byte(sid))
if b == nil { if b == nil {
// session does not exist, it shouldn't happen, session bucket creation happens once at `Acquire`, // session does not exist, it shouldn't happen, session bucket creation happens once at `Acquire`,
// no need to accept the `bolt.bucket.CreateBucketIfNotExists`'s performance cost. // no need to accept the `bbolt.bucket.CreateBucketIfNotExists`'s performance cost.
golog.Debugf("unreachable session access for '%s'", sid) golog.Debugf("unreachable session access for '%s'", sid)
} }
@ -105,7 +105,7 @@ func getExpirationBucketName(bsid []byte) []byte {
// Cleanup removes any invalid(have expired) session entries on initialization. // Cleanup removes any invalid(have expired) session entries on initialization.
func (db *Database) cleanup() error { func (db *Database) cleanup() error {
return db.Service.Update(func(tx *bolt.Tx) error { return db.Service.Update(func(tx *bbolt.Tx) error {
b := db.getBucket(tx) b := db.getBucket(tx)
c := b.Cursor() c := b.Cursor()
// loop through all buckets, find one with expiration. // loop through all buckets, find one with expiration.
@ -151,7 +151,7 @@ var expirationKey = []byte("exp") // it can be random.
// if the return value is LifeTime{} then the session manager sets the life time based on the expiration duration lives in configuration. // if the return value is LifeTime{} then the session manager sets the life time based on the expiration duration lives in configuration.
func (db *Database) Acquire(sid string, expires time.Duration) (lifetime sessions.LifeTime) { func (db *Database) Acquire(sid string, expires time.Duration) (lifetime sessions.LifeTime) {
bsid := []byte(sid) bsid := []byte(sid)
err := db.Service.Update(func(tx *bolt.Tx) (err error) { err := db.Service.Update(func(tx *bbolt.Tx) (err error) {
root := db.getBucket(tx) root := db.getBucket(tx)
if expires > 0 { // should check or create the expiration bucket. if expires > 0 { // should check or create the expiration bucket.
@ -218,7 +218,7 @@ func (db *Database) OnUpdateExpiration(sid string, newExpires time.Duration) err
return err return err
} }
err = db.Service.Update(func(tx *bolt.Tx) error { err = db.Service.Update(func(tx *bbolt.Tx) error {
expirationName := getExpirationBucketName([]byte(sid)) expirationName := getExpirationBucketName([]byte(sid))
root := db.getBucket(tx) root := db.getBucket(tx)
b := root.Bucket(expirationName) b := root.Bucket(expirationName)
@ -250,7 +250,7 @@ func (db *Database) Set(sid string, lifetime sessions.LifeTime, key string, valu
return return
} }
err = db.Service.Update(func(tx *bolt.Tx) error { err = db.Service.Update(func(tx *bbolt.Tx) error {
b := db.getBucketForSession(tx, sid) b := db.getBucketForSession(tx, sid)
if b == nil { if b == nil {
return nil return nil
@ -270,7 +270,7 @@ func (db *Database) Set(sid string, lifetime sessions.LifeTime, key string, valu
// Get retrieves a session value based on the key. // Get retrieves a session value based on the key.
func (db *Database) Get(sid string, key string) (value interface{}) { func (db *Database) Get(sid string, key string) (value interface{}) {
err := db.Service.View(func(tx *bolt.Tx) error { err := db.Service.View(func(tx *bbolt.Tx) error {
b := db.getBucketForSession(tx, sid) b := db.getBucketForSession(tx, sid)
if b == nil { if b == nil {
return nil return nil
@ -293,7 +293,7 @@ func (db *Database) Get(sid string, key string) (value interface{}) {
// Visit loops through all session keys and values. // Visit loops through all session keys and values.
func (db *Database) Visit(sid string, cb func(key string, value interface{})) { func (db *Database) Visit(sid string, cb func(key string, value interface{})) {
db.Service.View(func(tx *bolt.Tx) error { db.Service.View(func(tx *bbolt.Tx) error {
b := db.getBucketForSession(tx, sid) b := db.getBucketForSession(tx, sid)
if b == nil { if b == nil {
return nil return nil
@ -314,7 +314,7 @@ func (db *Database) Visit(sid string, cb func(key string, value interface{})) {
// Len returns the length of the session's entries (keys). // Len returns the length of the session's entries (keys).
func (db *Database) Len(sid string) (n int) { func (db *Database) Len(sid string) (n int) {
db.Service.View(func(tx *bolt.Tx) error { db.Service.View(func(tx *bbolt.Tx) error {
b := db.getBucketForSession(tx, sid) b := db.getBucketForSession(tx, sid)
if b == nil { if b == nil {
return nil return nil
@ -329,7 +329,7 @@ func (db *Database) Len(sid string) (n int) {
// Delete removes a session key value based on its key. // Delete removes a session key value based on its key.
func (db *Database) Delete(sid string, key string) (deleted bool) { func (db *Database) Delete(sid string, key string) (deleted bool) {
err := db.Service.Update(func(tx *bolt.Tx) error { err := db.Service.Update(func(tx *bbolt.Tx) error {
b := db.getBucketForSession(tx, sid) b := db.getBucketForSession(tx, sid)
if b == nil { if b == nil {
return sessions.ErrNotFound return sessions.ErrNotFound
@ -343,7 +343,7 @@ func (db *Database) Delete(sid string, key string) (deleted bool) {
// Clear removes all session key values but it keeps the session entry. // Clear removes all session key values but it keeps the session entry.
func (db *Database) Clear(sid string) { func (db *Database) Clear(sid string) {
db.Service.Update(func(tx *bolt.Tx) error { db.Service.Update(func(tx *bbolt.Tx) error {
b := db.getBucketForSession(tx, sid) b := db.getBucketForSession(tx, sid)
if b == nil { if b == nil {
return nil return nil
@ -358,7 +358,7 @@ func (db *Database) Clear(sid string) {
// Release destroys the session, it clears and removes the session entry, // Release destroys the session, it clears and removes the session entry,
// session manager will create a new session ID on the next request after this call. // session manager will create a new session ID on the next request after this call.
func (db *Database) Release(sid string) { func (db *Database) Release(sid string) {
db.Service.Update(func(tx *bolt.Tx) error { db.Service.Update(func(tx *bbolt.Tx) error {
// delete the session bucket. // delete the session bucket.
b := db.getBucket(tx) b := db.getBucket(tx)
bsid := []byte(sid) bsid := []byte(sid)