ToMiddleware converts CORSConfig to middleware or returns an error for invalid configuration
()
| 143 | |
| 144 | // ToMiddleware converts CORSConfig to middleware or returns an error for invalid configuration |
| 145 | func (config CORSConfig) ToMiddleware() (echo.MiddlewareFunc, error) { |
| 146 | // Defaults |
| 147 | if config.Skipper == nil { |
| 148 | config.Skipper = DefaultSkipper |
| 149 | } |
| 150 | hasCustomAllowMethods := true |
| 151 | if len(config.AllowMethods) == 0 { |
| 152 | hasCustomAllowMethods = false |
| 153 | config.AllowMethods = []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete} |
| 154 | } |
| 155 | |
| 156 | allowMethods := strings.Join(config.AllowMethods, ",") |
| 157 | allowHeaders := strings.Join(config.AllowHeaders, ",") |
| 158 | exposeHeaders := strings.Join(config.ExposeHeaders, ",") |
| 159 | |
| 160 | maxAge := "0" |
| 161 | if config.MaxAge > 0 { |
| 162 | maxAge = strconv.Itoa(config.MaxAge) |
| 163 | } |
| 164 | |
| 165 | allowOriginFunc := config.UnsafeAllowOriginFunc |
| 166 | if config.UnsafeAllowOriginFunc == nil { |
| 167 | if len(config.AllowOrigins) == 0 { |
| 168 | return nil, errors.New("at least one AllowOrigins is required or UnsafeAllowOriginFunc must be provided") |
| 169 | } |
| 170 | allowOriginFunc = config.defaultAllowOriginFunc |
| 171 | for _, origin := range config.AllowOrigins { |
| 172 | if origin == "*" { |
| 173 | if config.AllowCredentials { |
| 174 | return nil, fmt.Errorf("* as allowed origin and AllowCredentials=true is insecure and not allowed. Use custom UnsafeAllowOriginFunc") |
| 175 | } |
| 176 | allowOriginFunc = config.starAllowOriginFunc |
| 177 | break |
| 178 | } |
| 179 | if err := validateOrigin(origin, "allow origin"); err != nil { |
| 180 | return nil, err |
| 181 | } |
| 182 | } |
| 183 | config.AllowOrigins = append([]string(nil), config.AllowOrigins...) |
| 184 | } |
| 185 | |
| 186 | return func(next echo.HandlerFunc) echo.HandlerFunc { |
| 187 | return func(c *echo.Context) error { |
| 188 | if config.Skipper(c) { |
| 189 | return next(c) |
| 190 | } |
| 191 | |
| 192 | req := c.Request() |
| 193 | res := c.Response() |
| 194 | origin := req.Header.Get(echo.HeaderOrigin) |
| 195 | |
| 196 | res.Header().Add(echo.HeaderVary, echo.HeaderOrigin) |
| 197 | |
| 198 | // Preflight request is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method, |
| 199 | // Access-Control-Request-Headers, and the Origin header. See: https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request |
| 200 | // For simplicity we just consider method type and later `Origin` header. |
| 201 | preflight := req.Method == http.MethodOptions |
| 202 |