/*
Middleware generates a middleware handler function that works inside of a Gin request
to set the correct CORS headers.  It accepts a cors.Options struct for configuration.
*/
178418
func Middleware(config Config) gin.HandlerFunc {
	forceOriginMatch := false

	if config.Origins == "" {
		panic("You must set at least a single valid origin. If you don't want CORS, to apply, simply remove the middleware.")
	}

	if config.Origins == "*" {
		forceOriginMatch = true
	}

	config.prepare()

	// Create the Middleware function
	return func(context *gin.Context) {
		// Read the Origin header from the HTTP request
		currentOrigin := context.Request.Header.Get(OriginKey)
		context.Writer.Header().Add("Vary", OriginKey)

		// CORS headers are added whenever the browser request includes an "Origin" header
		// However, if no Origin is supplied, they should never be added.
		if currentOrigin == "" {
			return
		}

		originMatch := false
		if !forceOriginMatch {
			originMatch = matchOrigin(currentOrigin, config)
		}

		if forceOriginMatch || originMatch {
			valid := false
			preflight := false

			if context.Request.Method == optionsMethod {
				requestMethod := context.Request.Header.Get(RequestMethodKey)
				if requestMethod != "" {
					preflight = true
					valid = handlePreflight(context, config, requestMethod)
				}
			}

			if !preflight {
				valid = handleRequest(context, config)
			}

			if valid {

				if config.Credentials {
					context.Writer.Header().Set(AllowCredentialsKey, config.credentials)
					// Allowed origins cannot be the string "*" cannot be used for a resource that supports credentials.
					context.Writer.Header().Set(AllowOriginKey, currentOrigin)
				} else if forceOriginMatch {
					context.Writer.Header().Set(AllowOriginKey, "*")
				} else {
					context.Writer.Header().Set(AllowOriginKey, currentOrigin)
				}

				//If this is a preflight request, we are finished, quit.
				//Otherwise this is a normal request and operations should proceed at normal
				if preflight {
					context.AbortWithStatus(200)
				}
				return
			}
		}

		//If it reaches here, it was not a valid request
		context.Abort()
	}
}
1350464
func CorsHandler(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		jsonp := false
		if cbName := req.FormValue("callback"); cbName != "" && req.Method == "GET" {
			rw.Header().Set("Content-Type", "text/javascript")
			rw.Write([]byte(fmt.Sprintf("%v(", cbName)))
			jsonp = true
		} else {
			rw.Header().Set("Content-Type", "application/json")
			if origin := req.Header.Get("Origin"); origin != "" {
				rw.Header().Add("Access-Control-Allow-Origin", origin)
			}
			if methods := req.Header.Get("Access-Control-Request-Method"); methods != "" {
				rw.Header().Add("Access-Control-Allow-Methods", methods)
			}
			if headers := req.Header.Get("Access-Control-Request-Headers"); headers != "" {
				rw.Header().Add("Access-Control-Allow-Headers", headers)
			}
			rw.Header().Add("Access-Control-Allow-Credentials", "true")

			// If we're getting an OPTIONS request, just send response
			if req.Method == "OPTIONS" {
				rw.WriteHeader(http.StatusOK)
				return
			}
		}
		handler.ServeHTTP(rw, req)
		if jsonp {
			rw.Write([]byte(");"))
		}
	})
}
830838
func Middleware(level int, o ...Option) goa.Middleware {
	opts := options{
		ignoreRange:  true,
		minSize:      256,
		contentTypes: defaultContentTypes,
	}
	opts.statusCodes = make(map[int]struct{}, len(defaultStatusCodes))
	for _, v := range defaultStatusCodes {
		opts.statusCodes[v] = struct{}{}
	}
	for _, opt := range o {
		err := opt(&opts)
		if err != nil {
			panic(err)
		}
	}
	gzipPool := sync.Pool{
		New: func() interface{} {
			gz, err := gzip.NewWriterLevel(ioutil.Discard, level)
			if err != nil {
				panic(err)
			}
			return gz
		},
	}
	return func(h goa.Handler) goa.Handler {
		return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) (err error) {
			// Skip compression if the client doesn't accept gzip encoding, is
			// requesting a WebSocket or the data is already compressed.
			if !strings.Contains(req.Header.Get(headerAcceptEncoding), encodingGzip) ||
				len(req.Header.Get(headerSecWebSocketKey)) > 0 ||
				rw.Header().Get(headerContentEncoding) == encodingGzip ||
				(!opts.ignoreRange && req.Header.Get(headerRange) != "") {
				return h(ctx, rw, req)
			}

			// Set the appropriate gzip headers.
			resp := goa.ContextResponse(ctx)

			// Get the original http.ResponseWriter
			w := resp.SwitchWriter(nil)

			// Wrap the original http.ResponseWriter with our gzipResponseWriter
			grw := &gzipResponseWriter{
				ResponseWriter: w,
				pool:           &gzipPool,
				statusCode:     http.StatusOK,
				o:              opts,
			}

			// Set the new http.ResponseWriter
			resp.SwitchWriter(grw)

			// We cannot do ranges, if possibly gzipped responses.
			req.Header.Del("Range")

			// Call the next handler supplying the gzipResponseWriter instead of
			// the original.
			err = h(ctx, rw, req)
			if err != nil {
				return
			}

			// Check for uncompressed data
			if grw.buf.Len() > 0 {
				w.Header().Set(headerContentLength, strconv.Itoa(grw.buf.Len()))
				w.WriteHeader(grw.statusCode)
				_, err = w.Write(grw.buf.Bytes())
				return
			}

			// Flush compressor.
			if grw.gzw != nil {
				if err = grw.gzw.Close(); err != nil {
					return
				}
				gzipPool.Put(grw.gzw)
				return
			}
			// No writes, set status code.
			if grw.shouldCompress == nil {
				w.WriteHeader(grw.statusCode)
			}
			return
		}
	}
}
682805
func (s *ServeMux) MiddlewareFunc(path string, m MiddlewareFunc) *Route {
	return s.Route(path).MiddlewareFunc(m)
}
726897
func Middleware(d echo.Renderer) echo.MiddlewareFunc {
	return func(h echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			c.SetRenderer(d)
			return h.Handle(c)
		})
	}
}
1191564
func AddMiddleware(configuration *config.HTTPConfiguration, middlewareName string, middleware *config.Middleware) bool {
	if _, ok := configuration.Middlewares[middlewareName]; !ok {
		configuration.Middlewares[middlewareName] = middleware
		return true
	}

	return reflect.DeepEqual(configuration.Middlewares[middlewareName], middleware)
}
902198
func MiddlewareWithConfig(config Config) echo.MiddlewareFunc {
	// Defaults
	if config.Skipper == nil {
		config.Skipper = DefaultConfig.Skipper
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if config.Skipper(c) || config.CheckPermission(c) {
				return next(c)
			}

			return echo.ErrForbidden
		}
	}
}
234178
func WrapHandler(handler http.Handler) Middleware {
	return func(ctx *Context) error {
		handler.ServeHTTP(ctx.Res, ctx.Req)
		return nil
	}
}
562521
func (c corsWrapper) build() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		c.HandlerFunc(ctx.Writer, ctx.Request)
		if !c.optionPassthrough &&
			ctx.Request.Method == http.MethodOptions &&
			ctx.GetHeader("Access-Control-Request-Method") != "" {
			// Abort processing next Gin middlewares.
			ctx.AbortWithStatus(http.StatusOK)
		}
	}
}
263194
func handlerToMiddleware(m Handler) Middleware {
	return func(h Handler) Handler {
		return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
			if err := m(ctx, rw, req); err != nil {
				return err
			}
			return h(ctx, rw, req)
		}
	}
}
985271
func NewMiddleware(cfg Config) *Middleware {
	m := &Middleware{newGraph(cfg.Scope, cfg.Logger, cfg.ContextExtractor)}

	if lvl := cfg.SuccessLevel; lvl != nil {
		m.graph.succLevel = *lvl
	}
	if lvl := cfg.FailureLevel; lvl != nil {
		m.graph.failLevel = *lvl
	}
	if lvl := cfg.ApplicationErrorLevel; lvl != nil {
		m.graph.appErrLevel = *lvl
	}

	return m
}
240199
func (o *Options) Handler(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		initOnce.Do(func() {
			options = make(map[*http.Request]*Options)
			responded = make(map[*http.Request]bool)
		})
		mutex.Lock()
		options[r] = o
		mutex.Unlock()
		defer func() {
			mutex.Lock()
			delete(options, r)
			delete(responded, r)
			mutex.Unlock()
		}()
		handler.ServeHTTP(w, r)
	})
}
1027941
func (mw *Middleware) UseHandler(handler http.Handler) {
	x := func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
			handler.ServeHTTP(w, req)
			next.ServeHTTP(w, req)
		})
	}

	mw.Use(x)
}
838765
func (c CORSMiddleware) WrapHandler(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
		// If "api-cors-header" is not given, but "api-enable-cors" is true, we set cors to "*"
		// otherwise, all head values will be passed to HTTP handler
		corsHeaders := c.defaultHeaders
		if corsHeaders == "" {
			corsHeaders = "*"
		}

		logrus.Debugf("CORS header is enabled and set to: %s", corsHeaders)
		w.Header().Add("Access-Control-Allow-Origin", corsHeaders)
		w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth")
		w.Header().Add("Access-Control-Allow-Methods", "HEAD, GET, POST, DELETE, PUT, OPTIONS")
		return handler(ctx, w, r, vars)
	}
}
180945
func MiddlewareContentType(contentType string) Middleware {
	return func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
			// Content type
			handleContentType(contentType, rw)

			// Next handler
			h.ServeHTTP(rw, r)
		})
	}
}
352710
func HeaderHandler(headers ...string) func(*http.Request) map[string]interface{} {
	return func(req *http.Request) map[string]interface{} {
		result := map[string]interface{}{}
		for _, header := range headers {
			if val := req.Header.Get(header); val != "" {
				result[header] = val
			}
		}
		return result
	}
}
1044938
func (h HTTPConstructor) CreateMiddleware(next ContextHandler) ContextHandler {
	o := outerWrap{
		next: next,
	}
	outer := h(&o)
	return HandlerFunc(func(ctx context.Context, rw http.ResponseWriter, r *http.Request) {
		//		// TODO: A million dollars to who can figure out how to do this cleaner with the called
		//		//       function really owning this context while also not calling h() each time
		if o.ctx != nil {
			panic("I was never reset.  Logic error!")
		}
		o.ctx = ctx
		outer.ServeHTTP(rw, r)
		o.ctx = nil
	})
}