summaryrefslogtreecommitdiff
path: root/vendor/github.com/gin-gonic/gin
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2022-09-28 18:30:40 +0100
committerLibravatar GitHub <noreply@github.com>2022-09-28 18:30:40 +0100
commita156188b3eb5cb3da44aa1b7452265f5fa38a607 (patch)
tree7097fa48d56fbabc7c2c8750b1f3bc9321d71c0f /vendor/github.com/gin-gonic/gin
parent[bugfix] Fix emphasis being added to emoji shortcodes with markdown parsing (... (diff)
downloadgotosocial-a156188b3eb5cb3da44aa1b7452265f5fa38a607.tar.xz
[chore] update dependencies, bump to Go 1.19.1 (#826)
* update dependencies, bump Go version to 1.19 * bump test image Go version * update golangci-lint * update gotosocial-drone-build * sign * linting, go fmt * update swagger docs * update swagger docs * whitespace * update contributing.md * fuckin whoopsie doopsie * linterino, linteroni * fix followrequest test not starting processor * fix other api/client tests not starting processor * fix remaining tests where processor not started * bump go-runners version * don't check last-webfingered-at, processor may have updated this * update swagger command * update bun to latest version * fix embed to work the same as before with new bun Signed-off-by: kim <grufwub@gmail.com> Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
Diffstat (limited to 'vendor/github.com/gin-gonic/gin')
-rw-r--r--vendor/github.com/gin-gonic/gin/.golangci.yml39
-rw-r--r--vendor/github.com/gin-gonic/gin/.goreleaser.yaml57
-rw-r--r--vendor/github.com/gin-gonic/gin/.travis.yml48
-rw-r--r--vendor/github.com/gin-gonic/gin/AUTHORS.md617
-rw-r--r--vendor/github.com/gin-gonic/gin/CHANGELOG.md48
-rw-r--r--vendor/github.com/gin-gonic/gin/CONTRIBUTING.md2
-rw-r--r--vendor/github.com/gin-gonic/gin/Makefile10
-rw-r--r--vendor/github.com/gin-gonic/gin/README.md186
-rw-r--r--vendor/github.com/gin-gonic/gin/any.go10
-rw-r--r--vendor/github.com/gin-gonic/gin/auth.go4
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/any.go10
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/binding.go24
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go22
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/default_validator.go40
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/form.go15
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/form_mapping.go59
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/header.go10
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/json.go12
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/msgpack.go8
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go32
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/protobuf.go15
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/query.go4
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/toml.go35
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/uri.go6
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/xml.go8
-rw-r--r--vendor/github.com/gin-gonic/gin/binding/yaml.go8
-rw-r--r--vendor/github.com/gin-gonic/gin/context.go316
-rw-r--r--vendor/github.com/gin-gonic/gin/context_appengine.go2
-rw-r--r--vendor/github.com/gin-gonic/gin/debug.go14
-rw-r--r--vendor/github.com/gin-gonic/gin/deprecated.go4
-rw-r--r--vendor/github.com/gin-gonic/gin/errors.go14
-rw-r--r--vendor/github.com/gin-gonic/gin/fs.go4
-rw-r--r--vendor/github.com/gin-gonic/gin/gin.go129
-rw-r--r--vendor/github.com/gin-gonic/gin/internal/json/go_json.go23
-rw-r--r--vendor/github.com/gin-gonic/gin/internal/json/json.go6
-rw-r--r--vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go2
-rw-r--r--vendor/github.com/gin-gonic/gin/logger.go17
-rw-r--r--vendor/github.com/gin-gonic/gin/mode.go17
-rw-r--r--vendor/github.com/gin-gonic/gin/recovery.go18
-rw-r--r--vendor/github.com/gin-gonic/gin/render/any.go10
-rw-r--r--vendor/github.com/gin-gonic/gin/render/data.go2
-rw-r--r--vendor/github.com/gin-gonic/gin/render/html.go10
-rw-r--r--vendor/github.com/gin-gonic/gin/render/json.go44
-rw-r--r--vendor/github.com/gin-gonic/gin/render/msgpack.go8
-rw-r--r--vendor/github.com/gin-gonic/gin/render/protobuf.go6
-rw-r--r--vendor/github.com/gin-gonic/gin/render/reader.go2
-rw-r--r--vendor/github.com/gin-gonic/gin/render/redirect.go2
-rw-r--r--vendor/github.com/gin-gonic/gin/render/render.go3
-rw-r--r--vendor/github.com/gin-gonic/gin/render/text.go6
-rw-r--r--vendor/github.com/gin-gonic/gin/render/toml.go36
-rw-r--r--vendor/github.com/gin-gonic/gin/render/xml.go4
-rw-r--r--vendor/github.com/gin-gonic/gin/render/yaml.go4
-rw-r--r--vendor/github.com/gin-gonic/gin/response_writer.go18
-rw-r--r--vendor/github.com/gin-gonic/gin/routergroup.go52
-rw-r--r--vendor/github.com/gin-gonic/gin/test_helpers.go2
-rw-r--r--vendor/github.com/gin-gonic/gin/tree.go22
-rw-r--r--vendor/github.com/gin-gonic/gin/utils.go21
-rw-r--r--vendor/github.com/gin-gonic/gin/version.go4
58 files changed, 1403 insertions, 748 deletions
diff --git a/vendor/github.com/gin-gonic/gin/.golangci.yml b/vendor/github.com/gin-gonic/gin/.golangci.yml
new file mode 100644
index 000000000..c5e1de388
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/.golangci.yml
@@ -0,0 +1,39 @@
+run:
+ timeout: 5m
+linters:
+ enable:
+ - asciicheck
+ - depguard
+ - dogsled
+ - durationcheck
+ - errcheck
+ - errorlint
+ - exportloopref
+ - gci
+ - gofmt
+ - goimports
+ - gosec
+ - misspell
+ - nakedret
+ - nilerr
+ - nolintlint
+ - revive
+ - wastedassign
+issues:
+ exclude-rules:
+ - linters:
+ - structcheck
+ - unused
+ text: "`data` is unused"
+ - linters:
+ - staticcheck
+ text: "SA1019:"
+ - linters:
+ - revive
+ text: "var-naming:"
+ - linters:
+ - revive
+ text: "exported:"
+ - path: _test\.go
+ linters:
+ - gosec # security is not make sense in tests
diff --git a/vendor/github.com/gin-gonic/gin/.goreleaser.yaml b/vendor/github.com/gin-gonic/gin/.goreleaser.yaml
new file mode 100644
index 000000000..e435e56aa
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/.goreleaser.yaml
@@ -0,0 +1,57 @@
+project_name: gin
+
+builds:
+ -
+ # If true, skip the build.
+ # Useful for library projects.
+ # Default is false
+ skip: true
+
+changelog:
+ # Set it to true if you wish to skip the changelog generation.
+ # This may result in an empty release notes on GitHub/GitLab/Gitea.
+ skip: false
+
+ # Changelog generation implementation to use.
+ #
+ # Valid options are:
+ # - `git`: uses `git log`;
+ # - `github`: uses the compare GitHub API, appending the author login to the changelog.
+ # - `gitlab`: uses the compare GitLab API, appending the author name and email to the changelog.
+ # - `github-native`: uses the GitHub release notes generation API, disables the groups feature.
+ #
+ # Defaults to `git`.
+ use: git
+
+ # Sorts the changelog by the commit's messages.
+ # Could either be asc, desc or empty
+ # Default is empty
+ sort: asc
+
+ # Group commits messages by given regex and title.
+ # Order value defines the order of the groups.
+ # Proving no regex means all commits will be grouped under the default group.
+ # Groups are disabled when using github-native, as it already groups things by itself.
+ #
+ # Default is no groups.
+ groups:
+ - title: Features
+ regexp: "^.*feat[(\\w)]*:+.*$"
+ order: 0
+ - title: 'Bug fixes'
+ regexp: "^.*fix[(\\w)]*:+.*$"
+ order: 1
+ - title: 'Enhancements'
+ regexp: "^.*chore[(\\w)]*:+.*$"
+ order: 2
+ - title: Others
+ order: 999
+
+ filters:
+ # Commit messages matching the regexp listed here will be removed from
+ # the changelog
+ # Default is empty
+ exclude:
+ - '^docs'
+ - 'CICD'
+ - typo
diff --git a/vendor/github.com/gin-gonic/gin/.travis.yml b/vendor/github.com/gin-gonic/gin/.travis.yml
deleted file mode 100644
index bcc21414d..000000000
--- a/vendor/github.com/gin-gonic/gin/.travis.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-language: go
-
-matrix:
- fast_finish: true
- include:
- - go: 1.13.x
- - go: 1.13.x
- env:
- - TESTTAGS=nomsgpack
- - go: 1.14.x
- - go: 1.14.x
- env:
- - TESTTAGS=nomsgpack
- - go: 1.15.x
- - go: 1.15.x
- env:
- - TESTTAGS=nomsgpack
- - go: master
-
-git:
- depth: 10
-
-before_install:
- - if [[ "${GO111MODULE}" = "on" ]]; then mkdir "${HOME}/go"; export GOPATH="${HOME}/go"; fi
-
-install:
- - if [[ "${GO111MODULE}" = "on" ]]; then go mod download; fi
- - if [[ "${GO111MODULE}" = "on" ]]; then export PATH="${GOPATH}/bin:${GOROOT}/bin:${PATH}"; fi
- - if [[ "${GO111MODULE}" = "on" ]]; then make tools; fi
-
-go_import_path: github.com/gin-gonic/gin
-
-script:
- - make vet
- - make fmt-check
- - make misspell-check
- - make test
-
-after_success:
- - bash <(curl -s https://codecov.io/bash)
-
-notifications:
- webhooks:
- urls:
- - https://webhooks.gitter.im/e/7f95bf605c4d356372f4
- on_success: change # options: [always|never|change] default: always
- on_failure: always # options: [always|never|change] default: always
- on_start: false # default: false
diff --git a/vendor/github.com/gin-gonic/gin/AUTHORS.md b/vendor/github.com/gin-gonic/gin/AUTHORS.md
index c634e6be0..b4773ef3d 100644
--- a/vendor/github.com/gin-gonic/gin/AUTHORS.md
+++ b/vendor/github.com/gin-gonic/gin/AUTHORS.md
@@ -2,232 +2,405 @@ List of all the awesome people working to make Gin the best Web Framework in Go.
## gin 1.x series authors
-**Gin Core Team:** Bo-Yi Wu (@appleboy), 田欧 (@thinkerou), Javier Provecho (@javierprovecho)
+**Gin Core Team:** Bo-Yi Wu (@appleboy), thinkerou (@thinkerou), Javier Provecho (@javierprovecho)
## gin 0.x series authors
**Maintainers:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho)
-People and companies, who have contributed, in alphabetical order.
-
-**@858806258 (杰哥)**
-- Fix typo in example
-
-
-**@achedeuzot (Klemen Sever)**
-- Fix newline debug printing
-
-
-**@adammck (Adam Mckaig)**
-- Add MIT license
-
-
-**@AlexanderChen1989 (Alexander)**
-- Typos in README
-
-
-**@alexanderdidenko (Aleksandr Didenko)**
-- Add support multipart/form-data
-
-
-**@alexandernyquist (Alexander Nyquist)**
-- Using template.Must to fix multiple return issue
-- ★ Added support for OPTIONS verb
-- ★ Setting response headers before calling WriteHeader
-- Improved documentation for model binding
-- ★ Added Content.Redirect()
-- ★ Added tons of Unit tests
-
-
-**@austinheap (Austin Heap)**
-- Added travis CI integration
-
-
-**@andredublin (Andre Dublin)**
-- Fix typo in comment
-
-
-**@bredov (Ludwig Valda Vasquez)**
-- Fix html templating in debug mode
-
-
-**@bluele (Jun Kimura)**
-- Fixes code examples in README
-
-
-**@chad-russell**
-- ★ Support for serializing gin.H into XML
-
-
-**@dickeyxxx (Jeff Dickey)**
-- Typos in README
-- Add example about serving static files
-
-
-**@donileo (Adonis)**
-- Add NoMethod handler
-
-
-**@dutchcoders (DutchCoders)**
-- ★ Fix security bug that allows client to spoof ip
-- Fix typo. r.HTMLTemplates -> SetHTMLTemplate
-
-
-**@el3ctro- (Joshua Loper)**
-- Fix typo in example
-
-
-**@ethankan (Ethan Kan)**
-- Unsigned integers in binding
-
-
-**(Evgeny Persienko)**
-- Validate sub structures
-
-
-**@frankbille (Frank Bille)**
-- Add support for HTTP Realm Auth
-
-
-**@fmd (Fareed Dudhia)**
-- Fix typo. SetHTTPTemplate -> SetHTMLTemplate
-
-
-**@ironiridis (Christopher Harrington)**
-- Remove old reference
-
-
-**@jammie-stackhouse (Jamie Stackhouse)**
-- Add more shortcuts for router methods
-
-
-**@jasonrhansen**
-- Fix spelling and grammar errors in documentation
-
-
-**@JasonSoft (Jason Lee)**
-- Fix typo in comment
-
-
-**@joiggama (Ignacio Galindo)**
-- Add utf-8 charset header on renders
-
-
-**@julienschmidt (Julien Schmidt)**
-- gofmt the code examples
-
-
-**@kelcecil (Kel Cecil)**
-- Fix readme typo
-
-
-**@kyledinh (Kyle Dinh)**
-- Adds RunTLS()
-
-
-**@LinusU (Linus Unnebäck)**
-- Small fixes in README
-
-
-**@loongmxbt (Saint Asky)**
-- Fix typo in example
-
-
-**@lucas-clemente (Lucas Clemente)**
-- ★ work around path.Join removing trailing slashes from routes
-
-
-**@mattn (Yasuhiro Matsumoto)**
-- Improve color logger
-
-
-**@mdigger (Dmitry Sedykh)**
-- Fixes Form binding when content-type is x-www-form-urlencoded
-- No repeat call c.Writer.Status() in gin.Logger
-- Fixes Content-Type for json render
-
-
-**@mirzac (Mirza Ceric)**
-- Fix debug printing
-
-
-**@mopemope (Yutaka Matsubara)**
-- ★ Adds Godep support (Dependencies Manager)
-- Fix variadic parameter in the flexible render API
-- Fix Corrupted plain render
-- Add Pluggable View Renderer Example
-
-
-**@msemenistyi (Mykyta Semenistyi)**
-- update Readme.md. Add code to String method
-
-
-**@msoedov (Sasha Myasoedov)**
-- ★ Adds tons of unit tests.
-
-
-**@ngerakines (Nick Gerakines)**
-- ★ Improves API, c.GET() doesn't panic
-- Adds MustGet() method
-
-
-**@r8k (Rajiv Kilaparti)**
-- Fix Port usage in README.
-
-
-**@rayrod2030 (Ray Rodriguez)**
-- Fix typo in example
-
-
-**@rns**
-- Fix typo in example
-
-
-**@RobAWilkinson (Robert Wilkinson)**
-- Add example of forms and params
-
-
-**@rogierlommers (Rogier Lommers)**
-- Add updated static serve example
-
-**@rw-access (Ross Wolf)**
-- Added support to mix exact and param routes
-
-**@se77en (Damon Zhao)**
-- Improve color logging
-
-
-**@silasb (Silas Baronda)**
-- Fixing quotes in README
-
-
-**@SkuliOskarsson (Skuli Oskarsson)**
-- Fixes some texts in README II
-
-
-**@slimmy (Jimmy Pettersson)**
-- Added messages for required bindings
-
-
-**@smira (Andrey Smirnov)**
-- Add support for ignored/unexported fields in binding
-
-
-**@superalsrk (SRK.Lyu)**
-- Update httprouter godeps
-
-
-**@tebeka (Miki Tebeka)**
-- Use net/http constants instead of numeric values
-
-
-**@techjanitor**
-- Update context.go reserved IPs
-
-
-**@yosssi (Keiji Yoshida)**
-- Fix link in README
+------
+People and companies, who have contributed, in alphabetical order.
-**@yuyabee**
-- Fixed README
+- 178inaba <178inaba@users.noreply.github.com>
+- A. F <hello@clivern.com>
+- ABHISHEK SONI <abhishek.rocks26@gmail.com>
+- Abhishek Chanda <achanda@users.noreply.github.com>
+- Abner Chen <houjunchen@gmail.com>
+- AcoNCodes <acongame@gmail.com>
+- Adam Dratwinski <adam.dratwinski@gmail.com>
+- Adam Mckaig <adam.mckaig@gmail.com>
+- Adam Zielinski <MusicAdam@users.noreply.github.com>
+- Adonis <donileo@gmail.com>
+- Alan Wang <azzwacb9001@126.com>
+- Albin Gilles <gilles.albin@gmail.com>
+- Aleksandr Didenko <aa.didenko@yandex.ru>
+- Alessandro (Ale) Segala <43508+ItalyPaleAle@users.noreply.github.com>
+- Alex <AWulkan@users.noreply.github.com>
+- Alexander <alexanderchenmh@gmail.com>
+- Alexander Lokhman <alex.lokhman@gmail.com>
+- Alexander Melentyev <55826637+alexander-melentyev@users.noreply.github.com>
+- Alexander Nyquist <nyquist.alexander@gmail.com>
+- Allen Ren <kulong0105@gmail.com>
+- AllinGo <tanhp@outlook.com>
+- Ammar Bandukwala <ammar@ammar.io>
+- An Xiao (Luffy) <hac@zju.edu.cn>
+- Andre Dublin <81dublin@gmail.com>
+- Andrew Szeto <github@jabagawee.com>
+- Andrey Abramov <andreyabramov.aaa@gmail.com>
+- Andrey Nering <andrey.nering@gmail.com>
+- Andrey Smirnov <Smirnov.Andrey@gmail.com>
+- Andrii Bubis <firstrow@gmail.com>
+- André Bazaglia <bazaglia@users.noreply.github.com>
+- Andy Pan <panjf2000@gmail.com>
+- Antoine GIRARD <sapk@users.noreply.github.com>
+- Anup Kumar Panwar <1anuppanwar@gmail.com>
+- Aravinth Sundaram <gosh.aravind@gmail.com>
+- Artem <horechek@gmail.com>
+- Ashwani <ashwanisharma686@gmail.com>
+- Aurelien Regat-Barrel <arb@cyberkarma.net>
+- Austin Heap <me@austinheap.com>
+- Barnabus <jbampton@users.noreply.github.com>
+- Bo-Yi Wu <appleboy.tw@gmail.com>
+- Boris Borshevsky <BorisBorshevsky@gmail.com>
+- Boyi Wu <p581581@gmail.com>
+- BradyBromley <51128276+BradyBromley@users.noreply.github.com>
+- Brendan Fosberry <brendan@shopkeep.com>
+- Brian Wigginton <brianwigginton@gmail.com>
+- Carlos Eduardo <carlosedp@gmail.com>
+- Chad Russell <chaddouglasrussell@gmail.com>
+- Charles <cxjava@gmail.com>
+- Christian Muehlhaeuser <muesli@gmail.com>
+- Christian Persson <saser@live.se>
+- Christopher Harrington <ironiridis@gmail.com>
+- Damon Zhao <yijun.zhao@outlook.com>
+- Dan Markham <dmarkham@gmail.com>
+- Dang Nguyen <hoangdang.me@gmail.com>
+- Daniel Krom <kromdan@gmail.com>
+- Daniel M. Lambea <dmlambea@gmail.com>
+- Danieliu <liudanking@gmail.com>
+- David Irvine <aviddiviner@gmail.com>
+- David Zhang <crispgm@gmail.com>
+- Davor Kapsa <dvrkps@users.noreply.github.com>
+- DeathKing <DeathKing@users.noreply.github.com>
+- Dennis Cho <47404603+forest747@users.noreply.github.com>
+- Dmitry Dorogin <dmirogin@ya.ru>
+- Dmitry Kutakov <vkd.castle@gmail.com>
+- Dmitry Sedykh <dmitrys@d3h.local>
+- Don2Quixote <35610661+Don2Quixote@users.noreply.github.com>
+- Donn Pebe <iam@donnpebe.com>
+- Dustin Decker <dustindecker@protonmail.com>
+- Eason Lin <easonlin404@gmail.com>
+- Edward Betts <edward@4angle.com>
+- Egor Seredin <4819888+agmt@users.noreply.github.com>
+- Emmanuel Goh <emmanuel@visenze.com>
+- Equim <sayaka@ekyu.moe>
+- Eren A. Akyol <eren@redmc.me>
+- Eric_Lee <xplzv@126.com>
+- Erik Bender <erik.bender@develerik.dev>
+- Ethan Kan <ethankan@neoplot.com>
+- Evgeny Persienko <e.persienko@office.ngs.ru>
+- Faisal Alam <ifaisalalam@gmail.com>
+- Fareed Dudhia <fareeddudhia@googlemail.com>
+- Filip Figiel <figiel.filip@gmail.com>
+- Florian Polster <couchpolster@icqmail.com>
+- Frank Bille <github@frankbille.dk>
+- Franz Bettag <franz@bett.ag>
+- Ganlv <ganlvtech@users.noreply.github.com>
+- Gaozhen Ying <yinggaozhen@hotmail.com>
+- George Gabolaev <gabolaev98@gmail.com>
+- George Kirilenko <necryin@users.noreply.github.com>
+- Georges Varouchas <georges.varouchas@gmail.com>
+- Gordon Tyler <gordon@doxxx.net>
+- Harindu Perera <harinduenator@gmail.com>
+- Helios <674876158@qq.com>
+- Henry Kwan <piengeng@users.noreply.github.com>
+- Henry Yee <henry@yearning.io>
+- Himanshu Mishra <OrkoHunter@users.noreply.github.com>
+- Hiroyuki Tanaka <h.tanaka.0325@gmail.com>
+- Ibraheem Ahmed <ibrah1440@gmail.com>
+- Ignacio Galindo <joiggama@gmail.com>
+- Igor H. Vieira <zignd.igor@gmail.com>
+- Ildar1111 <54001462+Ildar1111@users.noreply.github.com>
+- Iskander (Alex) Sharipov <iskander.sharipov@intel.com>
+- Ismail Gjevori <isgjevori@protonmail.com>
+- Ivan Chen <allenivan@gmail.com>
+- JINNOUCHI Yasushi <delphinus@remora.cx>
+- James Pettyjohn <japettyjohn@users.noreply.github.com>
+- Jamie Stackhouse <jamie.stackhouse@redspace.com>
+- Jason Lee <jawc@hotmail.com>
+- Javier Provecho <j.provecho@dartekstudios.com>
+- Javier Provecho <javier.provecho@bq.com>
+- Javier Provecho <javiertitan@gmail.com>
+- Javier Provecho Fernandez <j.provecho@dartekstudios.com>
+- Javier Provecho Fernandez <javiertitan@gmail.com>
+- Jean-Christophe Lebreton <jclebreton@gmail.com>
+- Jeff <laojianzi1994@gmail.com>
+- Jeremy Loy <jeremy.b.loy@icloud.com>
+- Jim Filippou <p3160253@aueb.gr>
+- Jimmy Pettersson <jimmy@expertmaker.com>
+- John Bampton <jbampton@users.noreply.github.com>
+- Johnny Dallas <johnnydallas0308@gmail.com>
+- Johnny Dallas <theonlyjohnny@theonlyjohnny.sh>
+- Jonathan (JC) Chen <jc@dijonkitchen.org>
+- Josep Jesus Bigorra Algaba <42377845+averageflow@users.noreply.github.com>
+- Josh Horowitz <joshua.m.horowitz@gmail.com>
+- Joshua Loper <josh.el3@gmail.com>
+- Julien Schmidt <github@julienschmidt.com>
+- Jun Kimura <jksmphone@gmail.com>
+- Justin Beckwith <justin.beckwith@gmail.com>
+- Justin Israel <justinisrael@gmail.com>
+- Justin Mayhew <mayhew@live.ca>
+- Jérôme Laforge <jerome-laforge@users.noreply.github.com>
+- Kacper Bąk <56700396+53jk1@users.noreply.github.com>
+- Kamron Batman <kamronbatman@users.noreply.github.com>
+- Kane Rogers <kane@cleanstream.com.au>
+- Kaushik Neelichetty <kaushikneelichetty6132@gmail.com>
+- Keiji Yoshida <yoshida.keiji.84@gmail.com>
+- Kel Cecil <kel.cecil@listhub.com>
+- Kevin Mulvey <kmulvey@linux.com>
+- Kevin Zhu <ipandtcp@gmail.com>
+- Kirill Motkov <motkov.kirill@gmail.com>
+- Klemen Sever <ksever@student.42.fr>
+- Kristoffer A. Iversen <kristoffer.a.iversen@gmail.com>
+- Krzysztof Szafrański <k.p.szafranski@gmail.com>
+- Kumar McMillan <kumar.mcmillan@gmail.com>
+- Kyle Mcgill <email@kylescottmcgill.com>
+- Lanco <35420416+lancoLiu@users.noreply.github.com>
+- Levi Olson <olson.levi@gmail.com>
+- Lin Kao-Yuan <mosdeo@gmail.com>
+- Linus Unnebäck <linus@folkdatorn.se>
+- Lucas Clemente <lucas@clemente.io>
+- Ludwig Valda Vasquez <bredov@gmail.com>
+- Luis GG <lggomez@users.noreply.github.com>
+- MW Lim <williamchange@gmail.com>
+- Maksimov Sergey <konjoot@gmail.com>
+- Manjusaka <lizheao940510@gmail.com>
+- Manu MA <manu.mtza@gmail.com>
+- Manu MA <manu.valladolid@gmail.com>
+- Manu Mtz-Almeida <manu.valladolid@gmail.com>
+- Manu Mtz.-Almeida <manu.valladolid@gmail.com>
+- Manuel Alonso <manuelalonso@invisionapp.com>
+- Mara Kim <hacker.root@gmail.com>
+- Mario Kostelac <mario@intercom.io>
+- Martin Karlsch <martin@karlsch.com>
+- Matt Newberry <mnewberry@opentable.com>
+- Matt Williams <gh@mattyw.net>
+- Matthieu MOREL <mmorel-35@users.noreply.github.com>
+- Max Hilbrunner <mhilbrunner@users.noreply.github.com>
+- Maxime Soulé <btik-git@scoubidou.com>
+- MetalBreaker <johnymichelson@gmail.com>
+- Michael Puncel <mpuncel@squareup.com>
+- MichaelDeSteven <51652084+MichaelDeSteven@users.noreply.github.com>
+- Mike <38686456+icy4ever@users.noreply.github.com>
+- Mike Stipicevic <mst@ableton.com>
+- Miki Tebeka <miki.tebeka@gmail.com>
+- Miles <MilesLin@users.noreply.github.com>
+- Mirza Ceric <mirza.ceric@b2match.com>
+- Mykyta Semenistyi <nikeiwe@gmail.com>
+- Naoki Takano <honten@tinkermode.com>
+- Ngalim Siregar <ngalim.siregar@gmail.com>
+- Ni Hao <supernihaooo@qq.com>
+- Nick Gerakines <nick@gerakines.net>
+- Nikifor Seryakov <nikandfor@gmail.com>
+- Notealot <714804968@qq.com>
+- Olivier Mengué <dolmen@cpan.org>
+- Olivier Robardet <orobardet@users.noreply.github.com>
+- Pablo Moncada <pablo.moncada@bq.com>
+- Pablo Moncada <pmoncadaisla@gmail.com>
+- Panmax <967168@qq.com>
+- Peperoncino <2wua4nlyi@gmail.com>
+- Philipp Meinen <philipp@bind.ch>
+- Pierre Massat <pierre@massat.io>
+- Qt <golang.chen@gmail.com>
+- Quentin ROYER <aydendevg@gmail.com>
+- README Bot <35302948+codetriage-readme-bot@users.noreply.github.com>
+- Rafal Zajac <rzajac@gmail.com>
+- Rahul Datta Roy <rahuldroy@users.noreply.github.com>
+- Rajiv Kilaparti <rajivk085@gmail.com>
+- Raphael Gavache <raphael.gavache@datadoghq.com>
+- Ray Rodriguez <rayrod2030@gmail.com>
+- Regner Blok-Andersen <shadowdf@gmail.com>
+- Remco <remco@dutchcoders.io>
+- Rex Lee(李俊) <duguying2008@gmail.com>
+- Richard Lee <dlackty@gmail.com>
+- Riverside <wangyb65@gmail.com>
+- Robert Wilkinson <wilkinson.robert.a@gmail.com>
+- Rogier Lommers <rogier@lommers.org>
+- Rohan Pai <me@rohanpai.com>
+- Romain Beuque <rbeuque74@gmail.com>
+- Roman Belyakovsky <ihryamzik@gmail.com>
+- Roman Zaynetdinov <627197+zaynetro@users.noreply.github.com>
+- Roman Zaynetdinov <roman.zaynetdinov@lekane.com>
+- Ronald Petty <ronald.petty@rx-m.com>
+- Ross Wolf <31489089+rw-access@users.noreply.github.com>
+- Roy Lou <roylou@gmail.com>
+- Rubi <14269809+codenoid@users.noreply.github.com>
+- Ryan <46182144+ryanker@users.noreply.github.com>
+- Ryan J. Yoder <me@ryanjyoder.com>
+- SRK.Lyu <superalsrk@gmail.com>
+- Sai <sairoutine@gmail.com>
+- Samuel Abreu <sdepaula@gmail.com>
+- Santhosh Kumar <santhoshkumarr1096@gmail.com>
+- Sasha Melentyev <sasha@melentyev.io>
+- Sasha Myasoedov <msoedov@gmail.com>
+- Segev Finer <segev208@gmail.com>
+- Sergey Egorov <egorovhome@gmail.com>
+- Sergey Fedchenko <seregayoga@bk.ru>
+- Sergey Gonimar <sergey.gonimar@gmail.com>
+- Sergey Ponomarev <me@sergey-ponomarev.ru>
+- Serica <943914044@qq.com>
+- Shamus Taylor <Shamus03@me.com>
+- Shilin Wang <jarvisfironman@gmail.com>
+- Shuo <openset.wang@gmail.com>
+- Skuli Oskarsson <skuli@codeiak.io>
+- Snawoot <vladislav-ex-github@vm-0.com>
+- Sridhar Ratnakumar <srid@srid.ca>
+- Steeve Chailloux <steeve@chaahk.com>
+- Sudhir Mishra <sudhirxps@gmail.com>
+- Suhas Karanth <sudo-suhas@users.noreply.github.com>
+- TaeJun Park <miking38@gmail.com>
+- Tatsuya Hoshino <tatsuya7.hoshino7@gmail.com>
+- Tevic <tevic.tt@gmail.com>
+- Tevin Jeffrey <tev.jeffrey@gmail.com>
+- The Gitter Badger <badger@gitter.im>
+- Thibault Jamet <tjamet@users.noreply.github.com>
+- Thomas Boerger <thomas@webhippie.de>
+- Thomas Schaffer <loopfz@gmail.com>
+- Tommy Chu <tommychu2256@gmail.com>
+- Tudor Roman <tudurom@gmail.com>
+- Uwe Dauernheim <djui@users.noreply.github.com>
+- Valentine Oragbakosi <valentine13400@gmail.com>
+- Vas N <pnvasanth@users.noreply.github.com>
+- Vasilyuk Vasiliy <By-Vasiliy@users.noreply.github.com>
+- Victor Castell <victor@victorcastell.com>
+- Vince Yuan <vince.yuan@gmail.com>
+- Vyacheslav Dubinin <vyacheslav.dubinin@gmail.com>
+- Waynerv <ampedee@gmail.com>
+- Weilin Shi <934587911@qq.com>
+- Xudong Cai <fifsky@gmail.com>
+- Yasuhiro Matsumoto <mattn.jp@gmail.com>
+- Yehezkiel Syamsuhadi <ybs@ybs.im>
+- Yoshiki Nakagawa <yyoshiki41@gmail.com>
+- Yoshiyuki Kinjo <yskkin+github@gmail.com>
+- Yue Yang <g1enyy0ung@gmail.com>
+- ZYunH <zyunhjob@163.com>
+- Zach Newburgh <zach.newburgh@gmail.com>
+- Zasda Yusuf Mikail <zasdaym@gmail.com>
+- ZhangYunHao <zyunhjob@163.com>
+- ZhiFeng Hu <hufeng1987@gmail.com>
+- Zhu Xi <zhuxi910511@163.com>
+- a2tt <usera2tt@gmail.com>
+- ahuigo <1781999+ahuigo@users.noreply.github.com>
+- ali <anio@users.noreply.github.com>
+- aljun <salameryy@163.com>
+- andrea <crypto.andrea@protonmail.ch>
+- andriikushch <andrii.kushch@gmail.com>
+- anoty <anjunyou@foxmail.com>
+- awkj <hzzbiu@gmail.com>
+- axiaoxin <254606826@qq.com>
+- bbiao <bbbiao@gmail.com>
+- bestgopher <84328409@qq.com>
+- betahu <zhong.wenhuang@foxmail.com>
+- bigwheel <k.bigwheel+eng@gmail.com>
+- bn4t <17193640+bn4t@users.noreply.github.com>
+- bullgare <bullgare@gmail.com>
+- chainhelen <chainhelen@gmail.com>
+- chenyang929 <chenyang929code@gmail.com>
+- chriswhelix <chris.williams@helix.com>
+- collinmsn <4130944@qq.com>
+- cssivision <cssivision@gmail.com>
+- danielalves <alves.lopes.dan@gmail.com>
+- delphinus <delphinus@remora.cx>
+- dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+- dickeyxxx <jeff@dickeyxxx.com>
+- edebernis <emeric.debernis@gmail.com>
+- error10 <error@ioerror.us>
+- esplo <esplo@users.noreply.github.com>
+- eudore <30709860+eudore@users.noreply.github.com>
+- ffhelicopter <32922889+ffhelicopter@users.noreply.github.com>
+- filikos <11477309+filikos@users.noreply.github.com>
+- forging2012 <forging2012@users.noreply.github.com>
+- goqihoo <goqihoo@gmail.com>
+- grapeVine <treeui.old@gmail.com>
+- guonaihong <guonaihong@qq.com>
+- heige <daheige@users.noreply.github.com>
+- heige <zhuwei313@hotmail.com>
+- hellojukay <hellojukay@163.com>
+- henrylee2cn <henrylee2cn@gmail.com>
+- htobenothing <htobenothing@gmail.com>
+- iamhesir <78344375+iamhesir@users.noreply.github.com>
+- ijaa <kailiu2013@gmail.com>
+- ishanray <ishan.iipm@gmail.com>
+- ishanray <ishanray@users.noreply.github.com>
+- itcloudy <272685110@qq.com>
+- jarodsong6 <jarodsong6@gmail.com>
+- jasonrhansen <jasonrodneyhansen@gmail.com>
+- jincheng9 <perfume0607@gmail.com>
+- joeADSP <75027008+joeADSP@users.noreply.github.com>
+- junfengye <junfeng.yejf@gmail.com>
+- kaiiak <aNxFi37X@outlook.com>
+- kebo <kevinke2020@outlook.com>
+- keke <19yamashita15@gmail.com>
+- kishor kunal raj <68464660+kishorkunal-raj@users.noreply.github.com>
+- kyledinh <kyledinh@gmail.com>
+- lantw44 <lantw44@gmail.com>
+- likakuli <1154584512@qq.com>
+- linfangrong <linfangrong.liuxin@qq.com>
+- linzi <873804682@qq.com>
+- llgoer <yanghuxiao@vip.qq.com>
+- long-road <13412081338@163.com>
+- mbesancon <mathieu.besancon@gmail.com>
+- mehdy <mehdy.khoshnoody@gmail.com>
+- metal A-wing <freedom.awing.777@gmail.com>
+- micanzhang <micanzhang@gmail.com>
+- minarc <ragnhildmowinckel@gmail.com>
+- mllu <mornlyn@gmail.com>
+- mopemoepe <yutaka.matsubara@gmail.com>
+- msoedov <msoedov@gmail.com>
+- mstmdev <mstmdev@gmail.com>
+- novaeye <fcoffee@gmail.com>
+- olebedev <oolebedev@gmail.com>
+- phithon <phith0n@users.noreply.github.com>
+- pjgg <pablo.gonzalez.granados@gmail.com>
+- qm012 <67568757+qm012@users.noreply.github.com>
+- raymonder jin <rayjingithub@gmail.com>
+- rns <ruslan.shvedov@gmail.com>
+- root@andrea:~# <crypto.andrea@protonmail.ch>
+- sekky0905 <20237968+sekky0905@users.noreply.github.com>
+- senhtry <w169q169@gmail.com>
+- shadrus <shadrus@gmail.com>
+- silasb <silas.baronda@gmail.com>
+- solos <lxl1217@gmail.com>
+- songjiayang <songjiayang@users.noreply.github.com>
+- sope <shenshouer@163.com>
+- srt180 <30768686+srt180@users.noreply.github.com>
+- stackerzzq <foo_stacker@yeah.net>
+- sunshineplan <sunshineplan@users.noreply.github.com>
+- syssam <s.y.s.sam.sys@gmail.com>
+- techjanitor <puntme@gmail.com>
+- techjanitor <techjanitor@users.noreply.github.com>
+- thinkerou <thinkerou@gmail.com>
+- thinkgo <49174849+thinkgos@users.noreply.github.com>
+- tsirolnik <tsirolnik@users.noreply.github.com>
+- tyltr <31768692+tylitianrui@users.noreply.github.com>
+- vinhha96 <anhvinha1@gmail.com>
+- voidman <retmain@foxmail.com>
+- vz <vzvway@gmail.com>
+- wei <wei840222@gmail.com>
+- weibaohui <weibaohui@yeah.net>
+- whirosan <whirosan@users.noreply.github.com>
+- willnewrelic <will@newrelic.com>
+- wssccc <wssccc@qq.com>
+- wuhuizuo <wuhuizuo@126.com>
+- xyb <xyb4638@gmail.com>
+- y-yagi <yuuji.yaginuma@gmail.com>
+- yiranzai <wuqingdzx@gmail.com>
+- youzeliang <youzel@126.com>
+- yugu <chenzilong_1227@foxmail.com>
+- yuyabe <yuyabee@gmail.com>
+- zebozhuang <zebozhuang@163.com>
+- zero11-0203 <93071220+zero11-0203@users.noreply.github.com>
+- zesani <7sin@outlook.co.th>
+- zhanweidu <zhanweidu@163.com>
+- zhing <zqwillseven@gmail.com>
+- ziheng <zihenglv@gmail.com>
+- zzjin <zzjin@users.noreply.github.com>
+- 森 優太 <59682979+uta-mori@users.noreply.github.com>
+- 杰哥 <858806258@qq.com>
+- 涛叔 <hi@taoshu.in>
+- 市民233 <mengrenxiong@gmail.com>
+- 尹宝强 <wmdandme@gmail.com>
+- 梦溪笔谈 <loongmxbt@gmail.com>
+- 飞雪无情 <ls8707@gmail.com>
+- 寻寻觅觅的Gopher <zoujh99@qq.com>
diff --git a/vendor/github.com/gin-gonic/gin/CHANGELOG.md b/vendor/github.com/gin-gonic/gin/CHANGELOG.md
index 4c806a5a7..1bc51a8c9 100644
--- a/vendor/github.com/gin-gonic/gin/CHANGELOG.md
+++ b/vendor/github.com/gin-gonic/gin/CHANGELOG.md
@@ -1,5 +1,53 @@
# Gin ChangeLog
+## Gin v1.8.1
+
+### ENHANCEMENTS
+
+* feat(context): add ContextWithFallback feature flag [#3172](https://github.com/gin-gonic/gin/pull/3172)
+
+## Gin v1.8.0
+
+## Break Changes
+
+* TrustedProxies: Add default IPv6 support and refactor [#2967](https://github.com/gin-gonic/gin/pull/2967). Please replace `RemoteIP() (net.IP, bool)` with `RemoteIP() net.IP`
+* gin.Context with fallback value from gin.Context.Request.Context() [#2751](https://github.com/gin-gonic/gin/pull/2751)
+
+### BUGFIXES
+
+* Fixed SetOutput() panics on go 1.17 [#2861](https://github.com/gin-gonic/gin/pull/2861)
+* Fix: wrong when wildcard follows named param [#2983](https://github.com/gin-gonic/gin/pull/2983)
+* Fix: missing sameSite when do context.reset() [#3123](https://github.com/gin-gonic/gin/pull/3123)
+
+### ENHANCEMENTS
+
+* Use Header() instead of deprecated HeaderMap [#2694](https://github.com/gin-gonic/gin/pull/2694)
+* RouterGroup.Handle regular match optimization of http method [#2685](https://github.com/gin-gonic/gin/pull/2685)
+* Add support go-json, another drop-in json replacement [#2680](https://github.com/gin-gonic/gin/pull/2680)
+* Use errors.New to replace fmt.Errorf will much better [#2707](https://github.com/gin-gonic/gin/pull/2707)
+* Use Duration.Truncate for truncating precision [#2711](https://github.com/gin-gonic/gin/pull/2711)
+* Get client IP when using Cloudflare [#2723](https://github.com/gin-gonic/gin/pull/2723)
+* Optimize code adjust [#2700](https://github.com/gin-gonic/gin/pull/2700/files)
+* Optimize code and reduce code cyclomatic complexity [#2737](https://github.com/gin-gonic/gin/pull/2737)
+* Improve sliceValidateError.Error performance [#2765](https://github.com/gin-gonic/gin/pull/2765)
+* Support custom struct tag [#2720](https://github.com/gin-gonic/gin/pull/2720)
+* Improve router group tests [#2787](https://github.com/gin-gonic/gin/pull/2787)
+* Fallback Context.Deadline() Context.Done() Context.Err() to Context.Request.Context() [#2769](https://github.com/gin-gonic/gin/pull/2769)
+* Some codes optimize [#2830](https://github.com/gin-gonic/gin/pull/2830) [#2834](https://github.com/gin-gonic/gin/pull/2834) [#2838](https://github.com/gin-gonic/gin/pull/2838) [#2837](https://github.com/gin-gonic/gin/pull/2837) [#2788](https://github.com/gin-gonic/gin/pull/2788) [#2848](https://github.com/gin-gonic/gin/pull/2848) [#2851](https://github.com/gin-gonic/gin/pull/2851) [#2701](https://github.com/gin-gonic/gin/pull/2701)
+* TrustedProxies: Add default IPv6 support and refactor [#2967](https://github.com/gin-gonic/gin/pull/2967)
+* Test(route): expose performRequest func [#3012](https://github.com/gin-gonic/gin/pull/3012)
+* Support h2c with prior knowledge [#1398](https://github.com/gin-gonic/gin/pull/1398)
+* Feat attachment filename support utf8 [#3071](https://github.com/gin-gonic/gin/pull/3071)
+* Feat: add StaticFileFS [#2749](https://github.com/gin-gonic/gin/pull/2749)
+* Feat(context): return GIN Context from Value method [#2825](https://github.com/gin-gonic/gin/pull/2825)
+* Feat: automatically SetMode to TestMode when run go test [#3139](https://github.com/gin-gonic/gin/pull/3139)
+* Add TOML bining for gin [#3081](https://github.com/gin-gonic/gin/pull/3081)
+* IPv6 add default trusted proxies [#3033](https://github.com/gin-gonic/gin/pull/3033)
+
+### DOCS
+
+* Add note about nomsgpack tag to the readme [#2703](https://github.com/gin-gonic/gin/pull/2703)
+
## Gin v1.7.7
### BUGFIXES
diff --git a/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md b/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
index 97daa808f..d1c723c67 100644
--- a/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
+++ b/vendor/github.com/gin-gonic/gin/CONTRIBUTING.md
@@ -8,6 +8,6 @@
- With pull requests:
- Open your pull request against `master`
- Your pull request should have no more than two commits, if not you should squash them.
- - It should pass all tests in the available continuous integration systems such as TravisCI.
+ - It should pass all tests in the available continuous integration systems such as GitHub Actions.
- You should add/modify tests to cover your proposed code changes.
- If your pull request contains a new feature, please document it on the README.
diff --git a/vendor/github.com/gin-gonic/gin/Makefile b/vendor/github.com/gin-gonic/gin/Makefile
index 1a9919395..5d55b444c 100644
--- a/vendor/github.com/gin-gonic/gin/Makefile
+++ b/vendor/github.com/gin-gonic/gin/Makefile
@@ -1,5 +1,6 @@
GO ?= go
GOFMT ?= gofmt "-s"
+GO_VERSION=$(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
PACKAGES ?= $(shell $(GO) list ./...)
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)
GOFILES := $(shell find . -name "*.go")
@@ -67,5 +68,10 @@ misspell:
.PHONY: tools
tools:
- go install golang.org/x/lint/golint; \
- go install github.com/client9/misspell/cmd/misspell;
+ @if [ $(GO_VERSION) -gt 15 ]; then \
+ $(GO) install golang.org/x/lint/golint@latest; \
+ $(GO) install github.com/client9/misspell/cmd/misspell@latest; \
+ elif [ $(GO_VERSION) -lt 16 ]; then \
+ $(GO) install golang.org/x/lint/golint; \
+ $(GO) install github.com/client9/misspell/cmd/misspell; \
+ fi
diff --git a/vendor/github.com/gin-gonic/gin/README.md b/vendor/github.com/gin-gonic/gin/README.md
index 9bf459b09..5cc8321b6 100644
--- a/vendor/github.com/gin-gonic/gin/README.md
+++ b/vendor/github.com/gin-gonic/gin/README.md
@@ -2,7 +2,7 @@
<img align="right" width="159px" src="https://raw.githubusercontent.com/gin-gonic/logo/master/color.png">
-[![Build Status](https://travis-ci.org/gin-gonic/gin.svg)](https://travis-ci.org/gin-gonic/gin)
+[![Build Status](https://github.com/gin-gonic/gin/workflows/Run%20Tests/badge.svg?branch=master)](https://github.com/gin-gonic/gin/actions?query=branch%3Amaster)
[![codecov](https://codecov.io/gh/gin-gonic/gin/branch/master/graph/badge.svg)](https://codecov.io/gh/gin-gonic/gin)
[![Go Report Card](https://goreportcard.com/badge/github.com/gin-gonic/gin)](https://goreportcard.com/report/github.com/gin-gonic/gin)
[![GoDoc](https://pkg.go.dev/badge/github.com/gin-gonic/gin?status.svg)](https://pkg.go.dev/github.com/gin-gonic/gin?tab=doc)
@@ -23,7 +23,8 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
- [Quick start](#quick-start)
- [Benchmarks](#benchmarks)
- [Gin v1. stable](#gin-v1-stable)
- - [Build with jsoniter](#build-with-jsoniter)
+ - [Build with jsoniter/go-json](#build-with-json-replacement)
+ - [Build without `MsgPack` rendering feature](#build-without-msgpack-rendering-feature)
- [API Examples](#api-examples)
- [Using GET, POST, PUT, PATCH, DELETE and OPTIONS](#using-get-post-put-patch-delete-and-options)
- [Parameters in path](#parameters-in-path)
@@ -77,7 +78,7 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
- [http2 server push](#http2-server-push)
- [Define format for the log of routes](#define-format-for-the-log-of-routes)
- [Set and get a cookie](#set-and-get-a-cookie)
- - [Don't trust all proxies](#don't-trust-all-proxies)
+ - [Don't trust all proxies](#dont-trust-all-proxies)
- [Testing](#testing)
- [Users](#users)
@@ -85,7 +86,7 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
To install Gin package, you need to install Go and set your Go workspace first.
-1. The first need [Go](https://golang.org/) installed (**version 1.13+ is required**), then you can use the below Go command to install Gin.
+1. You first need [Go](https://golang.org/) installed (**version 1.14+ is required**), then you can use the below Go command to install Gin.
```sh
$ go get -u github.com/gin-gonic/gin
@@ -113,12 +114,16 @@ $ cat example.go
```go
package main
-import "github.com/gin-gonic/gin"
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
+ c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
@@ -183,13 +188,28 @@ Gin uses a custom version of [HttpRouter](https://github.com/julienschmidt/httpr
- [x] Battle tested.
- [x] API frozen, new releases will not break your code.
-## Build with [jsoniter](https://github.com/json-iterator/go)
+## Build with json replacement
-Gin uses `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
+Gin uses `encoding/json` as default json package but you can change it by build from other tags.
+[jsoniter](https://github.com/json-iterator/go)
```sh
$ go build -tags=jsoniter .
```
+[go-json](https://github.com/goccy/go-json)
+```sh
+$ go build -tags=go_json .
+```
+
+## Build without `MsgPack` rendering feature
+
+Gin enables `MsgPack` rendering feature by default. But you can disable this feature by specifying `nomsgpack` build tag.
+
+```sh
+$ go build -tags=nomsgpack .
+```
+
+This is useful to reduce the binary size of executable files. See the [detail information](https://github.com/gin-gonic/gin/pull/1852).
## API Examples
@@ -241,14 +261,15 @@ func main() {
// For each matched request Context will hold the route definition
router.POST("/user/:name/*action", func(c *gin.Context) {
- c.FullPath() == "/user/:name/*action" // true
+ b := c.FullPath() == "/user/:name/*action" // true
+ c.String(http.StatusOK, "%t", b)
})
// This handler will add a new router for /user/groups.
// Exact routes are resolved before param routes, regardless of the order they were defined.
// Routes starting with /user/groups are never interpreted as /user/:name/... routes
router.GET("/user/groups", func(c *gin.Context) {
- c.String(http.StatusOK, "The available groups are [...]", name)
+ c.String(http.StatusOK, "The available groups are [...]")
})
router.Run(":8080")
@@ -283,7 +304,7 @@ func main() {
message := c.PostForm("message")
nick := c.DefaultPostForm("nick", "anonymous")
- c.JSON(200, gin.H{
+ c.JSON(http.StatusOK, gin.H{
"status": "posted",
"message": message,
"nick": nick,
@@ -367,7 +388,7 @@ func main() {
// Set a lower memory limit for multipart forms (default is 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
- // single file
+ // Single file
file, _ := c.FormFile("file")
log.Println(file.Filename)
@@ -496,6 +517,7 @@ func main() {
// nested group
testing := authorized.Group("testing")
+ // visit 0.0.0.0:8080/testing/analytics
testing.GET("/analytics", analyticsEndpoint)
}
@@ -552,7 +574,7 @@ func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
+ c.String(http.StatusOK, "pong")
})
   router.Run(":8080")
@@ -584,7 +606,7 @@ func main() {
router.Use(gin.Recovery())
router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
+ c.String(http.StatusOK, "pong")
})
router.Run(":8080")
@@ -612,7 +634,7 @@ func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
+ c.String(http.StatusOK, "pong")
})
router.Run(":8080")
@@ -631,7 +653,7 @@ func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
+ c.String(http.StatusOK, "pong")
})
router.Run(":8080")
@@ -640,7 +662,7 @@ func main() {
### Model binding and validation
-To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
+To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML, TOML and standard form values (foo=bar&boo=baz).
Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://godoc.org/github.com/go-playground/validator#hdr-Baked_In_Validators_and_Tags).
@@ -648,10 +670,10 @@ Note that you need to set the corresponding binding tag on all fields you want t
Also, Gin provides two sets of methods for binding:
- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`, `BindHeader`
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`, `BindHeader`, `BindTOML`
- **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`, `ShouldBindHeader`
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`, `ShouldBindHeader`, `ShouldBindTOML`,
- **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
@@ -687,7 +709,7 @@ func main() {
// Example for binding XML (
// <?xml version="1.0" encoding="UTF-8"?>
// <root>
- // <user>user</user>
+ // <user>manu</user>
// <password>123</password>
// </root>)
router.POST("/loginXML", func(c *gin.Context) {
@@ -830,6 +852,7 @@ package main
import (
"log"
+ "net/http"
"github.com/gin-gonic/gin"
)
@@ -852,7 +875,7 @@ func startPage(c *gin.Context) {
log.Println(person.Name)
log.Println(person.Address)
}
- c.String(200, "Success")
+ c.String(http.StatusOK, "Success")
}
```
@@ -866,6 +889,7 @@ package main
import (
"log"
+ "net/http"
"time"
"github.com/gin-gonic/gin"
@@ -889,7 +913,7 @@ func startPage(c *gin.Context) {
var person Person
// If `GET`, only `Form` binding engine (`query`) used.
// If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
- // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
+ // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L88
if c.ShouldBind(&person) == nil {
log.Println(person.Name)
log.Println(person.Address)
@@ -898,7 +922,7 @@ func startPage(c *gin.Context) {
log.Println(person.UnixTime)
}
- c.String(200, "Success")
+ c.String(http.StatusOK, "Success")
}
```
@@ -914,7 +938,11 @@ See the [detail information](https://github.com/gin-gonic/gin/issues/846).
```go
package main
-import "github.com/gin-gonic/gin"
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
type Person struct {
ID string `uri:"id" binding:"required,uuid"`
@@ -926,10 +954,10 @@ func main() {
route.GET("/:name/:id", func(c *gin.Context) {
var person Person
if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err})
+ c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
return
}
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ c.JSON(http.StatusOK, gin.H{"name": person.Name, "uuid": person.ID})
})
route.Run(":8088")
}
@@ -948,6 +976,8 @@ package main
import (
"fmt"
+ "net/http"
+
"github.com/gin-gonic/gin"
)
@@ -962,11 +992,11 @@ func main() {
h := testHeader{}
if err := c.ShouldBindHeader(&h); err != nil {
- c.JSON(200, err)
+ c.JSON(http.StatusOK, err)
}
fmt.Printf("%#v\n", h)
- c.JSON(200, gin.H{"Rate": h.Rate, "Domain": h.Domain})
+ c.JSON(http.StatusOK, gin.H{"Rate": h.Rate, "Domain": h.Domain})
})
r.Run()
@@ -996,7 +1026,7 @@ type myForm struct {
func formHandler(c *gin.Context) {
var fakeForm myForm
c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
+ c.JSON(http.StatusOK, gin.H{"color": fakeForm.Colors})
}
...
@@ -1201,14 +1231,14 @@ func main() {
// Serves unicode entities
r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
+ c.JSON(http.StatusOK, gin.H{
"html": "<b>Hello, world!</b>",
})
})
// Serves literal characters
r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
+ c.PureJSON(http.StatusOK, gin.H{
"html": "<b>Hello, world!</b>",
})
})
@@ -1226,7 +1256,8 @@ func main() {
router.Static("/assets", "./assets")
router.StaticFS("/more_static", http.Dir("my_file_system"))
router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
+ router.StaticFileFS("/more_favicon.ico", "more_favicon.ico", http.Dir("my_file_system"))
+
// Listen and serve on 0.0.0.0:8080
router.Run(":8080")
}
@@ -1392,7 +1423,7 @@ import (
func formatAsDate(t time.Time) string {
year, month, day := t.Date()
- return fmt.Sprintf("%d%02d/%02d", year, month, day)
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
}
func main() {
@@ -1454,7 +1485,7 @@ r.GET("/test", func(c *gin.Context) {
r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
+ c.JSON(http.StatusOK, gin.H{"hello": "world"})
})
```
@@ -1607,6 +1638,7 @@ package main
import (
"log"
+ "net/http"
"github.com/gin-gonic/autotls"
"github.com/gin-gonic/gin"
@@ -1617,7 +1649,7 @@ func main() {
// Ping handler
r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
+ c.String(http.StatusOK, "pong")
})
log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
@@ -1631,6 +1663,7 @@ package main
import (
"log"
+ "net/http"
"github.com/gin-gonic/autotls"
"github.com/gin-gonic/gin"
@@ -1642,7 +1675,7 @@ func main() {
// Ping handler
r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
+ c.String(http.StatusOK, "pong")
})
m := autocert.Manager{
@@ -1811,7 +1844,7 @@ func main() {
quit := make(chan os.Signal)
// kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT
- // kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
+ // kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")
@@ -1903,7 +1936,7 @@ type StructD struct {
func GetDataB(c *gin.Context) {
var b StructB
c.Bind(&b)
- c.JSON(200, gin.H{
+ c.JSON(http.StatusOK, gin.H{
"a": b.NestedStruct,
"b": b.FieldB,
})
@@ -1912,7 +1945,7 @@ func GetDataB(c *gin.Context) {
func GetDataC(c *gin.Context) {
var b StructC
c.Bind(&b)
- c.JSON(200, gin.H{
+ c.JSON(http.StatusOK, gin.H{
"a": b.NestedStructPointer,
"c": b.FieldC,
})
@@ -1921,7 +1954,7 @@ func GetDataC(c *gin.Context) {
func GetDataD(c *gin.Context) {
var b StructD
c.Bind(&b)
- c.JSON(200, gin.H{
+ c.JSON(http.StatusOK, gin.H{
"x": b.NestedAnonyStruct,
"d": b.FieldD,
})
@@ -1984,7 +2017,7 @@ func SomeHandler(c *gin.Context) {
objA := formA{}
objB := formB{}
// This reads c.Request.Body and stores the result into the context.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ if errA := c.ShouldBindBodyWith(&objA, binding.Form); errA == nil {
c.String(http.StatusOK, `the body should be formA`)
// At this time, it reuses body stored in the context.
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
@@ -2006,6 +2039,61 @@ enough to call binding at once.
can be called by `c.ShouldBind()` multiple times without any damage to
performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+### Bind form-data request with custom struct and custom tag
+
+```go
+const (
+ customerTag = "url"
+ defaultMemory = 32 << 20
+)
+
+type customerBinding struct {}
+
+func (customerBinding) Name() string {
+ return "form"
+}
+
+func (customerBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := req.ParseForm(); err != nil {
+ return err
+ }
+ if err := req.ParseMultipartForm(defaultMemory); err != nil {
+ if err != http.ErrNotMultipart {
+ return err
+ }
+ }
+ if err := binding.MapFormWithTag(obj, req.Form, customerTag); err != nil {
+ return err
+ }
+ return validate(obj)
+}
+
+func validate(obj interface{}) error {
+ if binding.Validator == nil {
+ return nil
+ }
+ return binding.Validator.ValidateStruct(obj)
+}
+
+// Now we can do this!!!
+// FormA is a external type that we can't modify it's tag
+type FormA struct {
+ FieldA string `url:"field_a"`
+}
+
+func ListHandler(s *Service) func(ctx *gin.Context) {
+ return func(ctx *gin.Context) {
+ var urlBinding = customerBinding{}
+ var opt FormA
+ err := ctx.MustBindWith(&opt, urlBinding)
+ if err != nil {
+ ...
+ }
+ ...
+ }
+}
+```
+
### http2 server push
http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
@@ -2016,6 +2104,7 @@ package main
import (
"html/template"
"log"
+ "net/http"
"github.com/gin-gonic/gin"
)
@@ -2044,7 +2133,7 @@ func main() {
log.Printf("Failed to push: %v", err)
}
}
- c.HTML(200, "https", gin.H{
+ c.HTML(http.StatusOK, "https", gin.H{
"status": "success",
})
})
@@ -2200,10 +2289,16 @@ The `net/http/httptest` package is preferable way for HTTP testing.
```go
package main
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
func setupRouter() *gin.Engine {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
+ c.String(http.StatusOK, "pong")
})
return r
}
@@ -2231,10 +2326,10 @@ func TestPingRoute(t *testing.T) {
router := setupRouter()
w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
+ req, _ := http.NewRequest(http.MethodGet, "/ping", nil)
router.ServeHTTP(w, req)
- assert.Equal(t, 200, w.Code)
+ assert.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, "pong", w.Body.String())
}
```
@@ -2250,3 +2345,4 @@ Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framewor
* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
* [brigade](https://github.com/brigadecore/brigade): Event-based Scripting for Kubernetes.
* [dkron](https://github.com/distribworks/dkron): Distributed, fault tolerant job scheduling system.
+
diff --git a/vendor/github.com/gin-gonic/gin/any.go b/vendor/github.com/gin-gonic/gin/any.go
new file mode 100644
index 000000000..42b1ea46f
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/any.go
@@ -0,0 +1,10 @@
+// Copyright 2022 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.18
+// +build !go1.18
+
+package gin
+
+type any = interface{}
diff --git a/vendor/github.com/gin-gonic/gin/auth.go b/vendor/github.com/gin-gonic/gin/auth.go
index 4d8a6ce48..2503c5156 100644
--- a/vendor/github.com/gin-gonic/gin/auth.go
+++ b/vendor/github.com/gin-gonic/gin/auth.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -31,7 +31,7 @@ func (a authPairs) searchCredential(authValue string) (string, bool) {
return "", false
}
for _, pair := range a {
- if subtle.ConstantTimeCompare([]byte(pair.value), []byte(authValue)) == 1 {
+ if subtle.ConstantTimeCompare(bytesconv.StringToBytes(pair.value), bytesconv.StringToBytes(authValue)) == 1 {
return pair.user, true
}
}
diff --git a/vendor/github.com/gin-gonic/gin/binding/any.go b/vendor/github.com/gin-gonic/gin/binding/any.go
new file mode 100644
index 000000000..d8251a7c2
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/any.go
@@ -0,0 +1,10 @@
+// Copyright 2022 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.18
+// +build !go1.18
+
+package binding
+
+type any = interface{}
diff --git a/vendor/github.com/gin-gonic/gin/binding/binding.go b/vendor/github.com/gin-gonic/gin/binding/binding.go
index 5caeb581a..a58924ed3 100644
--- a/vendor/github.com/gin-gonic/gin/binding/binding.go
+++ b/vendor/github.com/gin-gonic/gin/binding/binding.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -22,6 +22,7 @@ const (
MIMEMSGPACK = "application/x-msgpack"
MIMEMSGPACK2 = "application/msgpack"
MIMEYAML = "application/x-yaml"
+ MIMETOML = "application/toml"
)
// Binding describes the interface which needs to be implemented for binding the
@@ -29,27 +30,27 @@ const (
// the form POST.
type Binding interface {
Name() string
- Bind(*http.Request, interface{}) error
+ Bind(*http.Request, any) error
}
// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
// but it reads the body from supplied bytes instead of req.Body.
type BindingBody interface {
Binding
- BindBody([]byte, interface{}) error
+ BindBody([]byte, any) error
}
// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
-// but it read the Params.
+// but it reads the Params.
type BindingUri interface {
Name() string
- BindUri(map[string][]string, interface{}) error
+ BindUri(map[string][]string, any) error
}
// StructValidator is the minimal interface which needs to be implemented in
// order for it to be used as the validator engine for ensuring the correctness
// of the request. Gin provides a default implementation for this using
-// https://github.com/go-playground/validator/tree/v8.18.2.
+// https://github.com/go-playground/validator/tree/v10.6.1.
type StructValidator interface {
// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
// If the received type is a slice|array, the validation should be performed travel on every element.
@@ -57,15 +58,15 @@ type StructValidator interface {
// If the received type is a struct or pointer to a struct, the validation should be performed.
// If the struct is not valid or the validation itself fails, a descriptive error should be returned.
// Otherwise nil must be returned.
- ValidateStruct(interface{}) error
+ ValidateStruct(any) error
// Engine returns the underlying validator engine which powers the
// StructValidator implementation.
- Engine() interface{}
+ Engine() any
}
// Validator is the default validator which implements the StructValidator
-// interface. It uses https://github.com/go-playground/validator/tree/v8.18.2
+// interface. It uses https://github.com/go-playground/validator/tree/v10.6.1
// under the hood.
var Validator StructValidator = &defaultValidator{}
@@ -83,6 +84,7 @@ var (
YAML = yamlBinding{}
Uri = uriBinding{}
Header = headerBinding{}
+ TOML = tomlBinding{}
)
// Default returns the appropriate Binding instance based on the HTTP method
@@ -103,6 +105,8 @@ func Default(method, contentType string) Binding {
return MsgPack
case MIMEYAML:
return YAML
+ case MIMETOML:
+ return TOML
case MIMEMultipartPOSTForm:
return FormMultipart
default: // case MIMEPOSTForm:
@@ -110,7 +114,7 @@ func Default(method, contentType string) Binding {
}
}
-func validate(obj interface{}) error {
+func validate(obj any) error {
if Validator == nil {
return nil
}
diff --git a/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go b/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go
index 9afa3dcf6..7f6a904ab 100644
--- a/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go
+++ b/vendor/github.com/gin-gonic/gin/binding/binding_nomsgpack.go
@@ -20,6 +20,7 @@ const (
MIMEMultipartPOSTForm = "multipart/form-data"
MIMEPROTOBUF = "application/x-protobuf"
MIMEYAML = "application/x-yaml"
+ MIMETOML = "application/toml"
)
// Binding describes the interface which needs to be implemented for binding the
@@ -27,42 +28,42 @@ const (
// the form POST.
type Binding interface {
Name() string
- Bind(*http.Request, interface{}) error
+ Bind(*http.Request, any) error
}
// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
// but it reads the body from supplied bytes instead of req.Body.
type BindingBody interface {
Binding
- BindBody([]byte, interface{}) error
+ BindBody([]byte, any) error
}
// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
-// but it read the Params.
+// but it reads the Params.
type BindingUri interface {
Name() string
- BindUri(map[string][]string, interface{}) error
+ BindUri(map[string][]string, any) error
}
// StructValidator is the minimal interface which needs to be implemented in
// order for it to be used as the validator engine for ensuring the correctness
// of the request. Gin provides a default implementation for this using
-// https://github.com/go-playground/validator/tree/v8.18.2.
+// https://github.com/go-playground/validator/tree/v10.6.1.
type StructValidator interface {
// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
// If the received type is not a struct, any validation should be skipped and nil must be returned.
// If the received type is a struct or pointer to a struct, the validation should be performed.
// If the struct is not valid or the validation itself fails, a descriptive error should be returned.
// Otherwise nil must be returned.
- ValidateStruct(interface{}) error
+ ValidateStruct(any) error
// Engine returns the underlying validator engine which powers the
// StructValidator implementation.
- Engine() interface{}
+ Engine() any
}
// Validator is the default validator which implements the StructValidator
-// interface. It uses https://github.com/go-playground/validator/tree/v8.18.2
+// interface. It uses https://github.com/go-playground/validator/tree/v10.6.1
// under the hood.
var Validator StructValidator = &defaultValidator{}
@@ -79,6 +80,7 @@ var (
YAML = yamlBinding{}
Uri = uriBinding{}
Header = headerBinding{}
+ TOML = tomlBinding{}
)
// Default returns the appropriate Binding instance based on the HTTP method
@@ -99,12 +101,14 @@ func Default(method, contentType string) Binding {
return YAML
case MIMEMultipartPOSTForm:
return FormMultipart
+ case MIMETOML:
+ return TOML
default: // case MIMEPOSTForm:
return Form
}
}
-func validate(obj interface{}) error {
+func validate(obj any) error {
if Validator == nil {
return nil
}
diff --git a/vendor/github.com/gin-gonic/gin/binding/default_validator.go b/vendor/github.com/gin-gonic/gin/binding/default_validator.go
index c57a120fc..c03afe75b 100644
--- a/vendor/github.com/gin-gonic/gin/binding/default_validator.go
+++ b/vendor/github.com/gin-gonic/gin/binding/default_validator.go
@@ -1,4 +1,4 @@
-// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -18,23 +18,35 @@ type defaultValidator struct {
validate *validator.Validate
}
-type sliceValidateError []error
+type SliceValidationError []error
-func (err sliceValidateError) Error() string {
- var errMsgs []string
- for i, e := range err {
- if e == nil {
- continue
+// Error concatenates all error elements in SliceValidationError into a single string separated by \n.
+func (err SliceValidationError) Error() string {
+ n := len(err)
+ switch n {
+ case 0:
+ return ""
+ default:
+ var b strings.Builder
+ if err[0] != nil {
+ fmt.Fprintf(&b, "[%d]: %s", 0, err[0].Error())
+ }
+ if n > 1 {
+ for i := 1; i < n; i++ {
+ if err[i] != nil {
+ b.WriteString("\n")
+ fmt.Fprintf(&b, "[%d]: %s", i, err[i].Error())
+ }
+ }
}
- errMsgs = append(errMsgs, fmt.Sprintf("[%d]: %s", i, e.Error()))
+ return b.String()
}
- return strings.Join(errMsgs, "\n")
}
var _ StructValidator = &defaultValidator{}
// ValidateStruct receives any kind of type, but only performed struct or pointer to struct type.
-func (v *defaultValidator) ValidateStruct(obj interface{}) error {
+func (v *defaultValidator) ValidateStruct(obj any) error {
if obj == nil {
return nil
}
@@ -47,7 +59,7 @@ func (v *defaultValidator) ValidateStruct(obj interface{}) error {
return v.validateStruct(obj)
case reflect.Slice, reflect.Array:
count := value.Len()
- validateRet := make(sliceValidateError, 0)
+ validateRet := make(SliceValidationError, 0)
for i := 0; i < count; i++ {
if err := v.ValidateStruct(value.Index(i).Interface()); err != nil {
validateRet = append(validateRet, err)
@@ -63,7 +75,7 @@ func (v *defaultValidator) ValidateStruct(obj interface{}) error {
}
// validateStruct receives struct type
-func (v *defaultValidator) validateStruct(obj interface{}) error {
+func (v *defaultValidator) validateStruct(obj any) error {
v.lazyinit()
return v.validate.Struct(obj)
}
@@ -71,8 +83,8 @@ func (v *defaultValidator) validateStruct(obj interface{}) error {
// Engine returns the underlying validator engine which powers the default
// Validator instance. This is useful if you want to register custom validations
// or struct level validations. See validator GoDoc for more info -
-// https://godoc.org/gopkg.in/go-playground/validator.v8
-func (v *defaultValidator) Engine() interface{} {
+// https://pkg.go.dev/github.com/go-playground/validator/v10
+func (v *defaultValidator) Engine() any {
v.lazyinit()
return v.validate
}
diff --git a/vendor/github.com/gin-gonic/gin/binding/form.go b/vendor/github.com/gin-gonic/gin/binding/form.go
index b93c34cf4..b17352bad 100644
--- a/vendor/github.com/gin-gonic/gin/binding/form.go
+++ b/vendor/github.com/gin-gonic/gin/binding/form.go
@@ -1,10 +1,11 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package binding
import (
+ "errors"
"net/http"
)
@@ -18,14 +19,12 @@ func (formBinding) Name() string {
return "form"
}
-func (formBinding) Bind(req *http.Request, obj interface{}) error {
+func (formBinding) Bind(req *http.Request, obj any) error {
if err := req.ParseForm(); err != nil {
return err
}
- if err := req.ParseMultipartForm(defaultMemory); err != nil {
- if err != http.ErrNotMultipart {
- return err
- }
+ if err := req.ParseMultipartForm(defaultMemory); err != nil && !errors.Is(err, http.ErrNotMultipart) {
+ return err
}
if err := mapForm(obj, req.Form); err != nil {
return err
@@ -37,7 +36,7 @@ func (formPostBinding) Name() string {
return "form-urlencoded"
}
-func (formPostBinding) Bind(req *http.Request, obj interface{}) error {
+func (formPostBinding) Bind(req *http.Request, obj any) error {
if err := req.ParseForm(); err != nil {
return err
}
@@ -51,7 +50,7 @@ func (formMultipartBinding) Name() string {
return "multipart/form-data"
}
-func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error {
+func (formMultipartBinding) Bind(req *http.Request, obj any) error {
if err := req.ParseMultipartForm(defaultMemory); err != nil {
return err
}
diff --git a/vendor/github.com/gin-gonic/gin/binding/form_mapping.go b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
index 2f4e45b40..98cebfecf 100644
--- a/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
+++ b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -16,22 +16,34 @@ import (
"github.com/gin-gonic/gin/internal/json"
)
-var errUnknownType = errors.New("unknown type")
+var (
+ errUnknownType = errors.New("unknown type")
-func mapUri(ptr interface{}, m map[string][]string) error {
+ // ErrConvertMapStringSlice can not covert to map[string][]string
+ ErrConvertMapStringSlice = errors.New("can not convert to map slices of strings")
+
+ // ErrConvertToMapString can not convert to map[string]string
+ ErrConvertToMapString = errors.New("can not convert to map of strings")
+)
+
+func mapURI(ptr any, m map[string][]string) error {
return mapFormByTag(ptr, m, "uri")
}
-func mapForm(ptr interface{}, form map[string][]string) error {
+func mapForm(ptr any, form map[string][]string) error {
return mapFormByTag(ptr, form, "form")
}
+func MapFormWithTag(ptr any, form map[string][]string, tag string) error {
+ return mapFormByTag(ptr, form, tag)
+}
+
var emptyField = reflect.StructField{}
-func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
+func mapFormByTag(ptr any, form map[string][]string, tag string) error {
// Check if ptr is a map
ptrVal := reflect.ValueOf(ptr)
- var pointed interface{}
+ var pointed any
if ptrVal.Kind() == reflect.Ptr {
ptrVal = ptrVal.Elem()
pointed = ptrVal.Interface()
@@ -49,7 +61,7 @@ func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
// setter tries to set value on a walking by fields of a struct
type setter interface {
- TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error)
+ TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSet bool, err error)
}
type formSource map[string][]string
@@ -57,11 +69,11 @@ type formSource map[string][]string
var _ setter = formSource(nil)
// TrySet tries to set a value by request's form source (like map[string][]string)
-func (form formSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSetted bool, err error) {
+func (form formSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSet bool, err error) {
return setByForm(value, field, form, tagValue, opt)
}
-func mappingByPtr(ptr interface{}, setter setter, tag string) error {
+func mappingByPtr(ptr any, setter setter, tag string) error {
_, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag)
return err
}
@@ -71,7 +83,7 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
return false, nil
}
- var vKind = value.Kind()
+ vKind := value.Kind()
if vKind == reflect.Ptr {
var isNew bool
@@ -80,14 +92,14 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
isNew = true
vPtr = reflect.New(value.Type().Elem())
}
- isSetted, err := mapping(vPtr.Elem(), field, setter, tag)
+ isSet, err := mapping(vPtr.Elem(), field, setter, tag)
if err != nil {
return false, err
}
- if isNew && isSetted {
+ if isNew && isSet {
value.Set(vPtr)
}
- return isSetted, nil
+ return isSet, nil
}
if vKind != reflect.Struct || !field.Anonymous {
@@ -103,19 +115,19 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
if vKind == reflect.Struct {
tValue := value.Type()
- var isSetted bool
+ var isSet bool
for i := 0; i < value.NumField(); i++ {
sf := tValue.Field(i)
if sf.PkgPath != "" && !sf.Anonymous { // unexported
continue
}
- ok, err := mapping(value.Field(i), tValue.Field(i), setter, tag)
+ ok, err := mapping(value.Field(i), sf, setter, tag)
if err != nil {
return false, err
}
- isSetted = isSetted || ok
+ isSet = isSet || ok
}
- return isSetted, nil
+ return isSet, nil
}
return false, nil
}
@@ -152,7 +164,7 @@ func tryToSetValue(value reflect.Value, field reflect.StructField, setter setter
return setter.TrySet(value, field, tagValue, setOpt)
}
-func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSetted bool, err error) {
+func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSet bool, err error) {
vs, ok := form[tagValue]
if !ok && !opt.isDefaultExists {
return false, nil
@@ -198,7 +210,7 @@ func setWithProperType(val string, value reflect.Value, field reflect.StructFiel
case reflect.Int64:
switch value.Interface().(type) {
case time.Duration:
- return setTimeDuration(val, value, field)
+ return setTimeDuration(val, value)
}
return setIntField(val, 64, value)
case reflect.Uint:
@@ -298,7 +310,6 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
t := time.Unix(tv/int64(d), tv%int64(d))
value.Set(reflect.ValueOf(t))
return nil
-
}
if val == "" {
@@ -348,7 +359,7 @@ func setSlice(vals []string, value reflect.Value, field reflect.StructField) err
return nil
}
-func setTimeDuration(val string, value reflect.Value, field reflect.StructField) error {
+func setTimeDuration(val string, value reflect.Value) error {
d, err := time.ParseDuration(val)
if err != nil {
return err
@@ -365,13 +376,13 @@ func head(str, sep string) (head string, tail string) {
return str[:idx], str[idx+len(sep):]
}
-func setFormMap(ptr interface{}, form map[string][]string) error {
+func setFormMap(ptr any, form map[string][]string) error {
el := reflect.TypeOf(ptr).Elem()
if el.Kind() == reflect.Slice {
ptrMap, ok := ptr.(map[string][]string)
if !ok {
- return errors.New("cannot convert to map slices of strings")
+ return ErrConvertMapStringSlice
}
for k, v := range form {
ptrMap[k] = v
@@ -382,7 +393,7 @@ func setFormMap(ptr interface{}, form map[string][]string) error {
ptrMap, ok := ptr.(map[string]string)
if !ok {
- return errors.New("cannot convert to map of strings")
+ return ErrConvertToMapString
}
for k, v := range form {
ptrMap[k] = v[len(v)-1] // pick last
diff --git a/vendor/github.com/gin-gonic/gin/binding/header.go b/vendor/github.com/gin-gonic/gin/binding/header.go
index 179ce4ea2..03bc78dae 100644
--- a/vendor/github.com/gin-gonic/gin/binding/header.go
+++ b/vendor/github.com/gin-gonic/gin/binding/header.go
@@ -1,3 +1,7 @@
+// Copyright 2022 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package binding
import (
@@ -12,7 +16,7 @@ func (headerBinding) Name() string {
return "header"
}
-func (headerBinding) Bind(req *http.Request, obj interface{}) error {
+func (headerBinding) Bind(req *http.Request, obj any) error {
if err := mapHeader(obj, req.Header); err != nil {
return err
@@ -21,7 +25,7 @@ func (headerBinding) Bind(req *http.Request, obj interface{}) error {
return validate(obj)
}
-func mapHeader(ptr interface{}, h map[string][]string) error {
+func mapHeader(ptr any, h map[string][]string) error {
return mappingByPtr(ptr, headerSource(h), "header")
}
@@ -29,6 +33,6 @@ type headerSource map[string][]string
var _ setter = headerSource(nil)
-func (hs headerSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSetted bool, err error) {
+func (hs headerSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (bool, error) {
return setByForm(value, field, hs, textproto.CanonicalMIMEHeaderKey(tagValue), opt)
}
diff --git a/vendor/github.com/gin-gonic/gin/binding/json.go b/vendor/github.com/gin-gonic/gin/binding/json.go
index d62e07059..36eb27a34 100644
--- a/vendor/github.com/gin-gonic/gin/binding/json.go
+++ b/vendor/github.com/gin-gonic/gin/binding/json.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -6,7 +6,7 @@ package binding
import (
"bytes"
- "fmt"
+ "errors"
"io"
"net/http"
@@ -30,18 +30,18 @@ func (jsonBinding) Name() string {
return "json"
}
-func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
+func (jsonBinding) Bind(req *http.Request, obj any) error {
if req == nil || req.Body == nil {
- return fmt.Errorf("invalid request")
+ return errors.New("invalid request")
}
return decodeJSON(req.Body, obj)
}
-func (jsonBinding) BindBody(body []byte, obj interface{}) error {
+func (jsonBinding) BindBody(body []byte, obj any) error {
return decodeJSON(bytes.NewReader(body), obj)
}
-func decodeJSON(r io.Reader, obj interface{}) error {
+func decodeJSON(r io.Reader, obj any) error {
decoder := json.NewDecoder(r)
if EnableDecoderUseNumber {
decoder.UseNumber()
diff --git a/vendor/github.com/gin-gonic/gin/binding/msgpack.go b/vendor/github.com/gin-gonic/gin/binding/msgpack.go
index 2a442996a..d1f035e44 100644
--- a/vendor/github.com/gin-gonic/gin/binding/msgpack.go
+++ b/vendor/github.com/gin-gonic/gin/binding/msgpack.go
@@ -1,4 +1,4 @@
-// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -21,15 +21,15 @@ func (msgpackBinding) Name() string {
return "msgpack"
}
-func (msgpackBinding) Bind(req *http.Request, obj interface{}) error {
+func (msgpackBinding) Bind(req *http.Request, obj any) error {
return decodeMsgPack(req.Body, obj)
}
-func (msgpackBinding) BindBody(body []byte, obj interface{}) error {
+func (msgpackBinding) BindBody(body []byte, obj any) error {
return decodeMsgPack(bytes.NewReader(body), obj)
}
-func decodeMsgPack(r io.Reader, obj interface{}) error {
+func decodeMsgPack(r io.Reader, obj any) error {
cdc := new(codec.MsgpackHandle)
if err := codec.NewDecoder(r, cdc).Decode(&obj); err != nil {
return err
diff --git a/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go b/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go
index f85a1aa60..4ebe83263 100644
--- a/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go
+++ b/vendor/github.com/gin-gonic/gin/binding/multipart_form_mapping.go
@@ -1,4 +1,4 @@
-// Copyright 2019 Gin Core Team. All rights reserved.
+// Copyright 2019 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -15,8 +15,16 @@ type multipartRequest http.Request
var _ setter = (*multipartRequest)(nil)
+var (
+ // ErrMultiFileHeader multipart.FileHeader invalid
+ ErrMultiFileHeader = errors.New("unsupported field type for multipart.FileHeader")
+
+ // ErrMultiFileHeaderLenInvalid array for []*multipart.FileHeader len invalid
+ ErrMultiFileHeaderLenInvalid = errors.New("unsupported len of array for []*multipart.FileHeader")
+)
+
// TrySet tries to set a value by the multipart request with the binding a form file
-func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error) {
+func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (bool, error) {
if files := r.MultipartForm.File[key]; len(files) != 0 {
return setByMultipartFormFile(value, field, files)
}
@@ -24,7 +32,7 @@ func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField
return setByForm(value, field, r.MultipartForm.Value, key, opt)
}
-func setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) {
+func setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSet bool, err error) {
switch value.Kind() {
case reflect.Ptr:
switch value.Interface().(type) {
@@ -40,26 +48,26 @@ func setByMultipartFormFile(value reflect.Value, field reflect.StructField, file
}
case reflect.Slice:
slice := reflect.MakeSlice(value.Type(), len(files), len(files))
- isSetted, err = setArrayOfMultipartFormFiles(slice, field, files)
- if err != nil || !isSetted {
- return isSetted, err
+ isSet, err = setArrayOfMultipartFormFiles(slice, field, files)
+ if err != nil || !isSet {
+ return isSet, err
}
value.Set(slice)
return true, nil
case reflect.Array:
return setArrayOfMultipartFormFiles(value, field, files)
}
- return false, errors.New("unsupported field type for multipart.FileHeader")
+ return false, ErrMultiFileHeader
}
-func setArrayOfMultipartFormFiles(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) {
+func setArrayOfMultipartFormFiles(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSet bool, err error) {
if value.Len() != len(files) {
- return false, errors.New("unsupported len of array for []*multipart.FileHeader")
+ return false, ErrMultiFileHeaderLenInvalid
}
for i := range files {
- setted, err := setByMultipartFormFile(value.Index(i), field, files[i:i+1])
- if err != nil || !setted {
- return setted, err
+ set, err := setByMultipartFormFile(value.Index(i), field, files[i:i+1])
+ if err != nil || !set {
+ return set, err
}
}
return true, nil
diff --git a/vendor/github.com/gin-gonic/gin/binding/protobuf.go b/vendor/github.com/gin-gonic/gin/binding/protobuf.go
index f9ece928d..44f2fdb93 100644
--- a/vendor/github.com/gin-gonic/gin/binding/protobuf.go
+++ b/vendor/github.com/gin-gonic/gin/binding/protobuf.go
@@ -1,14 +1,15 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package binding
import (
+ "errors"
"io/ioutil"
"net/http"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
)
type protobufBinding struct{}
@@ -17,7 +18,7 @@ func (protobufBinding) Name() string {
return "protobuf"
}
-func (b protobufBinding) Bind(req *http.Request, obj interface{}) error {
+func (b protobufBinding) Bind(req *http.Request, obj any) error {
buf, err := ioutil.ReadAll(req.Body)
if err != nil {
return err
@@ -25,8 +26,12 @@ func (b protobufBinding) Bind(req *http.Request, obj interface{}) error {
return b.BindBody(buf, obj)
}
-func (protobufBinding) BindBody(body []byte, obj interface{}) error {
- if err := proto.Unmarshal(body, obj.(proto.Message)); err != nil {
+func (protobufBinding) BindBody(body []byte, obj any) error {
+ msg, ok := obj.(proto.Message)
+ if !ok {
+ return errors.New("obj is not ProtoMessage")
+ }
+ if err := proto.Unmarshal(body, msg); err != nil {
return err
}
// Here it's same to return validate(obj), but util now we can't add
diff --git a/vendor/github.com/gin-gonic/gin/binding/query.go b/vendor/github.com/gin-gonic/gin/binding/query.go
index 219743f2a..c958b88bd 100644
--- a/vendor/github.com/gin-gonic/gin/binding/query.go
+++ b/vendor/github.com/gin-gonic/gin/binding/query.go
@@ -1,4 +1,4 @@
-// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -12,7 +12,7 @@ func (queryBinding) Name() string {
return "query"
}
-func (queryBinding) Bind(req *http.Request, obj interface{}) error {
+func (queryBinding) Bind(req *http.Request, obj any) error {
values := req.URL.Query()
if err := mapForm(obj, values); err != nil {
return err
diff --git a/vendor/github.com/gin-gonic/gin/binding/toml.go b/vendor/github.com/gin-gonic/gin/binding/toml.go
new file mode 100644
index 000000000..a6b8a90ab
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/toml.go
@@ -0,0 +1,35 @@
+// Copyright 2022 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package binding
+
+import (
+ "bytes"
+ "io"
+ "net/http"
+
+ "github.com/pelletier/go-toml/v2"
+)
+
+type tomlBinding struct{}
+
+func (tomlBinding) Name() string {
+ return "toml"
+}
+
+func decodeToml(r io.Reader, obj any) error {
+ decoder := toml.NewDecoder(r)
+ if err := decoder.Decode(obj); err != nil {
+ return err
+ }
+ return decoder.Decode(obj)
+}
+
+func (tomlBinding) Bind(req *http.Request, obj any) error {
+ return decodeToml(req.Body, obj)
+}
+
+func (tomlBinding) BindBody(body []byte, obj any) error {
+ return decodeToml(bytes.NewReader(body), obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/uri.go b/vendor/github.com/gin-gonic/gin/binding/uri.go
index f91ec3819..29151064a 100644
--- a/vendor/github.com/gin-gonic/gin/binding/uri.go
+++ b/vendor/github.com/gin-gonic/gin/binding/uri.go
@@ -1,4 +1,4 @@
-// Copyright 2018 Gin Core Team. All rights reserved.
+// Copyright 2018 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -10,8 +10,8 @@ func (uriBinding) Name() string {
return "uri"
}
-func (uriBinding) BindUri(m map[string][]string, obj interface{}) error {
- if err := mapUri(obj, m); err != nil {
+func (uriBinding) BindUri(m map[string][]string, obj any) error {
+ if err := mapURI(obj, m); err != nil {
return err
}
return validate(obj)
diff --git a/vendor/github.com/gin-gonic/gin/binding/xml.go b/vendor/github.com/gin-gonic/gin/binding/xml.go
index 4e9011496..a70f4ad36 100644
--- a/vendor/github.com/gin-gonic/gin/binding/xml.go
+++ b/vendor/github.com/gin-gonic/gin/binding/xml.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -17,14 +17,14 @@ func (xmlBinding) Name() string {
return "xml"
}
-func (xmlBinding) Bind(req *http.Request, obj interface{}) error {
+func (xmlBinding) Bind(req *http.Request, obj any) error {
return decodeXML(req.Body, obj)
}
-func (xmlBinding) BindBody(body []byte, obj interface{}) error {
+func (xmlBinding) BindBody(body []byte, obj any) error {
return decodeXML(bytes.NewReader(body), obj)
}
-func decodeXML(r io.Reader, obj interface{}) error {
+func decodeXML(r io.Reader, obj any) error {
decoder := xml.NewDecoder(r)
if err := decoder.Decode(obj); err != nil {
return err
diff --git a/vendor/github.com/gin-gonic/gin/binding/yaml.go b/vendor/github.com/gin-gonic/gin/binding/yaml.go
index a2d36d6a5..b0d36a358 100644
--- a/vendor/github.com/gin-gonic/gin/binding/yaml.go
+++ b/vendor/github.com/gin-gonic/gin/binding/yaml.go
@@ -1,4 +1,4 @@
-// Copyright 2018 Gin Core Team. All rights reserved.
+// Copyright 2018 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -18,15 +18,15 @@ func (yamlBinding) Name() string {
return "yaml"
}
-func (yamlBinding) Bind(req *http.Request, obj interface{}) error {
+func (yamlBinding) Bind(req *http.Request, obj any) error {
return decodeYAML(req.Body, obj)
}
-func (yamlBinding) BindBody(body []byte, obj interface{}) error {
+func (yamlBinding) BindBody(body []byte, obj any) error {
return decodeYAML(bytes.NewReader(body), obj)
}
-func decodeYAML(r io.Reader, obj interface{}) error {
+func decodeYAML(r io.Reader, obj any) error {
decoder := yaml.NewDecoder(r)
if err := decoder.Decode(obj); err != nil {
return err
diff --git a/vendor/github.com/gin-gonic/gin/context.go b/vendor/github.com/gin-gonic/gin/context.go
index 220d1bc7b..b1ad95e62 100644
--- a/vendor/github.com/gin-gonic/gin/context.go
+++ b/vendor/github.com/gin-gonic/gin/context.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -6,7 +6,6 @@ package gin
import (
"errors"
- "fmt"
"io"
"io/ioutil"
"log"
@@ -35,12 +34,17 @@ const (
MIMEPOSTForm = binding.MIMEPOSTForm
MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
MIMEYAML = binding.MIMEYAML
+ MIMETOML = binding.MIMETOML
)
// BodyBytesKey indicates a default body bytes key.
const BodyBytesKey = "_gin-gonic/gin/bodybyteskey"
-const abortIndex int8 = math.MaxInt8 / 2
+// ContextKey is the key that a Context returns itself for.
+const ContextKey = "_gin-gonic/gin/contextkey"
+
+// abortIndex represents a typical value used in abort functions.
+const abortIndex int8 = math.MaxInt8 >> 1
// Context is the most important part of gin. It allows us to pass variables between middleware,
// manage the flow, validate the JSON of a request and render a JSON response for example.
@@ -58,11 +62,11 @@ type Context struct {
params *Params
skippedNodes *[]skippedNode
- // This mutex protect Keys map
+ // This mutex protects Keys map.
mu sync.RWMutex
// Keys is a key/value pair exclusively for the context of each request.
- Keys map[string]interface{}
+ Keys map[string]any
// Errors is a list of errors attached to all the handlers/middlewares who used this context.
Errors errorMsgs
@@ -70,10 +74,10 @@ type Context struct {
// Accepted defines a list of manually accepted formats for content negotiation.
Accepted []string
- // queryCache use url.ParseQuery cached the param query result from c.Request.URL.Query()
+ // queryCache caches the query result from c.Request.URL.Query().
queryCache url.Values
- // formCache use url.ParseQuery cached PostForm contains the parsed form data from POST, PATCH,
+ // formCache caches c.Request.PostForm, which contains the parsed form data from POST, PATCH,
// or PUT body parameters.
formCache url.Values
@@ -88,16 +92,17 @@ type Context struct {
func (c *Context) reset() {
c.Writer = &c.writermem
- c.Params = c.Params[0:0]
+ c.Params = c.Params[:0]
c.handlers = nil
c.index = -1
c.fullPath = ""
c.Keys = nil
- c.Errors = c.Errors[0:0]
+ c.Errors = c.Errors[:0]
c.Accepted = nil
c.queryCache = nil
c.formCache = nil
+ c.sameSite = 0
*c.params = (*c.params)[:0]
*c.skippedNodes = (*c.skippedNodes)[:0]
}
@@ -115,7 +120,7 @@ func (c *Context) Copy() *Context {
cp.Writer = &cp.writermem
cp.index = abortIndex
cp.handlers = nil
- cp.Keys = map[string]interface{}{}
+ cp.Keys = map[string]any{}
for k, v := range c.Keys {
cp.Keys[k] = v
}
@@ -194,7 +199,7 @@ func (c *Context) AbortWithStatus(code int) {
// AbortWithStatusJSON calls `Abort()` and then `JSON` internally.
// This method stops the chain, writes the status code and return a JSON body.
// It also sets the Content-Type as "application/json".
-func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) {
+func (c *Context) AbortWithStatusJSON(code int, jsonObj any) {
c.Abort()
c.JSON(code, jsonObj)
}
@@ -221,7 +226,8 @@ func (c *Context) Error(err error) *Error {
panic("err is nil")
}
- parsedError, ok := err.(*Error)
+ var parsedError *Error
+ ok := errors.As(err, &parsedError)
if !ok {
parsedError = &Error{
Err: err,
@@ -239,10 +245,10 @@ func (c *Context) Error(err error) *Error {
// Set is used to store a new key/value pair exclusively for this context.
// It also lazy initializes c.Keys if it was not used previously.
-func (c *Context) Set(key string, value interface{}) {
+func (c *Context) Set(key string, value any) {
c.mu.Lock()
if c.Keys == nil {
- c.Keys = make(map[string]interface{})
+ c.Keys = make(map[string]any)
}
c.Keys[key] = value
@@ -250,8 +256,8 @@ func (c *Context) Set(key string, value interface{}) {
}
// Get returns the value for the given key, ie: (value, true).
-// If the value does not exists it returns (nil, false)
-func (c *Context) Get(key string) (value interface{}, exists bool) {
+// If the value does not exist it returns (nil, false)
+func (c *Context) Get(key string) (value any, exists bool) {
c.mu.RLock()
value, exists = c.Keys[key]
c.mu.RUnlock()
@@ -259,7 +265,7 @@ func (c *Context) Get(key string) (value interface{}, exists bool) {
}
// MustGet returns the value for the given key if it exists, otherwise it panics.
-func (c *Context) MustGet(key string) interface{} {
+func (c *Context) MustGet(key string) any {
if value, exists := c.Get(key); exists {
return value
}
@@ -347,9 +353,9 @@ func (c *Context) GetStringSlice(key string) (ss []string) {
}
// GetStringMap returns the value associated with the key as a map of interfaces.
-func (c *Context) GetStringMap(key string) (sm map[string]interface{}) {
+func (c *Context) GetStringMap(key string) (sm map[string]any) {
if val, ok := c.Get(key); ok && val != nil {
- sm, _ = val.(map[string]interface{})
+ sm, _ = val.(map[string]any)
}
return
}
@@ -384,6 +390,15 @@ func (c *Context) Param(key string) string {
return c.Params.ByName(key)
}
+// AddParam adds param to context and
+// replaces path param key with given value for e2e testing purposes
+// Example Route: "/user/:id"
+// AddParam("id", 1)
+// Result: "/user/1"
+func (c *Context) AddParam(key, value string) {
+ c.Params = append(c.Params, Param{Key: key, Value: value})
+}
+
// Query returns the keyed url query value if it exists,
// otherwise it returns an empty string `("")`.
// It is shortcut for `c.Request.URL.Query().Get(key)`
@@ -392,9 +407,9 @@ func (c *Context) Param(key string) string {
// c.Query("name") == "Manu"
// c.Query("value") == ""
// c.Query("wtf") == ""
-func (c *Context) Query(key string) string {
- value, _ := c.GetQuery(key)
- return value
+func (c *Context) Query(key string) (value string) {
+ value, _ = c.GetQuery(key)
+ return
}
// DefaultQuery returns the keyed url query value if it exists,
@@ -428,9 +443,9 @@ func (c *Context) GetQuery(key string) (string, bool) {
// QueryArray returns a slice of strings for a given query key.
// The length of the slice depends on the number of params with the given key.
-func (c *Context) QueryArray(key string) []string {
- values, _ := c.GetQueryArray(key)
- return values
+func (c *Context) QueryArray(key string) (values []string) {
+ values, _ = c.GetQueryArray(key)
+ return
}
func (c *Context) initQueryCache() {
@@ -445,18 +460,16 @@ func (c *Context) initQueryCache() {
// GetQueryArray returns a slice of strings for a given query key, plus
// a boolean value whether at least one value exists for the given key.
-func (c *Context) GetQueryArray(key string) ([]string, bool) {
+func (c *Context) GetQueryArray(key string) (values []string, ok bool) {
c.initQueryCache()
- if values, ok := c.queryCache[key]; ok && len(values) > 0 {
- return values, true
- }
- return []string{}, false
+ values, ok = c.queryCache[key]
+ return
}
// QueryMap returns a map for a given query key.
-func (c *Context) QueryMap(key string) map[string]string {
- dicts, _ := c.GetQueryMap(key)
- return dicts
+func (c *Context) QueryMap(key string) (dicts map[string]string) {
+ dicts, _ = c.GetQueryMap(key)
+ return
}
// GetQueryMap returns a map for a given query key, plus a boolean value
@@ -468,9 +481,9 @@ func (c *Context) GetQueryMap(key string) (map[string]string, bool) {
// PostForm returns the specified key from a POST urlencoded form or multipart form
// when it exists, otherwise it returns an empty string `("")`.
-func (c *Context) PostForm(key string) string {
- value, _ := c.GetPostForm(key)
- return value
+func (c *Context) PostForm(key string) (value string) {
+ value, _ = c.GetPostForm(key)
+ return
}
// DefaultPostForm returns the specified key from a POST urlencoded form or multipart form
@@ -499,9 +512,9 @@ func (c *Context) GetPostForm(key string) (string, bool) {
// PostFormArray returns a slice of strings for a given form key.
// The length of the slice depends on the number of params with the given key.
-func (c *Context) PostFormArray(key string) []string {
- values, _ := c.GetPostFormArray(key)
- return values
+func (c *Context) PostFormArray(key string) (values []string) {
+ values, _ = c.GetPostFormArray(key)
+ return
}
func (c *Context) initFormCache() {
@@ -509,7 +522,7 @@ func (c *Context) initFormCache() {
c.formCache = make(url.Values)
req := c.Request
if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
- if err != http.ErrNotMultipart {
+ if !errors.Is(err, http.ErrNotMultipart) {
debugPrint("error on parse multipart form array: %v", err)
}
}
@@ -519,18 +532,16 @@ func (c *Context) initFormCache() {
// GetPostFormArray returns a slice of strings for a given form key, plus
// a boolean value whether at least one value exists for the given key.
-func (c *Context) GetPostFormArray(key string) ([]string, bool) {
+func (c *Context) GetPostFormArray(key string) (values []string, ok bool) {
c.initFormCache()
- if values := c.formCache[key]; len(values) > 0 {
- return values, true
- }
- return []string{}, false
+ values, ok = c.formCache[key]
+ return
}
// PostFormMap returns a map for a given form key.
-func (c *Context) PostFormMap(key string) map[string]string {
- dicts, _ := c.GetPostFormMap(key)
- return dicts
+func (c *Context) PostFormMap(key string) (dicts map[string]string) {
+ dicts, _ = c.GetPostFormMap(key)
+ return
}
// GetPostFormMap returns a map for a given form key, plus a boolean value
@@ -594,47 +605,51 @@ func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error
return err
}
-// Bind checks the Content-Type to select a binding engine automatically,
-// Depending the "Content-Type" header different bindings are used:
+// Bind checks the Method and Content-Type to select a binding engine automatically,
+// Depending on the "Content-Type" header different bindings are used, for example:
// "application/json" --> JSON binding
// "application/xml" --> XML binding
-// otherwise --> returns an error.
// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
// It decodes the json payload into the struct specified as a pointer.
// It writes a 400 error and sets Content-Type header "text/plain" in the response if input is not valid.
-func (c *Context) Bind(obj interface{}) error {
+func (c *Context) Bind(obj any) error {
b := binding.Default(c.Request.Method, c.ContentType())
return c.MustBindWith(obj, b)
}
// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON).
-func (c *Context) BindJSON(obj interface{}) error {
+func (c *Context) BindJSON(obj any) error {
return c.MustBindWith(obj, binding.JSON)
}
// BindXML is a shortcut for c.MustBindWith(obj, binding.BindXML).
-func (c *Context) BindXML(obj interface{}) error {
+func (c *Context) BindXML(obj any) error {
return c.MustBindWith(obj, binding.XML)
}
// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query).
-func (c *Context) BindQuery(obj interface{}) error {
+func (c *Context) BindQuery(obj any) error {
return c.MustBindWith(obj, binding.Query)
}
// BindYAML is a shortcut for c.MustBindWith(obj, binding.YAML).
-func (c *Context) BindYAML(obj interface{}) error {
+func (c *Context) BindYAML(obj any) error {
return c.MustBindWith(obj, binding.YAML)
}
+// BindTOML is a shortcut for c.MustBindWith(obj, binding.TOML).
+func (c *Context) BindTOML(obj interface{}) error {
+ return c.MustBindWith(obj, binding.TOML)
+}
+
// BindHeader is a shortcut for c.MustBindWith(obj, binding.Header).
-func (c *Context) BindHeader(obj interface{}) error {
+func (c *Context) BindHeader(obj any) error {
return c.MustBindWith(obj, binding.Header)
}
// BindUri binds the passed struct pointer using binding.Uri.
// It will abort the request with HTTP 400 if any error occurs.
-func (c *Context) BindUri(obj interface{}) error {
+func (c *Context) BindUri(obj any) error {
if err := c.ShouldBindUri(obj); err != nil {
c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
return err
@@ -645,7 +660,7 @@ func (c *Context) BindUri(obj interface{}) error {
// MustBindWith binds the passed struct pointer using the specified binding engine.
// It will abort the request with HTTP 400 if any error occurs.
// See the binding package.
-func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
+func (c *Context) MustBindWith(obj any, b binding.Binding) error {
if err := c.ShouldBindWith(obj, b); err != nil {
c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
return err
@@ -653,46 +668,50 @@ func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
return nil
}
-// ShouldBind checks the Content-Type to select a binding engine automatically,
-// Depending the "Content-Type" header different bindings are used:
+// ShouldBind checks the Method and Content-Type to select a binding engine automatically,
+// Depending on the "Content-Type" header different bindings are used, for example:
// "application/json" --> JSON binding
// "application/xml" --> XML binding
-// otherwise --> returns an error
// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
// It decodes the json payload into the struct specified as a pointer.
-// Like c.Bind() but this method does not set the response status code to 400 and abort if the json is not valid.
-func (c *Context) ShouldBind(obj interface{}) error {
+// Like c.Bind() but this method does not set the response status code to 400 or abort if input is not valid.
+func (c *Context) ShouldBind(obj any) error {
b := binding.Default(c.Request.Method, c.ContentType())
return c.ShouldBindWith(obj, b)
}
// ShouldBindJSON is a shortcut for c.ShouldBindWith(obj, binding.JSON).
-func (c *Context) ShouldBindJSON(obj interface{}) error {
+func (c *Context) ShouldBindJSON(obj any) error {
return c.ShouldBindWith(obj, binding.JSON)
}
// ShouldBindXML is a shortcut for c.ShouldBindWith(obj, binding.XML).
-func (c *Context) ShouldBindXML(obj interface{}) error {
+func (c *Context) ShouldBindXML(obj any) error {
return c.ShouldBindWith(obj, binding.XML)
}
// ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query).
-func (c *Context) ShouldBindQuery(obj interface{}) error {
+func (c *Context) ShouldBindQuery(obj any) error {
return c.ShouldBindWith(obj, binding.Query)
}
// ShouldBindYAML is a shortcut for c.ShouldBindWith(obj, binding.YAML).
-func (c *Context) ShouldBindYAML(obj interface{}) error {
+func (c *Context) ShouldBindYAML(obj any) error {
return c.ShouldBindWith(obj, binding.YAML)
}
+// ShouldBindTOML is a shortcut for c.ShouldBindWith(obj, binding.TOML).
+func (c *Context) ShouldBindTOML(obj interface{}) error {
+ return c.ShouldBindWith(obj, binding.TOML)
+}
+
// ShouldBindHeader is a shortcut for c.ShouldBindWith(obj, binding.Header).
-func (c *Context) ShouldBindHeader(obj interface{}) error {
+func (c *Context) ShouldBindHeader(obj any) error {
return c.ShouldBindWith(obj, binding.Header)
}
// ShouldBindUri binds the passed struct pointer using the specified binding engine.
-func (c *Context) ShouldBindUri(obj interface{}) error {
+func (c *Context) ShouldBindUri(obj any) error {
m := make(map[string][]string)
for _, v := range c.Params {
m[v.Key] = []string{v.Value}
@@ -702,7 +721,7 @@ func (c *Context) ShouldBindUri(obj interface{}) error {
// ShouldBindWith binds the passed struct pointer using the specified binding engine.
// See the binding package.
-func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
+func (c *Context) ShouldBindWith(obj any, b binding.Binding) error {
return b.Bind(c.Request, obj)
}
@@ -711,7 +730,7 @@ func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
//
// NOTE: This method reads the body before binding. So you should use
// ShouldBindWith for better performance if you need to call only once.
-func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (err error) {
+func (c *Context) ShouldBindBodyWith(obj any, bb binding.BindingBody) (err error) {
var body []byte
if cb, ok := c.Get(BodyBytesKey); ok {
if cbb, ok := cb.([]byte); ok {
@@ -732,7 +751,7 @@ func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (e
// It called c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not.
// If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]).
// If the headers are not syntactically valid OR the remote IP does not correspond to a trusted proxy,
-// the remote IP (coming form Request.RemoteAddr) is returned.
+// the remote IP (coming from Request.RemoteAddr) is returned.
func (c *Context) ClientIP() string {
// Check if we're running on a trusted platform, continue running backwards if error
if c.engine.TrustedPlatform != "" {
@@ -750,10 +769,14 @@ func (c *Context) ClientIP() string {
}
}
- remoteIP, trusted := c.RemoteIP()
+ // It also checks if the remoteIP is a trusted proxy or not.
+ // In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks
+ // defined by Engine.SetTrustedProxies()
+ remoteIP := net.ParseIP(c.RemoteIP())
if remoteIP == nil {
return ""
}
+ trusted := c.engine.isTrustedProxy(remoteIP)
if trusted && c.engine.ForwardedByClientIP && c.engine.RemoteIPHeaders != nil {
for _, headerName := range c.engine.RemoteIPHeaders {
@@ -766,53 +789,13 @@ func (c *Context) ClientIP() string {
return remoteIP.String()
}
-func (e *Engine) isTrustedProxy(ip net.IP) bool {
- if e.trustedCIDRs != nil {
- for _, cidr := range e.trustedCIDRs {
- if cidr.Contains(ip) {
- return true
- }
- }
- }
- return false
-}
-
// RemoteIP parses the IP from Request.RemoteAddr, normalizes and returns the IP (without the port).
-// It also checks if the remoteIP is a trusted proxy or not.
-// In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks
-// defined by Engine.SetTrustedProxies()
-func (c *Context) RemoteIP() (net.IP, bool) {
+func (c *Context) RemoteIP() string {
ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr))
if err != nil {
- return nil, false
- }
- remoteIP := net.ParseIP(ip)
- if remoteIP == nil {
- return nil, false
- }
-
- return remoteIP, c.engine.isTrustedProxy(remoteIP)
-}
-
-func (e *Engine) validateHeader(header string) (clientIP string, valid bool) {
- if header == "" {
- return "", false
- }
- items := strings.Split(header, ",")
- for i := len(items) - 1; i >= 0; i-- {
- ipStr := strings.TrimSpace(items[i])
- ip := net.ParseIP(ipStr)
- if ip == nil {
- return "", false
- }
-
- // X-Forwarded-For is appended by proxy
- // Check IPs in reverse order and stop when find untrusted proxy
- if (i == 0) || (!e.isTrustedProxy(ip)) {
- return ipStr, true
- }
+ return ""
}
- return
+ return ip
}
// ContentType returns the Content-Type header of the request.
@@ -856,7 +839,7 @@ func (c *Context) Status(code int) {
c.Writer.WriteHeader(code)
}
-// Header is a intelligent shortcut for c.Writer.Header().Set(key, value).
+// Header is an intelligent shortcut for c.Writer.Header().Set(key, value).
// It writes a header in the response.
// If value == "", this method removes the header `c.Writer.Header().Del(key)`
func (c *Context) Header(key, value string) {
@@ -872,7 +855,7 @@ func (c *Context) GetHeader(key string) string {
return c.requestHeader(key)
}
-// GetRawData return stream data.
+// GetRawData returns stream data.
func (c *Context) GetRawData() ([]byte, error) {
return ioutil.ReadAll(c.Request.Body)
}
@@ -932,30 +915,30 @@ func (c *Context) Render(code int, r render.Render) {
// HTML renders the HTTP template specified by its file name.
// It also updates the HTTP code and sets the Content-Type as "text/html".
// See http://golang.org/doc/articles/wiki/
-func (c *Context) HTML(code int, name string, obj interface{}) {
+func (c *Context) HTML(code int, name string, obj any) {
instance := c.engine.HTMLRender.Instance(name, obj)
c.Render(code, instance)
}
// IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body.
// It also sets the Content-Type as "application/json".
-// WARNING: we recommend to use this only for development purposes since printing pretty JSON is
+// WARNING: we recommend using this only for development purposes since printing pretty JSON is
// more CPU and bandwidth consuming. Use Context.JSON() instead.
-func (c *Context) IndentedJSON(code int, obj interface{}) {
+func (c *Context) IndentedJSON(code int, obj any) {
c.Render(code, render.IndentedJSON{Data: obj})
}
// SecureJSON serializes the given struct as Secure JSON into the response body.
// Default prepends "while(1)," to response body if the given struct is array values.
// It also sets the Content-Type as "application/json".
-func (c *Context) SecureJSON(code int, obj interface{}) {
+func (c *Context) SecureJSON(code int, obj any) {
c.Render(code, render.SecureJSON{Prefix: c.engine.secureJSONPrefix, Data: obj})
}
// JSONP serializes the given struct as JSON into the response body.
// It adds padding to response body to request data from a server residing in a different domain than the client.
// It also sets the Content-Type as "application/javascript".
-func (c *Context) JSONP(code int, obj interface{}) {
+func (c *Context) JSONP(code int, obj any) {
callback := c.DefaultQuery("callback", "")
if callback == "" {
c.Render(code, render.JSON{Data: obj})
@@ -966,44 +949,49 @@ func (c *Context) JSONP(code int, obj interface{}) {
// JSON serializes the given struct as JSON into the response body.
// It also sets the Content-Type as "application/json".
-func (c *Context) JSON(code int, obj interface{}) {
+func (c *Context) JSON(code int, obj any) {
c.Render(code, render.JSON{Data: obj})
}
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
// It also sets the Content-Type as "application/json".
-func (c *Context) AsciiJSON(code int, obj interface{}) {
+func (c *Context) AsciiJSON(code int, obj any) {
c.Render(code, render.AsciiJSON{Data: obj})
}
// PureJSON serializes the given struct as JSON into the response body.
// PureJSON, unlike JSON, does not replace special html characters with their unicode entities.
-func (c *Context) PureJSON(code int, obj interface{}) {
+func (c *Context) PureJSON(code int, obj any) {
c.Render(code, render.PureJSON{Data: obj})
}
// XML serializes the given struct as XML into the response body.
// It also sets the Content-Type as "application/xml".
-func (c *Context) XML(code int, obj interface{}) {
+func (c *Context) XML(code int, obj any) {
c.Render(code, render.XML{Data: obj})
}
// YAML serializes the given struct as YAML into the response body.
-func (c *Context) YAML(code int, obj interface{}) {
+func (c *Context) YAML(code int, obj any) {
c.Render(code, render.YAML{Data: obj})
}
+// TOML serializes the given struct as TOML into the response body.
+func (c *Context) TOML(code int, obj interface{}) {
+ c.Render(code, render.TOML{Data: obj})
+}
+
// ProtoBuf serializes the given struct as ProtoBuf into the response body.
-func (c *Context) ProtoBuf(code int, obj interface{}) {
+func (c *Context) ProtoBuf(code int, obj any) {
c.Render(code, render.ProtoBuf{Data: obj})
}
// String writes the given string into the response body.
-func (c *Context) String(code int, format string, values ...interface{}) {
+func (c *Context) String(code int, format string, values ...any) {
c.Render(code, render.String{Format: format, Data: values})
}
-// Redirect returns a HTTP redirect to the specific location.
+// Redirect returns an HTTP redirect to the specific location.
func (c *Context) Redirect(code int, location string) {
c.Render(-1, render.Redirect{
Code: code,
@@ -1049,12 +1037,16 @@ func (c *Context) FileFromFS(filepath string, fs http.FileSystem) {
// FileAttachment writes the specified file into the body stream in an efficient way
// On the client side, the file will typically be downloaded with the given filename
func (c *Context) FileAttachment(filepath, filename string) {
- c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
+ if isASCII(filename) {
+ c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`)
+ } else {
+ c.Writer.Header().Set("Content-Disposition", `attachment; filename*=UTF-8''`+url.QueryEscape(filename))
+ }
http.ServeFile(c.Writer, c.Request, filepath)
}
// SSEvent writes a Server-Sent Event into the body stream.
-func (c *Context) SSEvent(name string, message interface{}) {
+func (c *Context) SSEvent(name string, message any) {
c.Render(-1, sse.Event{
Event: name,
Data: message,
@@ -1088,14 +1080,15 @@ func (c *Context) Stream(step func(w io.Writer) bool) bool {
type Negotiate struct {
Offered []string
HTMLName string
- HTMLData interface{}
- JSONData interface{}
- XMLData interface{}
- YAMLData interface{}
- Data interface{}
+ HTMLData any
+ JSONData any
+ XMLData any
+ YAMLData any
+ Data any
+ TOMLData any
}
-// Negotiate calls different Render according acceptable Accept format.
+// Negotiate calls different Render according to acceptable Accept format.
func (c *Context) Negotiate(code int, config Negotiate) {
switch c.NegotiateFormat(config.Offered...) {
case binding.MIMEJSON:
@@ -1114,6 +1107,10 @@ func (c *Context) Negotiate(code int, config Negotiate) {
data := chooseData(config.YAMLData, config.Data)
c.YAML(code, data)
+ case binding.MIMETOML:
+ data := chooseData(config.TOMLData, config.Data)
+ c.TOML(code, data)
+
default:
c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) // nolint: errcheck
}
@@ -1159,34 +1156,47 @@ func (c *Context) SetAccepted(formats ...string) {
/***** GOLANG.ORG/X/NET/CONTEXT *****/
/************************************/
-// Deadline always returns that there is no deadline (ok==false),
-// maybe you want to use Request.Context().Deadline() instead.
+// Deadline returns that there is no deadline (ok==false) when c.Request has no Context.
func (c *Context) Deadline() (deadline time.Time, ok bool) {
- return
+ if !c.engine.ContextWithFallback || c.Request == nil || c.Request.Context() == nil {
+ return
+ }
+ return c.Request.Context().Deadline()
}
-// Done always returns nil (chan which will wait forever),
-// if you want to abort your work when the connection was closed
-// you should use Request.Context().Done() instead.
+// Done returns nil (chan which will wait forever) when c.Request has no Context.
func (c *Context) Done() <-chan struct{} {
- return nil
+ if !c.engine.ContextWithFallback || c.Request == nil || c.Request.Context() == nil {
+ return nil
+ }
+ return c.Request.Context().Done()
}
-// Err always returns nil, maybe you want to use Request.Context().Err() instead.
+// Err returns nil when c.Request has no Context.
func (c *Context) Err() error {
- return nil
+ if !c.engine.ContextWithFallback || c.Request == nil || c.Request.Context() == nil {
+ return nil
+ }
+ return c.Request.Context().Err()
}
// Value returns the value associated with this context for key, or nil
// if no value is associated with key. Successive calls to Value with
// the same key returns the same result.
-func (c *Context) Value(key interface{}) interface{} {
+func (c *Context) Value(key any) any {
if key == 0 {
return c.Request
}
+ if key == ContextKey {
+ return c
+ }
if keyAsString, ok := key.(string); ok {
- val, _ := c.Get(keyAsString)
- return val
+ if val, exists := c.Get(keyAsString); exists {
+ return val
+ }
}
- return nil
+ if !c.engine.ContextWithFallback || c.Request == nil || c.Request.Context() == nil {
+ return nil
+ }
+ return c.Request.Context().Value(key)
}
diff --git a/vendor/github.com/gin-gonic/gin/context_appengine.go b/vendor/github.com/gin-gonic/gin/context_appengine.go
index 8bf938961..931313f61 100644
--- a/vendor/github.com/gin-gonic/gin/context_appengine.go
+++ b/vendor/github.com/gin-gonic/gin/context_appengine.go
@@ -1,4 +1,4 @@
-// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/vendor/github.com/gin-gonic/gin/debug.go b/vendor/github.com/gin-gonic/gin/debug.go
index 9bacc6857..25fd7c87f 100644
--- a/vendor/github.com/gin-gonic/gin/debug.go
+++ b/vendor/github.com/gin-gonic/gin/debug.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -12,7 +12,7 @@ import (
"strings"
)
-const ginSupportMinGoVer = 13
+const ginSupportMinGoVer = 14
// IsDebugging returns true if the framework is running in debug mode.
// Use SetMode(gin.ReleaseMode) to disable debug mode.
@@ -47,7 +47,7 @@ func debugPrintLoadTemplate(tmpl *template.Template) {
}
}
-func debugPrint(format string, values ...interface{}) {
+func debugPrint(format string, values ...any) {
if IsDebugging() {
if !strings.HasSuffix(format, "\n") {
format += "\n"
@@ -67,7 +67,7 @@ func getMinVer(v string) (uint64, error) {
func debugPrintWARNINGDefault() {
if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
- debugPrint(`[WARNING] Now Gin requires Go 1.13+.
+ debugPrint(`[WARNING] Now Gin requires Go 1.14+.
`)
}
@@ -95,9 +95,7 @@ at initialization. ie. before any route is registered or the router is listening
}
func debugPrintError(err error) {
- if err != nil {
- if IsDebugging() {
- fmt.Fprintf(DefaultErrorWriter, "[GIN-debug] [ERROR] %v\n", err)
- }
+ if err != nil && IsDebugging() {
+ fmt.Fprintf(DefaultErrorWriter, "[GIN-debug] [ERROR] %v\n", err)
}
}
diff --git a/vendor/github.com/gin-gonic/gin/deprecated.go b/vendor/github.com/gin-gonic/gin/deprecated.go
index ab4474296..fdad85547 100644
--- a/vendor/github.com/gin-gonic/gin/deprecated.go
+++ b/vendor/github.com/gin-gonic/gin/deprecated.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -12,7 +12,7 @@ import (
// BindWith binds the passed struct pointer using the specified binding engine.
// See the binding package.
-func (c *Context) BindWith(obj interface{}, b binding.Binding) error {
+func (c *Context) BindWith(obj any, b binding.Binding) error {
log.Println(`BindWith(\"interface{}, binding.Binding\") error is going to
be deprecated, please check issue #662 and either use MustBindWith() if you
want HTTP 400 to be automatically returned if any error occur, or use
diff --git a/vendor/github.com/gin-gonic/gin/errors.go b/vendor/github.com/gin-gonic/gin/errors.go
index 0f276c13d..2853ce8ed 100644
--- a/vendor/github.com/gin-gonic/gin/errors.go
+++ b/vendor/github.com/gin-gonic/gin/errors.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -34,7 +34,7 @@ const (
type Error struct {
Err error
Type ErrorType
- Meta interface{}
+ Meta any
}
type errorMsgs []*Error
@@ -48,13 +48,13 @@ func (msg *Error) SetType(flags ErrorType) *Error {
}
// SetMeta sets the error's meta data.
-func (msg *Error) SetMeta(data interface{}) *Error {
+func (msg *Error) SetMeta(data any) *Error {
msg.Meta = data
return msg
}
// JSON creates a properly formatted JSON
-func (msg *Error) JSON() interface{} {
+func (msg *Error) JSON() any {
jsonData := H{}
if msg.Meta != nil {
value := reflect.ValueOf(msg.Meta)
@@ -122,7 +122,7 @@ func (a errorMsgs) Last() *Error {
return nil
}
-// Errors returns an array will all the error messages.
+// Errors returns an array with all the error messages.
// Example:
// c.Error(errors.New("first"))
// c.Error(errors.New("second"))
@@ -139,14 +139,14 @@ func (a errorMsgs) Errors() []string {
return errorStrings
}
-func (a errorMsgs) JSON() interface{} {
+func (a errorMsgs) JSON() any {
switch length := len(a); length {
case 0:
return nil
case 1:
return a.Last().JSON()
default:
- jsonData := make([]interface{}, length)
+ jsonData := make([]any, length)
for i, err := range a {
jsonData[i] = err.JSON()
}
diff --git a/vendor/github.com/gin-gonic/gin/fs.go b/vendor/github.com/gin-gonic/gin/fs.go
index 007d9b755..64274735e 100644
--- a/vendor/github.com/gin-gonic/gin/fs.go
+++ b/vendor/github.com/gin-gonic/gin/fs.go
@@ -1,4 +1,4 @@
-// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -17,7 +17,7 @@ type neuteredReaddirFile struct {
http.File
}
-// Dir returns a http.Filesystem that can be used by http.FileServer(). It is used internally
+// Dir returns a http.FileSystem that can be used by http.FileServer(). It is used internally
// in router.Static().
// if listDirectory == true, then it works the same as http.Dir() otherwise it returns
// a filesystem that prevents http.FileServer() to list the directory files.
diff --git a/vendor/github.com/gin-gonic/gin/gin.go b/vendor/github.com/gin-gonic/gin/gin.go
index 58e76f41f..f9324299b 100644
--- a/vendor/github.com/gin-gonic/gin/gin.go
+++ b/vendor/github.com/gin-gonic/gin/gin.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -11,12 +11,13 @@ import (
"net/http"
"os"
"path"
- "reflect"
"strings"
"sync"
"github.com/gin-gonic/gin/internal/bytesconv"
"github.com/gin-gonic/gin/render"
+ "golang.org/x/net/http2"
+ "golang.org/x/net/http2/h2c"
)
const defaultMultipartMemory = 32 << 20 // 32 MB
@@ -28,15 +29,24 @@ var (
var defaultPlatform string
-var defaultTrustedCIDRs = []*net.IPNet{{IP: net.IP{0x0, 0x0, 0x0, 0x0}, Mask: net.IPMask{0x0, 0x0, 0x0, 0x0}}} // 0.0.0.0/0
+var defaultTrustedCIDRs = []*net.IPNet{
+ { // 0.0.0.0/0 (IPv4)
+ IP: net.IP{0x0, 0x0, 0x0, 0x0},
+ Mask: net.IPMask{0x0, 0x0, 0x0, 0x0},
+ },
+ { // ::/0 (IPv6)
+ IP: net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+ Mask: net.IPMask{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+ },
+}
// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)
-// HandlersChain defines a HandlerFunc array.
+// HandlersChain defines a HandlerFunc slice.
type HandlersChain []HandlerFunc
-// Last returns the last handler in the chain. ie. the last handler is the main one.
+// Last returns the last handler in the chain. i.e. the last handler is the main one.
func (c HandlersChain) Last() HandlerFunc {
if length := len(c); length > 0 {
return c[length-1]
@@ -52,15 +62,15 @@ type RouteInfo struct {
HandlerFunc HandlerFunc
}
-// RoutesInfo defines a RouteInfo array.
+// RoutesInfo defines a RouteInfo slice.
type RoutesInfo []RouteInfo
// Trusted platforms
const (
- // When running on Google App Engine. Trust X-Appengine-Remote-Addr
+ // PlatformGoogleAppEngine when running on Google App Engine. Trust X-Appengine-Remote-Addr
// for determining the client's IP
PlatformGoogleAppEngine = "X-Appengine-Remote-Addr"
- // When using Cloudflare's CDN. Trust CF-Connecting-IP for determining
+ // PlatformCloudflare when using Cloudflare's CDN. Trust CF-Connecting-IP for determining
// the client's IP
PlatformCloudflare = "CF-Connecting-IP"
)
@@ -70,14 +80,14 @@ const (
type Engine struct {
RouterGroup
- // Enables automatic redirection if the current route can't be matched but a
+ // RedirectTrailingSlash enables automatic redirection if the current route can't be matched but a
// handler for the path with (without) the trailing slash exists.
// For example if /foo/ is requested but a route only exists for /foo, the
// client is redirected to /foo with http status code 301 for GET requests
// and 307 for all other request methods.
RedirectTrailingSlash bool
- // If enabled, the router tries to fix the current request path, if no
+ // RedirectFixedPath if enabled, the router tries to fix the current request path, if no
// handle is registered for it.
// First superfluous path elements like ../ or // are removed.
// Afterwards the router does a case-insensitive lookup of the cleaned path.
@@ -88,7 +98,7 @@ type Engine struct {
// RedirectTrailingSlash is independent of this option.
RedirectFixedPath bool
- // If enabled, the router checks if another method is allowed for the
+ // HandleMethodNotAllowed if enabled, the router checks if another method is allowed for the
// current route, if the current request can not be routed.
// If this is the case, the request is answered with 'Method Not Allowed'
// and HTTP status code 405.
@@ -96,21 +106,22 @@ type Engine struct {
// handler.
HandleMethodNotAllowed bool
- // If enabled, client IP will be parsed from the request's headers that
+ // ForwardedByClientIP if enabled, client IP will be parsed from the request's headers that
// match those stored at `(*gin.Engine).RemoteIPHeaders`. If no IP was
// fetched, it falls back to the IP obtained from
// `(*gin.Context).Request.RemoteAddr`.
ForwardedByClientIP bool
- // DEPRECATED: USE `TrustedPlatform` WITH VALUE `gin.GoogleAppEngine` INSTEAD
+ // AppEngine was deprecated.
+ // Deprecated: USE `TrustedPlatform` WITH VALUE `gin.PlatformGoogleAppEngine` INSTEAD
// #726 #755 If enabled, it will trust some headers starting with
// 'X-AppEngine...' for better integration with that PaaS.
AppEngine bool
- // If enabled, the url.RawPath will be used to find parameters.
+ // UseRawPath if enabled, the url.RawPath will be used to find parameters.
UseRawPath bool
- // If true, the path value will be unescaped.
+ // UnescapePathValues if true, the path value will be unescaped.
// If UseRawPath is false (by default), the UnescapePathValues effectively is true,
// as url.Path gonna be used, which is already unescaped.
UnescapePathValues bool
@@ -119,20 +130,26 @@ type Engine struct {
// See the PR #1817 and issue #1644
RemoveExtraSlash bool
- // List of headers used to obtain the client IP when
+ // RemoteIPHeaders list of headers used to obtain the client IP when
// `(*gin.Engine).ForwardedByClientIP` is `true` and
// `(*gin.Context).Request.RemoteAddr` is matched by at least one of the
// network origins of list defined by `(*gin.Engine).SetTrustedProxies()`.
RemoteIPHeaders []string
- // If set to a constant of value gin.Platform*, trusts the headers set by
+ // TrustedPlatform if set to a constant of value gin.Platform*, trusts the headers set by
// that platform, for example to determine the client IP
TrustedPlatform string
- // Value of 'maxMemory' param that is given to http.Request's ParseMultipartForm
+ // MaxMultipartMemory value of 'maxMemory' param that is given to http.Request's ParseMultipartForm
// method call.
MaxMultipartMemory int64
+ // UseH2C enable h2c support.
+ UseH2C bool
+
+ // ContextWithFallback enable fallback Context.Deadline(), Context.Done(), Context.Err() and Context.Value() when Context.Request.Context() is not nil.
+ ContextWithFallback bool
+
delims render.Delims
secureJSONPrefix string
HTMLRender render.HTMLRender
@@ -152,7 +169,7 @@ type Engine struct {
var _ IRouter = &Engine{}
// New returns a new blank Engine instance without any middleware attached.
-// By default the configuration is:
+// By default, the configuration is:
// - RedirectTrailingSlash: true
// - RedirectFixedPath: false
// - HandleMethodNotAllowed: false
@@ -181,11 +198,11 @@ func New() *Engine {
trees: make(methodTrees, 0, 9),
delims: render.Delims{Left: "{{", Right: "}}"},
secureJSONPrefix: "while(1);",
- trustedProxies: []string{"0.0.0.0/0"},
+ trustedProxies: []string{"0.0.0.0/0", "::/0"},
trustedCIDRs: defaultTrustedCIDRs,
}
engine.RouterGroup.engine = engine
- engine.pool.New = func() interface{} {
+ engine.pool.New = func() any {
return engine.allocateContext()
}
return engine
@@ -199,13 +216,22 @@ func Default() *Engine {
return engine
}
+func (engine *Engine) Handler() http.Handler {
+ if !engine.UseH2C {
+ return engine
+ }
+
+ h2s := &http2.Server{}
+ return h2c.NewHandler(engine, h2s)
+}
+
func (engine *Engine) allocateContext() *Context {
v := make(Params, 0, engine.maxParams)
skippedNodes := make([]skippedNode, 0, engine.maxSections)
return &Context{engine: engine, params: &v, skippedNodes: &skippedNodes}
}
-// Delims sets template left and right delims and returns a Engine instance.
+// Delims sets template left and right delims and returns an Engine instance.
func (engine *Engine) Delims(left, right string) *Engine {
engine.delims = render.Delims{Left: left, Right: right}
return engine
@@ -259,7 +285,7 @@ func (engine *Engine) SetFuncMap(funcMap template.FuncMap) {
engine.FuncMap = funcMap
}
-// NoRoute adds handlers for NoRoute. It return a 404 code by default.
+// NoRoute adds handlers for NoRoute. It returns a 404 code by default.
func (engine *Engine) NoRoute(handlers ...HandlerFunc) {
engine.noRoute = handlers
engine.rebuild404Handlers()
@@ -271,7 +297,7 @@ func (engine *Engine) NoMethod(handlers ...HandlerFunc) {
engine.rebuild405Handlers()
}
-// Use attaches a global middleware to the router. ie. the middleware attached though Use() will be
+// Use attaches a global middleware to the router. i.e. the middleware attached through Use() will be
// included in the handlers chain for every single request. Even 404, 405, static files...
// For example, this is the right place for a logger or error management middleware.
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
@@ -353,7 +379,7 @@ func (engine *Engine) Run(addr ...string) (err error) {
address := resolveAddress(addr)
debugPrint("Listening and serving HTTP on %s\n", address)
- err = http.ListenAndServe(address, engine)
+ err = http.ListenAndServe(address, engine.Handler())
return
}
@@ -399,9 +425,9 @@ func (engine *Engine) SetTrustedProxies(trustedProxies []string) error {
return engine.parseTrustedProxies()
}
-// isUnsafeTrustedProxies compares Engine.trustedCIDRs and defaultTrustedCIDRs, it's not safe if equal (returns true)
+// isUnsafeTrustedProxies checks if Engine.trustedCIDRs contains all IPs, it's not safe if it has (returns true)
func (engine *Engine) isUnsafeTrustedProxies() bool {
- return reflect.DeepEqual(engine.trustedCIDRs, defaultTrustedCIDRs)
+ return engine.isTrustedProxy(net.ParseIP("0.0.0.0")) || engine.isTrustedProxy(net.ParseIP("::"))
}
// parseTrustedProxies parse Engine.trustedProxies to Engine.trustedCIDRs
@@ -411,6 +437,41 @@ func (engine *Engine) parseTrustedProxies() error {
return err
}
+// isTrustedProxy will check whether the IP address is included in the trusted list according to Engine.trustedCIDRs
+func (engine *Engine) isTrustedProxy(ip net.IP) bool {
+ if engine.trustedCIDRs == nil {
+ return false
+ }
+ for _, cidr := range engine.trustedCIDRs {
+ if cidr.Contains(ip) {
+ return true
+ }
+ }
+ return false
+}
+
+// validateHeader will parse X-Forwarded-For header and return the trusted client IP address
+func (engine *Engine) validateHeader(header string) (clientIP string, valid bool) {
+ if header == "" {
+ return "", false
+ }
+ items := strings.Split(header, ",")
+ for i := len(items) - 1; i >= 0; i-- {
+ ipStr := strings.TrimSpace(items[i])
+ ip := net.ParseIP(ipStr)
+ if ip == nil {
+ break
+ }
+
+ // X-Forwarded-For is appended by proxy
+ // Check IPs in reverse order and stop when find untrusted proxy
+ if (i == 0) || (!engine.isTrustedProxy(ip)) {
+ return ipStr, true
+ }
+ }
+ return "", false
+}
+
// parseIP parse a string representation of an IP and returns a net.IP with the
// minimum byte representation or nil if input is invalid.
func parseIP(ip string) net.IP {
@@ -437,12 +498,12 @@ func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) {
"Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.")
}
- err = http.ListenAndServeTLS(addr, certFile, keyFile, engine)
+ err = http.ListenAndServeTLS(addr, certFile, keyFile, engine.Handler())
return
}
// RunUnix attaches the router to a http.Server and starts listening and serving HTTP requests
-// through the specified unix socket (ie. a file).
+// through the specified unix socket (i.e. a file).
// Note: this method will block the calling goroutine indefinitely unless an error happens.
func (engine *Engine) RunUnix(file string) (err error) {
debugPrint("Listening and serving HTTP on unix:/%s", file)
@@ -460,7 +521,7 @@ func (engine *Engine) RunUnix(file string) (err error) {
defer listener.Close()
defer os.Remove(file)
- err = http.Serve(listener, engine)
+ err = http.Serve(listener, engine.Handler())
return
}
@@ -497,7 +558,7 @@ func (engine *Engine) RunListener(listener net.Listener) (err error) {
"Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.")
}
- err = http.Serve(listener, engine)
+ err = http.Serve(listener, engine.Handler())
return
}
@@ -513,9 +574,9 @@ func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
engine.pool.Put(c)
}
-// HandleContext re-enter a context that has been rewritten.
+// HandleContext re-enters a context that has been rewritten.
// This can be done by setting c.Request.URL.Path to your new target.
-// Disclaimer: You can loop yourself to death with this, use wisely.
+// Disclaimer: You can loop yourself to deal with this, use wisely.
func (engine *Engine) HandleContext(c *Context) {
oldIndexValue := c.index
c.reset()
@@ -556,7 +617,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
c.writermem.WriteHeaderNow()
return
}
- if httpMethod != "CONNECT" && rPath != "/" {
+ if httpMethod != http.MethodConnect && rPath != "/" {
if value.tsr && engine.RedirectTrailingSlash {
redirectTrailingSlash(c)
return
diff --git a/vendor/github.com/gin-gonic/gin/internal/json/go_json.go b/vendor/github.com/gin-gonic/gin/internal/json/go_json.go
new file mode 100644
index 000000000..23f717265
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/internal/json/go_json.go
@@ -0,0 +1,23 @@
+// Copyright 2017 Bo-Yi Wu. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+//go:build go_json
+// +build go_json
+
+package json
+
+import json "github.com/goccy/go-json"
+
+var (
+ // Marshal is exported by gin/json package.
+ Marshal = json.Marshal
+ // Unmarshal is exported by gin/json package.
+ Unmarshal = json.Unmarshal
+ // MarshalIndent is exported by gin/json package.
+ MarshalIndent = json.MarshalIndent
+ // NewDecoder is exported by gin/json package.
+ NewDecoder = json.NewDecoder
+ // NewEncoder is exported by gin/json package.
+ NewEncoder = json.NewEncoder
+)
diff --git a/vendor/github.com/gin-gonic/gin/internal/json/json.go b/vendor/github.com/gin-gonic/gin/internal/json/json.go
index 172aeb241..a26d7db2e 100644
--- a/vendor/github.com/gin-gonic/gin/internal/json/json.go
+++ b/vendor/github.com/gin-gonic/gin/internal/json/json.go
@@ -1,9 +1,9 @@
-// Copyright 2017 Bo-Yi Wu. All rights reserved.
+// Copyright 2017 Bo-Yi Wu. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
-//go:build !jsoniter
-// +build !jsoniter
+//go:build !jsoniter && !go_json
+// +build !jsoniter,!go_json
package json
diff --git a/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go b/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go
index 232f8dcad..853b1a901 100644
--- a/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go
+++ b/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go
@@ -1,4 +1,4 @@
-// Copyright 2017 Bo-Yi Wu. All rights reserved.
+// Copyright 2017 Bo-Yi Wu. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/vendor/github.com/gin-gonic/gin/logger.go b/vendor/github.com/gin-gonic/gin/logger.go
index d361b74d3..cd1e7fa6e 100644
--- a/vendor/github.com/gin-gonic/gin/logger.go
+++ b/vendor/github.com/gin-gonic/gin/logger.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -44,7 +44,7 @@ type LoggerConfig struct {
// Optional. Default value is gin.DefaultWriter.
Output io.Writer
- // SkipPaths is a url path array which logs are not written.
+ // SkipPaths is an url path array which logs are not written.
// Optional.
SkipPaths []string
}
@@ -70,12 +70,12 @@ type LogFormatterParams struct {
Path string
// ErrorMessage is set if error has occurred in processing the request.
ErrorMessage string
- // isTerm shows whether does gin's output descriptor refers to a terminal.
+ // isTerm shows whether gin's output descriptor refers to a terminal.
isTerm bool
// BodySize is the size of the Response Body
BodySize int
// Keys are the keys set on the request's context.
- Keys map[string]interface{}
+ Keys map[string]any
}
// StatusCodeColor is the ANSI color for appropriately logging http status code to a terminal.
@@ -138,8 +138,7 @@ var defaultLogFormatter = func(param LogFormatterParams) string {
}
if param.Latency > time.Minute {
- // Truncate in a golang < 1.8 safe way
- param.Latency = param.Latency - param.Latency%time.Second
+ param.Latency = param.Latency.Truncate(time.Second)
}
return fmt.Sprintf("[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %#v\n%s",
param.TimeStamp.Format("2006/01/02 - 15:04:05"),
@@ -162,12 +161,12 @@ func ForceConsoleColor() {
consoleColorMode = forceColor
}
-// ErrorLogger returns a handlerfunc for any error type.
+// ErrorLogger returns a HandlerFunc for any error type.
func ErrorLogger() HandlerFunc {
return ErrorLoggerT(ErrorTypeAny)
}
-// ErrorLoggerT returns a handlerfunc for a given error type.
+// ErrorLoggerT returns a HandlerFunc for a given error type.
func ErrorLoggerT(typ ErrorType) HandlerFunc {
return func(c *Context) {
c.Next()
@@ -179,7 +178,7 @@ func ErrorLoggerT(typ ErrorType) HandlerFunc {
}
// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter.
-// By default gin.DefaultWriter = os.Stdout.
+// By default, gin.DefaultWriter = os.Stdout.
func Logger() HandlerFunc {
return LoggerWithConfig(LoggerConfig{})
}
diff --git a/vendor/github.com/gin-gonic/gin/mode.go b/vendor/github.com/gin-gonic/gin/mode.go
index c8813aff2..545fdaaf8 100644
--- a/vendor/github.com/gin-gonic/gin/mode.go
+++ b/vendor/github.com/gin-gonic/gin/mode.go
@@ -1,10 +1,11 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package gin
import (
+ "flag"
"io"
"os"
@@ -41,8 +42,10 @@ var DefaultWriter io.Writer = os.Stdout
// DefaultErrorWriter is the default io.Writer used by Gin to debug errors
var DefaultErrorWriter io.Writer = os.Stderr
-var ginMode = debugCode
-var modeName = DebugMode
+var (
+ ginMode = debugCode
+ modeName = DebugMode
+)
func init() {
mode := os.Getenv(EnvGinMode)
@@ -52,7 +55,11 @@ func init() {
// SetMode sets gin mode according to input string.
func SetMode(value string) {
if value == "" {
- value = DebugMode
+ if flag.Lookup("test.v") != nil {
+ value = TestMode
+ } else {
+ value = DebugMode
+ }
}
switch value {
@@ -86,7 +93,7 @@ func EnableJsonDecoderDisallowUnknownFields() {
binding.EnableDecoderDisallowUnknownFields = true
}
-// Mode returns currently gin mode.
+// Mode returns current gin mode.
func Mode() string {
return modeName
}
diff --git a/vendor/github.com/gin-gonic/gin/recovery.go b/vendor/github.com/gin-gonic/gin/recovery.go
index 563f5aaa8..abb645105 100644
--- a/vendor/github.com/gin-gonic/gin/recovery.go
+++ b/vendor/github.com/gin-gonic/gin/recovery.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -6,6 +6,7 @@ package gin
import (
"bytes"
+ "errors"
"fmt"
"io"
"io/ioutil"
@@ -27,14 +28,14 @@ var (
)
// RecoveryFunc defines the function passable to CustomRecovery.
-type RecoveryFunc func(c *Context, err interface{})
+type RecoveryFunc func(c *Context, err any)
// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
func Recovery() HandlerFunc {
return RecoveryWithWriter(DefaultErrorWriter)
}
-//CustomRecovery returns a middleware that recovers from any panics and calls the provided handle func to handle it.
+// CustomRecovery returns a middleware that recovers from any panics and calls the provided handle func to handle it.
func CustomRecovery(handle RecoveryFunc) HandlerFunc {
return RecoveryWithWriter(DefaultErrorWriter, handle)
}
@@ -60,7 +61,8 @@ func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
// condition that warrants a panic stack trace.
var brokenPipe bool
if ne, ok := err.(*net.OpError); ok {
- if se, ok := ne.Err.(*os.SyscallError); ok {
+ var se *os.SyscallError
+ if errors.As(ne, &se) {
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
brokenPipe = true
}
@@ -100,7 +102,7 @@ func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
}
}
-func defaultHandleRecovery(c *Context, err interface{}) {
+func defaultHandleRecovery(c *Context, err any) {
c.AbortWithStatus(http.StatusInternalServerError)
}
@@ -153,7 +155,7 @@ func function(pc uintptr) []byte {
// runtime/debug.*T·ptrmethod
// and want
// *T.ptrmethod
- // Also the package path might contains dot (e.g. code.google.com/...),
+ // Also the package path might contain dot (e.g. code.google.com/...),
// so first eliminate the path prefix
if lastSlash := bytes.LastIndex(name, slash); lastSlash >= 0 {
name = name[lastSlash+1:]
@@ -165,7 +167,7 @@ func function(pc uintptr) []byte {
return name
}
+// timeFormat returns a customized time string for logger.
func timeFormat(t time.Time) string {
- timeString := t.Format("2006/01/02 - 15:04:05")
- return timeString
+ return t.Format("2006/01/02 - 15:04:05")
}
diff --git a/vendor/github.com/gin-gonic/gin/render/any.go b/vendor/github.com/gin-gonic/gin/render/any.go
new file mode 100644
index 000000000..b19ad45d9
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/render/any.go
@@ -0,0 +1,10 @@
+// Copyright 2021 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.18
+// +build !go1.18
+
+package render
+
+type any = interface{}
diff --git a/vendor/github.com/gin-gonic/gin/render/data.go b/vendor/github.com/gin-gonic/gin/render/data.go
index 6ba657ba0..a653ea309 100644
--- a/vendor/github.com/gin-gonic/gin/render/data.go
+++ b/vendor/github.com/gin-gonic/gin/render/data.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/vendor/github.com/gin-gonic/gin/render/html.go b/vendor/github.com/gin-gonic/gin/render/html.go
index 6696ece99..c308408d2 100644
--- a/vendor/github.com/gin-gonic/gin/render/html.go
+++ b/vendor/github.com/gin-gonic/gin/render/html.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -20,7 +20,7 @@ type Delims struct {
// HTMLRender interface is to be implemented by HTMLProduction and HTMLDebug.
type HTMLRender interface {
// Instance returns an HTML instance.
- Instance(string, interface{}) Render
+ Instance(string, any) Render
}
// HTMLProduction contains template reference and its delims.
@@ -41,13 +41,13 @@ type HTMLDebug struct {
type HTML struct {
Template *template.Template
Name string
- Data interface{}
+ Data any
}
var htmlContentType = []string{"text/html; charset=utf-8"}
// Instance (HTMLProduction) returns an HTML instance which it realizes Render interface.
-func (r HTMLProduction) Instance(name string, data interface{}) Render {
+func (r HTMLProduction) Instance(name string, data any) Render {
return HTML{
Template: r.Template,
Name: name,
@@ -56,7 +56,7 @@ func (r HTMLProduction) Instance(name string, data interface{}) Render {
}
// Instance (HTMLDebug) returns an HTML instance which it realizes Render interface.
-func (r HTMLDebug) Instance(name string, data interface{}) Render {
+func (r HTMLDebug) Instance(name string, data any) Render {
return HTML{
Template: r.loadTemplate(),
Name: name,
diff --git a/vendor/github.com/gin-gonic/gin/render/json.go b/vendor/github.com/gin-gonic/gin/render/json.go
index 418630939..af678e80d 100644
--- a/vendor/github.com/gin-gonic/gin/render/json.go
+++ b/vendor/github.com/gin-gonic/gin/render/json.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -16,39 +16,41 @@ import (
// JSON contains the given interface object.
type JSON struct {
- Data interface{}
+ Data any
}
// IndentedJSON contains the given interface object.
type IndentedJSON struct {
- Data interface{}
+ Data any
}
// SecureJSON contains the given interface object and its prefix.
type SecureJSON struct {
Prefix string
- Data interface{}
+ Data any
}
// JsonpJSON contains the given interface object its callback.
type JsonpJSON struct {
Callback string
- Data interface{}
+ Data any
}
// AsciiJSON contains the given interface object.
type AsciiJSON struct {
- Data interface{}
+ Data any
}
// PureJSON contains the given interface object.
type PureJSON struct {
- Data interface{}
+ Data any
}
-var jsonContentType = []string{"application/json; charset=utf-8"}
-var jsonpContentType = []string{"application/javascript; charset=utf-8"}
-var jsonAsciiContentType = []string{"application/json"}
+var (
+ jsonContentType = []string{"application/json; charset=utf-8"}
+ jsonpContentType = []string{"application/javascript; charset=utf-8"}
+ jsonASCIIContentType = []string{"application/json"}
+)
// Render (JSON) writes data with custom ContentType.
func (r JSON) Render(w http.ResponseWriter) (err error) {
@@ -64,7 +66,7 @@ func (r JSON) WriteContentType(w http.ResponseWriter) {
}
// WriteJSON marshals the given interface object and writes it with custom ContentType.
-func WriteJSON(w http.ResponseWriter, obj interface{}) error {
+func WriteJSON(w http.ResponseWriter, obj any) error {
writeContentType(w, jsonContentType)
jsonBytes, err := json.Marshal(obj)
if err != nil {
@@ -100,8 +102,7 @@ func (r SecureJSON) Render(w http.ResponseWriter) error {
// if the jsonBytes is array values
if bytes.HasPrefix(jsonBytes, bytesconv.StringToBytes("[")) && bytes.HasSuffix(jsonBytes,
bytesconv.StringToBytes("]")) {
- _, err = w.Write(bytesconv.StringToBytes(r.Prefix))
- if err != nil {
+ if _, err = w.Write(bytesconv.StringToBytes(r.Prefix)); err != nil {
return err
}
}
@@ -128,20 +129,19 @@ func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
}
callback := template.JSEscapeString(r.Callback)
- _, err = w.Write(bytesconv.StringToBytes(callback))
- if err != nil {
+ if _, err = w.Write(bytesconv.StringToBytes(callback)); err != nil {
return err
}
- _, err = w.Write(bytesconv.StringToBytes("("))
- if err != nil {
+
+ if _, err = w.Write(bytesconv.StringToBytes("(")); err != nil {
return err
}
- _, err = w.Write(ret)
- if err != nil {
+
+ if _, err = w.Write(ret); err != nil {
return err
}
- _, err = w.Write(bytesconv.StringToBytes(");"))
- if err != nil {
+
+ if _, err = w.Write(bytesconv.StringToBytes(");")); err != nil {
return err
}
@@ -176,7 +176,7 @@ func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
// WriteContentType (AsciiJSON) writes JSON ContentType.
func (r AsciiJSON) WriteContentType(w http.ResponseWriter) {
- writeContentType(w, jsonAsciiContentType)
+ writeContentType(w, jsonASCIIContentType)
}
// Render (PureJSON) writes custom ContentType and encodes the given interface object.
diff --git a/vendor/github.com/gin-gonic/gin/render/msgpack.go b/vendor/github.com/gin-gonic/gin/render/msgpack.go
index 6ef5b6e51..e0f30f7a9 100644
--- a/vendor/github.com/gin-gonic/gin/render/msgpack.go
+++ b/vendor/github.com/gin-gonic/gin/render/msgpack.go
@@ -1,4 +1,4 @@
-// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -13,13 +13,15 @@ import (
"github.com/ugorji/go/codec"
)
+// Check interface implemented here to support go build tag nomsgpack.
+// See: https://github.com/gin-gonic/gin/pull/1852/
var (
_ Render = MsgPack{}
)
// MsgPack contains the given interface object.
type MsgPack struct {
- Data interface{}
+ Data any
}
var msgpackContentType = []string{"application/msgpack; charset=utf-8"}
@@ -35,7 +37,7 @@ func (r MsgPack) Render(w http.ResponseWriter) error {
}
// WriteMsgPack writes MsgPack ContentType and encodes the given interface object.
-func WriteMsgPack(w http.ResponseWriter, obj interface{}) error {
+func WriteMsgPack(w http.ResponseWriter, obj any) error {
writeContentType(w, msgpackContentType)
var mh codec.MsgpackHandle
return codec.NewEncoder(w, &mh).Encode(obj)
diff --git a/vendor/github.com/gin-gonic/gin/render/protobuf.go b/vendor/github.com/gin-gonic/gin/render/protobuf.go
index 15aca9959..9331c4058 100644
--- a/vendor/github.com/gin-gonic/gin/render/protobuf.go
+++ b/vendor/github.com/gin-gonic/gin/render/protobuf.go
@@ -1,4 +1,4 @@
-// Copyright 2018 Gin Core Team. All rights reserved.
+// Copyright 2018 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -7,12 +7,12 @@ package render
import (
"net/http"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
)
// ProtoBuf contains the given interface object.
type ProtoBuf struct {
- Data interface{}
+ Data any
}
var protobufContentType = []string{"application/x-protobuf"}
diff --git a/vendor/github.com/gin-gonic/gin/render/reader.go b/vendor/github.com/gin-gonic/gin/render/reader.go
index d5282e492..5752d8d85 100644
--- a/vendor/github.com/gin-gonic/gin/render/reader.go
+++ b/vendor/github.com/gin-gonic/gin/render/reader.go
@@ -1,4 +1,4 @@
-// Copyright 2018 Gin Core Team. All rights reserved.
+// Copyright 2018 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/vendor/github.com/gin-gonic/gin/render/redirect.go b/vendor/github.com/gin-gonic/gin/render/redirect.go
index c006691ca..70e3a47e8 100644
--- a/vendor/github.com/gin-gonic/gin/render/redirect.go
+++ b/vendor/github.com/gin-gonic/gin/render/redirect.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/vendor/github.com/gin-gonic/gin/render/render.go b/vendor/github.com/gin-gonic/gin/render/render.go
index bcd568bfb..7955000c6 100644
--- a/vendor/github.com/gin-gonic/gin/render/render.go
+++ b/vendor/github.com/gin-gonic/gin/render/render.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -30,6 +30,7 @@ var (
_ Render = Reader{}
_ Render = AsciiJSON{}
_ Render = ProtoBuf{}
+ _ Render = TOML{}
)
func writeContentType(w http.ResponseWriter, value []string) {
diff --git a/vendor/github.com/gin-gonic/gin/render/text.go b/vendor/github.com/gin-gonic/gin/render/text.go
index 461b720af..77eafdfd8 100644
--- a/vendor/github.com/gin-gonic/gin/render/text.go
+++ b/vendor/github.com/gin-gonic/gin/render/text.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -14,7 +14,7 @@ import (
// String contains the given interface object slice and its format.
type String struct {
Format string
- Data []interface{}
+ Data []any
}
var plainContentType = []string{"text/plain; charset=utf-8"}
@@ -30,7 +30,7 @@ func (r String) WriteContentType(w http.ResponseWriter) {
}
// WriteString writes data according to its format and write custom ContentType.
-func WriteString(w http.ResponseWriter, format string, data []interface{}) (err error) {
+func WriteString(w http.ResponseWriter, format string, data []any) (err error) {
writeContentType(w, plainContentType)
if len(data) > 0 {
_, err = fmt.Fprintf(w, format, data...)
diff --git a/vendor/github.com/gin-gonic/gin/render/toml.go b/vendor/github.com/gin-gonic/gin/render/toml.go
new file mode 100644
index 000000000..40f044c88
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/render/toml.go
@@ -0,0 +1,36 @@
+// Copyright 2022 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package render
+
+import (
+ "net/http"
+
+ "github.com/pelletier/go-toml/v2"
+)
+
+// TOML contains the given interface object.
+type TOML struct {
+ Data any
+}
+
+var TOMLContentType = []string{"application/toml; charset=utf-8"}
+
+// Render (TOML) marshals the given interface object and writes data with custom ContentType.
+func (r TOML) Render(w http.ResponseWriter) error {
+ r.WriteContentType(w)
+
+ bytes, err := toml.Marshal(r.Data)
+ if err != nil {
+ return err
+ }
+
+ _, err = w.Write(bytes)
+ return err
+}
+
+// WriteContentType (TOML) writes TOML ContentType for response.
+func (r TOML) WriteContentType(w http.ResponseWriter) {
+ writeContentType(w, TOMLContentType)
+}
diff --git a/vendor/github.com/gin-gonic/gin/render/xml.go b/vendor/github.com/gin-gonic/gin/render/xml.go
index cc5390a2d..6af890179 100644
--- a/vendor/github.com/gin-gonic/gin/render/xml.go
+++ b/vendor/github.com/gin-gonic/gin/render/xml.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -11,7 +11,7 @@ import (
// XML contains the given interface object.
type XML struct {
- Data interface{}
+ Data any
}
var xmlContentType = []string{"application/xml; charset=utf-8"}
diff --git a/vendor/github.com/gin-gonic/gin/render/yaml.go b/vendor/github.com/gin-gonic/gin/render/yaml.go
index 0df783608..4f0ac01f6 100644
--- a/vendor/github.com/gin-gonic/gin/render/yaml.go
+++ b/vendor/github.com/gin-gonic/gin/render/yaml.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -12,7 +12,7 @@ import (
// YAML contains the given interface object.
type YAML struct {
- Data interface{}
+ Data any
}
var yamlContentType = []string{"application/x-yaml; charset=utf-8"}
diff --git a/vendor/github.com/gin-gonic/gin/response_writer.go b/vendor/github.com/gin-gonic/gin/response_writer.go
index 26826689a..77c7ed8fd 100644
--- a/vendor/github.com/gin-gonic/gin/response_writer.go
+++ b/vendor/github.com/gin-gonic/gin/response_writer.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -23,23 +23,23 @@ type ResponseWriter interface {
http.Flusher
http.CloseNotifier
- // Returns the HTTP response status code of the current request.
+ // Status returns the HTTP response status code of the current request.
Status() int
- // Returns the number of bytes already written into the response http body.
+ // Size returns the number of bytes already written into the response http body.
// See Written()
Size() int
- // Writes the string into the response body.
+ // WriteString writes the string into the response body.
WriteString(string) (int, error)
- // Returns true if the response body was already written.
+ // Written returns true if the response body was already written.
Written() bool
- // Forces to write the http header (status code + headers).
+ // WriteHeaderNow forces to write the http header (status code + headers).
WriteHeaderNow()
- // get the http.Pusher for server push
+ // Pusher get the http.Pusher for server push
Pusher() http.Pusher
}
@@ -107,12 +107,12 @@ func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return w.ResponseWriter.(http.Hijacker).Hijack()
}
-// CloseNotify implements the http.CloseNotify interface.
+// CloseNotify implements the http.CloseNotifier interface.
func (w *responseWriter) CloseNotify() <-chan bool {
return w.ResponseWriter.(http.CloseNotifier).CloseNotify()
}
-// Flush implements the http.Flush interface.
+// Flush implements the http.Flusher interface.
func (w *responseWriter) Flush() {
w.WriteHeaderNow()
w.ResponseWriter.(http.Flusher).Flush()
diff --git a/vendor/github.com/gin-gonic/gin/routergroup.go b/vendor/github.com/gin-gonic/gin/routergroup.go
index 15d9930d3..3c082d932 100644
--- a/vendor/github.com/gin-gonic/gin/routergroup.go
+++ b/vendor/github.com/gin-gonic/gin/routergroup.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -11,6 +11,18 @@ import (
"strings"
)
+var (
+ // regEnLetter matches english letters for http method name
+ regEnLetter = regexp.MustCompile("^[A-Z]+$")
+
+ // anyMethods for RouterGroup Any method
+ anyMethods = []string{
+ http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch,
+ http.MethodHead, http.MethodOptions, http.MethodDelete, http.MethodConnect,
+ http.MethodTrace,
+ }
+)
+
// IRouter defines all router handle interface includes single and group router.
type IRouter interface {
IRoutes
@@ -32,6 +44,7 @@ type IRoutes interface {
HEAD(string, ...HandlerFunc) IRoutes
StaticFile(string, string) IRoutes
+ StaticFileFS(string, string, http.FileSystem) IRoutes
Static(string, string) IRoutes
StaticFS(string, http.FileSystem) IRoutes
}
@@ -87,7 +100,7 @@ func (group *RouterGroup) handle(httpMethod, relativePath string, handlers Handl
// frequently used, non-standardized or custom methods (e.g. for internal
// communication with a proxy).
func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...HandlerFunc) IRoutes {
- if matches, err := regexp.MatchString("^[A-Z]+$", httpMethod); !matches || err != nil {
+ if matched := regEnLetter.MatchString(httpMethod); !matched {
panic("http method " + httpMethod + " is not valid")
}
return group.handle(httpMethod, relativePath, handlers)
@@ -131,27 +144,34 @@ func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) IRo
// Any registers a route that matches all the HTTP methods.
// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes {
- group.handle(http.MethodGet, relativePath, handlers)
- group.handle(http.MethodPost, relativePath, handlers)
- group.handle(http.MethodPut, relativePath, handlers)
- group.handle(http.MethodPatch, relativePath, handlers)
- group.handle(http.MethodHead, relativePath, handlers)
- group.handle(http.MethodOptions, relativePath, handlers)
- group.handle(http.MethodDelete, relativePath, handlers)
- group.handle(http.MethodConnect, relativePath, handlers)
- group.handle(http.MethodTrace, relativePath, handlers)
+ for _, method := range anyMethods {
+ group.handle(method, relativePath, handlers)
+ }
+
return group.returnObj()
}
// StaticFile registers a single route in order to serve a single file of the local filesystem.
// router.StaticFile("favicon.ico", "./resources/favicon.ico")
func (group *RouterGroup) StaticFile(relativePath, filepath string) IRoutes {
+ return group.staticFileHandler(relativePath, func(c *Context) {
+ c.File(filepath)
+ })
+}
+
+// StaticFileFS works just like `StaticFile` but a custom `http.FileSystem` can be used instead..
+// router.StaticFileFS("favicon.ico", "./resources/favicon.ico", Dir{".", false})
+// Gin by default user: gin.Dir()
+func (group *RouterGroup) StaticFileFS(relativePath, filepath string, fs http.FileSystem) IRoutes {
+ return group.staticFileHandler(relativePath, func(c *Context) {
+ c.FileFromFS(filepath, fs)
+ })
+}
+
+func (group *RouterGroup) staticFileHandler(relativePath string, handler HandlerFunc) IRoutes {
if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") {
panic("URL parameters can not be used when serving a static file")
}
- handler := func(c *Context) {
- c.File(filepath)
- }
group.GET(relativePath, handler)
group.HEAD(relativePath, handler)
return group.returnObj()
@@ -209,9 +229,7 @@ func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileS
func (group *RouterGroup) combineHandlers(handlers HandlersChain) HandlersChain {
finalSize := len(group.Handlers) + len(handlers)
- if finalSize >= int(abortIndex) {
- panic("too many handlers")
- }
+ assert1(finalSize < int(abortIndex), "too many handlers")
mergedHandlers := make(HandlersChain, finalSize)
copy(mergedHandlers, group.Handlers)
copy(mergedHandlers[len(group.Handlers):], handlers)
diff --git a/vendor/github.com/gin-gonic/gin/test_helpers.go b/vendor/github.com/gin-gonic/gin/test_helpers.go
index 3a7a5ddf6..b3be93b4e 100644
--- a/vendor/github.com/gin-gonic/gin/test_helpers.go
+++ b/vendor/github.com/gin-gonic/gin/test_helpers.go
@@ -1,4 +1,4 @@
-// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
diff --git a/vendor/github.com/gin-gonic/gin/tree.go b/vendor/github.com/gin-gonic/gin/tree.go
index 158a33908..88100eec8 100644
--- a/vendor/github.com/gin-gonic/gin/tree.go
+++ b/vendor/github.com/gin-gonic/gin/tree.go
@@ -31,8 +31,8 @@ type Param struct {
// It is therefore safe to read values by the index.
type Params []Param
-// Get returns the value of the first Param which key matches the given name.
-// If no matching Param is found, an empty string is returned.
+// Get returns the value of the first Param which key matches the given name and a boolean true.
+// If no matching Param is found, an empty string is returned and a boolean false .
func (ps Params) Get(name string) (string, bool) {
for _, entry := range ps {
if entry.Key == name {
@@ -81,7 +81,7 @@ func longestCommonPrefix(a, b string) int {
return i
}
-// addChild will add a child node, keeping wildcards at the end
+// addChild will add a child node, keeping wildcardChild at the end
func (n *node) addChild(child *node) {
if n.wildChild && len(n.children) > 0 {
wildcardChild := n.children[len(n.children)-1]
@@ -107,8 +107,7 @@ func countSections(path string) uint16 {
type nodeType uint8
const (
- static nodeType = iota // default
- root
+ root nodeType = iota + 1
param
catchAll
)
@@ -297,7 +296,7 @@ func (n *node) insertChild(path string, fullPath string, handlers HandlersChain)
break
}
- // The wildcard name must not contain ':' and '*'
+ // The wildcard name must only contain one ':' or '*' character
if !valid {
panic("only one wildcard per path segment is allowed, has: '" +
wildcard + "' in path '" + fullPath + "'")
@@ -326,7 +325,7 @@ func (n *node) insertChild(path string, fullPath string, handlers HandlersChain)
n.priority++
// if the path doesn't end with the wildcard, then there
- // will be another non-wildcard subpath starting with '/'
+ // will be another subpath starting with '/'
if len(wildcard) < len(path) {
path = path[len(wildcard):]
@@ -350,7 +349,12 @@ func (n *node) insertChild(path string, fullPath string, handlers HandlersChain)
}
if len(n.path) > 0 && n.path[len(n.path)-1] == '/' {
- panic("catch-all conflicts with existing handle for the path segment root in path '" + fullPath + "'")
+ pathSeg := strings.SplitN(n.children[0].path, "/", 2)[0]
+ panic("catch-all wildcard '" + path +
+ "' in new path '" + fullPath +
+ "' conflicts with existing path segment '" + pathSeg +
+ "' in existing prefix '" + n.path + pathSeg +
+ "'")
}
// currently fixed width 1 for '/'
@@ -531,7 +535,7 @@ walk: // Outer loop for walking the tree
// No handle found. Check if a handle for this path + a
// trailing slash exists for TSR recommendation
n = n.children[0]
- value.tsr = n.path == "/" && n.handlers != nil
+ value.tsr = (n.path == "/" && n.handlers != nil) || (n.path == "" && n.indices == "/")
}
return
diff --git a/vendor/github.com/gin-gonic/gin/utils.go b/vendor/github.com/gin-gonic/gin/utils.go
index c32f0eeb0..4021a2ab4 100644
--- a/vendor/github.com/gin-gonic/gin/utils.go
+++ b/vendor/github.com/gin-gonic/gin/utils.go
@@ -1,4 +1,4 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
@@ -12,13 +12,14 @@ import (
"reflect"
"runtime"
"strings"
+ "unicode"
)
// BindKey indicates a default bind key.
const BindKey = "_gin-gonic/gin/bindkey"
// Bind is a helper function for given interface object and returns a Gin middleware.
-func Bind(val interface{}) HandlerFunc {
+func Bind(val any) HandlerFunc {
value := reflect.ValueOf(val)
if value.Kind() == reflect.Ptr {
panic(`Bind struct can not be a pointer. Example:
@@ -50,7 +51,7 @@ func WrapH(h http.Handler) HandlerFunc {
}
// H is a shortcut for map[string]interface{}
-type H map[string]interface{}
+type H map[string]any
// MarshalXML allows type H to be used with xml.Marshal.
func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
@@ -89,7 +90,7 @@ func filterFlags(content string) string {
return content
}
-func chooseData(custom, wildcard interface{}) interface{} {
+func chooseData(custom, wildcard any) any {
if custom != nil {
return custom
}
@@ -120,7 +121,7 @@ func lastChar(str string) uint8 {
return str[len(str)-1]
}
-func nameOfFunction(f interface{}) string {
+func nameOfFunction(f any) string {
return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
}
@@ -151,3 +152,13 @@ func resolveAddress(addr []string) string {
panic("too many parameters")
}
}
+
+// https://stackoverflow.com/questions/53069040/checking-a-string-contains-only-ascii-characters
+func isASCII(s string) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] > unicode.MaxASCII {
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/gin-gonic/gin/version.go b/vendor/github.com/gin-gonic/gin/version.go
index 4b69b9b91..632ca7d1d 100644
--- a/vendor/github.com/gin-gonic/gin/version.go
+++ b/vendor/github.com/gin-gonic/gin/version.go
@@ -1,8 +1,8 @@
-// Copyright 2018 Gin Core Team. All rights reserved.
+// Copyright 2018 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package gin
// Version is the current gin framework's version.
-const Version = "v1.7.7"
+const Version = "v1.8.1"