mirror of
https://github.com/gofiber/fiber.git
synced 2025-05-30 11:22:53 +00:00
💥 v1.9.4 (#341)
* Update router.go Co-authored-by: Fenny <fenny@protonmail.com>
This commit is contained in:
parent
eb2f3d347f
commit
8ea25a79b9
16
.github/README.md
vendored
16
.github/README.md
vendored
@ -469,7 +469,7 @@ func main() {
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Available Middlewares
|
||||
## 🧬 Official Middlewares
|
||||
|
||||
For _easier_ and _more clear_ work, we've put [middleware](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
@ -490,6 +490,15 @@ For _easier_ and _more clear_ work, we've put [middleware](https://docs.gofiber.
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Media
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -519,9 +528,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_de.md
vendored
14
.github/README_de.md
vendored
@ -489,6 +489,15 @@ Für _eine leichtere_ und _übersichtlichere_ arbeit haben wir die [middleware](
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Medien
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -518,9 +527,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_es.md
vendored
14
.github/README_es.md
vendored
@ -486,6 +486,15 @@ Para un trabajo _más claro_ y _sencillo_, hemos puesto cada [middleware](https:
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Medios
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -515,9 +524,12 @@ Fiber es un proyecto open source que se mantiene a través de donaciones para pa
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_fr.md
vendored
14
.github/README_fr.md
vendored
@ -486,6 +486,15 @@ For _easier_ and _more clear_ work, we've put [middleware](https://docs.gofiber.
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Media
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -515,9 +524,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
30
.github/README_he.md
vendored
30
.github/README_he.md
vendored
@ -597,6 +597,15 @@ func main() {
|
||||
- [CORS](https://github.com/gofiber/cors)
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
@ -648,15 +657,18 @@ Fiber היא פרויקט קוד פתוח שתשלום חשובונתיו מסת
|
||||
|
||||
| | משתמש | תרומה |
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :---- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
|
||||
<div dir="rtl">
|
||||
|
14
.github/README_id.md
vendored
14
.github/README_id.md
vendored
@ -488,6 +488,15 @@ For _easier_ and _more clear_ work, we've put [middleware](https://docs.gofiber.
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Media
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -517,9 +526,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_ja.md
vendored
14
.github/README_ja.md
vendored
@ -490,6 +490,15 @@ For _easier_ and _more clear_ work, we've put [middleware](https://docs.gofiber.
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 メディア
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -519,9 +528,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_ko.md
vendored
14
.github/README_ko.md
vendored
@ -490,6 +490,15 @@ For _easier_ and _more clear_ work, we've put [middleware](https://docs.gofiber.
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 미디어
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -519,9 +528,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_nl.md
vendored
14
.github/README_nl.md
vendored
@ -490,6 +490,15 @@ Voor _eenvoudiger_ en _duidelijker_ werk hebben we de beschikbare [middleware](h
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Media
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -519,9 +528,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_pt.md
vendored
14
.github/README_pt.md
vendored
@ -486,6 +486,15 @@ For _easier_ and _more clear_ work, we've put [middleware](https://docs.gofiber.
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Mídia
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -515,9 +524,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_ru.md
vendored
14
.github/README_ru.md
vendored
@ -488,6 +488,15 @@ func main() {
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Медиа
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -517,9 +526,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_tr.md
vendored
14
.github/README_tr.md
vendored
@ -484,6 +484,15 @@ _Kolay_ ve _daha temiz_ çalışma için [ara katmanlarımızı](https://docs.go
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 Medya
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Şubat 2020_
|
||||
@ -512,9 +521,12 @@ Fiber, alan adı, gitbook, netlify, serverless yer sağlayıcısı giderleri ve
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
14
.github/README_zh-CN.md
vendored
14
.github/README_zh-CN.md
vendored
@ -489,6 +489,15 @@ For _easier_ and _more clear_ work, we've put [middleware](https://docs.gofiber.
|
||||
- [CSRF](https://github.com/gofiber/csrf)
|
||||
- [JWT](https://github.com/gofiber/jwt)
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- https://github.com/arsmn/fiber-swagger
|
||||
- https://github.com/arsmn/fiber-casbin
|
||||
- https://github.com/arsmn/fiber-introspect
|
||||
- https://github.com/shareed2k/fiber_tracing
|
||||
- https://github.com/shareed2k/fiber_limiter
|
||||
|
||||
## 💬 媒体
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) — _03 Feb 2020_
|
||||
@ -518,9 +527,12 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
||||
| :---------------------------------------------------------- | :---------------------------------------------- | :------- |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales)| ☕ x 5 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | @justdave | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|
36
app.go
36
app.go
@ -1,6 +1,6 @@
|
||||
// 🚀 Fiber is an Express inspired web framework written in Go with 💖
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
|
||||
package fiber
|
||||
|
||||
@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
// Version of current package
|
||||
const Version = "1.9.3"
|
||||
const Version = "1.9.4"
|
||||
|
||||
// Map is a shortcut for map[string]interface{}
|
||||
type Map map[string]interface{}
|
||||
@ -32,7 +32,7 @@ type Map map[string]interface{}
|
||||
// App denotes the Fiber application.
|
||||
type App struct {
|
||||
server *fasthttp.Server // FastHTTP server
|
||||
routes []*Route // Route stack
|
||||
routes [][]*Route // Route stack
|
||||
Settings *Settings // Fiber settings
|
||||
}
|
||||
|
||||
@ -112,6 +112,8 @@ func New(settings ...*Settings) *App {
|
||||
schemaDecoderQuery.IgnoreUnknownKeys(true)
|
||||
// Create app
|
||||
app := new(App)
|
||||
// Create route stack
|
||||
app.routes = make([][]*Route, len(methodINT), len(methodINT))
|
||||
// Create settings
|
||||
app.Settings = new(Settings)
|
||||
// Set default settings
|
||||
@ -236,7 +238,7 @@ func (app *App) All(path string, handlers ...func(*Ctx)) *App {
|
||||
|
||||
// Group is used for Routes with common prefix to define a new sub-router with optional middleware.
|
||||
func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
|
||||
prefix = groupPaths(grp.prefix, prefix)
|
||||
prefix = getGroupPath(grp.prefix, prefix)
|
||||
if len(handlers) > 0 {
|
||||
grp.app.registerMethod("USE", prefix, handlers...)
|
||||
}
|
||||
@ -248,7 +250,7 @@ func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
|
||||
|
||||
// Static : https://fiber.wiki/application#static
|
||||
func (grp *Group) Static(prefix, root string, config ...Static) *Group {
|
||||
prefix = groupPaths(grp.prefix, prefix)
|
||||
prefix = getGroupPath(grp.prefix, prefix)
|
||||
grp.app.registerStatic(prefix, root, config...)
|
||||
return grp
|
||||
}
|
||||
@ -269,67 +271,67 @@ func (grp *Group) Use(args ...interface{}) *Group {
|
||||
log.Fatalf("Invalid Use() arguments, must be (prefix, handler) or (handler)")
|
||||
}
|
||||
}
|
||||
grp.app.registerMethod("USE", groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod("USE", getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Connect : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Connect(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodConnect, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodConnect, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Put : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Put(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodPut, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodPut, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Post : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Post(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodPost, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodPost, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Delete : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Delete(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodDelete, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodDelete, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Head : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Head(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodHead, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodHead, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Patch : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Patch(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodPatch, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodPatch, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Options : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Options(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodOptions, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodOptions, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Trace : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Trace(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodTrace, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodTrace, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Get : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodGet, groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod(MethodGet, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// All matches all HTTP methods and complete paths
|
||||
func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod("ALL", groupPaths(grp.prefix, path), handlers...)
|
||||
grp.app.registerMethod("ALL", getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
|
39
app_test.go
39
app_test.go
@ -1,6 +1,6 @@
|
||||
// 🚀 Fiber is an Express inspired web framework written in Go with 💖
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
|
||||
// go test -v -coverprofile cover.out .
|
||||
// go tool cover -html=cover.out -o cover.html
|
||||
@ -9,8 +9,10 @@
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@ -32,6 +34,39 @@ func is200(t *testing.T, app *App, url string, m ...string) {
|
||||
t.Fatalf("%s - %s - %v", method, url, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Order(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
app.Get("/", func(c *Ctx) {
|
||||
c.Write("1")
|
||||
c.Next()
|
||||
})
|
||||
app.All("/", func(c *Ctx) {
|
||||
c.Write("2")
|
||||
c.Next()
|
||||
})
|
||||
app.Use(func(c *Ctx) {
|
||||
c.Write("3")
|
||||
c.Next()
|
||||
})
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
resp, err := app.Test(req)
|
||||
if err != nil {
|
||||
t.Fatalf(`%s: %s`, t.Name(), err)
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
t.Fatalf(`%s: StatusCode %v`, t.Name(), resp.StatusCode)
|
||||
}
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatalf(`%s: Error %s`, t.Name(), err)
|
||||
}
|
||||
if string(body) != "123" {
|
||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), "123", string(body))
|
||||
}
|
||||
}
|
||||
func Test_Methods(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
DisableStartupMessage: true,
|
||||
|
23
ctx.go
23
ctx.go
@ -1,6 +1,6 @@
|
||||
// 🚀 Fiber is an Express inspired web framework written in Go with 💖
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
|
||||
package fiber
|
||||
|
||||
@ -30,14 +30,17 @@ import (
|
||||
// Ctx represents the Context which hold the HTTP request and response.
|
||||
// It has methods for the request query string, parameters, body, HTTP headers and so on.
|
||||
type Ctx struct {
|
||||
app *App // Reference to *App
|
||||
route *Route // Reference to *Route
|
||||
index int // Index of the current stack
|
||||
method string // HTTP method
|
||||
path string // HTTP path
|
||||
values []string // Route parameter values
|
||||
// Internal fields
|
||||
app *App // Reference to *App
|
||||
route *Route // Reference to *Route
|
||||
index int // Index of the current handler in the stack
|
||||
method string // HTTP method
|
||||
path string // HTTP path
|
||||
values []string // Route parameter values
|
||||
err error // Contains error if caught
|
||||
|
||||
// External fields
|
||||
Fasthttp *fasthttp.RequestCtx // Reference to *fasthttp.RequestCtx
|
||||
err error // Contains error if caught
|
||||
}
|
||||
|
||||
// Range struct
|
||||
@ -801,7 +804,7 @@ func (ctx *Ctx) SendStatus(status int) {
|
||||
ctx.Fasthttp.Response.SetStatusCode(status)
|
||||
// Only set status body when there is no response body
|
||||
if len(ctx.Fasthttp.Response.Body()) == 0 {
|
||||
ctx.Fasthttp.Response.SetBodyString(statusMessages[status])
|
||||
ctx.Fasthttp.Response.SetBodyString(statusMessage[status])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// 🚀 Fiber is an Express inspired web framework written in Go with 💖
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
|
||||
package fiber
|
||||
|
||||
@ -549,7 +549,7 @@ func Test_Params(t *testing.T) {
|
||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result)
|
||||
}
|
||||
})
|
||||
req, _ := http.NewRequest("GET", "/test/john", nil)
|
||||
req := httptest.NewRequest("GET", "/test/john", nil)
|
||||
resp, err := app.Test(req)
|
||||
if err != nil {
|
||||
t.Fatalf(`%s: %s`, t.Name(), err)
|
||||
@ -557,7 +557,8 @@ func Test_Params(t *testing.T) {
|
||||
if resp.StatusCode != 200 {
|
||||
t.Fatalf(`%s: StatusCode %v`, t.Name(), resp.StatusCode)
|
||||
}
|
||||
req, _ = http.NewRequest("GET", "/test2/im/a/cookie", nil)
|
||||
req = httptest.NewRequest("GET", "/test2/im/a/cookie", nil)
|
||||
t.Log(req.URL)
|
||||
resp, err = app.Test(req)
|
||||
if err != nil {
|
||||
t.Fatalf(`%s: %s`, t.Name(), err)
|
||||
|
161
params.go
Normal file
161
params.go
Normal file
@ -0,0 +1,161 @@
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚠️ This path parser was based on urlpath by @ucarion (MIT License).
|
||||
// 💖 Modified for the Fiber router by @renanbastos93 & @renewerner87
|
||||
// 🤖 ucarion/urlpath - renanbastos93/fastpath - renewerner87/fastpath
|
||||
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// paramsParser holds the path segments and param names
|
||||
type parsedParams struct {
|
||||
Segs []paramSeg
|
||||
Keys []string
|
||||
}
|
||||
|
||||
// paramsSeg holds the segment metadata
|
||||
type paramSeg struct {
|
||||
Param string
|
||||
Const string
|
||||
IsParam bool
|
||||
IsOptional bool
|
||||
IsLast bool
|
||||
}
|
||||
|
||||
var paramsDummy = make([]string, 100, 100)
|
||||
|
||||
// New ...
|
||||
func parseParams(pattern string) (p parsedParams) {
|
||||
var patternCount int
|
||||
aPattern := []string{""}
|
||||
if pattern != "" {
|
||||
aPattern = strings.Split(pattern, "/")[1:] // every route starts with an "/"
|
||||
}
|
||||
patternCount = len(aPattern)
|
||||
|
||||
var out = make([]paramSeg, patternCount)
|
||||
var params []string
|
||||
var segIndex int
|
||||
for i := 0; i < patternCount; i++ {
|
||||
partLen := len(aPattern[i])
|
||||
if partLen == 0 { // skip empty parts
|
||||
continue
|
||||
}
|
||||
// is parameter ?
|
||||
if aPattern[i][0] == '*' || aPattern[i][0] == ':' {
|
||||
out[segIndex] = paramSeg{
|
||||
Param: paramTrimmer(aPattern[i]),
|
||||
IsParam: true,
|
||||
IsOptional: aPattern[i] == "*" || aPattern[i][partLen-1] == '?',
|
||||
}
|
||||
params = append(params, out[segIndex].Param)
|
||||
} else {
|
||||
// combine const segments
|
||||
if segIndex > 0 && out[segIndex-1].IsParam == false {
|
||||
segIndex--
|
||||
out[segIndex].Const += "/" + aPattern[i]
|
||||
// create new const segment
|
||||
} else {
|
||||
out[segIndex] = paramSeg{
|
||||
Const: aPattern[i],
|
||||
}
|
||||
}
|
||||
}
|
||||
segIndex++
|
||||
}
|
||||
if segIndex == 0 {
|
||||
segIndex++
|
||||
}
|
||||
out[segIndex-1].IsLast = true
|
||||
|
||||
p = parsedParams{Segs: out[:segIndex:segIndex], Keys: params}
|
||||
return
|
||||
}
|
||||
|
||||
// Match ...
|
||||
func (p *parsedParams) matchParams(s string) ([]string, bool) {
|
||||
lenKeys := len(p.Keys)
|
||||
params := paramsDummy[0:lenKeys:lenKeys]
|
||||
var i, j, paramsIterator, partLen int
|
||||
if len(s) > 0 {
|
||||
s = s[1:]
|
||||
}
|
||||
for index, segment := range p.Segs {
|
||||
partLen = len(s)
|
||||
// check parameter
|
||||
if segment.IsParam {
|
||||
// determine parameter length
|
||||
if segment.IsLast {
|
||||
i = partLen
|
||||
} else if segment.Param == "*" {
|
||||
// for the expressjs behavior -> "/api/*/:param" - "/api/joker/batman/robin/1" -> "joker/batman/robin", "1"
|
||||
i = findCharPos(s, '/', strings.Count(s, "/")-(len(p.Segs)-(index+1))+1)
|
||||
} else {
|
||||
i = strings.IndexByte(s, '/')
|
||||
}
|
||||
if i == -1 {
|
||||
i = partLen
|
||||
}
|
||||
|
||||
if false == segment.IsOptional && i == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
params[paramsIterator] = s[:i]
|
||||
paramsIterator++
|
||||
} else {
|
||||
// check const segment
|
||||
i = len(segment.Const)
|
||||
if partLen < i || (i == 0 && partLen > 0) || s[:i] != segment.Const || (partLen > i && s[i] != '/') {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
// reduce founded part from the string
|
||||
if partLen > 0 {
|
||||
j = i + 1
|
||||
if segment.IsLast || partLen < j {
|
||||
j = i
|
||||
}
|
||||
|
||||
s = s[j:]
|
||||
}
|
||||
}
|
||||
|
||||
return params, true
|
||||
}
|
||||
|
||||
func paramTrimmer(param string) string {
|
||||
start := 0
|
||||
end := len(param)
|
||||
|
||||
if param[start] != ':' { // is not a param
|
||||
return param
|
||||
}
|
||||
start++
|
||||
if param[end-1] == '?' { // is ?
|
||||
end--
|
||||
}
|
||||
|
||||
return param[start:end]
|
||||
}
|
||||
func findCharPos(s string, char byte, matchCount int) int {
|
||||
if matchCount == 0 {
|
||||
matchCount = 1
|
||||
}
|
||||
endPos, pos := 0, 0
|
||||
for matchCount > 0 && pos != -1 {
|
||||
if pos > 0 {
|
||||
s = s[pos+1:]
|
||||
endPos++
|
||||
}
|
||||
pos = strings.IndexByte(s, char)
|
||||
endPos += pos
|
||||
matchCount--
|
||||
}
|
||||
return endPos
|
||||
}
|
246
params_test.go
Normal file
246
params_test.go
Normal file
@ -0,0 +1,246 @@
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚠️ This path parser was based on urlpath by @ucarion (MIT License).
|
||||
// 💖 Modified for the Fiber router by @renanbastos93 & @renewerner87
|
||||
// 🤖 ucarion/urlpath - renanbastos93/fastpath - renewerner87/fastpath
|
||||
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// params testing
|
||||
|
||||
type testCase struct {
|
||||
uri string
|
||||
params []string
|
||||
ok bool
|
||||
}
|
||||
|
||||
func Test_With_Param_And_Wildcard(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/v1/:param/*"),
|
||||
[]testCase{
|
||||
{uri: "/api/v1/entity", params: []string{"entity", ""}, ok: true},
|
||||
{uri: "/api/v1/entity/", params: []string{"entity", ""}, ok: true},
|
||||
{uri: "/api/v1/entity/1", params: []string{"entity", "1"}, ok: true},
|
||||
{uri: "/api/v", params: nil, ok: false},
|
||||
{uri: "/api/v2", params: nil, ok: false},
|
||||
{uri: "/api/v1/", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func Test_With_A_Param_Optional(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/v1/:param?"),
|
||||
[]testCase{
|
||||
{uri: "/api/v1", params: []string{""}, ok: true},
|
||||
{uri: "/api/v1/", params: []string{""}, ok: true},
|
||||
{uri: "/api/v1/optional", params: []string{"optional"}, ok: true},
|
||||
{uri: "/api/v", params: nil, ok: false},
|
||||
{uri: "/api/v2", params: nil, ok: false},
|
||||
{uri: "/api/xyz", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func Test_With_With_Wildcard(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/v1/*"),
|
||||
[]testCase{
|
||||
{uri: "/api/v1", params: []string{""}, ok: true},
|
||||
{uri: "/api/v1/", params: []string{""}, ok: true},
|
||||
{uri: "/api/v1/entity", params: []string{"entity"}, ok: true},
|
||||
{uri: "/api/v1/entity/1/2", params: []string{"entity/1/2"}, ok: true},
|
||||
{uri: "/api/v", params: nil, ok: false},
|
||||
{uri: "/api/v2", params: nil, ok: false},
|
||||
{uri: "/api/abc", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_Param(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/v1/:param"),
|
||||
[]testCase{
|
||||
{uri: "/api/v1/entity", params: []string{"entity"}, ok: true},
|
||||
{uri: "/api/v1", params: nil, ok: false},
|
||||
{uri: "/api/v1/", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func Test_With_Without_A_Param_Or_Wildcard(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/v1/const"),
|
||||
[]testCase{
|
||||
{uri: "/api/v1/const", params: []string{}, ok: true},
|
||||
{uri: "/api/v1", params: nil, ok: false},
|
||||
{uri: "/api/v1/", params: nil, ok: false},
|
||||
{uri: "/api/v1/something", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_A_Param_And_Wildcard_Differents_Positions(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/v1/:param/abc/*"),
|
||||
[]testCase{
|
||||
{uri: "/api/v1/well/abc/wildcard", params: []string{"well", "wildcard"}, ok: true},
|
||||
{uri: "/api/v1/well/abc/", params: []string{"well", ""}, ok: true},
|
||||
{uri: "/api/v1/well/abc", params: []string{"well", ""}, ok: true},
|
||||
{uri: "/api/v1/well/ttt", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_Params_And_Optional(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/:day/:month?/:year?"),
|
||||
[]testCase{
|
||||
{uri: "/api/1", params: []string{"1", "", ""}, ok: true},
|
||||
{uri: "/api/1/", params: []string{"1", "", ""}, ok: true},
|
||||
{uri: "/api/1/2", params: []string{"1", "2", ""}, ok: true},
|
||||
{uri: "/api/1/2/3", params: []string{"1", "2", "3"}, ok: true},
|
||||
{uri: "/api/", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_Simple_Wildcard(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/*"),
|
||||
[]testCase{
|
||||
{uri: "/api/", params: []string{""}, ok: true},
|
||||
{uri: "/api/joker", params: []string{"joker"}, ok: true},
|
||||
{uri: "/api", params: []string{""}, ok: true},
|
||||
{uri: "/api/v1/entity", params: []string{"v1/entity"}, ok: true},
|
||||
{uri: "/api2/v1/entity", params: nil, ok: false},
|
||||
{uri: "/api_ignore/v1/entity", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_Wildcard_And_Optional(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/*/:param?"),
|
||||
[]testCase{
|
||||
{uri: "/api/", params: []string{"", ""}, ok: true},
|
||||
{uri: "/api/joker", params: []string{"joker", ""}, ok: true},
|
||||
{uri: "/api/joker/batman", params: []string{"joker", "batman"}, ok: true},
|
||||
{uri: "/api/joker/batman/robin", params: []string{"joker/batman", "robin"}, ok: true},
|
||||
{uri: "/api/joker/batman/robin/1", params: []string{"joker/batman/robin", "1"}, ok: true},
|
||||
{uri: "/api", params: []string{"", ""}, ok: true},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_Wildcard_And_Param(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/*/:param"),
|
||||
[]testCase{
|
||||
{uri: "/api/test/abc", params: []string{"test", "abc"}, ok: true},
|
||||
{uri: "/api/joker/batman", params: []string{"joker", "batman"}, ok: true},
|
||||
{uri: "/api/joker/batman/robin", params: []string{"joker/batman", "robin"}, ok: true},
|
||||
{uri: "/api/joker/batman/robin/1", params: []string{"joker/batman/robin", "1"}, ok: true},
|
||||
{uri: "/api", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_Wildcard_And_2Params(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/api/*/:param/:param2"),
|
||||
[]testCase{
|
||||
{uri: "/api/test/abc", params: nil, ok: false},
|
||||
{uri: "/api/joker/batman", params: nil, ok: false},
|
||||
{uri: "/api/joker/batman/robin", params: []string{"joker", "batman", "robin"}, ok: true},
|
||||
{uri: "/api/joker/batman/robin/1", params: []string{"joker/batman", "robin", "1"}, ok: true},
|
||||
{uri: "/api/joker/batman/robin/1/2", params: []string{"joker/batman/robin", "1", "2"}, ok: true},
|
||||
{uri: "/api", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_Simple_Path(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/"),
|
||||
[]testCase{
|
||||
{uri: "/api", params: nil, ok: false},
|
||||
{uri: "", params: []string{}, ok: true},
|
||||
{uri: "/", params: []string{}, ok: true},
|
||||
},
|
||||
)
|
||||
}
|
||||
func Test_With_With_Empty_Path(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams(""),
|
||||
[]testCase{
|
||||
{uri: "/api", params: nil, ok: false},
|
||||
{uri: "", params: []string{}, ok: true},
|
||||
{uri: "/", params: []string{}, ok: true},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func Test_With_With_FileName(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/config/abc.json"),
|
||||
[]testCase{
|
||||
{uri: "/config/abc.json", params: []string{}, ok: true},
|
||||
{uri: "config/abc.json", params: nil, ok: false},
|
||||
{uri: "/config/efg.json", params: nil, ok: false},
|
||||
{uri: "/config", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func Test_With_With_FileName_And_Wildcard(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/config/*.json"),
|
||||
[]testCase{
|
||||
{uri: "/config/abc.json", params: []string{"abc.json"}, ok: true},
|
||||
{uri: "/config/efg.json", params: []string{"efg.json"}, ok: true},
|
||||
//{uri: "/config/efg.csv", params: nil, ok: false},// doesn`t work, current: params: "efg.csv", true
|
||||
{uri: "config/abc.json", params: nil, ok: false},
|
||||
{uri: "/config", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func Test_With_With_Simple_Path_And_NoMatch(t *testing.T) {
|
||||
checkCases(
|
||||
t,
|
||||
parseParams("/xyz"),
|
||||
[]testCase{
|
||||
{uri: "xyz", params: nil, ok: false},
|
||||
{uri: "xyz/", params: nil, ok: false},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func checkCases(tParent *testing.T, parser parsedParams, tcases []testCase) {
|
||||
for _, tcase := range tcases {
|
||||
tParent.Run(fmt.Sprintf("%+v", tcase), func(t *testing.T) {
|
||||
params, ok := parser.matchParams(tcase.uri)
|
||||
if !reflect.DeepEqual(params, tcase.params) {
|
||||
t.Errorf("Path.Match() got = %v, want %v", params, tcase.params)
|
||||
}
|
||||
if ok != tcase.ok {
|
||||
t.Errorf("Path.Match() got1 = %v, want %v", ok, tcase.ok)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
247
router.go
247
router.go
@ -1,107 +1,101 @@
|
||||
// 🚀 Fiber is an Express inspired web framework written in Go with 💖
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"log"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// Route struct
|
||||
// Route metadata
|
||||
type Route struct {
|
||||
isGet bool // allows HEAD requests if GET
|
||||
// Internal fields
|
||||
use bool // USE matches path prefixes
|
||||
star bool // Path equals '*' or '/*'
|
||||
root bool // Path equals '/'
|
||||
parsed parsedParams // parsed contains parsed params segments
|
||||
|
||||
isMiddleware bool // is middleware route
|
||||
|
||||
isStar bool // path == '*'
|
||||
isSlash bool // path == '/'
|
||||
isRegex bool // needs regex parsing
|
||||
|
||||
Method string // http method
|
||||
Path string // original path
|
||||
Params []string // path params
|
||||
Regexp *regexp.Regexp // regexp matcher
|
||||
|
||||
Handler func(*Ctx) // ctx handler
|
||||
// External fields for ctx.Route() method
|
||||
Path string // Registered route path
|
||||
Method string // HTTP method
|
||||
Params []string // Slice containing the params names
|
||||
Handler func(*Ctx) // Ctx handler
|
||||
}
|
||||
|
||||
func (app *App) nextRoute(ctx *Ctx) {
|
||||
// Keep track of head matches
|
||||
lenr := len(app.routes) - 1
|
||||
mINT := methodINT[ctx.method]
|
||||
// Get stack length
|
||||
lenr := len(app.routes[mINT]) - 1
|
||||
// Loop over stack starting from previous index
|
||||
for ctx.index < lenr {
|
||||
// Increment stack index
|
||||
ctx.index++
|
||||
route := app.routes[ctx.index]
|
||||
match, values := route.matchRoute(ctx.method, ctx.path)
|
||||
if match {
|
||||
ctx.route = route
|
||||
ctx.values = values
|
||||
route.Handler(ctx)
|
||||
// Generate ETag if enabled / found
|
||||
if app.Settings.ETag {
|
||||
setETag(ctx, ctx.Fasthttp.Response.Body(), false)
|
||||
}
|
||||
return
|
||||
// Get *Route
|
||||
route := app.routes[mINT][ctx.index]
|
||||
// Check if it matches the request path
|
||||
match, values := route.matchRoute(ctx.path)
|
||||
// No match, continue
|
||||
if !match {
|
||||
continue
|
||||
}
|
||||
// Match! Set route and param values to Ctx
|
||||
ctx.route = route
|
||||
ctx.values = values
|
||||
// Execute handler
|
||||
route.Handler(ctx)
|
||||
// Generate ETag if enabled
|
||||
if app.Settings.ETag {
|
||||
setETag(ctx, false)
|
||||
}
|
||||
return
|
||||
}
|
||||
// Send a 404
|
||||
// Send a 404 by default if no route is matched
|
||||
if len(ctx.Fasthttp.Response.Body()) == 0 {
|
||||
ctx.SendStatus(404)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Route) matchRoute(method, path string) (match bool, values []string) {
|
||||
// is route middleware? matches all http methods
|
||||
if r.isMiddleware {
|
||||
// '*' or '/' means its a valid match
|
||||
if r.isStar || r.isSlash {
|
||||
func (r *Route) matchRoute(path string) (match bool, values []string) {
|
||||
// Middleware routes allow prefix matches
|
||||
if r.use {
|
||||
// Match any path if route equals '*' or '/'
|
||||
if r.star || r.root {
|
||||
return true, values
|
||||
}
|
||||
// if midware path starts with req.path
|
||||
// Middleware matches path prefix
|
||||
if strings.HasPrefix(path, r.Path) {
|
||||
return true, values
|
||||
}
|
||||
// middlewares dont support regex so bye!
|
||||
// No prefix match, and we do not allow params in app.use
|
||||
return false, values
|
||||
}
|
||||
// non-middleware route, http method must match!
|
||||
// the wildcard method is for .All() & .Use() methods
|
||||
// If route is GET, also match HEAD requests
|
||||
if r.Method == method || r.Method[0] == '*' || (r.isGet && len(method) == 4 && method == "HEAD") {
|
||||
// '*' means we match anything
|
||||
if r.isStar {
|
||||
return true, values
|
||||
}
|
||||
// simple '/' bool, so you avoid unnecessary comparison for long paths
|
||||
if r.isSlash && path == "/" {
|
||||
return true, values
|
||||
}
|
||||
// does this route need regex matching?
|
||||
// does req.path match regex pattern?
|
||||
if r.isRegex && r.Regexp.MatchString(path) {
|
||||
// do we have parameters
|
||||
if len(r.Params) > 0 {
|
||||
// get values for parameters
|
||||
matches := r.Regexp.FindAllStringSubmatch(path, -1)
|
||||
// did we get the values?
|
||||
if len(matches) > 0 && len(matches[0]) > 1 {
|
||||
values = matches[0][1:len(matches[0])]
|
||||
return true, values
|
||||
}
|
||||
return false, values
|
||||
}
|
||||
return true, values
|
||||
}
|
||||
// last thing to do is to check for a simple path match
|
||||
if len(r.Path) == len(path) && r.Path == path {
|
||||
return true, values
|
||||
// '*' wildcard matches any path
|
||||
if r.star {
|
||||
return true, values
|
||||
}
|
||||
// Check if a single '/' matches
|
||||
if r.root && path == "/" {
|
||||
return true, values
|
||||
}
|
||||
// Does this route have parameters
|
||||
if len(r.Params) > 0 {
|
||||
// Do we have a match?
|
||||
params, ok := r.parsed.matchParams(path)
|
||||
// We have a match!
|
||||
if ok {
|
||||
return true, params
|
||||
}
|
||||
}
|
||||
// Check for a simple path match
|
||||
if len(r.Path) == len(path) && r.Path == path {
|
||||
return true, values
|
||||
}
|
||||
|
||||
// Nothing match
|
||||
return false, values
|
||||
}
|
||||
@ -110,7 +104,7 @@ func (app *App) handler(fctx *fasthttp.RequestCtx) {
|
||||
// get fiber context from sync pool
|
||||
ctx := acquireCtx(fctx)
|
||||
defer releaseCtx(ctx)
|
||||
// attach app poiner and compress settings
|
||||
// Attach app poiner to access the routes
|
||||
ctx.app = app
|
||||
|
||||
// Case sensitive routing
|
||||
@ -149,44 +143,45 @@ func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
|
||||
path = strings.TrimRight(path, "/")
|
||||
}
|
||||
// Set route booleans
|
||||
var isGet = method == "GET"
|
||||
var isMiddleware = method == "USE"
|
||||
var isUse = method == "USE"
|
||||
// Middleware / All allows all HTTP methods
|
||||
if isMiddleware || method == "ALL" {
|
||||
if isUse || method == "ALL" {
|
||||
method = "*"
|
||||
}
|
||||
var isStar = path == "*" || path == "/*"
|
||||
// Middleware containing only a `/` equals wildcard
|
||||
if isMiddleware && path == "/" {
|
||||
if isUse && path == "/" {
|
||||
isStar = true
|
||||
}
|
||||
var isSlash = path == "/"
|
||||
var isRegex = false
|
||||
var isRoot = path == "/"
|
||||
// Route properties
|
||||
var Params = getParams(original)
|
||||
var Regexp *regexp.Regexp
|
||||
// Params requires regex pattern
|
||||
if len(Params) > 0 {
|
||||
regex, err := getRegex(path)
|
||||
if err != nil {
|
||||
log.Fatal("Router: Invalid path pattern: " + path)
|
||||
}
|
||||
isRegex = true
|
||||
Regexp = regex
|
||||
}
|
||||
var isParsed = parseParams(original)
|
||||
for i := range handlers {
|
||||
app.routes = append(app.routes, &Route{
|
||||
isGet: isGet,
|
||||
isMiddleware: isMiddleware,
|
||||
isStar: isStar,
|
||||
isSlash: isSlash,
|
||||
isRegex: isRegex,
|
||||
Method: method,
|
||||
Path: path,
|
||||
Params: Params,
|
||||
Regexp: Regexp,
|
||||
Handler: handlers[i],
|
||||
})
|
||||
route := &Route{
|
||||
use: isUse,
|
||||
star: isStar,
|
||||
root: isRoot,
|
||||
parsed: isParsed,
|
||||
|
||||
Path: path,
|
||||
Method: method,
|
||||
Params: isParsed.Keys,
|
||||
Handler: handlers[i],
|
||||
}
|
||||
if method == "*" {
|
||||
// Add handler to all HTTP methods
|
||||
for m := range methodINT {
|
||||
app.addRoute(m, route)
|
||||
}
|
||||
continue
|
||||
}
|
||||
// Add route to stack
|
||||
app.addRoute(method, route)
|
||||
// Add route to HEAD method if GET
|
||||
if method == MethodGet {
|
||||
app.addRoute(MethodHead, route)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,13 +213,13 @@ func (app *App) registerStatic(prefix, root string, config ...Static) {
|
||||
root = root[:len(root)-1]
|
||||
}
|
||||
// isSlash ?
|
||||
var isSlash = prefix == "/"
|
||||
var isRoot = prefix == "/"
|
||||
if strings.Contains(prefix, "*") {
|
||||
wildcard = true
|
||||
prefix = strings.Split(prefix, "*")[0]
|
||||
}
|
||||
var stripper = len(prefix)
|
||||
if isSlash {
|
||||
if isRoot {
|
||||
stripper = 0
|
||||
}
|
||||
// Fileserver settings
|
||||
@ -252,30 +247,36 @@ func (app *App) registerStatic(prefix, root string, config ...Static) {
|
||||
}
|
||||
}
|
||||
fileHandler := fs.NewRequestHandler()
|
||||
app.routes = append(app.routes, &Route{
|
||||
isMiddleware: true,
|
||||
isSlash: isSlash,
|
||||
Method: "*",
|
||||
Path: prefix,
|
||||
route := &Route{
|
||||
use: true,
|
||||
root: isRoot,
|
||||
Method: "*",
|
||||
Path: prefix,
|
||||
Handler: func(c *Ctx) {
|
||||
// Only handle GET & HEAD methods
|
||||
if c.method == "GET" || c.method == "HEAD" {
|
||||
// Do stuff
|
||||
if wildcard {
|
||||
c.Fasthttp.Request.SetRequestURI(prefix)
|
||||
}
|
||||
// Serve file
|
||||
fileHandler(c.Fasthttp)
|
||||
|
||||
// Finish request if found and not forbidden
|
||||
status := c.Fasthttp.Response.StatusCode()
|
||||
if status != 404 && status != 403 {
|
||||
return
|
||||
}
|
||||
// Reset response
|
||||
c.Fasthttp.Response.Reset()
|
||||
// Do stuff
|
||||
if wildcard {
|
||||
c.Fasthttp.Request.SetRequestURI(prefix)
|
||||
}
|
||||
// Serve file
|
||||
fileHandler(c.Fasthttp)
|
||||
|
||||
// Finish request if found and not forbidden
|
||||
status := c.Fasthttp.Response.StatusCode()
|
||||
if status != 404 && status != 403 {
|
||||
return
|
||||
}
|
||||
// Reset response
|
||||
c.Fasthttp.Response.Reset()
|
||||
// Next middleware
|
||||
c.Next()
|
||||
},
|
||||
})
|
||||
}
|
||||
// Add route to stack
|
||||
app.addRoute(MethodGet, route)
|
||||
app.addRoute(MethodHead, route)
|
||||
}
|
||||
|
||||
func (app *App) addRoute(method string, route *Route) {
|
||||
m := methodINT[method]
|
||||
app.routes[m] = append(app.routes[m], route)
|
||||
}
|
||||
|
619
router_test.go
Normal file
619
router_test.go
Normal file
@ -0,0 +1,619 @@
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚠️ This path parser was based on urlpath by @ucarion (MIT License).
|
||||
// 💖 Modified for the Fiber router by @renanbastos93 & @renewerner87
|
||||
// 🤖 ucarion/urlpath - renanbastos93/fastpath - renewerner87/fastpath
|
||||
|
||||
// router benchmarks
|
||||
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var app *App
|
||||
|
||||
func init() {
|
||||
app = New()
|
||||
h := func(c *Ctx) {}
|
||||
for _, r := range githubAPI {
|
||||
switch r.method {
|
||||
case "GET":
|
||||
app.Get(r.path, h)
|
||||
case "POST":
|
||||
app.Post(r.path, h)
|
||||
case "PUT":
|
||||
app.Put(r.path, h)
|
||||
case "PATCH":
|
||||
app.Patch(r.path, h)
|
||||
case "DELETE":
|
||||
app.Delete(r.path, h)
|
||||
default:
|
||||
panic("Unknow HTTP method: " + r.method)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_All_Routes(b *testing.B) {
|
||||
var match bool
|
||||
var params []string
|
||||
for n := 0; n < b.N; n++ {
|
||||
for _, r := range testRoutes {
|
||||
match, params = matchRoute(r.method, r.path)
|
||||
}
|
||||
if match {
|
||||
if len(params) > 0 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Last_Route(b *testing.B) {
|
||||
var match bool
|
||||
var params []string
|
||||
for n := 0; n < b.N; n++ {
|
||||
match, params = matchRoute("DELETE", "/user/keys/1337")
|
||||
}
|
||||
if match {
|
||||
if len(params) > 0 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
func Benchmark_First_Route(b *testing.B) {
|
||||
var match bool
|
||||
var params []string
|
||||
for n := 0; n < b.N; n++ {
|
||||
match, params = matchRoute("GET", "/authorizations")
|
||||
}
|
||||
if match {
|
||||
if len(params) > 0 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func matchRoute(method, path string) (match bool, values []string) {
|
||||
mINT := methodINT[method]
|
||||
for i := range app.routes[mINT] {
|
||||
match, values = app.routes[mINT][i].matchRoute(path)
|
||||
if match {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type testRoute struct {
|
||||
method string
|
||||
path string
|
||||
}
|
||||
|
||||
var testRoutes = []testRoute{
|
||||
// OAuth Authorizations
|
||||
{"GET", "/authorizations"},
|
||||
{"GET", "/authorizations/1337"},
|
||||
{"POST", "/authorizations"},
|
||||
{"PUT", "/authorizations/clients/inf1nd873nf8912g9t"},
|
||||
{"PATCH", "/authorizations/1337"},
|
||||
{"DELETE", "/authorizations/1337"},
|
||||
{"GET", "/applications/2nds981mng6azl127y/tokens/sn108hbe1geheibf13f"},
|
||||
{"DELETE", "/applications/2nds981mng6azl127y/tokens"},
|
||||
{"DELETE", "/applications/2nds981mng6azl127y/tokens/sn108hbe1geheibf13f"},
|
||||
|
||||
// Activity
|
||||
{"GET", "/events"},
|
||||
{"GET", "/repos/fenny/fiber/events"},
|
||||
{"GET", "/networks/fenny/fiber/events"},
|
||||
{"GET", "/orgs/gofiber/events"},
|
||||
{"GET", "/users/fenny/received_events"},
|
||||
{"GET", "/users/fenny/received_events/public"},
|
||||
{"GET", "/users/fenny/events"},
|
||||
{"GET", "/users/fenny/events/public"},
|
||||
{"GET", "/users/fenny/events/orgs/gofiber"},
|
||||
{"GET", "/feeds"},
|
||||
{"GET", "/notifications"},
|
||||
{"GET", "/repos/fenny/fiber/notifications"},
|
||||
{"PUT", "/notifications"},
|
||||
{"PUT", "/repos/fenny/fiber/notifications"},
|
||||
{"GET", "/notifications/threads/1337"},
|
||||
{"PATCH", "/notifications/threads/1337"},
|
||||
{"GET", "/notifications/threads/1337/subscription"},
|
||||
{"PUT", "/notifications/threads/1337/subscription"},
|
||||
{"DELETE", "/notifications/threads/1337/subscription"},
|
||||
{"GET", "/repos/fenny/fiber/stargazers"},
|
||||
{"GET", "/users/fenny/starred"},
|
||||
{"GET", "/user/starred"},
|
||||
{"GET", "/user/starred/fenny/fiber"},
|
||||
{"PUT", "/user/starred/fenny/fiber"},
|
||||
{"DELETE", "/user/starred/fenny/fiber"},
|
||||
{"GET", "/repos/fenny/fiber/subscribers"},
|
||||
{"GET", "/users/fenny/subscriptions"},
|
||||
{"GET", "/user/subscriptions"},
|
||||
{"GET", "/repos/fenny/fiber/subscription"},
|
||||
{"PUT", "/repos/fenny/fiber/subscription"},
|
||||
{"DELETE", "/repos/fenny/fiber/subscription"},
|
||||
{"GET", "/user/subscriptions/fenny/fiber"},
|
||||
{"PUT", "/user/subscriptions/fenny/fiber"},
|
||||
{"DELETE", "/user/subscriptions/fenny/fiber"},
|
||||
|
||||
// Gists
|
||||
{"GET", "/users/fenny/gists"},
|
||||
{"GET", "/gists"},
|
||||
{"GET", "/gists/public"},
|
||||
{"GET", "/gists/starred"},
|
||||
{"GET", "/gists/1337"},
|
||||
{"POST", "/gists"},
|
||||
{"PATCH", "/gists/1337"},
|
||||
{"PUT", "/gists/1337/star"},
|
||||
{"DELETE", "/gists/1337/star"},
|
||||
{"GET", "/gists/1337/star"},
|
||||
{"POST", "/gists/1337/forks"},
|
||||
{"DELETE", "/gists/1337"},
|
||||
|
||||
// Git Data
|
||||
{"GET", "/repos/fenny/fiber/git/blobs/v948b24g98ubngw9082bn02giub"},
|
||||
{"POST", "/repos/fenny/fiber/git/blobs"},
|
||||
{"GET", "/repos/fenny/fiber/git/commits/v948b24g98ubngw9082bn02giub"},
|
||||
{"POST", "/repos/fenny/fiber/git/commits"},
|
||||
{"GET", "/repos/fenny/fiber/git/refs/im/a/wildcard"},
|
||||
{"GET", "/repos/fenny/fiber/git/refs"},
|
||||
{"POST", "/repos/fenny/fiber/git/refs"},
|
||||
{"PATCH", "/repos/fenny/fiber/git/refs/im/a/wildcard"},
|
||||
{"DELETE", "/repos/fenny/fiber/git/refs/im/a/wildcard"},
|
||||
{"GET", "/repos/fenny/fiber/git/tags/v948b24g98ubngw9082bn02giub"},
|
||||
{"POST", "/repos/fenny/fiber/git/tags"},
|
||||
{"GET", "/repos/fenny/fiber/git/trees/v948b24g98ubngw9082bn02giub"},
|
||||
{"POST", "/repos/fenny/fiber/git/trees"},
|
||||
|
||||
// Issues
|
||||
{"GET", "/issues"},
|
||||
{"GET", "/user/issues"},
|
||||
{"GET", "/orgs/gofiber/issues"},
|
||||
{"GET", "/repos/fenny/fiber/issues"},
|
||||
{"GET", "/repos/fenny/fiber/issues/1000"},
|
||||
{"POST", "/repos/fenny/fiber/issues"},
|
||||
{"PATCH", "/repos/fenny/fiber/issues/1000"},
|
||||
{"GET", "/repos/fenny/fiber/assignees"},
|
||||
{"GET", "/repos/fenny/fiber/assignees/nic"},
|
||||
{"GET", "/repos/fenny/fiber/issues/1000/comments"},
|
||||
{"GET", "/repos/fenny/fiber/issues/comments"},
|
||||
{"GET", "/repos/fenny/fiber/issues/comments/1337"},
|
||||
{"POST", "/repos/fenny/fiber/issues/1000/comments"},
|
||||
{"PATCH", "/repos/fenny/fiber/issues/comments/1337"},
|
||||
{"DELETE", "/repos/fenny/fiber/issues/comments/1337"},
|
||||
{"GET", "/repos/fenny/fiber/issues/1000/events"},
|
||||
{"GET", "/repos/fenny/fiber/issues/events"},
|
||||
{"GET", "/repos/fenny/fiber/issues/events/1337"},
|
||||
{"GET", "/repos/fenny/fiber/labels"},
|
||||
{"GET", "/repos/fenny/fiber/labels/john"},
|
||||
{"POST", "/repos/fenny/fiber/labels"},
|
||||
{"PATCH", "/repos/fenny/fiber/labels/john"},
|
||||
{"DELETE", "/repos/fenny/fiber/labels/john"},
|
||||
{"GET", "/repos/fenny/fiber/issues/1000/labels"},
|
||||
{"POST", "/repos/fenny/fiber/issues/1000/labels"},
|
||||
{"DELETE", "/repos/fenny/fiber/issues/1000/labels/john"},
|
||||
{"PUT", "/repos/fenny/fiber/issues/1000/labels"},
|
||||
{"DELETE", "/repos/fenny/fiber/issues/1000/labels"},
|
||||
{"GET", "/repos/fenny/fiber/milestones/1000/labels"},
|
||||
{"GET", "/repos/fenny/fiber/milestones"},
|
||||
{"GET", "/repos/fenny/fiber/milestones/1000"},
|
||||
{"POST", "/repos/fenny/fiber/milestones"},
|
||||
{"PATCH", "/repos/fenny/fiber/milestones/1000"},
|
||||
{"DELETE", "/repos/fenny/fiber/milestones/1000"},
|
||||
|
||||
// Miscellaneous
|
||||
{"GET", "/emojis"},
|
||||
{"GET", "/gitignore/templates"},
|
||||
{"GET", "/gitignore/templates/john"},
|
||||
{"POST", "/markdown"},
|
||||
{"POST", "/markdown/raw"},
|
||||
{"GET", "/meta"},
|
||||
{"GET", "/rate_limit"},
|
||||
|
||||
// Organizations
|
||||
{"GET", "/users/fenny/orgs"},
|
||||
{"GET", "/user/orgs"},
|
||||
{"GET", "/orgs/gofiber"},
|
||||
{"PATCH", "/orgs/gofiber"},
|
||||
{"GET", "/orgs/gofiber/members"},
|
||||
{"GET", "/orgs/gofiber/members/fenny"},
|
||||
{"DELETE", "/orgs/gofiber/members/fenny"},
|
||||
{"GET", "/orgs/gofiber/public_members"},
|
||||
{"GET", "/orgs/gofiber/public_members/fenny"},
|
||||
{"PUT", "/orgs/gofiber/public_members/fenny"},
|
||||
{"DELETE", "/orgs/gofiber/public_members/fenny"},
|
||||
{"GET", "/orgs/gofiber/teams"},
|
||||
{"GET", "/teams/1337"},
|
||||
{"POST", "/orgs/gofiber/teams"},
|
||||
{"PATCH", "/teams/1337"},
|
||||
{"DELETE", "/teams/1337"},
|
||||
{"GET", "/teams/1337/members"},
|
||||
{"GET", "/teams/1337/members/fenny"},
|
||||
{"PUT", "/teams/1337/members/fenny"},
|
||||
{"DELETE", "/teams/1337/members/fenny"},
|
||||
{"GET", "/teams/1337/repos"},
|
||||
{"GET", "/teams/1337/repos/fenny/fiber"},
|
||||
{"PUT", "/teams/1337/repos/fenny/fiber"},
|
||||
{"DELETE", "/teams/1337/repos/fenny/fiber"},
|
||||
{"GET", "/user/teams"},
|
||||
|
||||
// Pull Requests
|
||||
{"GET", "/repos/fenny/fiber/pulls"},
|
||||
{"GET", "/repos/fenny/fiber/pulls/1000"},
|
||||
{"POST", "/repos/fenny/fiber/pulls"},
|
||||
{"PATCH", "/repos/fenny/fiber/pulls/1000"},
|
||||
{"GET", "/repos/fenny/fiber/pulls/1000/commits"},
|
||||
{"GET", "/repos/fenny/fiber/pulls/1000/files"},
|
||||
{"GET", "/repos/fenny/fiber/pulls/1000/merge"},
|
||||
{"PUT", "/repos/fenny/fiber/pulls/1000/merge"},
|
||||
{"GET", "/repos/fenny/fiber/pulls/1000/comments"},
|
||||
{"GET", "/repos/fenny/fiber/pulls/comments"},
|
||||
{"GET", "/repos/fenny/fiber/pulls/comments/1000"},
|
||||
{"PUT", "/repos/fenny/fiber/pulls/1000/comments"},
|
||||
{"PATCH", "/repos/fenny/fiber/pulls/comments/1000"},
|
||||
{"DELETE", "/repos/fenny/fiber/pulls/comments/1000"},
|
||||
|
||||
// Repositories
|
||||
{"GET", "/user/repos"},
|
||||
{"GET", "/users/fenny/repos"},
|
||||
{"GET", "/orgs/gofiber/repos"},
|
||||
{"GET", "/repositories"},
|
||||
{"POST", "/user/repos"},
|
||||
{"POST", "/orgs/gofiber/repos"},
|
||||
{"GET", "/repos/fenny/fiber"},
|
||||
{"PATCH", "/repos/fenny/fiber"},
|
||||
{"GET", "/repos/fenny/fiber/contributors"},
|
||||
{"GET", "/repos/fenny/fiber/languages"},
|
||||
{"GET", "/repos/fenny/fiber/teams"},
|
||||
{"GET", "/repos/fenny/fiber/tags"},
|
||||
{"GET", "/repos/fenny/fiber/branches"},
|
||||
{"GET", "/repos/fenny/fiber/branches/master"},
|
||||
{"DELETE", "/repos/fenny/fiber"},
|
||||
{"GET", "/repos/fenny/fiber/collaborators"},
|
||||
{"GET", "/repos/fenny/fiber/collaborators/fenny"},
|
||||
{"PUT", "/repos/fenny/fiber/collaborators/fenny"},
|
||||
{"DELETE", "/repos/fenny/fiber/collaborators/fenny"},
|
||||
{"GET", "/repos/fenny/fiber/comments"},
|
||||
{"GET", "/repos/fenny/fiber/commits/v948b24g98ubngw9082bn02giub/comments"},
|
||||
{"POST", "/repos/fenny/fiber/commits/v948b24g98ubngw9082bn02giub/comments"},
|
||||
{"GET", "/repos/fenny/fiber/comments/1337"},
|
||||
{"PATCH", "/repos/fenny/fiber/comments/1337"},
|
||||
{"DELETE", "/repos/fenny/fiber/comments/1337"},
|
||||
{"GET", "/repos/fenny/fiber/commits"},
|
||||
{"GET", "/repos/fenny/fiber/commits/v948b24g98ubngw9082bn02giub"},
|
||||
{"GET", "/repos/fenny/fiber/readme"},
|
||||
{"GET", "/repos/fenny/fiber/contents/im/a/wildcard"},
|
||||
{"PUT", "/repos/fenny/fiber/contents/im/a/wildcard"},
|
||||
{"DELETE", "/repos/fenny/fiber/contents/im/a/wildcard"},
|
||||
{"GET", "/repos/fenny/fiber/gzip/google"},
|
||||
{"GET", "/repos/fenny/fiber/keys"},
|
||||
{"GET", "/repos/fenny/fiber/keys/1337"},
|
||||
{"POST", "/repos/fenny/fiber/keys"},
|
||||
{"PATCH", "/repos/fenny/fiber/keys/1337"},
|
||||
{"DELETE", "/repos/fenny/fiber/keys/1337"},
|
||||
{"GET", "/repos/fenny/fiber/downloads"},
|
||||
{"GET", "/repos/fenny/fiber/downloads/1337"},
|
||||
{"DELETE", "/repos/fenny/fiber/downloads/1337"},
|
||||
{"GET", "/repos/fenny/fiber/forks"},
|
||||
{"POST", "/repos/fenny/fiber/forks"},
|
||||
{"GET", "/repos/fenny/fiber/hooks"},
|
||||
{"GET", "/repos/fenny/fiber/hooks/1337"},
|
||||
{"POST", "/repos/fenny/fiber/hooks"},
|
||||
{"PATCH", "/repos/fenny/fiber/hooks/1337"},
|
||||
{"POST", "/repos/fenny/fiber/hooks/1337/tests"},
|
||||
{"DELETE", "/repos/fenny/fiber/hooks/1337"},
|
||||
{"POST", "/repos/fenny/fiber/merges"},
|
||||
{"GET", "/repos/fenny/fiber/releases"},
|
||||
{"GET", "/repos/fenny/fiber/releases/1337"},
|
||||
{"POST", "/repos/fenny/fiber/releases"},
|
||||
{"PATCH", "/repos/fenny/fiber/releases/1337"},
|
||||
{"DELETE", "/repos/fenny/fiber/releases/1337"},
|
||||
{"GET", "/repos/fenny/fiber/releases/1337/assets"},
|
||||
{"GET", "/repos/fenny/fiber/stats/contributors"},
|
||||
{"GET", "/repos/fenny/fiber/stats/commit_activity"},
|
||||
{"GET", "/repos/fenny/fiber/stats/code_frequency"},
|
||||
{"GET", "/repos/fenny/fiber/stats/participation"},
|
||||
{"GET", "/repos/fenny/fiber/stats/punch_card"},
|
||||
{"GET", "/repos/fenny/fiber/statuses/google"},
|
||||
{"POST", "/repos/fenny/fiber/statuses/google"},
|
||||
|
||||
// Search
|
||||
{"GET", "/search/repositories"},
|
||||
{"GET", "/search/code"},
|
||||
{"GET", "/search/issues"},
|
||||
{"GET", "/search/users"},
|
||||
{"GET", "/legacy/issues/search/fenny/fibersitory/locked/finish"},
|
||||
{"GET", "/legacy/repos/search/finish"},
|
||||
{"GET", "/legacy/user/search/finish"},
|
||||
{"GET", "/legacy/user/email/info@gofiber.io"},
|
||||
|
||||
// Users
|
||||
{"GET", "/users/fenny"},
|
||||
{"GET", "/user"},
|
||||
{"PATCH", "/user"},
|
||||
{"GET", "/users"},
|
||||
{"GET", "/user/emails"},
|
||||
{"POST", "/user/emails"},
|
||||
{"DELETE", "/user/emails"},
|
||||
{"GET", "/users/fenny/followers"},
|
||||
{"GET", "/user/followers"},
|
||||
{"GET", "/users/fenny/following"},
|
||||
{"GET", "/user/following"},
|
||||
{"GET", "/user/following/fenny"},
|
||||
{"GET", "/users/fenny/following/renan"},
|
||||
{"PUT", "/user/following/fenny"},
|
||||
{"DELETE", "/user/following/fenny"},
|
||||
{"GET", "/users/fenny/keys"},
|
||||
{"GET", "/user/keys"},
|
||||
{"GET", "/user/keys/1337"},
|
||||
{"POST", "/user/keys"},
|
||||
{"PATCH", "/user/keys/1337"},
|
||||
{"DELETE", "/user/keys/1337"},
|
||||
}
|
||||
|
||||
var githubAPI = []testRoute{
|
||||
// OAuth Authorizations
|
||||
{"GET", "/authorizations"},
|
||||
{"GET", "/authorizations/:id"},
|
||||
{"POST", "/authorizations"},
|
||||
{"PUT", "/authorizations/clients/:client_id"},
|
||||
{"PATCH", "/authorizations/:id"},
|
||||
{"DELETE", "/authorizations/:id"},
|
||||
{"GET", "/applications/:client_id/tokens/:access_token"},
|
||||
{"DELETE", "/applications/:client_id/tokens"},
|
||||
{"DELETE", "/applications/:client_id/tokens/:access_token"},
|
||||
|
||||
// Activity
|
||||
{"GET", "/events"},
|
||||
{"GET", "/repos/:owner/:repo/events"},
|
||||
{"GET", "/networks/:owner/:repo/events"},
|
||||
{"GET", "/orgs/:org/events"},
|
||||
{"GET", "/users/:user/received_events"},
|
||||
{"GET", "/users/:user/received_events/public"},
|
||||
{"GET", "/users/:user/events"},
|
||||
{"GET", "/users/:user/events/public"},
|
||||
{"GET", "/users/:user/events/orgs/:org"},
|
||||
{"GET", "/feeds"},
|
||||
{"GET", "/notifications"},
|
||||
{"GET", "/repos/:owner/:repo/notifications"},
|
||||
{"PUT", "/notifications"},
|
||||
{"PUT", "/repos/:owner/:repo/notifications"},
|
||||
{"GET", "/notifications/threads/:id"},
|
||||
{"PATCH", "/notifications/threads/:id"},
|
||||
{"GET", "/notifications/threads/:id/subscription"},
|
||||
{"PUT", "/notifications/threads/:id/subscription"},
|
||||
{"DELETE", "/notifications/threads/:id/subscription"},
|
||||
{"GET", "/repos/:owner/:repo/stargazers"},
|
||||
{"GET", "/users/:user/starred"},
|
||||
{"GET", "/user/starred"},
|
||||
{"GET", "/user/starred/:owner/:repo"},
|
||||
{"PUT", "/user/starred/:owner/:repo"},
|
||||
{"DELETE", "/user/starred/:owner/:repo"},
|
||||
{"GET", "/repos/:owner/:repo/subscribers"},
|
||||
{"GET", "/users/:user/subscriptions"},
|
||||
{"GET", "/user/subscriptions"},
|
||||
{"GET", "/repos/:owner/:repo/subscription"},
|
||||
{"PUT", "/repos/:owner/:repo/subscription"},
|
||||
{"DELETE", "/repos/:owner/:repo/subscription"},
|
||||
{"GET", "/user/subscriptions/:owner/:repo"},
|
||||
{"PUT", "/user/subscriptions/:owner/:repo"},
|
||||
{"DELETE", "/user/subscriptions/:owner/:repo"},
|
||||
|
||||
// Gists
|
||||
{"GET", "/users/:user/gists"},
|
||||
{"GET", "/gists"},
|
||||
{"GET", "/gists/public"},
|
||||
{"GET", "/gists/starred"},
|
||||
{"GET", "/gists/:id"},
|
||||
{"POST", "/gists"},
|
||||
{"PATCH", "/gists/:id"},
|
||||
{"PUT", "/gists/:id/star"},
|
||||
{"DELETE", "/gists/:id/star"},
|
||||
{"GET", "/gists/:id/star"},
|
||||
{"POST", "/gists/:id/forks"},
|
||||
{"DELETE", "/gists/:id"},
|
||||
|
||||
// Git Data
|
||||
{"GET", "/repos/:owner/:repo/git/blobs/:sha"},
|
||||
{"POST", "/repos/:owner/:repo/git/blobs"},
|
||||
{"GET", "/repos/:owner/:repo/git/commits/:sha"},
|
||||
{"POST", "/repos/:owner/:repo/git/commits"},
|
||||
{"GET", "/repos/:owner/:repo/git/refs/*"},
|
||||
{"GET", "/repos/:owner/:repo/git/refs"},
|
||||
{"POST", "/repos/:owner/:repo/git/refs"},
|
||||
{"PATCH", "/repos/:owner/:repo/git/refs/*"},
|
||||
{"DELETE", "/repos/:owner/:repo/git/refs/*"},
|
||||
{"GET", "/repos/:owner/:repo/git/tags/:sha"},
|
||||
{"POST", "/repos/:owner/:repo/git/tags"},
|
||||
{"GET", "/repos/:owner/:repo/git/trees/:sha"},
|
||||
{"POST", "/repos/:owner/:repo/git/trees"},
|
||||
|
||||
// Issues
|
||||
{"GET", "/issues"},
|
||||
{"GET", "/user/issues"},
|
||||
{"GET", "/orgs/:org/issues"},
|
||||
{"GET", "/repos/:owner/:repo/issues"},
|
||||
{"GET", "/repos/:owner/:repo/issues/:number"},
|
||||
{"POST", "/repos/:owner/:repo/issues"},
|
||||
{"PATCH", "/repos/:owner/:repo/issues/:number"},
|
||||
{"GET", "/repos/:owner/:repo/assignees"},
|
||||
{"GET", "/repos/:owner/:repo/assignees/:assignee"},
|
||||
{"GET", "/repos/:owner/:repo/issues/:number/comments"},
|
||||
{"GET", "/repos/:owner/:repo/issues/comments"},
|
||||
{"GET", "/repos/:owner/:repo/issues/comments/:id"},
|
||||
{"POST", "/repos/:owner/:repo/issues/:number/comments"},
|
||||
{"PATCH", "/repos/:owner/:repo/issues/comments/:id"},
|
||||
{"DELETE", "/repos/:owner/:repo/issues/comments/:id"},
|
||||
{"GET", "/repos/:owner/:repo/issues/:number/events"},
|
||||
{"GET", "/repos/:owner/:repo/issues/events"},
|
||||
{"GET", "/repos/:owner/:repo/issues/events/:id"},
|
||||
{"GET", "/repos/:owner/:repo/labels"},
|
||||
{"GET", "/repos/:owner/:repo/labels/:name"},
|
||||
{"POST", "/repos/:owner/:repo/labels"},
|
||||
{"PATCH", "/repos/:owner/:repo/labels/:name"},
|
||||
{"DELETE", "/repos/:owner/:repo/labels/:name"},
|
||||
{"GET", "/repos/:owner/:repo/issues/:number/labels"},
|
||||
{"POST", "/repos/:owner/:repo/issues/:number/labels"},
|
||||
{"DELETE", "/repos/:owner/:repo/issues/:number/labels/:name"},
|
||||
{"PUT", "/repos/:owner/:repo/issues/:number/labels"},
|
||||
{"DELETE", "/repos/:owner/:repo/issues/:number/labels"},
|
||||
{"GET", "/repos/:owner/:repo/milestones/:number/labels"},
|
||||
{"GET", "/repos/:owner/:repo/milestones"},
|
||||
{"GET", "/repos/:owner/:repo/milestones/:number"},
|
||||
{"POST", "/repos/:owner/:repo/milestones"},
|
||||
{"PATCH", "/repos/:owner/:repo/milestones/:number"},
|
||||
{"DELETE", "/repos/:owner/:repo/milestones/:number"},
|
||||
|
||||
// Miscellaneous
|
||||
{"GET", "/emojis"},
|
||||
{"GET", "/gitignore/templates"},
|
||||
{"GET", "/gitignore/templates/:name"},
|
||||
{"POST", "/markdown"},
|
||||
{"POST", "/markdown/raw"},
|
||||
{"GET", "/meta"},
|
||||
{"GET", "/rate_limit"},
|
||||
|
||||
// Organizations
|
||||
{"GET", "/users/:user/orgs"},
|
||||
{"GET", "/user/orgs"},
|
||||
{"GET", "/orgs/:org"},
|
||||
{"PATCH", "/orgs/:org"},
|
||||
{"GET", "/orgs/:org/members"},
|
||||
{"GET", "/orgs/:org/members/:user"},
|
||||
{"DELETE", "/orgs/:org/members/:user"},
|
||||
{"GET", "/orgs/:org/public_members"},
|
||||
{"GET", "/orgs/:org/public_members/:user"},
|
||||
{"PUT", "/orgs/:org/public_members/:user"},
|
||||
{"DELETE", "/orgs/:org/public_members/:user"},
|
||||
{"GET", "/orgs/:org/teams"},
|
||||
{"GET", "/teams/:id"},
|
||||
{"POST", "/orgs/:org/teams"},
|
||||
{"PATCH", "/teams/:id"},
|
||||
{"DELETE", "/teams/:id"},
|
||||
{"GET", "/teams/:id/members"},
|
||||
{"GET", "/teams/:id/members/:user"},
|
||||
{"PUT", "/teams/:id/members/:user"},
|
||||
{"DELETE", "/teams/:id/members/:user"},
|
||||
{"GET", "/teams/:id/repos"},
|
||||
{"GET", "/teams/:id/repos/:owner/:repo"},
|
||||
{"PUT", "/teams/:id/repos/:owner/:repo"},
|
||||
{"DELETE", "/teams/:id/repos/:owner/:repo"},
|
||||
{"GET", "/user/teams"},
|
||||
|
||||
// Pull Requests
|
||||
{"GET", "/repos/:owner/:repo/pulls"},
|
||||
{"GET", "/repos/:owner/:repo/pulls/:number"},
|
||||
{"POST", "/repos/:owner/:repo/pulls"},
|
||||
{"PATCH", "/repos/:owner/:repo/pulls/:number"},
|
||||
{"GET", "/repos/:owner/:repo/pulls/:number/commits"},
|
||||
{"GET", "/repos/:owner/:repo/pulls/:number/files"},
|
||||
{"GET", "/repos/:owner/:repo/pulls/:number/merge"},
|
||||
{"PUT", "/repos/:owner/:repo/pulls/:number/merge"},
|
||||
{"GET", "/repos/:owner/:repo/pulls/:number/comments"},
|
||||
{"GET", "/repos/:owner/:repo/pulls/comments"},
|
||||
{"GET", "/repos/:owner/:repo/pulls/comments/:number"},
|
||||
{"PUT", "/repos/:owner/:repo/pulls/:number/comments"},
|
||||
{"PATCH", "/repos/:owner/:repo/pulls/comments/:number"},
|
||||
{"DELETE", "/repos/:owner/:repo/pulls/comments/:number"},
|
||||
|
||||
// Repositories
|
||||
{"GET", "/user/repos"},
|
||||
{"GET", "/users/:user/repos"},
|
||||
{"GET", "/orgs/:org/repos"},
|
||||
{"GET", "/repositories"},
|
||||
{"POST", "/user/repos"},
|
||||
{"POST", "/orgs/:org/repos"},
|
||||
{"GET", "/repos/:owner/:repo"},
|
||||
{"PATCH", "/repos/:owner/:repo"},
|
||||
{"GET", "/repos/:owner/:repo/contributors"},
|
||||
{"GET", "/repos/:owner/:repo/languages"},
|
||||
{"GET", "/repos/:owner/:repo/teams"},
|
||||
{"GET", "/repos/:owner/:repo/tags"},
|
||||
{"GET", "/repos/:owner/:repo/branches"},
|
||||
{"GET", "/repos/:owner/:repo/branches/:branch"},
|
||||
{"DELETE", "/repos/:owner/:repo"},
|
||||
{"GET", "/repos/:owner/:repo/collaborators"},
|
||||
{"GET", "/repos/:owner/:repo/collaborators/:user"},
|
||||
{"PUT", "/repos/:owner/:repo/collaborators/:user"},
|
||||
{"DELETE", "/repos/:owner/:repo/collaborators/:user"},
|
||||
{"GET", "/repos/:owner/:repo/comments"},
|
||||
{"GET", "/repos/:owner/:repo/commits/:sha/comments"},
|
||||
{"POST", "/repos/:owner/:repo/commits/:sha/comments"},
|
||||
{"GET", "/repos/:owner/:repo/comments/:id"},
|
||||
{"PATCH", "/repos/:owner/:repo/comments/:id"},
|
||||
{"DELETE", "/repos/:owner/:repo/comments/:id"},
|
||||
{"GET", "/repos/:owner/:repo/commits"},
|
||||
{"GET", "/repos/:owner/:repo/commits/:sha"},
|
||||
{"GET", "/repos/:owner/:repo/readme"},
|
||||
{"GET", "/repos/:owner/:repo/contents/*"},
|
||||
{"PUT", "/repos/:owner/:repo/contents/*"},
|
||||
{"DELETE", "/repos/:owner/:repo/contents/*"},
|
||||
{"GET", "/repos/:owner/:repo/:archive_format/:ref"},
|
||||
{"GET", "/repos/:owner/:repo/keys"},
|
||||
{"GET", "/repos/:owner/:repo/keys/:id"},
|
||||
{"POST", "/repos/:owner/:repo/keys"},
|
||||
{"PATCH", "/repos/:owner/:repo/keys/:id"},
|
||||
{"DELETE", "/repos/:owner/:repo/keys/:id"},
|
||||
{"GET", "/repos/:owner/:repo/downloads"},
|
||||
{"GET", "/repos/:owner/:repo/downloads/:id"},
|
||||
{"DELETE", "/repos/:owner/:repo/downloads/:id"},
|
||||
{"GET", "/repos/:owner/:repo/forks"},
|
||||
{"POST", "/repos/:owner/:repo/forks"},
|
||||
{"GET", "/repos/:owner/:repo/hooks"},
|
||||
{"GET", "/repos/:owner/:repo/hooks/:id"},
|
||||
{"POST", "/repos/:owner/:repo/hooks"},
|
||||
{"PATCH", "/repos/:owner/:repo/hooks/:id"},
|
||||
{"POST", "/repos/:owner/:repo/hooks/:id/tests"},
|
||||
{"DELETE", "/repos/:owner/:repo/hooks/:id"},
|
||||
{"POST", "/repos/:owner/:repo/merges"},
|
||||
{"GET", "/repos/:owner/:repo/releases"},
|
||||
{"GET", "/repos/:owner/:repo/releases/:id"},
|
||||
{"POST", "/repos/:owner/:repo/releases"},
|
||||
{"PATCH", "/repos/:owner/:repo/releases/:id"},
|
||||
{"DELETE", "/repos/:owner/:repo/releases/:id"},
|
||||
{"GET", "/repos/:owner/:repo/releases/:id/assets"},
|
||||
{"GET", "/repos/:owner/:repo/stats/contributors"},
|
||||
{"GET", "/repos/:owner/:repo/stats/commit_activity"},
|
||||
{"GET", "/repos/:owner/:repo/stats/code_frequency"},
|
||||
{"GET", "/repos/:owner/:repo/stats/participation"},
|
||||
{"GET", "/repos/:owner/:repo/stats/punch_card"},
|
||||
{"GET", "/repos/:owner/:repo/statuses/:ref"},
|
||||
{"POST", "/repos/:owner/:repo/statuses/:ref"},
|
||||
|
||||
// Search
|
||||
{"GET", "/search/repositories"},
|
||||
{"GET", "/search/code"},
|
||||
{"GET", "/search/issues"},
|
||||
{"GET", "/search/users"},
|
||||
{"GET", "/legacy/issues/search/:owner/:repository/:state/:keyword"},
|
||||
{"GET", "/legacy/repos/search/:keyword"},
|
||||
{"GET", "/legacy/user/search/:keyword"},
|
||||
{"GET", "/legacy/user/email/:email"},
|
||||
|
||||
// Users
|
||||
{"GET", "/users/:user"},
|
||||
{"GET", "/user"},
|
||||
{"PATCH", "/user"},
|
||||
{"GET", "/users"},
|
||||
{"GET", "/user/emails"},
|
||||
{"POST", "/user/emails"},
|
||||
{"DELETE", "/user/emails"},
|
||||
{"GET", "/users/:user/followers"},
|
||||
{"GET", "/user/followers"},
|
||||
{"GET", "/users/:user/following"},
|
||||
{"GET", "/user/following"},
|
||||
{"GET", "/user/following/:user"},
|
||||
{"GET", "/users/:user/following/:target_user"},
|
||||
{"PUT", "/user/following/:user"},
|
||||
{"DELETE", "/user/following/:user"},
|
||||
{"GET", "/users/:user/keys"},
|
||||
{"GET", "/user/keys"},
|
||||
{"GET", "/user/keys/:id"},
|
||||
{"POST", "/user/keys"},
|
||||
{"PATCH", "/user/keys/:id"},
|
||||
{"DELETE", "/user/keys/:id"},
|
||||
}
|
462
utils.go
462
utils.go
@ -1,6 +1,6 @@
|
||||
// 🚀 Fiber is an Express inspired web framework written in Go with 💖
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
|
||||
package fiber
|
||||
|
||||
@ -10,15 +10,14 @@ import (
|
||||
"hash/crc32"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Document elke line gelijk even
|
||||
func setETag(ctx *Ctx, body []byte, weak bool) {
|
||||
// Generate and set ETag header to response
|
||||
func setETag(ctx *Ctx, weak bool) {
|
||||
body := ctx.Fasthttp.Response.Body()
|
||||
// Skips ETag if no response body is present
|
||||
if len(body) <= 0 {
|
||||
return
|
||||
@ -45,7 +44,7 @@ func setETag(ctx *Ctx, body []byte, weak bool) {
|
||||
return
|
||||
}
|
||||
// W/1 != W/2 || W/1 != 2
|
||||
ctx.Set("ETag", etag)
|
||||
ctx.Set(HeaderETag, etag)
|
||||
return
|
||||
}
|
||||
if strings.Contains(clientEtag, etag) {
|
||||
@ -55,10 +54,10 @@ func setETag(ctx *Ctx, body []byte, weak bool) {
|
||||
return
|
||||
}
|
||||
// 1 != 2
|
||||
ctx.Set("ETag", etag)
|
||||
ctx.Set(HeaderETag, etag)
|
||||
}
|
||||
|
||||
func groupPaths(prefix, path string) string {
|
||||
func getGroupPath(prefix, path string) string {
|
||||
if path == "/" {
|
||||
path = ""
|
||||
}
|
||||
@ -67,67 +66,6 @@ func groupPaths(prefix, path string) string {
|
||||
return path
|
||||
}
|
||||
|
||||
func getParams(path string) (params []string) {
|
||||
if len(path) < 1 {
|
||||
return
|
||||
}
|
||||
segments := strings.Split(path, "/")
|
||||
replacer := strings.NewReplacer(":", "", "?", "")
|
||||
for i := range segments {
|
||||
s := segments[i]
|
||||
if s == "" {
|
||||
continue
|
||||
} else if s[0] == ':' {
|
||||
params = append(params, replacer.Replace(s))
|
||||
}
|
||||
if strings.Contains(s, "*") {
|
||||
params = append(params, "*")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getRegex(path string) (*regexp.Regexp, error) {
|
||||
pattern := "^"
|
||||
segments := strings.Split(path, "/")
|
||||
for i := range segments {
|
||||
s := segments[i]
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
if s[0] == ':' {
|
||||
if strings.Contains(s, "?") {
|
||||
pattern += "(?:/([^/]+?))?"
|
||||
} else {
|
||||
pattern += "/(?:([^/]+?))"
|
||||
}
|
||||
} else if s[0] == '*' {
|
||||
pattern += "/(.*)"
|
||||
} else {
|
||||
pattern += "/" + s
|
||||
}
|
||||
}
|
||||
pattern += "/?$"
|
||||
regex, err := regexp.Compile(pattern)
|
||||
return regex, err
|
||||
}
|
||||
|
||||
func getFiles(root string) (files []string, dir bool, err error) {
|
||||
root = filepath.Clean(root)
|
||||
if _, err := os.Lstat(root); err != nil {
|
||||
return files, dir, fmt.Errorf("%s", err)
|
||||
}
|
||||
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
files = append(files, path)
|
||||
} else {
|
||||
dir = true
|
||||
}
|
||||
return err
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func getMIME(extension string) (mime string) {
|
||||
if extension == "" {
|
||||
return mime
|
||||
@ -228,8 +166,21 @@ func parseTokenList(noneMatchBytes []byte) []string {
|
||||
return list
|
||||
}
|
||||
|
||||
// HTTP methods and their unique INTs
|
||||
var methodINT = map[string]int{
|
||||
MethodGet: 0,
|
||||
MethodHead: 1,
|
||||
MethodPost: 2,
|
||||
MethodPut: 3,
|
||||
MethodPatch: 4,
|
||||
MethodDelete: 5,
|
||||
MethodConnect: 6,
|
||||
MethodOptions: 7,
|
||||
MethodTrace: 8,
|
||||
}
|
||||
|
||||
// HTTP status codes were copied from net/http.
|
||||
var statusMessages = map[int]string{
|
||||
var statusMessage = map[int]string{
|
||||
100: "Continue",
|
||||
101: "Switching Protocols",
|
||||
102: "Processing",
|
||||
@ -296,18 +247,15 @@ var statusMessages = map[int]string{
|
||||
|
||||
// MIME types were copied from labstack/echo
|
||||
const (
|
||||
MIMETextXML = "text/xml"
|
||||
MIMETextHTML = "text/html"
|
||||
MIMETextPlain = "text/plain"
|
||||
|
||||
MIMETextXML = "text/xml"
|
||||
MIMETextHTML = "text/html"
|
||||
MIMETextPlain = "text/plain"
|
||||
MIMEApplicationJSON = "application/json"
|
||||
MIMEApplicationJavaScript = "application/javascript"
|
||||
MIMEApplicationXML = "application/xml"
|
||||
MIMEApplicationForm = "application/x-www-form-urlencoded"
|
||||
|
||||
MIMEMultipartForm = "multipart/form-data"
|
||||
|
||||
MIMEOctetStream = "application/octet-stream"
|
||||
MIMEMultipartForm = "multipart/form-data"
|
||||
MIMEOctetStream = "application/octet-stream"
|
||||
)
|
||||
|
||||
// MIME types were copied from nginx/mime.types.
|
||||
@ -542,110 +490,77 @@ const (
|
||||
|
||||
// HTTP Headers were copied from net/http.
|
||||
const (
|
||||
// Authentication
|
||||
HeaderAuthorization = "Authorization"
|
||||
HeaderProxyAuthenticate = "Proxy-Authenticate"
|
||||
HeaderProxyAuthorization = "Proxy-Authorization"
|
||||
HeaderWWWAuthenticate = "WWW-Authenticate"
|
||||
|
||||
// Caching
|
||||
HeaderAge = "Age"
|
||||
HeaderCacheControl = "Cache-Control"
|
||||
HeaderClearSiteData = "Clear-Site-Data"
|
||||
HeaderExpires = "Expires"
|
||||
HeaderPragma = "Pragma"
|
||||
HeaderWarning = "Warning"
|
||||
|
||||
// Client hints
|
||||
HeaderAcceptCH = "Accept-CH"
|
||||
HeaderAcceptCHLifetime = "Accept-CH-Lifetime"
|
||||
HeaderContentDPR = "Content-DPR"
|
||||
HeaderDPR = "DPR"
|
||||
HeaderEarlyData = "Early-Data"
|
||||
HeaderSaveData = "Save-Data"
|
||||
HeaderViewportWidth = "Viewport-Width"
|
||||
HeaderWidth = "Width"
|
||||
|
||||
// Conditionals
|
||||
HeaderETag = "ETag"
|
||||
HeaderIfMatch = "If-Match"
|
||||
HeaderIfModifiedSince = "If-Modified-Since"
|
||||
HeaderIfNoneMatch = "If-None-Match"
|
||||
HeaderIfUnmodifiedSince = "If-Unmodified-Since"
|
||||
HeaderLastModified = "Last-Modified"
|
||||
HeaderVary = "Vary"
|
||||
|
||||
// Connection management
|
||||
HeaderConnection = "Connection"
|
||||
HeaderKeepAlive = "Keep-Alive"
|
||||
|
||||
// Content negotiation
|
||||
HeaderAccept = "Accept"
|
||||
HeaderAcceptCharset = "Accept-Charset"
|
||||
HeaderAcceptEncoding = "Accept-Encoding"
|
||||
HeaderAcceptLanguage = "Accept-Language"
|
||||
|
||||
// Controls
|
||||
HeaderCookie = "Cookie"
|
||||
HeaderExpect = "Expect"
|
||||
HeaderMaxForwards = "Max-Forwards"
|
||||
HeaderSetCookie = "Set-Cookie"
|
||||
|
||||
// CORS
|
||||
HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
|
||||
HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers"
|
||||
HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods"
|
||||
HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin"
|
||||
HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers"
|
||||
HeaderAccessControlMaxAge = "Access-Control-Max-Age"
|
||||
HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers"
|
||||
HeaderAccessControlRequestMethod = "Access-Control-Request-Method"
|
||||
HeaderOrigin = "Origin"
|
||||
HeaderTimingAllowOrigin = "Timing-Allow-Origin"
|
||||
HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies"
|
||||
|
||||
// Do Not Track
|
||||
HeaderDNT = "DNT"
|
||||
HeaderTk = "Tk"
|
||||
|
||||
// Downloads
|
||||
HeaderContentDisposition = "Content-Disposition"
|
||||
|
||||
// Message body information
|
||||
HeaderContentEncoding = "Content-Encoding"
|
||||
HeaderContentLanguage = "Content-Language"
|
||||
HeaderContentLength = "Content-Length"
|
||||
HeaderContentLocation = "Content-Location"
|
||||
HeaderContentType = "Content-Type"
|
||||
|
||||
// Proxies
|
||||
HeaderForwarded = "Forwarded"
|
||||
HeaderVia = "Via"
|
||||
HeaderXForwardedFor = "X-Forwarded-For"
|
||||
HeaderXForwardedHost = "X-Forwarded-Host"
|
||||
HeaderXForwardedProto = "X-Forwarded-Proto"
|
||||
|
||||
// Redirects
|
||||
HeaderLocation = "Location"
|
||||
|
||||
// Request context
|
||||
HeaderFrom = "From"
|
||||
HeaderHost = "Host"
|
||||
HeaderReferer = "Referer"
|
||||
HeaderReferrerPolicy = "Referrer-Policy"
|
||||
HeaderUserAgent = "User-Agent"
|
||||
|
||||
// Response context
|
||||
HeaderAllow = "Allow"
|
||||
HeaderServer = "Server"
|
||||
|
||||
// Range requests
|
||||
HeaderAcceptRanges = "Accept-Ranges"
|
||||
HeaderContentRange = "Content-Range"
|
||||
HeaderIfRange = "If-Range"
|
||||
HeaderRange = "Range"
|
||||
|
||||
// Security
|
||||
HeaderAuthorization = "Authorization"
|
||||
HeaderProxyAuthenticate = "Proxy-Authenticate"
|
||||
HeaderProxyAuthorization = "Proxy-Authorization"
|
||||
HeaderWWWAuthenticate = "WWW-Authenticate"
|
||||
HeaderAge = "Age"
|
||||
HeaderCacheControl = "Cache-Control"
|
||||
HeaderClearSiteData = "Clear-Site-Data"
|
||||
HeaderExpires = "Expires"
|
||||
HeaderPragma = "Pragma"
|
||||
HeaderWarning = "Warning"
|
||||
HeaderAcceptCH = "Accept-CH"
|
||||
HeaderAcceptCHLifetime = "Accept-CH-Lifetime"
|
||||
HeaderContentDPR = "Content-DPR"
|
||||
HeaderDPR = "DPR"
|
||||
HeaderEarlyData = "Early-Data"
|
||||
HeaderSaveData = "Save-Data"
|
||||
HeaderViewportWidth = "Viewport-Width"
|
||||
HeaderWidth = "Width"
|
||||
HeaderETag = "ETag"
|
||||
HeaderIfMatch = "If-Match"
|
||||
HeaderIfModifiedSince = "If-Modified-Since"
|
||||
HeaderIfNoneMatch = "If-None-Match"
|
||||
HeaderIfUnmodifiedSince = "If-Unmodified-Since"
|
||||
HeaderLastModified = "Last-Modified"
|
||||
HeaderVary = "Vary"
|
||||
HeaderConnection = "Connection"
|
||||
HeaderKeepAlive = "Keep-Alive"
|
||||
HeaderAccept = "Accept"
|
||||
HeaderAcceptCharset = "Accept-Charset"
|
||||
HeaderAcceptEncoding = "Accept-Encoding"
|
||||
HeaderAcceptLanguage = "Accept-Language"
|
||||
HeaderCookie = "Cookie"
|
||||
HeaderExpect = "Expect"
|
||||
HeaderMaxForwards = "Max-Forwards"
|
||||
HeaderSetCookie = "Set-Cookie"
|
||||
HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
|
||||
HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers"
|
||||
HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods"
|
||||
HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin"
|
||||
HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers"
|
||||
HeaderAccessControlMaxAge = "Access-Control-Max-Age"
|
||||
HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers"
|
||||
HeaderAccessControlRequestMethod = "Access-Control-Request-Method"
|
||||
HeaderOrigin = "Origin"
|
||||
HeaderTimingAllowOrigin = "Timing-Allow-Origin"
|
||||
HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies"
|
||||
HeaderDNT = "DNT"
|
||||
HeaderTk = "Tk"
|
||||
HeaderContentDisposition = "Content-Disposition"
|
||||
HeaderContentEncoding = "Content-Encoding"
|
||||
HeaderContentLanguage = "Content-Language"
|
||||
HeaderContentLength = "Content-Length"
|
||||
HeaderContentLocation = "Content-Location"
|
||||
HeaderContentType = "Content-Type"
|
||||
HeaderForwarded = "Forwarded"
|
||||
HeaderVia = "Via"
|
||||
HeaderXForwardedFor = "X-Forwarded-For"
|
||||
HeaderXForwardedHost = "X-Forwarded-Host"
|
||||
HeaderXForwardedProto = "X-Forwarded-Proto"
|
||||
HeaderLocation = "Location"
|
||||
HeaderFrom = "From"
|
||||
HeaderHost = "Host"
|
||||
HeaderReferer = "Referer"
|
||||
HeaderReferrerPolicy = "Referrer-Policy"
|
||||
HeaderUserAgent = "User-Agent"
|
||||
HeaderAllow = "Allow"
|
||||
HeaderServer = "Server"
|
||||
HeaderAcceptRanges = "Accept-Ranges"
|
||||
HeaderContentRange = "Content-Range"
|
||||
HeaderIfRange = "If-Range"
|
||||
HeaderRange = "Range"
|
||||
HeaderContentSecurityPolicy = "Content-Security-Policy"
|
||||
HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
|
||||
HeaderCrossOriginResourcePolicy = "Cross-Origin-Resource-Policy"
|
||||
@ -660,107 +575,94 @@ const (
|
||||
HeaderXFrameOptions = "X-Frame-Options"
|
||||
HeaderXPoweredBy = "X-Powered-By"
|
||||
HeaderXXSSProtection = "X-XSS-Protection"
|
||||
|
||||
// Server-sent event
|
||||
HeaderLastEventID = "Last-Event-ID"
|
||||
HeaderNEL = "NEL"
|
||||
HeaderPingFrom = "Ping-From"
|
||||
HeaderPingTo = "Ping-To"
|
||||
HeaderReportTo = "Report-To"
|
||||
|
||||
// Transfer coding
|
||||
HeaderTE = "TE"
|
||||
HeaderTrailer = "Trailer"
|
||||
HeaderTransferEncoding = "Transfer-Encoding"
|
||||
|
||||
// WebSockets
|
||||
HeaderSecWebSocketAccept = "Sec-WebSocket-Accept"
|
||||
HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions"
|
||||
HeaderSecWebSocketKey = "Sec-WebSocket-Key"
|
||||
HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol"
|
||||
HeaderSecWebSocketVersion = "Sec-WebSocket-Version"
|
||||
|
||||
// Other
|
||||
HeaderAcceptPatch = "Accept-Patch"
|
||||
HeaderAcceptPushPolicy = "Accept-Push-Policy"
|
||||
HeaderAcceptSignature = "Accept-Signature"
|
||||
HeaderAltSvc = "Alt-Svc"
|
||||
HeaderDate = "Date"
|
||||
HeaderIndex = "Index"
|
||||
HeaderLargeAllocation = "Large-Allocation"
|
||||
HeaderLink = "Link"
|
||||
HeaderPushPolicy = "Push-Policy"
|
||||
HeaderRetryAfter = "Retry-After"
|
||||
HeaderServerTiming = "Server-Timing"
|
||||
HeaderSignature = "Signature"
|
||||
HeaderSignedHeaders = "Signed-Headers"
|
||||
HeaderSourceMap = "SourceMap"
|
||||
HeaderUpgrade = "Upgrade"
|
||||
HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control"
|
||||
HeaderXPingback = "X-Pingback"
|
||||
HeaderXRequestID = "X-Request-ID"
|
||||
HeaderXRequestedWith = "X-Requested-With"
|
||||
HeaderXRobotsTag = "X-Robots-Tag"
|
||||
HeaderXUACompatible = "X-UA-Compatible"
|
||||
HeaderLastEventID = "Last-Event-ID"
|
||||
HeaderNEL = "NEL"
|
||||
HeaderPingFrom = "Ping-From"
|
||||
HeaderPingTo = "Ping-To"
|
||||
HeaderReportTo = "Report-To"
|
||||
HeaderTE = "TE"
|
||||
HeaderTrailer = "Trailer"
|
||||
HeaderTransferEncoding = "Transfer-Encoding"
|
||||
HeaderSecWebSocketAccept = "Sec-WebSocket-Accept"
|
||||
HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions"
|
||||
HeaderSecWebSocketKey = "Sec-WebSocket-Key"
|
||||
HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol"
|
||||
HeaderSecWebSocketVersion = "Sec-WebSocket-Version"
|
||||
HeaderAcceptPatch = "Accept-Patch"
|
||||
HeaderAcceptPushPolicy = "Accept-Push-Policy"
|
||||
HeaderAcceptSignature = "Accept-Signature"
|
||||
HeaderAltSvc = "Alt-Svc"
|
||||
HeaderDate = "Date"
|
||||
HeaderIndex = "Index"
|
||||
HeaderLargeAllocation = "Large-Allocation"
|
||||
HeaderLink = "Link"
|
||||
HeaderPushPolicy = "Push-Policy"
|
||||
HeaderRetryAfter = "Retry-After"
|
||||
HeaderServerTiming = "Server-Timing"
|
||||
HeaderSignature = "Signature"
|
||||
HeaderSignedHeaders = "Signed-Headers"
|
||||
HeaderSourceMap = "SourceMap"
|
||||
HeaderUpgrade = "Upgrade"
|
||||
HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control"
|
||||
HeaderXPingback = "X-Pingback"
|
||||
HeaderXRequestID = "X-Request-ID"
|
||||
HeaderXRequestedWith = "X-Requested-With"
|
||||
HeaderXRobotsTag = "X-Robots-Tag"
|
||||
HeaderXUACompatible = "X-UA-Compatible"
|
||||
)
|
||||
|
||||
// HTTP status codes were copied from net/http.
|
||||
const (
|
||||
StatusContinue = 100 // RFC 7231, 6.2.1
|
||||
StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2
|
||||
StatusProcessing = 102 // RFC 2518, 10.1
|
||||
StatusEarlyHints = 103 // RFC 8297
|
||||
|
||||
StatusOK = 200 // RFC 7231, 6.3.1
|
||||
StatusCreated = 201 // RFC 7231, 6.3.2
|
||||
StatusAccepted = 202 // RFC 7231, 6.3.3
|
||||
StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4
|
||||
StatusNoContent = 204 // RFC 7231, 6.3.5
|
||||
StatusResetContent = 205 // RFC 7231, 6.3.6
|
||||
StatusPartialContent = 206 // RFC 7233, 4.1
|
||||
StatusMultiStatus = 207 // RFC 4918, 11.1
|
||||
StatusAlreadyReported = 208 // RFC 5842, 7.1
|
||||
StatusIMUsed = 226 // RFC 3229, 10.4.1
|
||||
|
||||
StatusMultipleChoices = 300 // RFC 7231, 6.4.1
|
||||
StatusMovedPermanently = 301 // RFC 7231, 6.4.2
|
||||
StatusFound = 302 // RFC 7231, 6.4.3
|
||||
StatusSeeOther = 303 // RFC 7231, 6.4.4
|
||||
StatusNotModified = 304 // RFC 7232, 4.1
|
||||
StatusUseProxy = 305 // RFC 7231, 6.4.5
|
||||
|
||||
StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7
|
||||
StatusPermanentRedirect = 308 // RFC 7538, 3
|
||||
|
||||
StatusBadRequest = 400 // RFC 7231, 6.5.1
|
||||
StatusUnauthorized = 401 // RFC 7235, 3.1
|
||||
StatusPaymentRequired = 402 // RFC 7231, 6.5.2
|
||||
StatusForbidden = 403 // RFC 7231, 6.5.3
|
||||
StatusNotFound = 404 // RFC 7231, 6.5.4
|
||||
StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5
|
||||
StatusNotAcceptable = 406 // RFC 7231, 6.5.6
|
||||
StatusProxyAuthRequired = 407 // RFC 7235, 3.2
|
||||
StatusRequestTimeout = 408 // RFC 7231, 6.5.7
|
||||
StatusConflict = 409 // RFC 7231, 6.5.8
|
||||
StatusGone = 410 // RFC 7231, 6.5.9
|
||||
StatusLengthRequired = 411 // RFC 7231, 6.5.10
|
||||
StatusPreconditionFailed = 412 // RFC 7232, 4.2
|
||||
StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11
|
||||
StatusRequestURITooLong = 414 // RFC 7231, 6.5.12
|
||||
StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13
|
||||
StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4
|
||||
StatusExpectationFailed = 417 // RFC 7231, 6.5.14
|
||||
StatusTeapot = 418 // RFC 7168, 2.3.3
|
||||
StatusMisdirectedRequest = 421 // RFC 7540, 9.1.2
|
||||
StatusUnprocessableEntity = 422 // RFC 4918, 11.2
|
||||
StatusLocked = 423 // RFC 4918, 11.3
|
||||
StatusFailedDependency = 424 // RFC 4918, 11.4
|
||||
StatusUpgradeRequired = 426 // RFC 7231, 6.5.15
|
||||
StatusPreconditionRequired = 428 // RFC 6585, 3
|
||||
StatusTooManyRequests = 429 // RFC 6585, 4
|
||||
StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5
|
||||
StatusUnavailableForLegalReasons = 451 // RFC 7725, 3
|
||||
|
||||
StatusContinue = 100 // RFC 7231, 6.2.1
|
||||
StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2
|
||||
StatusProcessing = 102 // RFC 2518, 10.1
|
||||
StatusEarlyHints = 103 // RFC 8297
|
||||
StatusOK = 200 // RFC 7231, 6.3.1
|
||||
StatusCreated = 201 // RFC 7231, 6.3.2
|
||||
StatusAccepted = 202 // RFC 7231, 6.3.3
|
||||
StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4
|
||||
StatusNoContent = 204 // RFC 7231, 6.3.5
|
||||
StatusResetContent = 205 // RFC 7231, 6.3.6
|
||||
StatusPartialContent = 206 // RFC 7233, 4.1
|
||||
StatusMultiStatus = 207 // RFC 4918, 11.1
|
||||
StatusAlreadyReported = 208 // RFC 5842, 7.1
|
||||
StatusIMUsed = 226 // RFC 3229, 10.4.1
|
||||
StatusMultipleChoices = 300 // RFC 7231, 6.4.1
|
||||
StatusMovedPermanently = 301 // RFC 7231, 6.4.2
|
||||
StatusFound = 302 // RFC 7231, 6.4.3
|
||||
StatusSeeOther = 303 // RFC 7231, 6.4.4
|
||||
StatusNotModified = 304 // RFC 7232, 4.1
|
||||
StatusUseProxy = 305 // RFC 7231, 6.4.5
|
||||
StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7
|
||||
StatusPermanentRedirect = 308 // RFC 7538, 3
|
||||
StatusBadRequest = 400 // RFC 7231, 6.5.1
|
||||
StatusUnauthorized = 401 // RFC 7235, 3.1
|
||||
StatusPaymentRequired = 402 // RFC 7231, 6.5.2
|
||||
StatusForbidden = 403 // RFC 7231, 6.5.3
|
||||
StatusNotFound = 404 // RFC 7231, 6.5.4
|
||||
StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5
|
||||
StatusNotAcceptable = 406 // RFC 7231, 6.5.6
|
||||
StatusProxyAuthRequired = 407 // RFC 7235, 3.2
|
||||
StatusRequestTimeout = 408 // RFC 7231, 6.5.7
|
||||
StatusConflict = 409 // RFC 7231, 6.5.8
|
||||
StatusGone = 410 // RFC 7231, 6.5.9
|
||||
StatusLengthRequired = 411 // RFC 7231, 6.5.10
|
||||
StatusPreconditionFailed = 412 // RFC 7232, 4.2
|
||||
StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11
|
||||
StatusRequestURITooLong = 414 // RFC 7231, 6.5.12
|
||||
StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13
|
||||
StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4
|
||||
StatusExpectationFailed = 417 // RFC 7231, 6.5.14
|
||||
StatusTeapot = 418 // RFC 7168, 2.3.3
|
||||
StatusMisdirectedRequest = 421 // RFC 7540, 9.1.2
|
||||
StatusUnprocessableEntity = 422 // RFC 4918, 11.2
|
||||
StatusLocked = 423 // RFC 4918, 11.3
|
||||
StatusFailedDependency = 424 // RFC 4918, 11.4
|
||||
StatusUpgradeRequired = 426 // RFC 7231, 6.5.15
|
||||
StatusPreconditionRequired = 428 // RFC 6585, 3
|
||||
StatusTooManyRequests = 429 // RFC 6585, 4
|
||||
StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5
|
||||
StatusUnavailableForLegalReasons = 451 // RFC 7725, 3
|
||||
StatusInternalServerError = 500 // RFC 7231, 6.6.1
|
||||
StatusNotImplemented = 501 // RFC 7231, 6.6.2
|
||||
StatusBadGateway = 502 // RFC 7231, 6.6.3
|
||||
|
Loading…
x
Reference in New Issue
Block a user