Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
0d0395aed3 | |||
51f0ef8b07 | |||
88488351b0 | |||
567de19169 | |||
e641d4ab82 | |||
1238974274 | |||
f894742c19 | |||
796e03648c | |||
5c9b3fa52c | |||
cf4846e6a6 | |||
69f558022a | |||
30e66044d0 | |||
bec00ec825 | |||
79e0d17cc9 | |||
da1a40b05a | |||
a22aeebf59 | |||
dbbc835584 | |||
d075cad469 | |||
3f5d6253cd | |||
57b7130fd8 |
@ -2,9 +2,10 @@ language: go
|
||||
sudo: false
|
||||
|
||||
go:
|
||||
- 1.5.4
|
||||
- 1.6.3
|
||||
- 1.7.3
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- tip
|
||||
|
||||
script:
|
||||
|
11
README.md
11
README.md
@ -4,8 +4,7 @@
|
||||
[](https://codecov.io/gh/gin-contrib/cors)
|
||||
[](https://goreportcard.com/report/github.com/gin-contrib/cors)
|
||||
[](https://godoc.org/github.com/gin-contrib/cors)
|
||||
[](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
[](https://gitter.im/gin-gonic/gin)
|
||||
|
||||
Gin middleware/handler to enable CORS support.
|
||||
|
||||
@ -16,13 +15,13 @@ Gin middleware/handler to enable CORS support.
|
||||
Download and install it:
|
||||
|
||||
```sh
|
||||
$ go get gopkg.in/gin-contrib/cors.v1
|
||||
$ go get github.com/gin-contrib/cors
|
||||
```
|
||||
|
||||
Import it in your code:
|
||||
|
||||
```go
|
||||
import "gopkg.in/gin-contrib/cors.v1"
|
||||
import "github.com/gin-contrib/cors"
|
||||
```
|
||||
|
||||
### Canonical example:
|
||||
@ -33,8 +32,8 @@ package main
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gopkg.in/gin-contrib/cors.v1"
|
||||
"gopkg.in/gin-gonic/gin.v1"
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -3,11 +3,12 @@ package cors
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/gin-gonic/gin.v1"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type cors struct {
|
||||
allowAllOrigins bool
|
||||
allowCredentials bool
|
||||
allowOriginFunc func(string) bool
|
||||
allowOrigins []string
|
||||
exposeHeaders []string
|
||||
@ -22,6 +23,7 @@ func newCors(config Config) *cors {
|
||||
return &cors{
|
||||
allowOriginFunc: config.AllowOriginFunc,
|
||||
allowAllOrigins: config.AllowAllOrigins,
|
||||
allowCredentials: config.AllowCredentials,
|
||||
allowOrigins: normalize(config.AllowOrigins),
|
||||
normalHeaders: generateNormalHeaders(config),
|
||||
preflightHeaders: generatePreflightHeaders(config),
|
||||
|
12
cors.go
12
cors.go
@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/gin-gonic/gin.v1"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Config represents all available options for the middleware.
|
||||
@ -14,7 +14,7 @@ type Config struct {
|
||||
|
||||
// AllowedOrigins is a list of origins a cross-domain request can be executed from.
|
||||
// If the special "*" value is present in the list, all origins will be allowed.
|
||||
// Default value is ["*"]
|
||||
// Default value is []
|
||||
AllowOrigins []string
|
||||
|
||||
// AllowOriginFunc is a custom function to validate the origin. It take the origin
|
||||
@ -28,8 +28,6 @@ type Config struct {
|
||||
|
||||
// AllowedHeaders is list of non simple headers the client is allowed to use with
|
||||
// cross-domain requests.
|
||||
// If the special "*" value is present in the list, all headers will be allowed.
|
||||
// Default value is [] but "Origin" is always appended to the list.
|
||||
AllowHeaders []string
|
||||
|
||||
// AllowCredentials indicates whether the request can include user credentials like
|
||||
@ -69,8 +67,8 @@ func (c Config) Validate() error {
|
||||
return errors.New("conflict settings: all origins disabled")
|
||||
}
|
||||
for _, origin := range c.AllowOrigins {
|
||||
if !strings.HasPrefix(origin, "http://") && !strings.HasPrefix(origin, "https://") {
|
||||
return errors.New("bad origin: origins must include http:// or https://")
|
||||
if origin != "*" && !strings.HasPrefix(origin, "http://") && !strings.HasPrefix(origin, "https://") {
|
||||
return errors.New("bad origin: origins must either be '*' or include http:// or https://")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -79,7 +77,7 @@ func (c Config) Validate() error {
|
||||
// DefaultConfig returns a generic default configuration mapped to localhost.
|
||||
func DefaultConfig() Config {
|
||||
return Config{
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "HEAD"},
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"},
|
||||
AllowHeaders: []string{"Origin", "Content-Length", "Content-Type"},
|
||||
AllowCredentials: false,
|
||||
MaxAge: 12 * time.Hour,
|
||||
|
56
cors_test.go
56
cors_test.go
@ -7,8 +7,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/gin-gonic/gin.v1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -217,7 +217,7 @@ func TestPassesAllowedOrigins(t *testing.T) {
|
||||
AllowMethods: []string{" GeT ", "get", "post", "PUT ", "Head", "POST"},
|
||||
AllowHeaders: []string{"Content-type", "timeStamp "},
|
||||
ExposeHeaders: []string{"Data", "x-User"},
|
||||
AllowCredentials: true,
|
||||
AllowCredentials: false,
|
||||
MaxAge: 12 * time.Hour,
|
||||
AllowOriginFunc: func(origin string) bool {
|
||||
return origin == "http://github.com"
|
||||
@ -226,37 +226,43 @@ func TestPassesAllowedOrigins(t *testing.T) {
|
||||
|
||||
// no CORS request, origin == ""
|
||||
w := performRequest(router, "GET", "")
|
||||
assert.Equal(t, w.Body.String(), "get")
|
||||
assert.Equal(t, "get", w.Body.String())
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Expose-Headers"))
|
||||
|
||||
// allowed CORS request
|
||||
w = performRequest(router, "GET", "http://google.com")
|
||||
assert.Equal(t, w.Body.String(), "get")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Origin"), "http://google.com")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Credentials"), "true")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Expose-Headers"), "Data,X-User")
|
||||
assert.Equal(t, "get", w.Body.String())
|
||||
assert.Equal(t, "http://google.com", w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Equal(t, "", w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
assert.Equal(t, "Data,X-User", w.Header().Get("Access-Control-Expose-Headers"))
|
||||
|
||||
w = performRequest(router, "GET", "http://github.com")
|
||||
assert.Equal(t, "get", w.Body.String())
|
||||
assert.Equal(t, "http://github.com", w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Equal(t, "", w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
assert.Equal(t, "Data,X-User", w.Header().Get("Access-Control-Expose-Headers"))
|
||||
|
||||
// deny CORS request
|
||||
w = performRequest(router, "GET", "https://google.com")
|
||||
assert.Equal(t, w.Code, 403)
|
||||
assert.Equal(t, 403, w.Code)
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Expose-Headers"))
|
||||
|
||||
// allowed CORS prefligh request
|
||||
w = performRequest(router, "OPTIONS", "http://github.com")
|
||||
assert.Equal(t, w.Code, 200)
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Origin"), "http://github.com")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Credentials"), "true")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Methods"), "GET,POST,PUT,HEAD")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Headers"), "Content-Type,Timestamp")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Max-Age"), "43200")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, "http://github.com", w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Equal(t, "", w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
assert.Equal(t, "GET,POST,PUT,HEAD", w.Header().Get("Access-Control-Allow-Methods"))
|
||||
assert.Equal(t, "Content-Type,Timestamp", w.Header().Get("Access-Control-Allow-Headers"))
|
||||
assert.Equal(t, "43200", w.Header().Get("Access-Control-Max-Age"))
|
||||
|
||||
// deny CORS prefligh request
|
||||
w = performRequest(router, "OPTIONS", "http://example.com")
|
||||
assert.Equal(t, w.Code, 403)
|
||||
assert.Equal(t, 403, w.Code)
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Methods"))
|
||||
@ -276,24 +282,26 @@ func TestPassesAllowedAllOrigins(t *testing.T) {
|
||||
|
||||
// no CORS request, origin == ""
|
||||
w := performRequest(router, "GET", "")
|
||||
assert.Equal(t, w.Body.String(), "get")
|
||||
assert.Equal(t, "get", w.Body.String())
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Expose-Headers"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
|
||||
// allowed CORS request
|
||||
w = performRequest(router, "POST", "example.com")
|
||||
assert.Equal(t, w.Body.String(), "post")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Origin"), "*")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Expose-Headers"), "Data2,X-User2")
|
||||
assert.Equal(t, "post", w.Body.String())
|
||||
assert.Equal(t, "*", w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Equal(t, "Data2,X-User2", w.Header().Get("Access-Control-Expose-Headers"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
assert.Equal(t, "*", w.Header().Get("Access-Control-Allow-Origin"))
|
||||
|
||||
// allowed CORS prefligh request
|
||||
w = performRequest(router, "OPTIONS", "https://facebook.com")
|
||||
assert.Equal(t, w.Code, 200)
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Origin"), "*")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Methods"), "PATCH,GET,POST")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Allow-Headers"), "Content-Type,Testheader")
|
||||
assert.Equal(t, w.Header().Get("Access-Control-Max-Age"), "36000")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, "*", w.Header().Get("Access-Control-Allow-Origin"))
|
||||
assert.Equal(t, "PATCH,GET,POST", w.Header().Get("Access-Control-Allow-Methods"))
|
||||
assert.Equal(t, "Content-Type,Testheader", w.Header().Get("Access-Control-Allow-Headers"))
|
||||
assert.Equal(t, "36000", w.Header().Get("Access-Control-Max-Age"))
|
||||
assert.Empty(t, w.Header().Get("Access-Control-Allow-Credentials"))
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package main
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gopkg.in/gin-contrib/cors.v1"
|
||||
"gopkg.in/gin-gonic/gin.v1"
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
Reference in New Issue
Block a user