diff --git a/go.mod b/go.mod
index e9a264fdfdf18..37dad70e491d1 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,6 @@ require (
 	gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b
 	gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b
 	gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca
-	gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4
 	gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439
 	gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5
 	gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60
@@ -40,6 +39,7 @@ require (
 	github.com/gliderlabs/ssh v0.3.1
 	github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a // indirect
 	github.com/go-chi/chi v1.5.0
+	github.com/go-chi/cors v1.1.1
 	github.com/go-enry/go-enry/v2 v2.5.2
 	github.com/go-git/go-billy/v5 v5.0.0
 	github.com/go-git/go-git/v5 v5.2.0
diff --git a/go.sum b/go.sum
index c169da1c76157..60d9fd696c6e1 100644
--- a/go.sum
+++ b/go.sum
@@ -54,8 +54,6 @@ gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b h1:2ZE0JE3bKVBcP1VTrW
 gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b/go.mod h1:W5hKG8T1GBfypp5CRQlgoJU4figIL0jhx02y4XA/NOA=
 gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca h1:f5P41nXmXd/YOh8f6098Q0F1Y0QfpyRPSSIkni2XH4Q=
 gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca/go.mod h1:J5h3N+1nKTXtU1x4GxexaQKgAz8UiWecNwi/CfX7CtQ=
-gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4 h1:e2rAFDejB0qN8OrY4xP4XSu8/yT6QmWxDZpB3J7r2GU=
-gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4/go.mod h1:rtOK4J20kpMD9XcNsnO5YA843YSTe/MUMbDj/TJ/Q7A=
 gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439 h1:88c34YM29a1GlWLrLBaG/GTT2htDdJz1u3n9+lmPolg=
 gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439/go.mod h1:IsQPHx73HnnqFBYiVHjg87q4XBZyGXXu77xANukvZuk=
 gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5 h1:6rbhThlqfOb+sSmhrsVFz3bZoAeoloe7TZqyeiPbbWI=
@@ -65,7 +63,6 @@ gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60/go.mod h1:g5ope1b+iWhB
 gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
 gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a h1:aOKEXkDTnh4euoH0so/THLXeHtQuqHmDPb1xEk6Ehok=
 gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
-gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827/go.mod h1:/rvxMjIkOq4BM8uPUb+VHuU02ZfAO6R4+wD//tiCiRw=
 gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
 gitea.com/macaron/macaron v1.5.0 h1:TvWEcHw1/zaHlo0GTuKEukLh3A99+QsU2mjBrXLXjVQ=
 gitea.com/macaron/macaron v1.5.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY=
@@ -102,7 +99,6 @@ github.com/RoaringBitmap/roaring v0.5.5 h1:naNqvO1mNnghk2UvcsqnzHDBn9DRbCIRy94Gm
 github.com/RoaringBitmap/roaring v0.5.5/go.mod h1:puNo5VdzwbaIQxSiDIwfXl4Hnc+fbovcX4IW/dSTtUk=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
-github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68=
 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
 github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
@@ -326,6 +322,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us
 github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
 github.com/go-chi/chi v1.5.0 h1:2ZcJZozJ+rj6BA0c19ffBUGXEKAT/aOLOtQjD46vBRA=
 github.com/go-chi/chi v1.5.0/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k=
+github.com/go-chi/cors v1.1.1 h1:eHuqxsIw89iXcWnWUN8R72JMibABJTN/4IOYI5WERvw=
+github.com/go-chi/cors v1.1.1/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I=
 github.com/go-enry/go-enry/v2 v2.5.2 h1:3f3PFAO6JitWkPi1GQ5/m6Xu4gNL1U5soJ8QaYqJ0YQ=
 github.com/go-enry/go-enry/v2 v2.5.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
 github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
diff --git a/routers/routes/chi.go b/routers/routes/chi.go
index 5ff7a728ff1ba..949cf30d17178 100644
--- a/routers/routes/chi.go
+++ b/routers/routes/chi.go
@@ -26,6 +26,7 @@ import (
 
 	"github.com/go-chi/chi"
 	"github.com/go-chi/chi/middleware"
+	"github.com/go-chi/cors"
 	"github.com/prometheus/client_golang/prometheus"
 )
 
@@ -207,6 +208,15 @@ func NewChi() chi.Router {
 		setupAccessLogger(c)
 	}
 
+	if setting.CORSConfig.Enabled {
+		c.Use(cors.Handler(cors.Options{
+			AllowedOrigins:   setting.CORSConfig.AllowDomain,
+			AllowedMethods:   setting.CORSConfig.Methods,
+			AllowCredentials: setting.CORSConfig.AllowCredentials,
+			MaxAge:           int(setting.CORSConfig.MaxAge.Seconds()),
+		}))
+	}
+
 	c.Use(public.Custom(
 		&public.Options{
 			SkipLogging: setting.DisableRouterLog,
diff --git a/routers/routes/macaron.go b/routers/routes/macaron.go
index 170bc7d493dff..2a9fd6ee29f49 100644
--- a/routers/routes/macaron.go
+++ b/routers/routes/macaron.go
@@ -36,7 +36,6 @@ import (
 	"gitea.com/macaron/binding"
 	"gitea.com/macaron/cache"
 	"gitea.com/macaron/captcha"
-	"gitea.com/macaron/cors"
 	"gitea.com/macaron/csrf"
 	"gitea.com/macaron/gzip"
 	"gitea.com/macaron/i18n"
@@ -957,16 +956,6 @@ func RegisterMacaronRoutes(m *macaron.Macaron) {
 	}
 
 	var handlers []macaron.Handler
-	if setting.CORSConfig.Enabled {
-		handlers = append(handlers, cors.CORS(cors.Options{
-			Scheme:           setting.CORSConfig.Scheme,
-			AllowDomain:      setting.CORSConfig.AllowDomain,
-			AllowSubdomain:   setting.CORSConfig.AllowSubdomain,
-			Methods:          setting.CORSConfig.Methods,
-			MaxAgeSeconds:    int(setting.CORSConfig.MaxAge.Seconds()),
-			AllowCredentials: setting.CORSConfig.AllowCredentials,
-		}))
-	}
 	handlers = append(handlers, ignSignIn)
 	m.Group("/api", func() {
 		apiv1.RegisterRoutes(m)
diff --git a/vendor/gitea.com/macaron/cors/.drone.yml b/vendor/gitea.com/macaron/cors/.drone.yml
deleted file mode 100644
index 39499f444a57d..0000000000000
--- a/vendor/gitea.com/macaron/cors/.drone.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-kind: pipeline
-name: default
-
-steps:
-- name: test
-  image: golang:1.11
-  commands:
-  - go build -v
-  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
diff --git a/vendor/gitea.com/macaron/cors/.gitignore b/vendor/gitea.com/macaron/cors/.gitignore
deleted file mode 100644
index f1c181ec9c5c9..0000000000000
--- a/vendor/gitea.com/macaron/cors/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-# Binaries for programs and plugins
-*.exe
-*.exe~
-*.dll
-*.so
-*.dylib
-
-# Test binary, build with `go test -c`
-*.test
-
-# Output of the go coverage tool, specifically when used with LiteIDE
-*.out
diff --git a/vendor/gitea.com/macaron/cors/LICENSE b/vendor/gitea.com/macaron/cors/LICENSE
deleted file mode 100644
index 261eeb9e9f8b2..0000000000000
--- a/vendor/gitea.com/macaron/cors/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/gitea.com/macaron/cors/README.md b/vendor/gitea.com/macaron/cors/README.md
deleted file mode 100644
index 5ef70e3579f69..0000000000000
--- a/vendor/gitea.com/macaron/cors/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# cors
-
-[![Build Status](https://drone.gitea.com/api/badges/macaron/cors/status.svg)](https://drone.gitea.com/macaron/cors)
-
-Package cors is a middleware that handles CORS requests & headers for Macaron.
diff --git a/vendor/gitea.com/macaron/cors/cors.go b/vendor/gitea.com/macaron/cors/cors.go
deleted file mode 100644
index 2d0613f2bc283..0000000000000
--- a/vendor/gitea.com/macaron/cors/cors.go
+++ /dev/null
@@ -1,169 +0,0 @@
-package cors
-
-import (
-	"fmt"
-	"log"
-	"net/http"
-	"net/url"
-	"strconv"
-	"strings"
-
-	macaron "gitea.com/macaron/macaron"
-)
-
-const version = "0.1.1"
-
-const anyDomain = "!*"
-
-// Version returns the version of this module
-func Version() string {
-	return version
-}
-
-/*
-Options to configure the CORS middleware read from the [cors] section of the ini configuration file.
-
-SCHEME may be http or https as accepted schemes or the '*' wildcard to accept any scheme.
-
-ALLOW_DOMAIN may be a comma separated list of domains that are allowed to run CORS requests
-Special values are the  a single '*' wildcard that will allow any domain to send requests without
-credentials and the special '!*' wildcard which will reply with requesting domain in the 'access-control-allow-origin'
-header and hence allow requess from any domain *with* credentials.
-
-ALLOW_SUBDOMAIN set to true accepts requests from any subdomain of ALLOW_DOMAIN.
-
-METHODS may be a comma separated list of HTTP-methods to be accepted.
-
-MAX_AGE_SECONDS may be the duration in secs for which the response is cached (default 600).
-ref: https://stackoverflow.com/questions/54300997/is-it-possible-to-cache-http-options-response?noredirect=1#comment95790277_54300997
-ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
-
-ALLOW_CREDENTIALS set to false rejects any request with credentials.
-*/
-type Options struct {
-	Section          string
-	Scheme           string
-	AllowDomain      []string
-	AllowSubdomain   bool
-	Methods          []string
-	MaxAgeSeconds    int
-	AllowCredentials bool
-}
-
-func prepareOptions(options []Options) Options {
-	var opt Options
-	if len(options) > 0 {
-		opt = options[0]
-	}
-
-	if len(opt.Section) == 0 {
-		opt.Section = "cors"
-	}
-	sec := macaron.Config().Section(opt.Section)
-
-	if len(opt.Scheme) == 0 {
-		opt.Scheme = sec.Key("SCHEME").MustString("http")
-	}
-	if len(opt.AllowDomain) == 0 {
-		opt.AllowDomain = sec.Key("ALLOW_DOMAIN").Strings(",")
-		if len(opt.AllowDomain) == 0 {
-			opt.AllowDomain = []string{"*"}
-		}
-	}
-	if !opt.AllowSubdomain {
-		opt.AllowSubdomain = sec.Key("ALLOW_SUBDOMAIN").MustBool(false)
-	}
-	if len(opt.Methods) == 0 {
-		opt.Methods = sec.Key("METHODS").Strings(",")
-		if len(opt.Methods) == 0 {
-			opt.Methods = []string{
-				http.MethodGet,
-				http.MethodHead,
-				http.MethodPost,
-				http.MethodPut,
-				http.MethodPatch,
-				http.MethodDelete,
-				http.MethodOptions,
-			}
-		}
-	}
-	if opt.MaxAgeSeconds <= 0 {
-		opt.MaxAgeSeconds = sec.Key("MAX_AGE_SECONDS").MustInt(600)
-	}
-	if !opt.AllowCredentials {
-		opt.AllowCredentials = sec.Key("ALLOW_CREDENTIALS").MustBool(true)
-	}
-
-	return opt
-}
-
-// CORS responds to preflight requests with adequat access-control-* respond headers
-// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
-// https://fetch.spec.whatwg.org/#cors-protocol-and-credentials
-func CORS(options ...Options) macaron.Handler {
-	opt := prepareOptions(options)
-	return func(ctx *macaron.Context, log *log.Logger) {
-		reqOptions := ctx.Req.Method == http.MethodOptions
-
-		headers := map[string]string{
-			"access-control-allow-methods": strings.Join(opt.Methods, ","),
-			"access-control-allow-headers": ctx.Req.Header.Get("access-control-request-headers"),
-			"access-control-max-age":       strconv.Itoa(opt.MaxAgeSeconds),
-		}
-		if opt.AllowDomain[0] == "*" {
-			headers["access-control-allow-origin"] = "*"
-		} else {
-			origin := ctx.Req.Header.Get("Origin")
-			if reqOptions && origin == "" {
-				respErrorf(ctx, log, http.StatusBadRequest, "missing origin header in CORS request")
-				return
-			}
-
-			u, err := url.Parse(origin)
-			if err != nil {
-				respErrorf(ctx, log, http.StatusBadRequest, "Failed to parse CORS origin header. Reason: %v", err)
-				return
-			}
-
-			ok := false
-			for _, d := range opt.AllowDomain {
-				if u.Hostname() == d || (opt.AllowSubdomain && strings.HasSuffix(u.Hostname(), "."+d)) || d == anyDomain {
-					ok = true
-					break
-				}
-			}
-			if ok {
-				if opt.Scheme != "*" {
-					u.Scheme = opt.Scheme
-				}
-				headers["access-control-allow-origin"] = u.String()
-				headers["access-control-allow-credentials"] = strconv.FormatBool(opt.AllowCredentials)
-				headers["vary"] = "Origin"
-			}
-			if reqOptions && !ok {
-				respErrorf(ctx, log, http.StatusBadRequest, "CORS request from prohibited domain %v", origin)
-				return
-			}
-		}
-		ctx.Resp.Before(func(w macaron.ResponseWriter) {
-			for k, v := range headers {
-				w.Header().Set(k, v)
-			}
-		})
-		if reqOptions {
-			ctx.Resp.WriteHeader(200) // return response
-			return
-		}
-	}
-}
-
-func respErrorf(ctx *macaron.Context, log *log.Logger, statusCode int, format string, a ...interface{}) {
-	msg := fmt.Sprintf(format, a...)
-	log.Println(msg)
-	ctx.WriteHeader(statusCode)
-	_, err := ctx.Write([]byte(msg))
-	if err != nil {
-		panic(err)
-	}
-	return
-}
diff --git a/vendor/gitea.com/macaron/cors/go.mod b/vendor/gitea.com/macaron/cors/go.mod
deleted file mode 100644
index 418aab88de2aa..0000000000000
--- a/vendor/gitea.com/macaron/cors/go.mod
+++ /dev/null
@@ -1,5 +0,0 @@
-module gitea.com/macaron/cors
-
-go 1.11
-
-require gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827
diff --git a/vendor/gitea.com/macaron/cors/go.sum b/vendor/gitea.com/macaron/cors/go.sum
deleted file mode 100644
index e3bcd933dc96f..0000000000000
--- a/vendor/gitea.com/macaron/cors/go.sum
+++ /dev/null
@@ -1,31 +0,0 @@
-gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
-gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
-gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827 h1:/rT4MEFjhdViy2BFWKUwbC0JSNSziEbBCM7q4/B9qgo=
-gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827/go.mod h1:/rvxMjIkOq4BM8uPUb+VHuU02ZfAO6R4+wD//tiCiRw=
-github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg=
-github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
-github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE=
-github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
-github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w=
-github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
-github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
-github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
-gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/vendor/github.com/go-chi/cors/LICENSE b/vendor/github.com/go-chi/cors/LICENSE
new file mode 100644
index 0000000000000..aee6182f9ac7f
--- /dev/null
+++ b/vendor/github.com/go-chi/cors/LICENSE
@@ -0,0 +1,21 @@
+Copyright (c) 2014 Olivier Poitrey <rs@dailymotion.com>
+Copyright (c) 2016-Present https://github.com/go-chi authors
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/go-chi/cors/README.md b/vendor/github.com/go-chi/cors/README.md
new file mode 100644
index 0000000000000..1cd6b7f11e14f
--- /dev/null
+++ b/vendor/github.com/go-chi/cors/README.md
@@ -0,0 +1,39 @@
+# CORS net/http middleware
+
+[go-chi/cors](https://github.com/go-chi/cors) is a fork of [github.com/rs/cors](https://github.com/rs/cors) that
+provides a `net/http` compatible middleware for performing preflight CORS checks on the server side. These headers
+are required for using the browser native [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
+
+This middleware is designed to be used as a top-level middleware on the [chi](https://github.com/go-chi/chi) router.
+Applying with within a `r.Group()` or using `With()` will not work without routes matching `OPTIONS` added.
+
+## Usage
+
+```go
+func main() {
+  r := chi.NewRouter()
+
+  // Basic CORS
+  // for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing
+  r.Use(cors.Handler(cors.Options{
+    // AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
+    AllowedOrigins:   []string{"*"},
+    // AllowOriginFunc:  func(r *http.Request, origin string) bool { return true },
+    AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
+    AllowedHeaders:   []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
+    ExposedHeaders:   []string{"Link"},
+    AllowCredentials: false,
+    MaxAge:           300, // Maximum value not ignored by any of major browsers
+  }))
+
+  r.Get("/", func(w http.ResponseWriter, r *http.Request) {
+    w.Write([]byte("welcome"))
+  })
+
+  http.ListenAndServe(":3000", r)
+}
+```
+
+## Credits
+
+All credit for the original work of this middleware goes out to [github.com/rs](github.com/rs).
diff --git a/vendor/github.com/go-chi/cors/cors.go b/vendor/github.com/go-chi/cors/cors.go
new file mode 100644
index 0000000000000..8df81636e3ba6
--- /dev/null
+++ b/vendor/github.com/go-chi/cors/cors.go
@@ -0,0 +1,400 @@
+// cors package is net/http handler to handle CORS related requests
+// as defined by http://www.w3.org/TR/cors/
+//
+// You can configure it by passing an option struct to cors.New:
+//
+//     c := cors.New(cors.Options{
+//         AllowedOrigins: []string{"foo.com"},
+//         AllowedMethods: []string{"GET", "POST", "DELETE"},
+//         AllowCredentials: true,
+//     })
+//
+// Then insert the handler in the chain:
+//
+//     handler = c.Handler(handler)
+//
+// See Options documentation for more options.
+//
+// The resulting handler is a standard net/http handler.
+package cors
+
+import (
+	"log"
+	"net/http"
+	"os"
+	"strconv"
+	"strings"
+)
+
+// Options is a configuration container to setup the CORS middleware.
+type Options 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.
+	// An origin may contain a wildcard (*) to replace 0 or more characters
+	// (i.e.: http://*.domain.com). Usage of wildcards implies a small performance penalty.
+	// Only one wildcard can be used per origin.
+	// Default value is ["*"]
+	AllowedOrigins []string
+
+	// AllowOriginFunc is a custom function to validate the origin. It takes the origin
+	// as argument and returns true if allowed or false otherwise. If this option is
+	// set, the content of AllowedOrigins is ignored.
+	AllowOriginFunc func(r *http.Request, origin string) bool
+
+	// AllowedMethods is a list of methods the client is allowed to use with
+	// cross-domain requests. Default value is simple methods (HEAD, GET and POST).
+	AllowedMethods []string
+
+	// 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.
+	AllowedHeaders []string
+
+	// ExposedHeaders indicates which headers are safe to expose to the API of a CORS
+	// API specification
+	ExposedHeaders []string
+
+	// AllowCredentials indicates whether the request can include user credentials like
+	// cookies, HTTP authentication or client side SSL certificates.
+	AllowCredentials bool
+
+	// MaxAge indicates how long (in seconds) the results of a preflight request
+	// can be cached
+	MaxAge int
+
+	// OptionsPassthrough instructs preflight to let other potential next handlers to
+	// process the OPTIONS method. Turn this on if your application handles OPTIONS.
+	OptionsPassthrough bool
+
+	// Debugging flag adds additional output to debug server side CORS issues
+	Debug bool
+}
+
+// Logger generic interface for logger
+type Logger interface {
+	Printf(string, ...interface{})
+}
+
+// Cors http handler
+type Cors struct {
+	// Debug logger
+	Log Logger
+
+	// Normalized list of plain allowed origins
+	allowedOrigins []string
+
+	// List of allowed origins containing wildcards
+	allowedWOrigins []wildcard
+
+	// Optional origin validator function
+	allowOriginFunc func(r *http.Request, origin string) bool
+
+	// Normalized list of allowed headers
+	allowedHeaders []string
+
+	// Normalized list of allowed methods
+	allowedMethods []string
+
+	// Normalized list of exposed headers
+	exposedHeaders []string
+	maxAge         int
+
+	// Set to true when allowed origins contains a "*"
+	allowedOriginsAll bool
+
+	// Set to true when allowed headers contains a "*"
+	allowedHeadersAll bool
+
+	allowCredentials  bool
+	optionPassthrough bool
+}
+
+// New creates a new Cors handler with the provided options.
+func New(options Options) *Cors {
+	c := &Cors{
+		exposedHeaders:    convert(options.ExposedHeaders, http.CanonicalHeaderKey),
+		allowOriginFunc:   options.AllowOriginFunc,
+		allowCredentials:  options.AllowCredentials,
+		maxAge:            options.MaxAge,
+		optionPassthrough: options.OptionsPassthrough,
+	}
+	if options.Debug && c.Log == nil {
+		c.Log = log.New(os.Stdout, "[cors] ", log.LstdFlags)
+	}
+
+	// Normalize options
+	// Note: for origins and methods matching, the spec requires a case-sensitive matching.
+	// As it may error prone, we chose to ignore the spec here.
+
+	// Allowed Origins
+	if len(options.AllowedOrigins) == 0 {
+		if options.AllowOriginFunc == nil {
+			// Default is all origins
+			c.allowedOriginsAll = true
+		}
+	} else {
+		c.allowedOrigins = []string{}
+		c.allowedWOrigins = []wildcard{}
+		for _, origin := range options.AllowedOrigins {
+			// Normalize
+			origin = strings.ToLower(origin)
+			if origin == "*" {
+				// If "*" is present in the list, turn the whole list into a match all
+				c.allowedOriginsAll = true
+				c.allowedOrigins = nil
+				c.allowedWOrigins = nil
+				break
+			} else if i := strings.IndexByte(origin, '*'); i >= 0 {
+				// Split the origin in two: start and end string without the *
+				w := wildcard{origin[0:i], origin[i+1:]}
+				c.allowedWOrigins = append(c.allowedWOrigins, w)
+			} else {
+				c.allowedOrigins = append(c.allowedOrigins, origin)
+			}
+		}
+	}
+
+	// Allowed Headers
+	if len(options.AllowedHeaders) == 0 {
+		// Use sensible defaults
+		c.allowedHeaders = []string{"Origin", "Accept", "Content-Type"}
+	} else {
+		// Origin is always appended as some browsers will always request for this header at preflight
+		c.allowedHeaders = convert(append(options.AllowedHeaders, "Origin"), http.CanonicalHeaderKey)
+		for _, h := range options.AllowedHeaders {
+			if h == "*" {
+				c.allowedHeadersAll = true
+				c.allowedHeaders = nil
+				break
+			}
+		}
+	}
+
+	// Allowed Methods
+	if len(options.AllowedMethods) == 0 {
+		// Default is spec's "simple" methods
+		c.allowedMethods = []string{http.MethodGet, http.MethodPost, http.MethodHead}
+	} else {
+		c.allowedMethods = convert(options.AllowedMethods, strings.ToUpper)
+	}
+
+	return c
+}
+
+// Handler creates a new Cors handler with passed options.
+func Handler(options Options) func(next http.Handler) http.Handler {
+	c := New(options)
+	return c.Handler
+}
+
+// AllowAll create a new Cors handler with permissive configuration allowing all
+// origins with all standard methods with any header and credentials.
+func AllowAll() *Cors {
+	return New(Options{
+		AllowedOrigins: []string{"*"},
+		AllowedMethods: []string{
+			http.MethodHead,
+			http.MethodGet,
+			http.MethodPost,
+			http.MethodPut,
+			http.MethodPatch,
+			http.MethodDelete,
+		},
+		AllowedHeaders:   []string{"*"},
+		AllowCredentials: false,
+	})
+}
+
+// Handler apply the CORS specification on the request, and add relevant CORS headers
+// as necessary.
+func (c *Cors) Handler(next http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != "" {
+			c.logf("Handler: Preflight request")
+			c.handlePreflight(w, r)
+			// Preflight requests are standalone and should stop the chain as some other
+			// middleware may not handle OPTIONS requests correctly. One typical example
+			// is authentication middleware ; OPTIONS requests won't carry authentication
+			// headers (see #1)
+			if c.optionPassthrough {
+				next.ServeHTTP(w, r)
+			} else {
+				w.WriteHeader(http.StatusOK)
+			}
+		} else {
+			c.logf("Handler: Actual request")
+			c.handleActualRequest(w, r)
+			next.ServeHTTP(w, r)
+		}
+	})
+}
+
+// handlePreflight handles pre-flight CORS requests
+func (c *Cors) handlePreflight(w http.ResponseWriter, r *http.Request) {
+	headers := w.Header()
+	origin := r.Header.Get("Origin")
+
+	if r.Method != http.MethodOptions {
+		c.logf("Preflight aborted: %s!=OPTIONS", r.Method)
+		return
+	}
+	// Always set Vary headers
+	// see https://github.com/rs/cors/issues/10,
+	//     https://github.com/rs/cors/commit/dbdca4d95feaa7511a46e6f1efb3b3aa505bc43f#commitcomment-12352001
+	headers.Add("Vary", "Origin")
+	headers.Add("Vary", "Access-Control-Request-Method")
+	headers.Add("Vary", "Access-Control-Request-Headers")
+
+	if origin == "" {
+		c.logf("Preflight aborted: empty origin")
+		return
+	}
+	if !c.isOriginAllowed(r, origin) {
+		c.logf("Preflight aborted: origin '%s' not allowed", origin)
+		return
+	}
+
+	reqMethod := r.Header.Get("Access-Control-Request-Method")
+	if !c.isMethodAllowed(reqMethod) {
+		c.logf("Preflight aborted: method '%s' not allowed", reqMethod)
+		return
+	}
+	reqHeaders := parseHeaderList(r.Header.Get("Access-Control-Request-Headers"))
+	if !c.areHeadersAllowed(reqHeaders) {
+		c.logf("Preflight aborted: headers '%v' not allowed", reqHeaders)
+		return
+	}
+	if c.allowedOriginsAll {
+		headers.Set("Access-Control-Allow-Origin", "*")
+	} else {
+		headers.Set("Access-Control-Allow-Origin", origin)
+	}
+	// Spec says: Since the list of methods can be unbounded, simply returning the method indicated
+	// by Access-Control-Request-Method (if supported) can be enough
+	headers.Set("Access-Control-Allow-Methods", strings.ToUpper(reqMethod))
+	if len(reqHeaders) > 0 {
+
+		// Spec says: Since the list of headers can be unbounded, simply returning supported headers
+		// from Access-Control-Request-Headers can be enough
+		headers.Set("Access-Control-Allow-Headers", strings.Join(reqHeaders, ", "))
+	}
+	if c.allowCredentials {
+		headers.Set("Access-Control-Allow-Credentials", "true")
+	}
+	if c.maxAge > 0 {
+		headers.Set("Access-Control-Max-Age", strconv.Itoa(c.maxAge))
+	}
+	c.logf("Preflight response headers: %v", headers)
+}
+
+// handleActualRequest handles simple cross-origin requests, actual request or redirects
+func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) {
+	headers := w.Header()
+	origin := r.Header.Get("Origin")
+
+	// Always set Vary, see https://github.com/rs/cors/issues/10
+	headers.Add("Vary", "Origin")
+	if origin == "" {
+		c.logf("Actual request no headers added: missing origin")
+		return
+	}
+	if !c.isOriginAllowed(r, origin) {
+		c.logf("Actual request no headers added: origin '%s' not allowed", origin)
+		return
+	}
+
+	// Note that spec does define a way to specifically disallow a simple method like GET or
+	// POST. Access-Control-Allow-Methods is only used for pre-flight requests and the
+	// spec doesn't instruct to check the allowed methods for simple cross-origin requests.
+	// We think it's a nice feature to be able to have control on those methods though.
+	if !c.isMethodAllowed(r.Method) {
+		c.logf("Actual request no headers added: method '%s' not allowed", r.Method)
+
+		return
+	}
+	if c.allowedOriginsAll {
+		headers.Set("Access-Control-Allow-Origin", "*")
+	} else {
+		headers.Set("Access-Control-Allow-Origin", origin)
+	}
+	if len(c.exposedHeaders) > 0 {
+		headers.Set("Access-Control-Expose-Headers", strings.Join(c.exposedHeaders, ", "))
+	}
+	if c.allowCredentials {
+		headers.Set("Access-Control-Allow-Credentials", "true")
+	}
+	c.logf("Actual response added headers: %v", headers)
+}
+
+// convenience method. checks if a logger is set.
+func (c *Cors) logf(format string, a ...interface{}) {
+	if c.Log != nil {
+		c.Log.Printf(format, a...)
+	}
+}
+
+// isOriginAllowed checks if a given origin is allowed to perform cross-domain requests
+// on the endpoint
+func (c *Cors) isOriginAllowed(r *http.Request, origin string) bool {
+	if c.allowOriginFunc != nil {
+		return c.allowOriginFunc(r, origin)
+	}
+	if c.allowedOriginsAll {
+		return true
+	}
+	origin = strings.ToLower(origin)
+	for _, o := range c.allowedOrigins {
+		if o == origin {
+			return true
+		}
+	}
+	for _, w := range c.allowedWOrigins {
+		if w.match(origin) {
+			return true
+		}
+	}
+	return false
+}
+
+// isMethodAllowed checks if a given method can be used as part of a cross-domain request
+// on the endpoint
+func (c *Cors) isMethodAllowed(method string) bool {
+	if len(c.allowedMethods) == 0 {
+		// If no method allowed, always return false, even for preflight request
+		return false
+	}
+	method = strings.ToUpper(method)
+	if method == http.MethodOptions {
+		// Always allow preflight requests
+		return true
+	}
+	for _, m := range c.allowedMethods {
+		if m == method {
+			return true
+		}
+	}
+	return false
+}
+
+// areHeadersAllowed checks if a given list of headers are allowed to used within
+// a cross-domain request.
+func (c *Cors) areHeadersAllowed(requestedHeaders []string) bool {
+	if c.allowedHeadersAll || len(requestedHeaders) == 0 {
+		return true
+	}
+	for _, header := range requestedHeaders {
+		header = http.CanonicalHeaderKey(header)
+		found := false
+		for _, h := range c.allowedHeaders {
+			if h == header {
+				found = true
+				break
+			}
+		}
+		if !found {
+			return false
+		}
+	}
+	return true
+}
diff --git a/vendor/github.com/go-chi/cors/utils.go b/vendor/github.com/go-chi/cors/utils.go
new file mode 100644
index 0000000000000..cd24831fcfccf
--- /dev/null
+++ b/vendor/github.com/go-chi/cors/utils.go
@@ -0,0 +1,70 @@
+package cors
+
+import "strings"
+
+const toLower = 'a' - 'A'
+
+type converter func(string) string
+
+type wildcard struct {
+	prefix string
+	suffix string
+}
+
+func (w wildcard) match(s string) bool {
+	return len(s) >= len(w.prefix+w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix)
+}
+
+// convert converts a list of string using the passed converter function
+func convert(s []string, c converter) []string {
+	out := []string{}
+	for _, i := range s {
+		out = append(out, c(i))
+	}
+	return out
+}
+
+// parseHeaderList tokenize + normalize a string containing a list of headers
+func parseHeaderList(headerList string) []string {
+	l := len(headerList)
+	h := make([]byte, 0, l)
+	upper := true
+	// Estimate the number headers in order to allocate the right splice size
+	t := 0
+	for i := 0; i < l; i++ {
+		if headerList[i] == ',' {
+			t++
+		}
+	}
+	headers := make([]string, 0, t)
+	for i := 0; i < l; i++ {
+		b := headerList[i]
+		if b >= 'a' && b <= 'z' {
+			if upper {
+				h = append(h, b-toLower)
+			} else {
+				h = append(h, b)
+			}
+		} else if b >= 'A' && b <= 'Z' {
+			if !upper {
+				h = append(h, b+toLower)
+			} else {
+				h = append(h, b)
+			}
+		} else if b == '-' || (b >= '0' && b <= '9') {
+			h = append(h, b)
+		}
+
+		if b == ' ' || b == ',' || i == l-1 {
+			if len(h) > 0 {
+				// Flush the found header
+				headers = append(headers, string(h))
+				h = h[:0]
+				upper = true
+			}
+		} else {
+			upper = b == '-'
+		}
+	}
+	return headers
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index ece72337909f8..d533e453f1125 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -28,9 +28,6 @@ gitea.com/macaron/cache/memcache
 # gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca
 ## explicit
 gitea.com/macaron/captcha
-# gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4
-## explicit
-gitea.com/macaron/cors
 # gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439
 ## explicit
 gitea.com/macaron/csrf
@@ -273,6 +270,9 @@ github.com/go-asn1-ber/asn1-ber
 ## explicit
 github.com/go-chi/chi
 github.com/go-chi/chi/middleware
+# github.com/go-chi/cors v1.1.1
+## explicit
+github.com/go-chi/cors
 # github.com/go-enry/go-enry/v2 v2.5.2
 ## explicit
 github.com/go-enry/go-enry/v2