diff --git a/Dockerfile.build b/Dockerfile.build
index 38d0be83..6c127b0e 100644
--- a/Dockerfile.build
+++ b/Dockerfile.build
@@ -1,4 +1,4 @@
-FROM golang:1.9-alpine
+FROM golang:1.9.3-alpine
RUN apk update && apk upgrade && apk add --no-cache bash git
RUN go get github.com/iris-contrib/cloud-native-go
diff --git a/README.md b/README.md
index fdaf6181..52bdccea 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://github.com/kataras/vscode-iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](_examples/) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
+[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](_examples/) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
Iris is a fast, simple yet fully featured and very efficient web framework for Go.
diff --git a/README_GR.md b/README_GR.md
index 8eb17c9b..fae98ae6 100644
--- a/README_GR.md
+++ b/README_GR.md
@@ -2,7 +2,7 @@
-[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://github.com/kataras/vscode-iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](_examples/) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
+[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](_examples/) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
Το Iris είναι ένα γρήγορο, απλό αλλά και πλήρως λειτουργικό και πολύ αποδοτικό web framework για τη Go.
diff --git a/README_RU.md b/README_RU.md
index 520cf0ca..f898d595 100644
--- a/README_RU.md
+++ b/README_RU.md
@@ -2,7 +2,7 @@
-[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://github.com/kataras/vscode-iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](_examples/) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
+[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](_examples/) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
Iris - это быстрая, простая, но полнофункциональная и очень эффективная веб-платформа для Go.
diff --git a/README_ZH.md b/README_ZH.md
index bd58ada6..aef23a95 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -2,7 +2,7 @@
-[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://github.com/kataras/vscode-iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](_examples/) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
+[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](_examples/) [![release](https://img.shields.io/badge/release%20-v10.0-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases)
Iris 是一款超快、简洁高效的 Go 语言 Web开发框架。
diff --git a/_examples/subdomains/www/main_test.go b/_examples/subdomains/www/main_test.go
index cd698384..db6c9421 100644
--- a/_examples/subdomains/www/main_test.go
+++ b/_examples/subdomains/www/main_test.go
@@ -47,7 +47,7 @@ func TestSubdomainWWW(t *testing.T) {
req := e.Request(test.method, test.path)
if subdomain := test.subdomain; subdomain != "" {
- req = req.WithURL("http://" + subdomain + "." + host)
+ req.WithURL("http://" + subdomain + "." + host)
}
req.Expect().
diff --git a/configuration.go b/configuration.go
index 4fb3f0ec..2d8e8cde 100644
--- a/configuration.go
+++ b/configuration.go
@@ -330,10 +330,16 @@ func WithPostMaxMemory(limit int64) Configurator {
// WithRemoteAddrHeader enables or adds a new or existing request header name
// that can be used to validate the client's real IP.
//
-// Existing values are:
-// "X-Real-Ip": false,
-// "X-Forwarded-For": false,
-// "CF-Connecting-IP": false
+// By-default no "X-" header is consired safe to be used for retrieving the
+// client's IP address, because those headers can manually change by
+// the client. But sometimes are useful e.g., when behind a proxy
+// you want to enable the "X-Forwarded-For" or when cloudflare
+// you want to enable the "CF-Connecting-IP", inneed you
+// can allow the `ctx.RemoteAddr()` to use any header
+// that the client may sent.
+//
+// Defaults to an empty map but an example usage is:
+// WithRemoteAddrHeader("X-Forwarded-For")
//
// Look `context.RemoteAddr()` for more.
func WithRemoteAddrHeader(headerName string) Configurator {
@@ -346,12 +352,12 @@ func WithRemoteAddrHeader(headerName string) Configurator {
}
// WithoutRemoteAddrHeader disables an existing request header name
-// that can be used to validate the client's real IP.
+// that can be used to validate and parse the client's real IP.
//
-// Existing values are:
-// "X-Real-Ip": false,
-// "X-Forwarded-For": false,
-// "CF-Connecting-IP": false
+//
+// Keep note that RemoteAddrHeaders is already defaults to an empty map
+// so you don't have to call this Configurator if you didn't
+// add allowed headers via configuration or via `WithRemoteAddrHeader` before.
//
// Look `context.RemoteAddr()` for more.
func WithoutRemoteAddrHeader(headerName string) Configurator {
@@ -511,13 +517,22 @@ type Configuration struct {
//
// Defaults to "iris.viewData"
ViewDataContextKey string `json:"viewDataContextKey,omitempty" yaml:"ViewDataContextKey" toml:"ViewDataContextKey"`
- // RemoteAddrHeaders returns the allowed request headers names
+ // RemoteAddrHeaders are the allowed request headers names
// that can be valid to parse the client's IP based on.
+ // By-default no "X-" header is consired safe to be used for retrieving the
+ // client's IP address, because those headers can manually change by
+ // the client. But sometimes are useful e.g., when behind a proxy
+ // you want to enable the "X-Forwarded-For" or when cloudflare
+ // you want to enable the "CF-Connecting-IP", inneed you
+ // can allow the `ctx.RemoteAddr()` to use any header
+ // that the client may sent.
//
- // Defaults to:
- // "X-Real-Ip": false,
- // "X-Forwarded-For": false,
- // "CF-Connecting-IP": false
+ // Defaults to an empty map but an example usage is:
+ // RemoteAddrHeaders {
+ // "X-Real-Ip": true,
+ // "X-Forwarded-For": true,
+ // "CF-Connecting-IP": true,
+ // }
//
// Look `context.RemoteAddr()` for more.
RemoteAddrHeaders map[string]bool `json:"remoteAddrHeaders,omitempty" yaml:"RemoteAddrHeaders" toml:"RemoteAddrHeaders"`
@@ -637,11 +652,20 @@ func (c Configuration) GetViewDataContextKey() string {
// GetRemoteAddrHeaders returns the allowed request headers names
// that can be valid to parse the client's IP based on.
+// By-default no "X-" header is consired safe to be used for retrieving the
+// client's IP address, because those headers can manually change by
+// the client. But sometimes are useful e.g., when behind a proxy
+// you want to enable the "X-Forwarded-For" or when cloudflare
+// you want to enable the "CF-Connecting-IP", inneed you
+// can allow the `ctx.RemoteAddr()` to use any header
+// that the client may sent.
//
-// Defaults to:
-// "X-Real-Ip": false,
-// "X-Forwarded-For": false,
-// "CF-Connecting-IP": false
+// Defaults to an empty map but an example usage is:
+// RemoteAddrHeaders {
+// "X-Real-Ip": true,
+// "X-Forwarded-For": true,
+// "CF-Connecting-IP": true,
+// }
//
// Look `context.RemoteAddr()` for more.
func (c Configuration) GetRemoteAddrHeaders() map[string]bool {
@@ -777,12 +801,8 @@ func DefaultConfiguration() Configuration {
TranslateLanguageContextKey: "iris.language",
ViewLayoutContextKey: "iris.viewLayout",
ViewDataContextKey: "iris.viewData",
- RemoteAddrHeaders: map[string]bool{
- "X-Real-Ip": false,
- "X-Forwarded-For": false,
- "CF-Connecting-IP": false,
- },
- EnableOptimizations: false,
- Other: make(map[string]interface{}),
+ RemoteAddrHeaders: make(map[string]bool),
+ EnableOptimizations: false,
+ Other: make(map[string]interface{}),
}
}
diff --git a/context/context.go b/context/context.go
index ed58bda7..494b18e5 100644
--- a/context/context.go
+++ b/context/context.go
@@ -1366,6 +1366,8 @@ func (ctx *context) IsWWW() bool {
return false
}
+const xForwardedForHeaderKey = "X-Forwarded-For"
+
// RemoteAddr tries to parse and return the real client's request IP.
//
// Based on allowed headers names that can be modified from Configuration.RemoteAddrHeaders.
@@ -1377,14 +1379,13 @@ func (ctx *context) IsWWW() bool {
// `Configuration.WithRemoteAddrHeader(...)`,
// `Configuration.WithoutRemoteAddrHeader(...)` for more.
func (ctx *context) RemoteAddr() string {
-
remoteHeaders := ctx.Application().ConfigurationReadOnly().GetRemoteAddrHeaders()
for headerName, enabled := range remoteHeaders {
if enabled {
headerValue := ctx.GetHeader(headerName)
// exception needed for 'X-Forwarded-For' only , if enabled.
- if headerName == "X-Forwarded-For" {
+ if headerName == xForwardedForHeaderKey {
idx := strings.IndexByte(headerValue, ',')
if idx >= 0 {
headerValue = headerValue[0:idx]