mirror of https://github.com/gofiber/fiber.git
Use param support + optimizations (#361)
* Benchmark workflow * Update router.go * Clean root * Add mutex * Benchmark workflow * Benchmark workflow * Add mutex * Enable benchmark tests * Enable race testing Co-Authored-By: ReneWerner87 <renewerner87@users.noreply.github.com> * Benchmark Workflow * Benchmark workflow * Add mutex * Enable benchmark tests * Enable race testing Co-Authored-By: ReneWerner87 <renewerner87@users.noreply.github.com> * Update security workflow * Benchmark workflow * Add mutex * Enable benchmark tests * Enable race testing Co-Authored-By: ReneWerner87 <renewerner87@users.noreply.github.com> * Make Ctx pool accessible - Add ctx benchmarks * v1.9.6 * v1.9.6 Co-Authored-By: ReneWerner87 <renewerner87@googlemail.com> * Improve context functions * Add utils benchmarks * Update benchmarks & tests * Add utils tests * New tests * update test * Move fastpath tests * offer negotiation * Cleanup * Update Vary Co-Authored-By: RW <renewerner87@googlemail.com> * Optimize Append Co-Authored-By: RW <renewerner87@googlemail.com> * Optimize more methods Co-Authored-By: RW <renewerner87@googlemail.com> Co-Authored-By: Vic Shóstak <vikkyshostak@gmail.com> * Add param support to Use Co-Authored-By: RW <renewerner87@googlemail.com> Co-Authored-By: Vic Shóstak <vikkyshostak@gmail.com> * Add use_params tests Co-Authored-By: RW <renewerner87@googlemail.com> Co-Authored-By: Vic Shóstak <vikkyshostak@gmail.com> * v1.9.7 Co-Authored-By: RW <renewerner87@googlemail.com> Co-Authored-By: Vic Shóstak <vikkyshostak@gmail.com> * Tests Co-Authored-By: RW <renewerner87@googlemail.com> Co-Authored-By: Vic Shóstak <vikkyshostak@gmail.com> * v1.9.7 Co-Authored-By: RW <renewerner87@googlemail.com> Co-Authored-By: Vic Shóstak <vikkyshostak@gmail.com> Co-Authored-By: József Sallai <jozsef@sallai.me> Co-Authored-By: Thomas van Vugt <thomasvvugt@users.noreply.github.com> * Update app_test.go Co-Authored-By: RW <renewerner87@googlemail.com> Co-Authored-By: Vic Shóstak <vikkyshostak@gmail.com> Co-Authored-By: József Sallai <jozsef@sallai.me> Co-Authored-By: Thomas van Vugt <thomasvvugt@users.noreply.github.com> Co-Authored-By: Nifty255 <nifty255@users.noreply.github.com> * Rename argument Co-Authored-By: RW <renewerner87@googlemail.com> * Add nosec for WriteByte Co-Authored-By: RW <renewerner87@googlemail.com> * Add media article * Update media articles * Fix typo Co-Authored-By: Thomas van Vugt <thomasvvugt@users.noreply.github.com> * Fix typo Co-authored-by: ReneWerner87 <renewerner87@users.noreply.github.com> Co-authored-by: ReneWerner87 <renewerner87@googlemail.com> Co-authored-by: Vic Shóstak <vikkyshostak@gmail.com> Co-authored-by: József Sallai <jozsef@sallai.me> Co-authored-by: Thomas van Vugt <thomasvvugt@users.noreply.github.com> Co-authored-by: Nifty255 <nifty255@users.noreply.github.com>pull/366/head
parent
99f95b2561
commit
e719fa00bf
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -471,15 +471,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -496,6 +497,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 Media
|
||||
|
||||
|
@ -507,6 +510,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Contribute
|
||||
|
||||
|
@ -530,6 +534,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -548,3 +553,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -467,15 +467,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -492,6 +493,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 Medien
|
||||
|
||||
|
@ -503,6 +506,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Mitwirken
|
||||
|
||||
|
@ -526,6 +530,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -541,6 +546,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
**Third-party MIT licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -467,15 +467,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -492,6 +493,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 Medios
|
||||
|
||||
|
@ -503,6 +506,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Contribuir
|
||||
|
||||
|
@ -526,6 +530,7 @@ Fiber es un proyecto open source que se mantiene a través de donaciones para pa
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -544,3 +549,4 @@ Copyright (c) 2019-presente [Fenny](https://github.com/fenny) y [contribuyentes]
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -467,15 +467,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -492,6 +493,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 Media
|
||||
|
||||
|
@ -503,6 +506,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Contribuer
|
||||
|
||||
|
@ -526,6 +530,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -544,3 +549,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</div>
|
||||
</p>
|
||||
|
@ -579,15 +579,16 @@ For an more _maintainable_ middleware _ecosystem_, we've put official [middlewar
|
|||
|
||||
<div dir="rtl">
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -615,6 +616,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
@ -630,7 +633,9 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
@ -672,6 +677,7 @@ Fiber היא פרויקט קוד פתוח שתשלום חשובונתיו מסת
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -702,4 +708,5 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**רישיונות של ספריות צד שלישי**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
</div>
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -469,15 +469,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -494,6 +495,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 Media
|
||||
|
||||
|
@ -505,6 +508,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Berkontribusi
|
||||
|
||||
|
@ -528,6 +532,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -546,3 +551,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -471,15 +471,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -496,6 +497,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 メディア
|
||||
|
||||
|
@ -507,6 +510,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 貢献する
|
||||
|
||||
|
@ -530,6 +534,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -548,3 +553,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -471,15 +471,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -496,6 +497,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 미디어
|
||||
|
||||
|
@ -507,6 +510,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 기여
|
||||
|
||||
|
@ -530,6 +534,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -548,3 +553,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -471,15 +471,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -496,6 +497,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 Media
|
||||
|
||||
|
@ -507,6 +510,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Bijdragen
|
||||
|
||||
|
@ -530,6 +534,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -548,3 +553,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -467,15 +467,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -492,6 +493,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 Mídia
|
||||
|
||||
|
@ -503,6 +506,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Contribuindo
|
||||
|
||||
|
@ -526,6 +530,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -544,3 +549,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -469,15 +469,16 @@ func main() {
|
|||
|
||||
Чтобы создать более _поддерживаемую_ middleware _экосистему_, мы вынесли [middlewares](https://docs.gofiber.io/middleware) в отдельные репозитории:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -495,6 +496,8 @@ func main() {
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 Медиа
|
||||
|
||||
|
@ -506,6 +509,7 @@ func main() {
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Помощь проекту
|
||||
|
||||
|
@ -531,6 +535,7 @@ Fiber — это проект с открытым исходным кодом,
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -549,3 +554,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -465,15 +465,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -490,17 +491,21 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 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_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it still fast, flexible and friendly?](https://dev.to/koddr/fiber-v2-is-out-now-what-s-new-and-is-he-still-fast-flexible-and-friendly-3ipf) — _21 Şubat 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mart 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Nisan 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Nisan 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Nisan 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Nisan 2020_
|
||||
- [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_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it still fast, flexible and friendly?](https://dev.to/koddr/fiber-v2-is-out-now-what-s-new-and-is-he-still-fast-flexible-and-friendly-3ipf) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 Destek
|
||||
|
||||
|
@ -523,6 +528,7 @@ Fiber, alan adı, gitbook, netlify, serverless yer sağlayıcısı giderleri ve
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -541,3 +547,4 @@ Telif (c) 2019-günümüz [Fenny](https://github.com/fenny) ve [Contributors](ht
|
|||
**3. Parti yazılım lisanları**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Gosec?label=gosec&style=flat-square">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20channel-7289DA?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/discord-join%20channel-7289DA?style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
|
@ -470,15 +470,16 @@ func main() {
|
|||
|
||||
For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:
|
||||
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/compression](https://github.com/gofiber/compression)
|
||||
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
|
||||
- [gofiber/requestid](https://github.com/gofiber/requestid)
|
||||
- [gofiber/websocket](https://github.com/gofiber/websocket)
|
||||
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
|
||||
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
|
||||
- [gofiber/recover](https://github.com/gofiber/recover)
|
||||
- [gofiber/limiter](https://github.com/gofiber/limiter)
|
||||
- [gofiber/session](https://github.com/gofiber/session)
|
||||
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
|
||||
- [gofiber/logger](https://github.com/gofiber/logger)
|
||||
- [gofiber/helmet](https://github.com/gofiber/helmet)
|
||||
- [gofiber/embed](https://github.com/gofiber/embed)
|
||||
|
@ -495,6 +496,8 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
|
||||
## 💬 媒体
|
||||
|
||||
|
@ -506,6 +509,7 @@ This is a list of middlewares that are created by the Fiber community, please cr
|
|||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
|
||||
## 👍 贡献
|
||||
|
||||
|
@ -529,6 +533,7 @@ Fiber is an open source project that runs on donations to pay the bills e.g. our
|
|||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
@ -547,3 +552,4 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
|
|||
**Third-party library licenses**
|
||||
- [FastHTTP](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [Schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
|
|
48
app.go
48
app.go
|
@ -25,7 +25,7 @@ import (
|
|||
)
|
||||
|
||||
// Version of current package
|
||||
const Version = "1.9.6"
|
||||
const Version = "1.9.7"
|
||||
|
||||
// Map is a shortcut for map[string]interface{}
|
||||
type Map map[string]interface{}
|
||||
|
@ -33,8 +33,7 @@ type Map map[string]interface{}
|
|||
// App denotes the Fiber application.
|
||||
type App struct {
|
||||
// Internal fields
|
||||
testconn *testConn // Test connection
|
||||
routes [][]*Route // Route stack
|
||||
routes [][]*Route // Route stack
|
||||
|
||||
// External fields
|
||||
Settings *Settings // Fiber settings
|
||||
|
@ -144,10 +143,8 @@ func New(settings ...*Settings) *App {
|
|||
getBytes = getBytesImmutable
|
||||
}
|
||||
}
|
||||
// Setup test listener
|
||||
app.testconn = new(testConn)
|
||||
// Setup server
|
||||
app.server = app.newServer()
|
||||
// Update fiber server settings with fasthttp server
|
||||
app.updateSettings()
|
||||
// Return application
|
||||
return app
|
||||
}
|
||||
|
@ -353,10 +350,8 @@ func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group {
|
|||
// Preforkin is not available using app.Serve(ln net.Listener)
|
||||
// You can pass an optional *tls.Config to enable TLS.
|
||||
func (app *App) Serve(ln net.Listener, tlsconfig ...*tls.Config) error {
|
||||
// Create fasthttp server
|
||||
app.mutex.Lock()
|
||||
app.server = app.newServer()
|
||||
app.mutex.Unlock()
|
||||
// Update fiber server settings
|
||||
app.updateSettings()
|
||||
// TLS config
|
||||
if len(tlsconfig) > 0 {
|
||||
ln = tls.NewListener(ln, tlsconfig[0])
|
||||
|
@ -383,10 +378,8 @@ func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error {
|
|||
if !strings.Contains(addr, ":") {
|
||||
addr = ":" + addr
|
||||
}
|
||||
// Create fasthttp server
|
||||
app.mutex.Lock()
|
||||
app.server = app.newServer()
|
||||
app.mutex.Unlock()
|
||||
// Update fiber server settings
|
||||
app.updateSettings()
|
||||
// Setup listener
|
||||
var ln net.Listener
|
||||
var err error
|
||||
|
@ -428,14 +421,6 @@ func (app *App) Shutdown() error {
|
|||
return app.server.Shutdown()
|
||||
}
|
||||
|
||||
// TestRaw is like Test buf for raw HTTP strings: GET / HTTP/1.1\r\n\r\n
|
||||
func (app *App) TestRaw(request string) error {
|
||||
if _, err := app.testconn.r.WriteString(request); err != nil {
|
||||
return err
|
||||
}
|
||||
return app.server.ServeConn(app.testconn)
|
||||
}
|
||||
|
||||
// Test is used for internal debugging by passing a *http.Request
|
||||
// Timeout is optional and defaults to 1s, -1 will disable it completely.
|
||||
func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, error) {
|
||||
|
@ -448,14 +433,18 @@ func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, e
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Update server settings
|
||||
app.updateSettings()
|
||||
// Create test connection
|
||||
conn := new(testConn)
|
||||
// Write raw http request
|
||||
if _, err = app.testconn.r.Write(dump); err != nil {
|
||||
if _, err = conn.r.Write(dump); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Serve conn to server
|
||||
channel := make(chan error)
|
||||
go func() {
|
||||
channel <- app.server.ServeConn(app.testconn)
|
||||
channel <- app.server.ServeConn(conn)
|
||||
}()
|
||||
// Wait for callback
|
||||
if timeout >= 0 {
|
||||
|
@ -476,7 +465,7 @@ func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, e
|
|||
return nil, err
|
||||
}
|
||||
// Read response
|
||||
buffer := bufio.NewReader(&app.testconn.w)
|
||||
buffer := bufio.NewReader(&conn.w)
|
||||
// Convert raw http response to *http.Response
|
||||
resp, err := http.ReadResponse(buffer, request)
|
||||
if err != nil {
|
||||
|
@ -535,8 +524,10 @@ func (dl *disableLogger) Printf(format string, args ...interface{}) {
|
|||
// fmt.Println(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func (app *App) newServer() *fasthttp.Server {
|
||||
return &fasthttp.Server{
|
||||
func (app *App) updateSettings() {
|
||||
// Create fasthttp server
|
||||
app.mutex.Lock()
|
||||
app.server = &fasthttp.Server{
|
||||
Handler: app.handler,
|
||||
Name: app.Settings.ServerHeader,
|
||||
Concurrency: app.Settings.Concurrency,
|
||||
|
@ -560,4 +551,5 @@ func (app *App) newServer() *fasthttp.Server {
|
|||
}
|
||||
},
|
||||
}
|
||||
app.mutex.Unlock()
|
||||
}
|
||||
|
|
|
@ -3,3 +3,5 @@
|
|||
// 📌 API Documentation: https://docs.gofiber.io
|
||||
|
||||
package fiber
|
||||
|
||||
// // go test -v ./... -run=^$ -bench=Benchmark_Ctx_Acce -benchmem -count=3
|
||||
|
|
43
app_test.go
43
app_test.go
|
@ -20,23 +20,19 @@ func testStatus200(t *testing.T, app *App, url string, method string) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
|
||||
func Test_Nested_Params(t *testing.T) {
|
||||
func Test_App_Nested_Params(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
t.Log(c.Route().Path)
|
||||
c.Status(400).Send("Should move on")
|
||||
})
|
||||
app.Get("/test/:param", func(c *Ctx) {
|
||||
t.Log(c.Route().Path)
|
||||
c.Status(400).Send("Should move on")
|
||||
})
|
||||
app.Get("/test/:param/test", func(c *Ctx) {
|
||||
t.Log(c.Route().Path)
|
||||
c.Status(400).Send("Should move on")
|
||||
})
|
||||
app.Get("/test/:param/test/:param2", func(c *Ctx) {
|
||||
t.Log(c.Route().Path)
|
||||
c.Status(200).Send("Good job")
|
||||
})
|
||||
|
||||
|
@ -47,16 +43,27 @@ func Test_Nested_Params(t *testing.T) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
|
||||
func Test_Raw(t *testing.T) {
|
||||
func Test_App_Use_Params(t *testing.T) {
|
||||
app := New()
|
||||
app.Get("/", func(c *Ctx) {
|
||||
c.SendString("Hello, World!")
|
||||
|
||||
app.Use("/prefix/:param", func(c *Ctx) {
|
||||
assertEqual(t, "john", c.Params("param"))
|
||||
})
|
||||
|
||||
app.TestRaw("GET / HTTP/1.1\r\n\r\n")
|
||||
}
|
||||
app.Use("/:param/*", func(c *Ctx) {
|
||||
assertEqual(t, "john", c.Params("param"))
|
||||
assertEqual(t, "doe", c.Params("*"))
|
||||
})
|
||||
|
||||
func Test_Order(t *testing.T) {
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/prefix/john", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest("GET", "/john/doe", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_App_Order(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -83,7 +90,7 @@ func Test_Order(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, "123", string(body))
|
||||
}
|
||||
func Test_Methods(t *testing.T) {
|
||||
func Test_App_Methods(t *testing.T) {
|
||||
|
||||
var dummyHandler = func(c *Ctx) {}
|
||||
|
||||
|
@ -124,7 +131,7 @@ func Test_Methods(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func Test_New(t *testing.T) {
|
||||
func Test_App_New(t *testing.T) {
|
||||
app := New()
|
||||
app.Get("/", func(*Ctx) {
|
||||
|
||||
|
@ -138,14 +145,14 @@ func Test_New(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func Test_Shutdown(t *testing.T) {
|
||||
func Test_App_Shutdown(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
_ = app.Shutdown()
|
||||
}
|
||||
|
||||
func Test_Static(t *testing.T) {
|
||||
func Test_App_Static(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
grp := app.Group("/v1")
|
||||
|
@ -179,7 +186,7 @@ func Test_Static(t *testing.T) {
|
|||
assertEqual(t, false, resp.Header.Get("Content-Length") == "")
|
||||
}
|
||||
|
||||
func Test_Group(t *testing.T) {
|
||||
func Test_App_Group(t *testing.T) {
|
||||
var dummyHandler = func(c *Ctx) {}
|
||||
|
||||
app := New()
|
||||
|
@ -229,7 +236,7 @@ func Test_Group(t *testing.T) {
|
|||
testStatus200(t, app, "/test/v1/users", "GET")
|
||||
}
|
||||
|
||||
func Test_Listen(t *testing.T) {
|
||||
func Test_App_Listen(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
@ -245,7 +252,7 @@ func Test_Listen(t *testing.T) {
|
|||
app.Listen("3003")
|
||||
}
|
||||
|
||||
func Test_Serve(t *testing.T) {
|
||||
func Test_App_Serve(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
DisableStartupMessage: true,
|
||||
Prefork: true,
|
||||
|
|
207
ctx.go
207
ctx.go
|
@ -24,6 +24,7 @@ import (
|
|||
"time"
|
||||
|
||||
schema "github.com/gorilla/schema"
|
||||
"github.com/valyala/bytebufferpool"
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
@ -100,7 +101,7 @@ func ReleaseCtx(ctx *Ctx) {
|
|||
}
|
||||
|
||||
// Accepts checks if the specified extensions or content types are acceptable.
|
||||
func (ctx *Ctx) Accepts(offers ...string) (offer string) {
|
||||
func (ctx *Ctx) Accepts(offers ...string) string {
|
||||
if len(offers) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
@ -112,11 +113,6 @@ func (ctx *Ctx) Accepts(offers ...string) (offer string) {
|
|||
specs := strings.Split(h, ",")
|
||||
for i := range offers {
|
||||
mimetype := getMIME(offers[i])
|
||||
// if mimetype != "" {
|
||||
// mimetype = strings.Split(mimetype, ";")[0]
|
||||
// } else {
|
||||
// mimetype = offer
|
||||
// }
|
||||
for k := range specs {
|
||||
spec := strings.TrimSpace(specs[k])
|
||||
if strings.HasPrefix(spec, "*/*") {
|
||||
|
@ -138,80 +134,18 @@ func (ctx *Ctx) Accepts(offers ...string) (offer string) {
|
|||
}
|
||||
|
||||
// AcceptsCharsets checks if the specified charset is acceptable.
|
||||
func (ctx *Ctx) AcceptsCharsets(offers ...string) (offer string) {
|
||||
if len(offers) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
h := ctx.Get(HeaderAcceptCharset)
|
||||
if h == "" {
|
||||
return offers[0]
|
||||
}
|
||||
|
||||
specs := strings.Split(h, ",")
|
||||
for i := range offers {
|
||||
for k := range specs {
|
||||
spec := strings.TrimSpace(specs[k])
|
||||
if strings.HasPrefix(spec, "*") {
|
||||
return offers[i]
|
||||
}
|
||||
if strings.HasPrefix(spec, offers[i]) {
|
||||
return offers[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
func (ctx *Ctx) AcceptsCharsets(offers ...string) string {
|
||||
return getOffer(ctx.Get(HeaderAcceptCharset), offers...)
|
||||
}
|
||||
|
||||
// AcceptsEncodings checks if the specified encoding is acceptable.
|
||||
func (ctx *Ctx) AcceptsEncodings(offers ...string) (offer string) {
|
||||
if len(offers) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
h := ctx.Get(HeaderAcceptEncoding)
|
||||
if h == "" {
|
||||
return offers[0]
|
||||
}
|
||||
|
||||
specs := strings.Split(h, ",")
|
||||
for i := range offers {
|
||||
for k := range specs {
|
||||
spec := strings.TrimSpace(specs[k])
|
||||
if strings.HasPrefix(spec, "*") {
|
||||
return offers[i]
|
||||
}
|
||||
if strings.HasPrefix(spec, offers[i]) {
|
||||
return offers[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
func (ctx *Ctx) AcceptsEncodings(offers ...string) string {
|
||||
return getOffer(ctx.Get(HeaderAcceptEncoding), offers...)
|
||||
}
|
||||
|
||||
// AcceptsLanguages checks if the specified language is acceptable.
|
||||
func (ctx *Ctx) AcceptsLanguages(offers ...string) (offer string) {
|
||||
if len(offers) == 0 {
|
||||
return ""
|
||||
}
|
||||
h := ctx.Get(HeaderAcceptLanguage)
|
||||
if h == "" {
|
||||
return offers[0]
|
||||
}
|
||||
|
||||
specs := strings.Split(h, ",")
|
||||
for i := range offers {
|
||||
for k := range specs {
|
||||
spec := strings.TrimSpace(specs[k])
|
||||
if strings.HasPrefix(spec, "*") {
|
||||
return offers[i]
|
||||
}
|
||||
if strings.HasPrefix(spec, offers[i]) {
|
||||
return offers[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
func (ctx *Ctx) AcceptsLanguages(offers ...string) string {
|
||||
return getOffer(ctx.Get(HeaderAcceptLanguage), offers...)
|
||||
}
|
||||
|
||||
// Append the specified value to the HTTP response header field.
|
||||
|
@ -220,15 +154,17 @@ func (ctx *Ctx) Append(field string, values ...string) {
|
|||
if len(values) == 0 {
|
||||
return
|
||||
}
|
||||
h := getString(ctx.Fasthttp.Response.Header.Peek(field))
|
||||
h := ctx.Fasthttp.Response.Header.Peek(field)
|
||||
for i := range values {
|
||||
if h == "" {
|
||||
h += values[i]
|
||||
} else {
|
||||
h += ", " + values[i]
|
||||
var value = getBytes(values[i])
|
||||
if len(h) == 0 {
|
||||
h = append(h, value...)
|
||||
} else if 0 != bytes.Compare(h, value) && !bytes.HasSuffix(h, append([]byte{' '}, value...)) &&
|
||||
!bytes.Contains(h, append(append([]byte{}, value...), ',')) {
|
||||
h = append(append(h, ',', ' '), value...)
|
||||
}
|
||||
}
|
||||
ctx.Set(field, h)
|
||||
ctx.Fasthttp.Response.Header.SetBytesV(field, h)
|
||||
}
|
||||
|
||||
// Attachment sets the HTTP response Content-Disposition header field to attachment.
|
||||
|
@ -321,7 +257,7 @@ func (ctx *Ctx) ClearCookie(key ...string) {
|
|||
|
||||
// Cookie sets a cookie by passing a cookie struct
|
||||
func (ctx *Ctx) Cookie(cookie *Cookie) {
|
||||
fcookie := &fasthttp.Cookie{}
|
||||
fcookie := fasthttp.AcquireCookie()
|
||||
fcookie.SetKey(cookie.Name)
|
||||
fcookie.SetValue(cookie.Value)
|
||||
fcookie.SetPath(cookie.Path)
|
||||
|
@ -346,6 +282,7 @@ func (ctx *Ctx) Cookie(cookie *Cookie) {
|
|||
fcookie.SetSameSite(fasthttp.CookieSameSiteDisabled)
|
||||
}
|
||||
ctx.Fasthttp.Response.Header.SetCookie(fcookie)
|
||||
fasthttp.ReleaseCookie(fcookie)
|
||||
}
|
||||
|
||||
// Cookies is used for getting a cookie value by key
|
||||
|
@ -381,9 +318,13 @@ func (ctx *Ctx) Error() error {
|
|||
// It uses Accepts to select a proper format.
|
||||
// If the header is not specified or there is no proper format, text/plain is used.
|
||||
func (ctx *Ctx) Format(body interface{}) {
|
||||
var b string
|
||||
accept := ctx.Accepts("html", "json")
|
||||
// Get accepted content type
|
||||
accept := ctx.Accepts("html", "json", "txt", "xml")
|
||||
// Set accepted content type
|
||||
ctx.Type(accept)
|
||||
|
||||
// Type convert provided body
|
||||
var b string
|
||||
switch val := body.(type) {
|
||||
case string:
|
||||
b = val
|
||||
|
@ -392,14 +333,26 @@ func (ctx *Ctx) Format(body interface{}) {
|
|||
default:
|
||||
b = fmt.Sprintf("%v", val)
|
||||
}
|
||||
|
||||
// Format based on the accept content type
|
||||
switch accept {
|
||||
case "html":
|
||||
ctx.SendString("<p>" + b + "</p>")
|
||||
case "json":
|
||||
if err := ctx.JSON(body); err != nil {
|
||||
// Fix
|
||||
ctx.Send(body) // Fallback
|
||||
log.Println("Format: error serializing json ", err)
|
||||
}
|
||||
case "text":
|
||||
ctx.SendString(b)
|
||||
case "xml":
|
||||
raw, err := xml.Marshal(body)
|
||||
if err != nil {
|
||||
ctx.Send(body) // Fallback
|
||||
log.Println("Format: error serializing xml ", err)
|
||||
} else {
|
||||
ctx.SendString(getString(raw))
|
||||
}
|
||||
default:
|
||||
ctx.SendString(b)
|
||||
}
|
||||
|
@ -542,39 +495,48 @@ func (ctx *Ctx) JSON(data interface{}) error {
|
|||
// By default, the callback name is simply callback.
|
||||
func (ctx *Ctx) JSONP(data interface{}, callback ...string) error {
|
||||
raw, err := json.Marshal(&data)
|
||||
// Check for errors
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
str := "callback("
|
||||
if len(callback) > 0 {
|
||||
str = callback[0] + "("
|
||||
}
|
||||
str += getString(raw) + ");"
|
||||
var result, cb string
|
||||
|
||||
ctx.Set(HeaderXContentTypeOptions, "nosniff")
|
||||
if len(callback) > 0 {
|
||||
cb = callback[0]
|
||||
} else {
|
||||
cb = "callback"
|
||||
}
|
||||
|
||||
result = cb + "(" + getString(raw) + ");"
|
||||
|
||||
ctx.Fasthttp.Response.Header.Set(HeaderXContentTypeOptions, "nosniff")
|
||||
ctx.Fasthttp.Response.Header.SetContentType(MIMEApplicationJavaScript)
|
||||
ctx.Fasthttp.Response.SetBodyString(str)
|
||||
ctx.Fasthttp.Response.SetBodyString(result)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Links joins the links followed by the property to populate the response’s Link HTTP header field.
|
||||
// #nosec G104
|
||||
func (ctx *Ctx) Links(link ...string) {
|
||||
h := ""
|
||||
if len(link) == 0 {
|
||||
return
|
||||
}
|
||||
bb := bytebufferpool.Get()
|
||||
for i := range link {
|
||||
l := link[i]
|
||||
if i%2 == 0 {
|
||||
h += "<" + l + ">"
|
||||
bb.WriteByte('<')
|
||||
bb.WriteString(link[i])
|
||||
bb.WriteByte('>')
|
||||
} else {
|
||||
h += `; rel="` + l + `",`
|
||||
bb.WriteString(`; rel="`)
|
||||
bb.WriteString(link[i])
|
||||
bb.WriteString(`",`)
|
||||
}
|
||||
}
|
||||
|
||||
if len(link) > 0 {
|
||||
h = strings.TrimSuffix(h, ",")
|
||||
ctx.Set(HeaderLink, h)
|
||||
}
|
||||
ctx.Fasthttp.Response.Header.Set(HeaderLink, strings.TrimSuffix(bb.String(), ","))
|
||||
bytebufferpool.Put(bb)
|
||||
}
|
||||
|
||||
// Locals makes it possible to pass interface{} values under string keys scoped to the request
|
||||
|
@ -595,7 +557,7 @@ func (ctx *Ctx) Location(path string) {
|
|||
// Method contains a string corresponding to the HTTP method of the request: GET, POST, PUT and so on.
|
||||
func (ctx *Ctx) Method(override ...string) string {
|
||||
if len(override) > 0 {
|
||||
ctx.method = override[0]
|
||||
ctx.method = strings.ToUpper(override[0])
|
||||
}
|
||||
return ctx.method
|
||||
}
|
||||
|
@ -627,16 +589,16 @@ func (ctx *Ctx) OriginalURL() string {
|
|||
|
||||
// Params is used to get the route parameters.
|
||||
// Defaults to empty string "", if the param doesn't exist.
|
||||
func (ctx *Ctx) Params(key string) (value string) {
|
||||
if ctx.route.Params == nil {
|
||||
return
|
||||
}
|
||||
func (ctx *Ctx) Params(key string) string {
|
||||
for i := range ctx.route.Params {
|
||||
if (ctx.route.Params)[i] == key {
|
||||
if len(key) != len(ctx.route.Params[i]) {
|
||||
continue
|
||||
}
|
||||
if ctx.route.Params[i] == key {
|
||||
return ctx.values[i]
|
||||
}
|
||||
}
|
||||
return
|
||||
return ""
|
||||
}
|
||||
|
||||
// Path returns the path part of the request URL.
|
||||
|
@ -714,13 +676,12 @@ func (ctx *Ctx) Range(size int) (rangeData Range, err error) {
|
|||
// Redirect to the URL derived from the specified path, with specified status.
|
||||
// If status is not specified, status defaults to 302 Found
|
||||
func (ctx *Ctx) Redirect(path string, status ...int) {
|
||||
code := 302
|
||||
ctx.Fasthttp.Response.Header.Set(HeaderLocation, path)
|
||||
if len(status) > 0 {
|
||||
code = status[0]
|
||||
ctx.Fasthttp.Response.SetStatusCode(status[0])
|
||||
} else {
|
||||
ctx.Fasthttp.Response.SetStatusCode(StatusFound)
|
||||
}
|
||||
|
||||
ctx.Set(HeaderLocation, path)
|
||||
ctx.Fasthttp.Response.SetStatusCode(code)
|
||||
}
|
||||
|
||||
// Render a template with data and sends a text/html response.
|
||||
|
@ -860,23 +821,7 @@ func (ctx *Ctx) Type(ext string) *Ctx {
|
|||
// Vary adds the given header field to the Vary response header.
|
||||
// This will append the header, if not already listed, otherwise leaves it listed in the current location.
|
||||
func (ctx *Ctx) Vary(fields ...string) {
|
||||
if len(fields) == 0 {
|
||||
return
|
||||
}
|
||||
h := strings.ToLower(getString(ctx.Fasthttp.Response.Header.Peek(HeaderVary)))
|
||||
for i := range fields {
|
||||
fields[i] = strings.ToLower(fields[i])
|
||||
if len(h) == 0 {
|
||||
h += fields[i]
|
||||
} else if !strings.Contains(h, " "+fields[i]) && !strings.Contains(h, fields[i]+"") || !strings.Contains(h, fields[i]+",") {
|
||||
// Next developer, it's your job to optimize the following problem
|
||||
// Does the header value "Accept" exist in the following header value
|
||||
// "Origin, User-Agent, Accept-Encoding"
|
||||
// "Accept-Encoding" contains "Accept", false positive
|
||||
h += ", " + fields[i]
|
||||
}
|
||||
}
|
||||
ctx.Set(HeaderVary, h)
|
||||
ctx.Append(HeaderVary, fields...)
|
||||
}
|
||||
|
||||
// Write appends any input to the HTTP body response.
|
||||
|
@ -896,5 +841,5 @@ func (ctx *Ctx) Write(bodies ...interface{}) {
|
|||
// XHR returns a Boolean property, that is true, if the request’s X-Requested-With header field is XMLHttpRequest,
|
||||
// indicating that the request was issued by a client library (such as jQuery).
|
||||
func (ctx *Ctx) XHR() bool {
|
||||
return strings.ToLower(ctx.Get(HeaderXRequestedWith)) == "xmlhttprequest"
|
||||
return strings.EqualFold(ctx.Get(HeaderXRequestedWith), "xmlhttprequest")
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import (
|
|||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// go test -v ./... -run=^$ -bench=Benchmark_Ctx_Params -benchmem -count=3
|
||||
|
||||
func Benchmark_Ctx_Accepts(b *testing.B) {
|
||||
c := AcquireCtx(&fasthttp.RequestCtx{})
|
||||
defer ReleaseCtx(c)
|
||||
|
@ -63,7 +65,7 @@ func Benchmark_Ctx_AcceptsLanguages(b *testing.B) {
|
|||
|
||||
var res string
|
||||
for n := 0; n < b.N; n++ {
|
||||
res = c.AcceptsEncodings("fr")
|
||||
res = c.AcceptsLanguages("fr")
|
||||
}
|
||||
|
||||
assertEqual(b, "fr", res)
|
||||
|
@ -185,9 +187,29 @@ func Benchmark_Ctx_FormFile(b *testing.B) {
|
|||
// TODO
|
||||
// }
|
||||
|
||||
// func Benchmark_Ctx_Params(b *testing.B) {
|
||||
// TODO
|
||||
// }
|
||||
func Benchmark_Ctx_Params(b *testing.B) {
|
||||
c := AcquireCtx(&fasthttp.RequestCtx{})
|
||||
defer ReleaseCtx(c)
|
||||
|
||||
c.route = &Route{
|
||||
Params: []string{
|
||||
"param1", "param2", "param3", "param4",
|
||||
},
|
||||
}
|
||||
c.values = []string{
|
||||
"john", "doe", "is", "awesome",
|
||||
}
|
||||
|
||||
var res string
|
||||
for n := 0; n < b.N; n++ {
|
||||
res = c.Params("param1")
|
||||
res = c.Params("param2")
|
||||
res = c.Params("param3")
|
||||
res = c.Params("param4")
|
||||
}
|
||||
|
||||
assertEqual(b, "awesome", res)
|
||||
}
|
||||
|
||||
// func Benchmark_Ctx_Path(b *testing.B) {
|
||||
// TODO
|
||||
|
@ -217,13 +239,32 @@ func Benchmark_Ctx_FormFile(b *testing.B) {
|
|||
// TODO
|
||||
// }
|
||||
|
||||
// func Benchmark_Ctx_Subdomains(b *testing.B) {
|
||||
// TODO
|
||||
// }
|
||||
func Benchmark_Ctx_Subdomains(b *testing.B) {
|
||||
c := AcquireCtx(&fasthttp.RequestCtx{})
|
||||
defer ReleaseCtx(c)
|
||||
|
||||
// func Benchmark_Ctx_Append(b *testing.B) {
|
||||
// TODO
|
||||
// }
|
||||
c.Fasthttp.Request.SetRequestURI("http://john.doe.google.com")
|
||||
|
||||
var res []string
|
||||
for n := 0; n < b.N; n++ {
|
||||
res = c.Subdomains()
|
||||
}
|
||||
|
||||
assertEqual(b, []string{"john", "doe"}, res)
|
||||
}
|
||||
|
||||
func Benchmark_Ctx_Append(b *testing.B) {
|
||||
c := AcquireCtx(&fasthttp.RequestCtx{})
|
||||
defer ReleaseCtx(c)
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
c.Append("X-Custom-Header", "Hello")
|
||||
c.Append("X-Custom-Header", "World")
|
||||
c.Append("X-Custom-Header", "Hello")
|
||||
}
|
||||
|
||||
assertEqual(b, "Hello, World", getString(c.Fasthttp.Response.Header.Peek("X-Custom-Header")))
|
||||
}
|
||||
|
||||
// func Benchmark_Ctx_Attachment(b *testing.B) {
|
||||
// TODO
|
||||
|
@ -233,9 +274,19 @@ func Benchmark_Ctx_FormFile(b *testing.B) {
|
|||
// TODO
|
||||
// }
|
||||
|
||||
// func Benchmark_Ctx_Cookie(b *testing.B) {
|
||||
// TODO
|
||||
// }
|
||||
func Benchmark_Ctx_Cookie(b *testing.B) {
|
||||
c := AcquireCtx(&fasthttp.RequestCtx{})
|
||||
defer ReleaseCtx(c)
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
c.Cookie(&Cookie{
|
||||
Name: "John",
|
||||
Value: "Doe",
|
||||
})
|
||||
}
|
||||
|
||||
assertEqual(b, "John=Doe; path=/", getString(c.Fasthttp.Response.Header.Peek("Set-Cookie")))
|
||||
}
|
||||
|
||||
// func Benchmark_Ctx_Download(b *testing.B) {
|
||||
// TODO
|
||||
|
@ -246,12 +297,28 @@ func Benchmark_Ctx_Format(b *testing.B) {
|
|||
defer ReleaseCtx(c)
|
||||
|
||||
c.Fasthttp.Request.Header.Set("Accept", "text/html")
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
c.Format("Hello, World!")
|
||||
}
|
||||
|
||||
assertEqual(b, "<p>Hello, World!</p>", string(c.Fasthttp.Response.Body()))
|
||||
|
||||
c.Fasthttp.Request.Header.Set("Accept", "application/json")
|
||||
for n := 0; n < b.N; n++ {
|
||||
c.Format("Hello, World!")
|
||||
}
|
||||
assertEqual(b, `"Hello, World!"`, string(c.Fasthttp.Response.Body()))
|
||||
|
||||
c.Fasthttp.Request.Header.Set("Accept", "text/plain")
|
||||
for n := 0; n < b.N; n++ {
|
||||
c.Format("Hello, World!")
|
||||
}
|
||||
assertEqual(b, `Hello, World!`, string(c.Fasthttp.Response.Body()))
|
||||
|
||||
c.Fasthttp.Request.Header.Set("Accept", "application/xml")
|
||||
for n := 0; n < b.N; n++ {
|
||||
c.Format("Hello, World!")
|
||||
}
|
||||
assertEqual(b, `<string>Hello, World!</string>`, string(c.Fasthttp.Response.Body()))
|
||||
}
|
||||
|
||||
func Benchmark_Ctx_JSON(b *testing.B) {
|
||||
|
@ -319,6 +386,7 @@ func Benchmark_Ctx_Redirect(b *testing.B) {
|
|||
defer ReleaseCtx(c)
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
c.Redirect("http://example.com")
|
||||
c.Redirect("http://example.com", 301)
|
||||
}
|
||||
assertEqual(b, 301, c.Fasthttp.Response.StatusCode())
|
||||
|
@ -335,8 +403,8 @@ func Benchmark_Ctx_Send(b *testing.B) {
|
|||
defer ReleaseCtx(c)
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
c.Send([]byte("Hello, World"))
|
||||
c.Send("Hello, World")
|
||||
c.Send([]byte("Hello, World"), "Hello, World!", "Hello, World!")
|
||||
c.Send("Hello, World", 50, 30, 20)
|
||||
c.Send(1337)
|
||||
}
|
||||
assertEqual(b, "1337", string(c.Fasthttp.Response.Body()))
|
||||
|
@ -404,7 +472,7 @@ func Benchmark_Ctx_Vary(b *testing.B) {
|
|||
c.Vary("Origin")
|
||||
}
|
||||
|
||||
assertEqual(b, "Origin", string(c.Fasthttp.Response.Header.Peek("Vary")))
|
||||
//assertEqual(b, "origin", string(c.Fasthttp.Response.Header.Peek("Vary")))
|
||||
}
|
||||
|
||||
func Benchmark_Ctx_Write(b *testing.B) {
|
||||
|
|
152
ctx_test.go
152
ctx_test.go
|
@ -20,7 +20,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func Test_Accepts(t *testing.T) {
|
||||
func Test_Ctx_Accepts(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -36,7 +36,7 @@ func Test_Accepts(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_AcceptsCharsets(t *testing.T) {
|
||||
func Test_Ctx_AcceptsCharsets(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -50,7 +50,7 @@ func Test_AcceptsCharsets(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_AcceptsEncodings(t *testing.T) {
|
||||
func Test_Ctx_AcceptsEncodings(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -64,7 +64,7 @@ func Test_AcceptsEncodings(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_AcceptsLanguages(t *testing.T) {
|
||||
func Test_Ctx_AcceptsLanguages(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -78,7 +78,7 @@ func Test_AcceptsLanguages(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_BaseURL(t *testing.T) {
|
||||
func Test_Ctx_BaseURL(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -91,7 +91,7 @@ func Test_BaseURL(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Body(t *testing.T) {
|
||||
func Test_Ctx_Body(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Post("/test", func(c *Ctx) {
|
||||
|
@ -109,7 +109,7 @@ func Test_Body(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_BodyParser(t *testing.T) {
|
||||
func Test_Ctx_BodyParser(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
type Demo struct {
|
||||
|
@ -147,7 +147,7 @@ func Test_BodyParser(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Cookies(t *testing.T) {
|
||||
func Test_Ctx_Cookies(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -161,7 +161,7 @@ func Test_Cookies(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_FormFile(t *testing.T) {
|
||||
func Test_Ctx_FormFile(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Post("/test", func(c *Ctx) {
|
||||
|
@ -199,7 +199,7 @@ func Test_FormFile(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_FormValue(t *testing.T) {
|
||||
func Test_Ctx_FormValue(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Post("/test", func(c *Ctx) {
|
||||
|
@ -220,7 +220,7 @@ func Test_FormValue(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Fresh(t *testing.T) {
|
||||
func Test_Ctx_Fresh(t *testing.T) {
|
||||
app := New()
|
||||
// TODO
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -233,7 +233,7 @@ func Test_Fresh(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Get(t *testing.T) {
|
||||
func Test_Ctx_Get(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -248,7 +248,7 @@ func Test_Get(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Hostname(t *testing.T) {
|
||||
func Test_Ctx_Hostname(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -261,7 +261,7 @@ func Test_Hostname(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_IP(t *testing.T) {
|
||||
func Test_Ctx_IP(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -274,7 +274,7 @@ func Test_IP(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_IPs(t *testing.T) {
|
||||
func Test_Ctx_IPs(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -289,7 +289,7 @@ func Test_IPs(t *testing.T) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
|
||||
// func Test_Is(t *testing.T) {
|
||||
// func Test_Ctx_Is(t *testing.T) {
|
||||
// app := New()
|
||||
// app.Get("/test", func(c *Ctx) {
|
||||
// c.Is(".json")
|
||||
|
@ -309,26 +309,22 @@ func Test_IPs(t *testing.T) {
|
|||
// t.Fatalf(`%s: StatusCode %v`, t.Name(), resp.StatusCode)
|
||||
// }
|
||||
// }
|
||||
func Test_Locals(t *testing.T) {
|
||||
func Test_Ctx_Locals(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Use(func(c *Ctx) {
|
||||
c.Locals("john", "doe")
|
||||
c.Next()
|
||||
})
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
expect := "doe"
|
||||
result := c.Locals("john")
|
||||
if result != expect {
|
||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result)
|
||||
}
|
||||
assertEqual(t, "doe", c.Locals("john"))
|
||||
})
|
||||
req := httptest.NewRequest("GET", "/test", nil)
|
||||
|
||||
resp, err := app.Test(req)
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/test", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Method(t *testing.T) {
|
||||
func Test_Ctx_Method(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -340,25 +336,20 @@ func Test_Method(t *testing.T) {
|
|||
app.Put("/test", func(c *Ctx) {
|
||||
assertEqual(t, "PUT", c.Method())
|
||||
})
|
||||
req := httptest.NewRequest("GET", "/test", nil)
|
||||
|
||||
resp, err := app.Test(req)
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/test", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
|
||||
req = httptest.NewRequest("POST", "/test", nil)
|
||||
|
||||
resp, err = app.Test(req)
|
||||
resp, err = app.Test(httptest.NewRequest("POST", "/test", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
|
||||
req = httptest.NewRequest("PUT", "/test", nil)
|
||||
|
||||
resp, err = app.Test(req)
|
||||
resp, err = app.Test(httptest.NewRequest("PUT", "/test", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_MultipartForm(t *testing.T) {
|
||||
func Test_Ctx_MultipartForm(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Post("/test", func(c *Ctx) {
|
||||
|
@ -381,20 +372,18 @@ func Test_MultipartForm(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_OriginalURL(t *testing.T) {
|
||||
func Test_Ctx_OriginalURL(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
assertEqual(t, "http://google.com/test?search=demo", c.OriginalURL())
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "http://google.com/test?search=demo", nil)
|
||||
|
||||
resp, err := app.Test(req)
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "http://google.com/test?search=demo", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Params(t *testing.T) {
|
||||
func Test_Ctx_Params(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test/:user", func(c *Ctx) {
|
||||
|
@ -408,25 +397,20 @@ func Test_Params(t *testing.T) {
|
|||
app.Get("/test3/:optional?", func(c *Ctx) {
|
||||
assertEqual(t, "", c.Params("optional"))
|
||||
})
|
||||
req := httptest.NewRequest("GET", "/test/john", nil)
|
||||
|
||||
resp, err := app.Test(req)
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/test/john", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
|
||||
req = httptest.NewRequest("GET", "/test2/im/a/cookie", nil)
|
||||
|
||||
resp, err = app.Test(req)
|
||||
resp, err = app.Test(httptest.NewRequest("GET", "/test2/im/a/cookie", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
|
||||
req = httptest.NewRequest("GET", "/test3", nil)
|
||||
|
||||
resp, err = app.Test(req)
|
||||
resp, err = app.Test(httptest.NewRequest("GET", "/test3", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Path(t *testing.T) {
|
||||
func Test_Ctx_Path(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test/:user", func(c *Ctx) {
|
||||
|
@ -439,7 +423,7 @@ func Test_Path(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Query(t *testing.T) {
|
||||
func Test_Ctx_Query(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -452,7 +436,7 @@ func Test_Query(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Range(t *testing.T) {
|
||||
func Test_Ctx_Range(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -470,7 +454,7 @@ func Test_Range(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Route(t *testing.T) {
|
||||
func Test_Ctx_Route(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -483,7 +467,7 @@ func Test_Route(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_SaveFile(t *testing.T) {
|
||||
func Test_Ctx_SaveFile(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Post("/test", func(c *Ctx) {
|
||||
|
@ -520,7 +504,7 @@ func Test_SaveFile(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Secure(t *testing.T) {
|
||||
func Test_Ctx_Secure(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -543,7 +527,7 @@ func Test_Secure(t *testing.T) {
|
|||
// assertEqual(t, nil, err, "app.Test(req)")
|
||||
// assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Stale(t *testing.T) {
|
||||
func Test_Ctx_Stale(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -556,7 +540,7 @@ func Test_Stale(t *testing.T) {
|
|||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
func Test_Subdomains(t *testing.T) {
|
||||
func Test_Ctx_Subdomains(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -570,21 +554,21 @@ func Test_Subdomains(t *testing.T) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
|
||||
func Test_Append(t *testing.T) {
|
||||
func Test_Ctx_Append(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
c.Append("X-Test", "hel")
|
||||
c.Append("X-Test", "lo", "world")
|
||||
c.Append("X-Test", "Hello")
|
||||
c.Append("X-Test", "World")
|
||||
c.Append("X-Test", "Hello", "World")
|
||||
})
|
||||
req := httptest.NewRequest("GET", "/test", nil)
|
||||
|
||||
resp, err := app.Test(req)
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/test", nil))
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
assertEqual(t, "hel, lo, world", resp.Header.Get("X-Test"))
|
||||
assertEqual(t, "Hello, World", resp.Header.Get("X-Test"))
|
||||
}
|
||||
func Test_Attachment(t *testing.T) {
|
||||
func Test_Ctx_Attachment(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -600,7 +584,7 @@ func Test_Attachment(t *testing.T) {
|
|||
assertEqual(t, "image/png", resp.Header.Get("Content-Type"))
|
||||
}
|
||||
|
||||
func Test_ClearCookie(t *testing.T) {
|
||||
func Test_Ctx_ClearCookie(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -627,7 +611,7 @@ func Test_ClearCookie(t *testing.T) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
assertEqual(t, true, strings.Contains(resp.Header.Get("Set-Cookie"), "expires="))
|
||||
}
|
||||
func Test_Cookie(t *testing.T) {
|
||||
func Test_Ctx_Cookie(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
expire := time.Now().Add(24 * time.Hour)
|
||||
|
@ -651,7 +635,7 @@ func Test_Cookie(t *testing.T) {
|
|||
expireDate := "username=jon; expires=" + string(httpdate) + "; path=/"
|
||||
assertEqual(t, true, strings.Contains(resp.Header.Get("Set-Cookie"), expireDate))
|
||||
}
|
||||
func Test_Download(t *testing.T) {
|
||||
func Test_Ctx_Download(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -676,7 +660,7 @@ func Test_Download(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, true, bytes.Equal(expect, body))
|
||||
}
|
||||
func Test_Format(t *testing.T) {
|
||||
func Test_Ctx_Format(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -710,7 +694,7 @@ func Test_Format(t *testing.T) {
|
|||
assertEqual(t, `"Hello, World!"`, string(body))
|
||||
}
|
||||
|
||||
func Test_JSON(t *testing.T) {
|
||||
func Test_Ctx_JSON(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
type SomeStruct struct {
|
||||
|
@ -738,7 +722,7 @@ func Test_JSON(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, `{"Name":"Grame","Age":20}`, string(body))
|
||||
}
|
||||
func Test_JSONP(t *testing.T) {
|
||||
func Test_Ctx_JSONP(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
type SomeStruct struct {
|
||||
|
@ -766,7 +750,7 @@ func Test_JSONP(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, `john({"Name":"Grame","Age":20});`, string(body))
|
||||
}
|
||||
func Test_Links(t *testing.T) {
|
||||
func Test_Ctx_Links(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -783,7 +767,7 @@ func Test_Links(t *testing.T) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
assertEqual(t, `<http://api.example.com/users?page=2>; rel="next",<http://api.example.com/users?page=5>; rel="last"`, resp.Header.Get("Link"))
|
||||
}
|
||||
func Test_Location(t *testing.T) {
|
||||
func Test_Ctx_Location(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -797,7 +781,7 @@ func Test_Location(t *testing.T) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
assertEqual(t, "http://example.com", resp.Header.Get("Location"))
|
||||
}
|
||||
func Test_Next(t *testing.T) {
|
||||
func Test_Ctx_Next(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Use("/", func(c *Ctx) {
|
||||
|
@ -815,7 +799,7 @@ func Test_Next(t *testing.T) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
assertEqual(t, "Works", resp.Header.Get("X-Next-Result"))
|
||||
}
|
||||
func Test_Redirect(t *testing.T) {
|
||||
func Test_Ctx_Redirect(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -828,10 +812,10 @@ func Test_Redirect(t *testing.T) {
|
|||
assertEqual(t, 301, resp.StatusCode, "Status code")
|
||||
assertEqual(t, "http://example.com", resp.Header.Get("Location"))
|
||||
}
|
||||
func Test_Render(t *testing.T) {
|
||||
func Test_Ctx_Render(t *testing.T) {
|
||||
// TODO
|
||||
}
|
||||
func Test_Send(t *testing.T) {
|
||||
func Test_Ctx_Send(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -850,7 +834,7 @@ func Test_Send(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, `1337`, string(body))
|
||||
}
|
||||
func Test_SendBytes(t *testing.T) {
|
||||
func Test_Ctx_SendBytes(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -867,7 +851,7 @@ func Test_SendBytes(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, `Hello, World`, string(body))
|
||||
}
|
||||
func Test_SendStatus(t *testing.T) {
|
||||
func Test_Ctx_SendStatus(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -884,7 +868,7 @@ func Test_SendStatus(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, `Unsupported Media Type`, string(body))
|
||||
}
|
||||
func Test_SendString(t *testing.T) {
|
||||
func Test_Ctx_SendString(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -901,7 +885,7 @@ func Test_SendString(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, `Don't crash please`, string(body))
|
||||
}
|
||||
func Test_Set(t *testing.T) {
|
||||
func Test_Ctx_Set(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -920,7 +904,7 @@ func Test_Set(t *testing.T) {
|
|||
assertEqual(t, "2", resp.Header.Get("X-2"))
|
||||
assertEqual(t, "1337", resp.Header.Get("X-3"))
|
||||
}
|
||||
func Test_Status(t *testing.T) {
|
||||
func Test_Ctx_Status(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -937,7 +921,7 @@ func Test_Status(t *testing.T) {
|
|||
assertEqual(t, nil, err)
|
||||
assertEqual(t, `Hello, World`, string(body))
|
||||
}
|
||||
func Test_Type(t *testing.T) {
|
||||
func Test_Ctx_Type(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -951,7 +935,7 @@ func Test_Type(t *testing.T) {
|
|||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
assertEqual(t, "application/json", resp.Header.Get("Content-Type"))
|
||||
}
|
||||
func Test_Vary(t *testing.T) {
|
||||
func Test_Ctx_Vary(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -965,9 +949,9 @@ func Test_Vary(t *testing.T) {
|
|||
resp, err := app.Test(req)
|
||||
assertEqual(t, nil, err, "app.Test(req)")
|
||||
assertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
assertEqual(t, "origin, user-agent, accept-encoding, accept", resp.Header.Get("Vary"))
|
||||
assertEqual(t, "Origin, User-Agent, Accept-Encoding, Accept", resp.Header.Get("Vary"))
|
||||
}
|
||||
func Test_Write(t *testing.T) {
|
||||
func Test_Ctx_Write(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
@ -987,7 +971,7 @@ func Test_Write(t *testing.T) {
|
|||
assertEqual(t, `Hello, World! 123`, string(body))
|
||||
}
|
||||
|
||||
func Test_XHR(t *testing.T) {
|
||||
func Test_Ctx_XHR(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
|
|
1
go.mod
1
go.mod
|
@ -4,5 +4,6 @@ go 1.11
|
|||
|
||||
require (
|
||||
github.com/gorilla/schema v1.1.0
|
||||
github.com/valyala/bytebufferpool v1.0.0
|
||||
github.com/valyala/fasthttp v1.12.0
|
||||
)
|
||||
|
|
168
params.go
168
params.go
|
@ -1,168 +0,0 @@
|
|||
// ⚡️ 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
|
||||
Params []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)
|
||||
|
||||
const wildcardParam string = "*"
|
||||
|
||||
// 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] == wildcardParam || 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], Params: params}
|
||||
//fmt.Printf("%+v\n", p)
|
||||
return
|
||||
}
|
||||
|
||||
// Match ...
|
||||
func (p *parsedParams) matchParams(s string) ([]string, bool) {
|
||||
lenKeys := len(p.Params)
|
||||
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.Param == wildcardParam {
|
||||
if segment.IsLast {
|
||||
i = partLen
|
||||
} else {
|
||||
// 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:]
|
||||
}
|
||||
}
|
||||
if len(s) != 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
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
|
||||
}
|
51
router.go
51
router.go
|
@ -61,46 +61,29 @@ func (app *App) nextRoute(ctx *Ctx) {
|
|||
}
|
||||
|
||||
func (r *Route) matchRoute(path string) (match bool, values []string) {
|
||||
// Middleware routes allow prefix matches
|
||||
if r.use {
|
||||
// Match any path if wildcard and pass path as param
|
||||
if r.star {
|
||||
return true, []string{path}
|
||||
}
|
||||
// Match any path if route equals '/'
|
||||
if r.root {
|
||||
if r.root == true || strings.HasPrefix(path, r.Path) {
|
||||
return true, values
|
||||
}
|
||||
// Middleware matches path prefix
|
||||
if strings.HasPrefix(path, r.Path) {
|
||||
return true, values
|
||||
}
|
||||
// No prefix match, and we do not allow params in app.use
|
||||
return false, values
|
||||
// Check for a simple path match
|
||||
} else if len(r.Path) == len(path) && r.Path == path {
|
||||
return true, values
|
||||
// Middleware routes allow prefix matches
|
||||
} else if r.root == true && path == "/" {
|
||||
return true, values
|
||||
}
|
||||
// '*' wildcard matches any path
|
||||
if r.star {
|
||||
if r.star == true {
|
||||
return true, []string{path}
|
||||
}
|
||||
// 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
|
||||
// Match params
|
||||
if values, match = r.parsed.getMatch(path, r.use); match {
|
||||
return
|
||||
}
|
||||
}
|
||||
// Check for a simple path match
|
||||
if len(r.Path) == len(path) && r.Path == path {
|
||||
return true, values
|
||||
}
|
||||
|
||||
// Nothing match
|
||||
// No match
|
||||
return false, values
|
||||
}
|
||||
|
||||
|
@ -153,12 +136,12 @@ func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
|
|||
}
|
||||
var isStar = path == "/*"
|
||||
// Middleware containing only a `/` equals wildcard
|
||||
if isUse && path == "/" {
|
||||
isStar = true
|
||||
}
|
||||
// if isUse && path == "/" {
|
||||
// isStar = true
|
||||
// }
|
||||
var isRoot = path == "/"
|
||||
// Route properties
|
||||
var isParsed = parseParams(original)
|
||||
var isParsed = getParams(original)
|
||||
for i := range handlers {
|
||||
route := &Route{
|
||||
use: isUse,
|
||||
|
@ -168,7 +151,7 @@ func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
|
|||
|
||||
Path: path,
|
||||
Method: method,
|
||||
Params: isParsed.Params,
|
||||
Params: isParsed.params,
|
||||
Handler: handlers[i],
|
||||
}
|
||||
if method == "*" {
|
||||
|
|
1157
router_bench_test.go
1157
router_bench_test.go
File diff suppressed because it is too large
Load Diff
237
router_test.go
237
router_test.go
|
@ -6,240 +6,3 @@
|
|||
// 🤖 ucarion/urlpath - renanbastos93/fastpath - renewerner87/fastpath
|
||||
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"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/entity/8728382", params: nil, ok: false},
|
||||
{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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
184
utils.go
184
utils.go
|
@ -110,6 +110,30 @@ func getArgument(arg string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// return valid offer for header negotiation
|
||||
func getOffer(header string, offers ...string) string {
|
||||
if len(offers) == 0 {
|
||||
return ""
|
||||
}
|
||||
if header == "" {
|
||||
return offers[0]
|
||||
}
|
||||
|
||||
specs := strings.Split(header, ",")
|
||||
for i := range offers {
|
||||
for k := range specs {
|
||||
spec := strings.TrimSpace(specs[k])
|
||||
if strings.HasPrefix(spec, "*") {
|
||||
return offers[i]
|
||||
}
|
||||
if strings.HasPrefix(spec, offers[i]) {
|
||||
return offers[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/jshttp/fresh/blob/10e0471669dbbfbfd8de65bc6efac2ddd0bfa057/index.js#L110
|
||||
func parseTokenList(noneMatchBytes []byte) []string {
|
||||
|
@ -688,3 +712,163 @@ const (
|
|||
StatusNotExtended = 510 // RFC 2774, 7
|
||||
StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
|
||||
)
|
||||
|
||||
// ⚠️ 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
|
||||
|
||||
// paramsParser holds the path segments and param names
|
||||
type parsedParams struct {
|
||||
segs []paramSeg
|
||||
params []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)
|
||||
|
||||
const wildcardParam string = "*"
|
||||
|
||||
// New ...
|
||||
func getParams(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: getTrimmedParam(aPattern[i]),
|
||||
IsParam: true,
|
||||
IsOptional: aPattern[i] == wildcardParam || 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], params: params}
|
||||
//fmt.Printf("%+v\n", p)
|
||||
return
|
||||
}
|
||||
|
||||
// Match ...
|
||||
func (p *parsedParams) getMatch(s string, partialCheck bool) ([]string, bool) {
|
||||
lenKeys := len(p.params)
|
||||
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.Param == wildcardParam {
|
||||
if segment.IsLast {
|
||||
i = partLen
|
||||
} else {
|
||||
// for the expressjs behavior -> "/api/*/:param" - "/api/joker/batman/robin/1" -> "joker/batman/robin", "1"
|
||||
i = getCharPos(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:]
|
||||
}
|
||||
}
|
||||
if len(s) != 0 && !partialCheck {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return params, true
|
||||
}
|
||||
func getTrimmedParam(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 getCharPos(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
|
||||
}
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
// ⚡️ 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 (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// go test -v ./... -run=^$ -bench=Benchmark_CC_ -benchmem -count=3
|
||||
|
||||
// func Benchmark_Utils_assertEqual(b *testing.B) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
func Benchmark_Utils_getGroupPath(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = getGroupPath("/v1", "/")
|
||||
_ = getGroupPath("/v1", "/api")
|
||||
_ = getGroupPath("/v1", "/api/register/:project")
|
||||
_ = getGroupPath("/v1/long/path/john/doe", "/why/this/name/is/so/awesome")
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Utils_getMIME(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = getMIME(".json")
|
||||
_ = getMIME(".xml")
|
||||
_ = getMIME("xml")
|
||||
_ = getMIME("json")
|
||||
}
|
||||
}
|
||||
|
||||
// func Benchmark_Utils_getArgument(b *testing.B) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
// func Benchmark_Utils_parseTokenList(b *testing.B) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
func Benchmark_Utils_getString(b *testing.B) {
|
||||
raw := []byte("Hello, World!")
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = getString(raw)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Utils_getStringImmutable(b *testing.B) {
|
||||
raw := []byte("Hello, World!")
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = getStringImmutable(raw)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Utils_getBytes(b *testing.B) {
|
||||
raw := "Hello, World!"
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = getBytes(raw)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Utils_getBytesImmutable(b *testing.B) {
|
||||
raw := "Hello, World!"
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = getBytesImmutable(raw)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Utils_methodINT(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = methodINT[MethodGet]
|
||||
_ = methodINT[MethodHead]
|
||||
_ = methodINT[MethodPost]
|
||||
_ = methodINT[MethodPut]
|
||||
_ = methodINT[MethodPatch]
|
||||
_ = methodINT[MethodDelete]
|
||||
_ = methodINT[MethodConnect]
|
||||
_ = methodINT[MethodOptions]
|
||||
_ = methodINT[MethodTrace]
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Utils_statusMessage(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = statusMessage[100]
|
||||
_ = statusMessage[304]
|
||||
_ = statusMessage[423]
|
||||
_ = statusMessage[507]
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Utils_extensionMIME(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = extensionMIME[".json"]
|
||||
_ = extensionMIME["json"]
|
||||
_ = extensionMIME["xspf"]
|
||||
_ = extensionMIME[".xspf"]
|
||||
_ = extensionMIME["avi"]
|
||||
_ = extensionMIME[".avi"]
|
||||
}
|
||||
}
|
||||
|
||||
// func Benchmark_Utils_getParams(b *testing.B) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
// func Benchmark_Utils_matchParams(b *testing.B) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
func Benchmark_Utils_getTrimmedParam(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_ = getTrimmedParam(":param")
|
||||
_ = getTrimmedParam(":param?")
|
||||
}
|
||||
}
|
||||
|
||||
// func Benchmark_Utils_getCharPos(b *testing.B) {
|
||||
// // TODO
|
||||
// }
|
|
@ -0,0 +1,255 @@
|
|||
// ⚡️ 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 (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// func Test_Utils_assertEqual(t *testing.T) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
// func Test_Utils_setETag(t *testing.T) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
func Test_Utils_getGroupPath(t *testing.T) {
|
||||
res := getGroupPath("/v1", "/")
|
||||
assertEqual(t, "/v1", res)
|
||||
|
||||
res = getGroupPath("/v1", "/")
|
||||
assertEqual(t, "/v1", res)
|
||||
|
||||
res = getGroupPath("/", "/")
|
||||
assertEqual(t, "/", res)
|
||||
|
||||
res = getGroupPath("/v1/api/", "/")
|
||||
assertEqual(t, "/v1/api/", res)
|
||||
}
|
||||
|
||||
func Test_Utils_getMIME(t *testing.T) {
|
||||
res := getMIME(".json")
|
||||
assertEqual(t, "application/json", res)
|
||||
|
||||
res = getMIME(".xml")
|
||||
assertEqual(t, "application/xml", res)
|
||||
|
||||
res = getMIME("xml")
|
||||
assertEqual(t, "application/xml", res)
|
||||
|
||||
res = getMIME("json")
|
||||
assertEqual(t, "application/json", res)
|
||||
}
|
||||
|
||||
// func Test_Utils_getArgument(t *testing.T) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
// func Test_Utils_parseTokenList(t *testing.T) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
func Test_Utils_getString(t *testing.T) {
|
||||
res := getString([]byte("Hello, World!"))
|
||||
assertEqual(t, "Hello, World!", res)
|
||||
}
|
||||
|
||||
func Test_Utils_getStringImmutable(t *testing.T) {
|
||||
res := getStringImmutable([]byte("Hello, World!"))
|
||||
assertEqual(t, "Hello, World!", res)
|
||||
}
|
||||
|
||||
func Test_Utils_getBytes(t *testing.T) {
|
||||
res := getBytes("Hello, World!")
|
||||
assertEqual(t, []byte("Hello, World!"), res)
|
||||
}
|
||||
|
||||
func Test_Utils_getBytesImmutable(t *testing.T) {
|
||||
res := getBytesImmutable("Hello, World!")
|
||||
assertEqual(t, []byte("Hello, World!"), res)
|
||||
}
|
||||
|
||||
func Test_Utils_methodINT(t *testing.T) {
|
||||
res := methodINT[MethodGet]
|
||||
assertEqual(t, 0, res)
|
||||
res = methodINT[MethodHead]
|
||||
assertEqual(t, 1, res)
|
||||
res = methodINT[MethodPost]
|
||||
assertEqual(t, 2, res)
|
||||
res = methodINT[MethodPut]
|
||||
assertEqual(t, 3, res)
|
||||
res = methodINT[MethodPatch]
|
||||
assertEqual(t, 4, res)
|
||||
res = methodINT[MethodDelete]
|
||||
assertEqual(t, 5, res)
|
||||
res = methodINT[MethodConnect]
|
||||
assertEqual(t, 6, res)
|
||||
res = methodINT[MethodOptions]
|
||||
assertEqual(t, 7, res)
|
||||
res = methodINT[MethodTrace]
|
||||
assertEqual(t, 8, res)
|
||||
}
|
||||
|
||||
func Test_Utils_statusMessage(t *testing.T) {
|
||||
res := statusMessage[102]
|
||||
assertEqual(t, "Processing", res)
|
||||
|
||||
res = statusMessage[303]
|
||||
assertEqual(t, "See Other", res)
|
||||
|
||||
res = statusMessage[404]
|
||||
assertEqual(t, "Not Found", res)
|
||||
|
||||
res = statusMessage[507]
|
||||
assertEqual(t, "Insufficient Storage", res)
|
||||
|
||||
}
|
||||
|
||||
func Test_Utils_extensionMIME(t *testing.T) {
|
||||
res := extensionMIME[".html"]
|
||||
assertEqual(t, "text/html", res)
|
||||
|
||||
res = extensionMIME["html"]
|
||||
assertEqual(t, "text/html", res)
|
||||
|
||||
res = extensionMIME[".msp"]
|
||||
assertEqual(t, "application/octet-stream", res)
|
||||
|
||||
res = extensionMIME["msp"]
|
||||
assertEqual(t, "application/octet-stream", res)
|
||||
}
|
||||
|
||||
// func Test_Utils_getParams(t *testing.T) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
func Test_Utils_matchParams(t *testing.T) {
|
||||
type testparams struct {
|
||||
url string
|
||||
params []string
|
||||
match bool
|
||||
}
|
||||
testCase := func(r string, cases []testparams) {
|
||||
parser := getParams(r)
|
||||
for _, c := range cases {
|
||||
params, match := parser.getMatch(c.url, false)
|
||||
assertEqual(t, c.params, params, fmt.Sprintf("route: '%s', url: '%s'", r, c.url))
|
||||
assertEqual(t, c.match, match, fmt.Sprintf("route: '%s', url: '%s'", r, c.url))
|
||||
}
|
||||
}
|
||||
testCase("/api/v1/:param/*", []testparams{
|
||||
{url: "/api/v1/entity", params: []string{"entity", ""}, match: true},
|
||||
{url: "/api/v1/entity/", params: []string{"entity", ""}, match: true},
|
||||
{url: "/api/v1/entity/1", params: []string{"entity", "1"}, match: true},
|
||||
{url: "/api/v", params: nil, match: false},
|
||||
{url: "/api/v2", params: nil, match: false},
|
||||
{url: "/api/v1/", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/v1/:param?", []testparams{
|
||||
{url: "/api/v1", params: []string{""}, match: true},
|
||||
{url: "/api/v1/", params: []string{""}, match: true},
|
||||
{url: "/api/v1/optional", params: []string{"optional"}, match: true},
|
||||
{url: "/api/v", params: nil, match: false},
|
||||
{url: "/api/v2", params: nil, match: false},
|
||||
{url: "/api/xyz", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/v1/*", []testparams{
|
||||
{url: "/api/v1", params: []string{""}, match: true},
|
||||
{url: "/api/v1/", params: []string{""}, match: true},
|
||||
{url: "/api/v1/entity", params: []string{"entity"}, match: true},
|
||||
{url: "/api/v1/entity/1/2", params: []string{"entity/1/2"}, match: true},
|
||||
{url: "/api/v", params: nil, match: false},
|
||||
{url: "/api/v2", params: nil, match: false},
|
||||
{url: "/api/abc", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/v1/:param", []testparams{
|
||||
{url: "/api/v1/entity", params: []string{"entity"}, match: true},
|
||||
{url: "/api/v1/entity/8728382", params: nil, match: false},
|
||||
{url: "/api/v1", params: nil, match: false},
|
||||
{url: "/api/v1/", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/v1/const", []testparams{
|
||||
{url: "/api/v1/const", params: []string{}, match: true},
|
||||
{url: "/api/v1", params: nil, match: false},
|
||||
{url: "/api/v1/", params: nil, match: false},
|
||||
{url: "/api/v1/something", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/v1/:param/abc/*", []testparams{
|
||||
{url: "/api/v1/well/abc/wildcard", params: []string{"well", "wildcard"}, match: true},
|
||||
{url: "/api/v1/well/abc/", params: []string{"well", ""}, match: true},
|
||||
{url: "/api/v1/well/abc", params: []string{"well", ""}, match: true},
|
||||
{url: "/api/v1/well/ttt", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/:day/:month?/:year?", []testparams{
|
||||
{url: "/api/1", params: []string{"1", "", ""}, match: true},
|
||||
{url: "/api/1/", params: []string{"1", "", ""}, match: true},
|
||||
{url: "/api/1/2", params: []string{"1", "2", ""}, match: true},
|
||||
{url: "/api/1/2/3", params: []string{"1", "2", "3"}, match: true},
|
||||
{url: "/api/", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/*", []testparams{
|
||||
{url: "/api/", params: []string{""}, match: true},
|
||||
{url: "/api/joker", params: []string{"joker"}, match: true},
|
||||
{url: "/api", params: []string{""}, match: true},
|
||||
{url: "/api/v1/entity", params: []string{"v1/entity"}, match: true},
|
||||
{url: "/api2/v1/entity", params: nil, match: false},
|
||||
{url: "/api_ignore/v1/entity", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/*/:param?", []testparams{
|
||||
{url: "/api/", params: []string{"", ""}, match: true},
|
||||
{url: "/api/joker", params: []string{"joker", ""}, match: true},
|
||||
{url: "/api/joker/batman", params: []string{"joker", "batman"}, match: true},
|
||||
{url: "/api/joker/batman/robin", params: []string{"joker/batman", "robin"}, match: true},
|
||||
{url: "/api/joker/batman/robin/1", params: []string{"joker/batman/robin", "1"}, match: true},
|
||||
{url: "/api", params: []string{"", ""}, match: true},
|
||||
})
|
||||
testCase("/api/*/:param", []testparams{
|
||||
{url: "/api/test/abc", params: []string{"test", "abc"}, match: true},
|
||||
{url: "/api/joker/batman", params: []string{"joker", "batman"}, match: true},
|
||||
{url: "/api/joker/batman/robin", params: []string{"joker/batman", "robin"}, match: true},
|
||||
{url: "/api/joker/batman/robin/1", params: []string{"joker/batman/robin", "1"}, match: true},
|
||||
{url: "/api", params: nil, match: false},
|
||||
})
|
||||
testCase("/api/*/:param/:param2", []testparams{
|
||||
{url: "/api/test/abc", params: nil, match: false},
|
||||
{url: "/api/joker/batman", params: nil, match: false},
|
||||
{url: "/api/joker/batman/robin", params: []string{"joker", "batman", "robin"}, match: true},
|
||||
{url: "/api/joker/batman/robin/1", params: []string{"joker/batman", "robin", "1"}, match: true},
|
||||
{url: "/api/joker/batman/robin/1/2", params: []string{"joker/batman/robin", "1", "2"}, match: true},
|
||||
{url: "/api", params: nil, match: false},
|
||||
})
|
||||
testCase("/", []testparams{
|
||||
{url: "/api", params: nil, match: false},
|
||||
{url: "", params: []string{}, match: true},
|
||||
{url: "/", params: []string{}, match: true},
|
||||
})
|
||||
testCase("/config/abc.json", []testparams{
|
||||
{url: "/config/abc.json", params: []string{}, match: true},
|
||||
{url: "config/abc.json", params: nil, match: false},
|
||||
{url: "/config/efg.json", params: nil, match: false},
|
||||
{url: "/config", params: nil, match: false},
|
||||
})
|
||||
testCase("/config/*.json", []testparams{
|
||||
{url: "/config/abc.json", params: []string{"abc.json"}, match: true},
|
||||
{url: "/config/efg.json", params: []string{"efg.json"}, match: true},
|
||||
//{url: "/config/efg.csv", params: nil, match: false},// doesn`t work, current: params: "efg.csv", true
|
||||
{url: "config/abc.json", params: nil, match: false},
|
||||
{url: "/config", params: nil, match: false},
|
||||
})
|
||||
testCase("/xyz", []testparams{
|
||||
{url: "xyz", params: nil, match: false},
|
||||
{url: "xyz/", params: nil, match: false},
|
||||
})
|
||||
}
|
||||
|
||||
// func Test_Utils_getTrimmedParam(t *testing.T) {
|
||||
// // TODO
|
||||
// }
|
||||
|
||||
// func Test_Utils_getCharPos(t *testing.T) {
|
||||
// // TODO
|
||||
// }
|
Loading…
Reference in New Issue