Skip to content

Commit

Permalink
Merge 9f73bbb into 10727df
Browse files Browse the repository at this point in the history
  • Loading branch information
deadcheat committed Sep 5, 2018
2 parents 10727df + 9f73bbb commit 3ccba1f
Show file tree
Hide file tree
Showing 12 changed files with 591 additions and 182 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
@@ -1,7 +1,7 @@
language: go
go:
- 1.9
- "1.10"
- "1.11"
go_import_path: github.com/deadcheat/goacors
before_install:
- go get -v -u github.com/modocache/gover
Expand Down
26 changes: 26 additions & 0 deletions README.md
Expand Up @@ -20,3 +20,29 @@ a cors-header middleware for goa(https://github.com/goadesign/goa)
AllowMethods: []string{goacors.GET},
}))
```

# Intermediate Match Mode

Intermediate Match Mode is using match logic allow wildcard in host, like `*.example.com`.

```
NOTIFY
Note that using wild card is not correct for specification of CORS.
And this mode is not recommended for production use.
I implemented this for only testing.
```

## how to use Intermediate Match Mode
To use this mode, you can use goacors.WithConfig like below,

```
service.Use(goacors.WithConfig(service, &goacors.GoaCORSConfig{
AllowOrigins: []string{"http://example.com"},
AllowMethods: []string{goacors.GET},
DomainStrategy: goacors.AllowIntermediateMatch,
}))
```

`DomainStrategy` option is added for this. default is `goacors.AllowStrict` and you need to change this to `goacors.AllowIntermediateMatch`

133 changes: 6 additions & 127 deletions cors.go
@@ -1,85 +1,15 @@
package goacors

import (
"net/http"
"strconv"
"strings"

"context"

"github.com/goadesign/goa"
)

type (
// GoaCORSConfig CORSチェック用のConfig
GoaCORSConfig struct {
Skipper Skipper
AllowOrigins []string
AllowMethods []string
AllowHeaders []string
AllowCredentials bool
ExposeHeaders []string
MaxAge int
}
)

var (
// DefaultGoaCORSConfig is the default CORS middleware config.
DefaultGoaCORSConfig = GoaCORSConfig{
Skipper: defaultSkipper,
AllowOrigins: []string{"*"},
AllowMethods: []string{GET, HEAD, PUT, PATCH, POST, DELETE},
}
)

const (
// DELETE HTTP Methods
DELETE = "DELETE"
// GET HTTP Methods
GET = "GET"
// HEAD HTTP Methods
HEAD = "HEAD"
// OPTIONS HTTP Methods
OPTIONS = "OPTIONS"
// PATCH HTTP Methods
PATCH = "PATCH"
// POST HTTP Methods
POST = "POST"
// PUT HTTP Methods
PUT = "PUT"
)

const (
// HeaderVary "Vary"
HeaderVary = "Vary"
// HeaderOrigin "Origin"
HeaderOrigin = "Origin"
// HeaderAccessControlRequestMethod "Access-Control-Request-Method"
HeaderAccessControlRequestMethod = "Access-Control-Request-Method"
// HeaderAccessControlRequestHeaders "Access-Control-Request-Headers"
HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers"
// HeaderAccessControlAllowOrigin Access-Control-Allow-Origin"
HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin"
// HeaderAccessControlAllowMethods "Access-Control-Allow-Methods"
HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods"
// HeaderAccessControlAllowHeaders "Access-Control-Allow-Headers"
HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers"
// HeaderAccessControlAllowCredentials "Access-Control-Allow-Credentials"
HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
// HeaderAccessControlExposeHeaders "Access-Control-Expose-Headers"
HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers"
// HeaderAccessControlMaxAge "Access-Control-Max-Age"
HeaderAccessControlMaxAge = "Access-Control-Max-Age"
// HeaderContentType "Content-Type"
HeaderContentType = "Content-Type"
)

// New serviceとDefaultConfigを利用してCORSヘッダチェックを行う
// New return middleware implements checking cors with default config
func New(service *goa.Service) goa.Middleware {
return WithConfig(service, &DefaultGoaCORSConfig)
}

// WithConfig Configを用いてCORSヘッダチェックを行う
// WithConfig create middleware with configure for this
func WithConfig(service *goa.Service, conf *GoaCORSConfig) goa.Middleware {
if conf == nil {
conf = &DefaultGoaCORSConfig
Expand All @@ -93,60 +23,9 @@ func WithConfig(service *goa.Service, conf *GoaCORSConfig) goa.Middleware {
if len(conf.AllowMethods) == 0 {
conf.AllowMethods = DefaultGoaCORSConfig.AllowMethods
}
allowMethods := strings.Join(conf.AllowMethods, ",")
allowHeaders := strings.Join(conf.AllowHeaders, ",")
exposeHeaders := strings.Join(conf.ExposeHeaders, ",")
maxAge := strconv.Itoa(conf.MaxAge)
return func(h goa.Handler) goa.Handler {
return func(c context.Context, rw http.ResponseWriter, req *http.Request) error {
// Skipper
if conf.Skipper(c, rw, req) {
return h(c, rw, req)
}
origin := req.Header.Get(HeaderOrigin)
// Check allowed origins
allowedOrigin := ""
for _, o := range conf.AllowOrigins {
if o == "*" || o == origin {
allowedOrigin = o
break
}
}

// Simple request
if req.Method != OPTIONS {
rw.Header().Add(HeaderVary, HeaderOrigin)
rw.Header().Set(HeaderAccessControlAllowOrigin, allowedOrigin)
if conf.AllowCredentials {
rw.Header().Set(HeaderAccessControlAllowCredentials, "true")
}
if exposeHeaders != "" {
rw.Header().Set(HeaderAccessControlExposeHeaders, exposeHeaders)
}
return h(c, rw, req)
}
// Preflight request
rw.Header().Add(HeaderVary, HeaderOrigin)
rw.Header().Add(HeaderVary, HeaderAccessControlRequestMethod)
rw.Header().Add(HeaderVary, HeaderAccessControlRequestHeaders)
rw.Header().Set(HeaderAccessControlAllowOrigin, allowedOrigin)
rw.Header().Set(HeaderAccessControlAllowMethods, allowMethods)
if conf.AllowCredentials {
rw.Header().Set(HeaderAccessControlAllowCredentials, "true")
}
if allowHeaders != "" {
rw.Header().Set(HeaderAccessControlAllowHeaders, allowHeaders)
} else {
h := req.Header.Get(HeaderAccessControlRequestHeaders)
if h != "" {
rw.Header().Set(HeaderAccessControlAllowHeaders, h)
}
}

if conf.MaxAge > 0 {
rw.Header().Set(HeaderAccessControlMaxAge, maxAge)
}
return service.Send(c, http.StatusNoContent, http.StatusText(http.StatusNoContent))
}
if conf.DomainStrategy != AllowIntermediateMatch {
conf.DomainStrategy = AllowStrict
}
factory := NewFactory()
return factory.Produce(service, conf)
}

0 comments on commit 3ccba1f

Please sign in to comment.