mirror of
https://github.com/kataras/iris.git
synced 2025-03-13 21:36:28 +01:00
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:
parent
6cf48df5c0
commit
f365be3c62
18
Gopkg.lock
generated
18
Gopkg.lock
generated
|
@ -277,6 +277,24 @@
|
|||
packages = ["."]
|
||||
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]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
|
|
14
Gopkg.toml
14
Gopkg.toml
|
@ -80,4 +80,16 @@
|
|||
|
||||
[[constraint]]
|
||||
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"
|
||||
|
|
65
HISTORY.md
65
HISTORY.md
|
@ -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.
|
||||
|
||||
# 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
|
||||
|
||||
I am overjoyed to announce stage 1 of the the Iris Web framework **10.7 stable release is now available**.
|
||||
|
|
|
@ -588,7 +588,6 @@ func main() {
|
|||
app.Run(
|
||||
iris.Addr(":8080"),
|
||||
iris.WithoutBanner,
|
||||
iris.WithoutVersionChecker,
|
||||
iris.WithoutServerError(iris.ErrServerClosed),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ func main() {
|
|||
|
||||
mvc.New(app).Handle(new(controllers.HomeController))
|
||||
|
||||
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
|
||||
app.Run(iris.Addr(":5000"))
|
||||
}
|
||||
|
||||
type err struct {
|
||||
|
|
|
@ -16,7 +16,7 @@ func main() {
|
|||
mvc.New(app.Party("/api/values/{id}")).
|
||||
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.
|
||||
|
|
|
@ -24,9 +24,7 @@ func main() {
|
|||
app.Delete("/del", delHandler)
|
||||
*/
|
||||
|
||||
// 24 August 2017: Iris has a built'n version updater but we don't need it
|
||||
// when benchmarking...
|
||||
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
|
||||
app.Run(iris.Addr(":5000"))
|
||||
}
|
||||
|
||||
// Set and Get
|
||||
|
|
|
@ -8,5 +8,5 @@ func main() {
|
|||
ctx.WriteString("value")
|
||||
})
|
||||
|
||||
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
|
||||
app.Run(iris.Addr(":5000"))
|
||||
}
|
||||
|
|
|
@ -50,8 +50,6 @@ func main() {
|
|||
app.Run(
|
||||
// Start the web server at localhost:8080
|
||||
iris.Addr("localhost:8080"),
|
||||
// disables updates:
|
||||
iris.WithoutVersionChecker,
|
||||
// skip err server closed when CTRL/CMD+C pressed:
|
||||
iris.WithoutServerError(iris.ErrServerClosed),
|
||||
// enables faster json serialization and more:
|
||||
|
|
|
@ -34,7 +34,6 @@ func main() {
|
|||
|
||||
app.Run(
|
||||
iris.Addr(":8080"),
|
||||
iris.WithoutVersionChecker,
|
||||
iris.WithoutServerError(iris.ErrServerClosed),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,5 @@ func main() {
|
|||
|
||||
// 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
|
||||
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed), iris.WithoutVersionChecker)
|
||||
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
|
||||
}
|
||||
|
|
|
@ -79,8 +79,6 @@ func main() {
|
|||
app.Run(
|
||||
// Starts the web server at localhost:8080
|
||||
iris.Addr("localhost:8080"),
|
||||
// Disables the updater.
|
||||
iris.WithoutVersionChecker,
|
||||
// Ignores err server closed log when CTRL/CMD+C pressed.
|
||||
iris.WithoutServerError(iris.ErrServerClosed),
|
||||
// Enables faster json serialization and more.
|
||||
|
|
|
@ -33,8 +33,6 @@ func main() {
|
|||
app.Run(
|
||||
// Start the web server at localhost:8080
|
||||
iris.Addr("localhost:8080"),
|
||||
// disables updates:
|
||||
iris.WithoutVersionChecker,
|
||||
// skip err server closed when CTRL/CMD+C pressed:
|
||||
iris.WithoutServerError(iris.ErrServerClosed),
|
||||
// enables faster json serialization and more:
|
||||
|
|
|
@ -68,5 +68,5 @@ func main() {
|
|||
// 3. refresh the page some times
|
||||
// 4. close the browser
|
||||
// 5. re-open the browser and re-play 2.
|
||||
app.Run(iris.Addr(":8080"), iris.WithoutVersionChecker)
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ func main() {
|
|||
}
|
||||
|
||||
// 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) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// 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
|
||||
// $ cd $GOPATH/src/github.com/kataras/iris/_examples/tutorial/url-shortener
|
||||
// $ go build
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"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
|
||||
|
@ -28,17 +28,17 @@ var (
|
|||
// 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.
|
||||
type DB struct {
|
||||
db *bolt.DB
|
||||
db *bbolt.DB
|
||||
}
|
||||
|
||||
var _ Store = &DB{}
|
||||
|
||||
// openDatabase open a new database connection
|
||||
// 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.
|
||||
// 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 {
|
||||
Panic(err)
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func openDatabase(stumb string) *bolt.DB {
|
|||
tableURLs,
|
||||
}
|
||||
|
||||
db.Update(func(tx *bolt.Tx) (err error) {
|
||||
db.Update(func(tx *bbolt.Tx) (err error) {
|
||||
for _, table := range tables {
|
||||
_, err = tx.CreateBucketIfNotExists(table)
|
||||
if err != nil {
|
||||
|
@ -73,7 +73,7 @@ func NewDB(stumb string) *DB {
|
|||
// Set sets a shorten url and its key
|
||||
// Note: Caller is responsible to generate a key.
|
||||
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)
|
||||
// Generate ID for the url
|
||||
// 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.
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ func (d *DB) Clear() error {
|
|||
// Returns an empty string if not found.
|
||||
func (d *DB) Get(key string) (value string) {
|
||||
keyB := []byte(key)
|
||||
d.db.Update(func(tx *bolt.Tx) error {
|
||||
d.db.Update(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket(tableURLs)
|
||||
if b == 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.
|
||||
func (d *DB) GetByValue(value string) (keys []string) {
|
||||
valueB := []byte(value)
|
||||
d.db.Update(func(tx *bolt.Tx) error {
|
||||
d.db.Update(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket(tableURLs)
|
||||
if b == nil {
|
||||
return nil
|
||||
|
@ -159,7 +159,7 @@ func (d *DB) GetByValue(value string) (keys []string) {
|
|||
|
||||
// Len returns all the "shorted" urls length
|
||||
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
|
||||
b := tx.Bucket(tableURLs)
|
||||
|
|
|
@ -530,7 +530,7 @@ func main() {
|
|||
todosApp.Handle(new(controllers.TodoController))
|
||||
|
||||
// start the web server at http://localhost:8080
|
||||
app.Run(iris.Addr(":8080"), iris.WithoutVersionChecker)
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -51,5 +51,5 @@ func main() {
|
|||
todosApp.Handle(new(controllers.TodoController))
|
||||
|
||||
// start the web server at http://localhost:8080
|
||||
app.Run(iris.Addr(":8080"), iris.WithoutVersionChecker)
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build go1.11beta3
|
||||
// +build go1.11
|
||||
|
||||
package main
|
||||
|
||||
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
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!")
|
||||
message := fmt.Sprintf("Hello, the current time is: %s", time.Now().String())
|
||||
js.Global().Get("document").Call("getElementById", "hello").Set("innerText", message)
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
/*
|
||||
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() {
|
||||
|
|
|
@ -222,14 +222,6 @@ var WithoutInterruptHandler = func(app *Application) {
|
|||
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.
|
||||
//
|
||||
// See `Configuration`.
|
||||
|
@ -388,11 +380,6 @@ type Configuration struct {
|
|||
// Defaults to false.
|
||||
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
|
||||
// for example, if /home/ path is requested but no handler for this Route found,
|
||||
// then the Router checks if /home handler exists, if yes,
|
||||
|
@ -677,10 +664,6 @@ func WithConfiguration(c Configuration) Configurator {
|
|||
main.DisableInterruptHandler = v
|
||||
}
|
||||
|
||||
if v := c.DisableVersionChecker; v {
|
||||
main.DisableVersionChecker = v
|
||||
}
|
||||
|
||||
if v := c.DisablePathCorrection; v {
|
||||
main.DisablePathCorrection = v
|
||||
}
|
||||
|
@ -758,7 +741,6 @@ func DefaultConfiguration() Configuration {
|
|||
return Configuration{
|
||||
DisableStartupLog: false,
|
||||
DisableInterruptHandler: false,
|
||||
DisableVersionChecker: false,
|
||||
DisablePathCorrection: false,
|
||||
EnablePathEscape: false,
|
||||
FireMethodNotAllowed: false,
|
||||
|
|
|
@ -77,13 +77,12 @@ func TestConfigurationOptions(t *testing.T) {
|
|||
func TestConfigurationOptionsDeep(t *testing.T) {
|
||||
charset := "MYCHARSET"
|
||||
|
||||
app := New().Configure(WithCharset(charset), WithoutBodyConsumptionOnUnmarshal, WithoutBanner, WithoutVersionChecker)
|
||||
app := New().Configure(WithCharset(charset), WithoutBodyConsumptionOnUnmarshal, WithoutBanner)
|
||||
|
||||
expected := DefaultConfiguration()
|
||||
expected.Charset = charset
|
||||
expected.DisableBodyConsumptionOnUnmarshal = true
|
||||
expected.DisableStartupLog = true
|
||||
expected.DisableVersionChecker = true
|
||||
|
||||
has := *app.config
|
||||
|
||||
|
@ -142,7 +141,6 @@ func TestConfigurationYAML(t *testing.T) {
|
|||
}()
|
||||
|
||||
yamlConfigurationContents := `
|
||||
DisableVersionChecker: true
|
||||
DisablePathCorrection: false
|
||||
EnablePathEscape: false
|
||||
FireMethodNotAllowed: true
|
||||
|
@ -165,10 +163,6 @@ Other:
|
|||
|
||||
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 {
|
||||
t.Fatalf("error on TestConfigurationYAML: Expected DisablePathCorrection %v but got %v", expected, c.DisablePathCorrection)
|
||||
}
|
||||
|
@ -241,7 +235,6 @@ func TestConfigurationTOML(t *testing.T) {
|
|||
}()
|
||||
|
||||
tomlConfigurationContents := `
|
||||
DisableVersionChecker = true
|
||||
EnablePathEscape = false
|
||||
FireMethodNotAllowed = true
|
||||
EnableOptimizations = true
|
||||
|
@ -265,10 +258,6 @@ Charset = "UTF-8"
|
|||
|
||||
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 {
|
||||
t.Fatalf("error on TestConfigurationTOML: Expected DisablePathCorrection %v but got %v", expected, c.DisablePathCorrection)
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ func TestProxy(t *testing.T) {
|
|||
t.Fatalf("%v while creating tcp4 listener for new tls local test listener", err)
|
||||
}
|
||||
// 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.GET("/").Expect().Status(iris.StatusOK).Body().Equal(expectedIndex)
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
package maintenance
|
||||
|
||||
// Start starts the maintenance process.
|
||||
func Start() {
|
||||
CheckForUpdates()
|
||||
}
|
|
@ -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.
|
||||
*/
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -105,7 +105,7 @@ func TestNumberEvaluatorRaw(t *testing.T) {
|
|||
{true, "-18446744073709553213213213213213121615"}, // 5
|
||||
{false, "42 18446744073709551615"}, // 6
|
||||
{false, "--42"}, // 7
|
||||
{false, "+42"}, // 9
|
||||
{false, "+42"}, // 8
|
||||
{false, "main.css"}, // 9
|
||||
{false, "/assets/main.css"}, // 10
|
||||
}
|
||||
|
|
|
@ -84,8 +84,7 @@ func New(t *testing.T, app *iris.Application, setters ...OptionSetter) *httpexpe
|
|||
setter.Set(conf)
|
||||
}
|
||||
|
||||
// set the logger or disable it (default) and disable the updater (for any case).
|
||||
app.Configure(iris.WithoutVersionChecker)
|
||||
// set the logger or disable it (default).
|
||||
app.Logger().SetLevel(conf.LogLevel)
|
||||
|
||||
if err := app.Build(); err != nil {
|
||||
|
|
7
iris.go
7
iris.go
|
@ -17,7 +17,6 @@ import (
|
|||
// core packages, needed to build the application
|
||||
"github.com/kataras/iris/core/errors"
|
||||
"github.com/kataras/iris/core/host"
|
||||
"github.com/kataras/iris/core/maintenance"
|
||||
"github.com/kataras/iris/core/netutil"
|
||||
"github.com/kataras/iris/core/router"
|
||||
// handlerconv conversions
|
||||
|
@ -34,7 +33,7 @@ import (
|
|||
|
||||
var (
|
||||
// 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.
|
||||
|
@ -811,10 +810,6 @@ func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error {
|
|||
app.Configure(withOrWithout...)
|
||||
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).
|
||||
err := serve(app)
|
||||
if err != nil {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/bbolt"
|
||||
"github.com/etcd-io/bbolt"
|
||||
"github.com/kataras/golog"
|
||||
"github.com/kataras/iris/core/errors"
|
||||
"github.com/kataras/iris/sessions"
|
||||
|
@ -25,7 +25,7 @@ type Database struct {
|
|||
// Service is the underline BoltDB database connection,
|
||||
// it's initialized at `New` or `NewFromDB`.
|
||||
// Can be used to get stats.
|
||||
Service *bolt.DB
|
||||
Service *bbolt.DB
|
||||
}
|
||||
|
||||
var errPathMissing = errors.New("path is required")
|
||||
|
@ -51,8 +51,8 @@ func New(path string, fileMode os.FileMode) (*Database, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
service, err := bolt.Open(path, fileMode,
|
||||
&bolt.Options{Timeout: 20 * time.Second},
|
||||
service, err := bbolt.Open(path, fileMode,
|
||||
&bbolt.Options{Timeout: 20 * time.Second},
|
||||
)
|
||||
|
||||
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.
|
||||
func NewFromDB(service *bolt.DB, bucketName string) (*Database, error) {
|
||||
func NewFromDB(service *bbolt.DB, bucketName string) (*Database, error) {
|
||||
bucket := []byte(bucketName)
|
||||
|
||||
service.Update(func(tx *bolt.Tx) (err error) {
|
||||
service.Update(func(tx *bbolt.Tx) (err error) {
|
||||
_, err = tx.CreateBucketIfNotExists(bucket)
|
||||
return
|
||||
})
|
||||
|
@ -78,15 +78,15 @@ func NewFromDB(service *bolt.DB, bucketName string) (*Database, error) {
|
|||
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)
|
||||
}
|
||||
|
||||
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))
|
||||
if b == nil {
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ func getExpirationBucketName(bsid []byte) []byte {
|
|||
|
||||
// Cleanup removes any invalid(have expired) session entries on initialization.
|
||||
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)
|
||||
c := b.Cursor()
|
||||
// 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.
|
||||
func (db *Database) Acquire(sid string, expires time.Duration) (lifetime sessions.LifeTime) {
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
err = db.Service.Update(func(tx *bolt.Tx) error {
|
||||
err = db.Service.Update(func(tx *bbolt.Tx) error {
|
||||
expirationName := getExpirationBucketName([]byte(sid))
|
||||
root := db.getBucket(tx)
|
||||
b := root.Bucket(expirationName)
|
||||
|
@ -250,7 +250,7 @@ func (db *Database) Set(sid string, lifetime sessions.LifeTime, key string, valu
|
|||
return
|
||||
}
|
||||
|
||||
err = db.Service.Update(func(tx *bolt.Tx) error {
|
||||
err = db.Service.Update(func(tx *bbolt.Tx) error {
|
||||
b := db.getBucketForSession(tx, sid)
|
||||
if b == 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.
|
||||
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)
|
||||
if b == 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.
|
||||
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)
|
||||
if b == 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).
|
||||
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)
|
||||
if b == 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.
|
||||
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)
|
||||
if b == nil {
|
||||
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.
|
||||
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)
|
||||
if b == nil {
|
||||
return nil
|
||||
|
@ -358,7 +358,7 @@ func (db *Database) Clear(sid string) {
|
|||
// 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.
|
||||
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.
|
||||
b := db.getBucket(tx)
|
||||
bsid := []byte(sid)
|
||||
|
|
Loading…
Reference in New Issue
Block a user