Compare commits

...

6 Commits

Author SHA1 Message Date
mehrdadbn9
7df2142389 fix: use require for error assertions (testifylint) 2026-02-22 00:11:36 +03:30
mehrdadbn9
1eb3a54158 test: improve coverage to meet 99% threshold
- Add TestContextGetRawDataNilBody to cover nil body error case
- Add SameSiteDefaultMode test case in SetCookieData
- Add 400ms latency test case for LatencyColor
- Add TestMarshalXMLforHSuccess for successful XML marshaling

Coverage improved from 99.1% to 99.2%
2026-02-21 23:55:47 +03:30
mehrdadbn9
65c72a8059 refactor(context): use http.StatusContinue constant instead of magic number 100
Replace magic number 100 with http.StatusContinue constant for better
code clarity and maintainability in bodyAllowedForStatus function.

Also fix typo in logger_test.go: colorForLantency -> colorForLatency

Fixes #4489
2026-02-21 23:38:37 +03:30
dependabot[bot]
81dba46872
chore(deps): bump github.com/go-playground/validator/v10 (#4509)
Bumps [github.com/go-playground/validator/v10](https://github.com/go-playground/validator) from 10.28.0 to 10.30.1.
- [Release notes](https://github.com/go-playground/validator/releases)
- [Commits](https://github.com/go-playground/validator/compare/v10.28.0...v10.30.1)

---
updated-dependencies:
- dependency-name: github.com/go-playground/validator/v10
  dependency-version: 10.30.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-21 22:39:56 +08:00
dependabot[bot]
0c219e7902
chore(deps): bump aquasecurity/trivy-action in the actions group (#4544)
Bumps the actions group with 1 update: [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action).


Updates `aquasecurity/trivy-action` from 0.34.0 to 0.34.1
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](https://github.com/aquasecurity/trivy-action/compare/0.34.0...0.34.1)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-21 22:33:30 +08:00
Bo-Yi Wu
00900fb3e1
ci: update CI workflows and standardize Trivy config quotes (#4531)
- Update gin workflow to use v2.9 and add Go 1.26 to the matrix
- Upgrade Trivy action to v0.34.0 in the scan workflow
- Change all single quotes to double quotes in Trivy workflow configuration

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2026-02-21 22:32:32 +08:00
8 changed files with 75 additions and 32 deletions

View File

@ -26,14 +26,14 @@ jobs:
- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.6
version: v2.9
args: --verbose
test:
needs: lint
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
go: ["1.24", "1.25"]
go: ["1.24", "1.25", "1.26"]
test-tags:
[
"",

View File

@ -9,7 +9,7 @@ on:
- master
schedule:
# Run daily at 00:00 UTC
- cron: '0 0 * * *'
- cron: "0 0 * * *"
workflow_dispatch: # Allow manual trigger
permissions:
@ -27,30 +27,30 @@ jobs:
fetch-depth: 0
- name: Run Trivy vulnerability scanner (source code)
uses: aquasecurity/trivy-action@0.34.0
uses: aquasecurity/trivy-action@0.34.1
with:
scan-type: 'fs'
scan-ref: '.'
scanners: 'vuln,secret,misconfig'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH,MEDIUM'
scan-type: "fs"
scan-ref: "."
scanners: "vuln,secret,misconfig"
format: "sarif"
output: "trivy-results.sarif"
severity: "CRITICAL,HIGH,MEDIUM"
ignore-unfixed: true
- name: Upload Trivy results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: 'trivy-results.sarif'
sarif_file: "trivy-results.sarif"
- name: Run Trivy scanner (table output for logs)
uses: aquasecurity/trivy-action@0.34.0
uses: aquasecurity/trivy-action@0.34.1
if: always()
with:
scan-type: 'fs'
scan-ref: '.'
scanners: 'vuln,secret,misconfig'
format: 'table'
severity: 'CRITICAL,HIGH,MEDIUM'
scan-type: "fs"
scan-ref: "."
scanners: "vuln,secret,misconfig"
format: "table"
severity: "CRITICAL,HIGH,MEDIUM"
ignore-unfixed: true
exit-code: '1'
exit-code: "1"

View File

@ -1056,6 +1056,7 @@ func (c *Context) requestHeader(key string) string {
/************************************/
// bodyAllowedForStatus is a copy of http.bodyAllowedForStatus non-exported function.
// Uses http.StatusContinue constant for better code clarity.
func bodyAllowedForStatus(status int) bool {
switch {
case status >= http.StatusContinue && status < http.StatusOK:

View File

@ -1031,6 +1031,7 @@ func TestContextGetCookie(t *testing.T) {
}
func TestContextBodyAllowedForStatus(t *testing.T) {
assert.False(t, bodyAllowedForStatus(http.StatusContinue))
assert.False(t, bodyAllowedForStatus(http.StatusProcessing))
assert.False(t, bodyAllowedForStatus(http.StatusNoContent))
assert.False(t, bodyAllowedForStatus(http.StatusNotModified))
@ -2947,6 +2948,16 @@ func TestContextGetRawData(t *testing.T) {
assert.Equal(t, "Fetch binary post data", string(data))
}
func TestContextGetRawDataNilBody(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
data, err := c.GetRawData()
assert.Nil(t, data)
require.Error(t, err)
assert.Equal(t, "cannot read nil body", err.Error())
}
func TestContextRenderDataFromReader(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
@ -3535,6 +3546,24 @@ func TestContextSetCookieData(t *testing.T) {
setCookie := c.Writer.Header().Get("Set-Cookie")
assert.Contains(t, setCookie, "SameSite=None")
})
// Test that SameSiteDefaultMode inherits from context's sameSite
t.Run("SameSiteDefaultMode inherits context sameSite", func(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.SetSameSite(http.SameSiteStrictMode)
cookie := &http.Cookie{
Name: "user",
Value: "gin",
Path: "/",
Domain: "localhost",
Secure: true,
HttpOnly: true,
SameSite: http.SameSiteDefaultMode,
}
c.SetCookieData(cookie)
setCookie := c.Writer.Header().Get("Set-Cookie")
assert.Contains(t, setCookie, "SameSite=Strict")
})
}
func TestGetMapFromFormData(t *testing.T) {

4
go.mod
View File

@ -7,7 +7,7 @@ toolchain go1.24.7
require (
github.com/bytedance/sonic v1.15.0
github.com/gin-contrib/sse v1.1.0
github.com/go-playground/validator/v10 v10.28.0
github.com/go-playground/validator/v10 v10.30.1
github.com/goccy/go-json v0.10.5
github.com/goccy/go-yaml v1.19.2
github.com/json-iterator/go v1.1.12
@ -29,7 +29,7 @@ require (
github.com/bytedance/sonic/loader v0.5.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect

8
go.sum
View File

@ -10,8 +10,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=
github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
@ -20,8 +20,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=

View File

@ -318,20 +318,21 @@ func TestColorForStatus(t *testing.T) {
}
func TestColorForLatency(t *testing.T) {
colorForLantency := func(latency time.Duration) string {
colorForLatency := func(latency time.Duration) string {
p := LogFormatterParams{
Latency: latency,
}
return p.LatencyColor()
}
assert.Equal(t, white, colorForLantency(time.Duration(0)), "0 should be white")
assert.Equal(t, white, colorForLantency(time.Millisecond*20), "20ms should be white")
assert.Equal(t, green, colorForLantency(time.Millisecond*150), "150ms should be green")
assert.Equal(t, cyan, colorForLantency(time.Millisecond*250), "250ms should be cyan")
assert.Equal(t, yellow, colorForLantency(time.Millisecond*600), "600ms should be yellow")
assert.Equal(t, magenta, colorForLantency(time.Millisecond*1500), "1.5s should be magenta")
assert.Equal(t, red, colorForLantency(time.Second*3), "other things should be red")
assert.Equal(t, white, colorForLatency(time.Duration(0)), "0 should be white")
assert.Equal(t, white, colorForLatency(time.Millisecond*20), "20ms should be white")
assert.Equal(t, green, colorForLatency(time.Millisecond*150), "150ms should be green")
assert.Equal(t, cyan, colorForLatency(time.Millisecond*250), "250ms should be cyan")
assert.Equal(t, blue, colorForLatency(time.Millisecond*400), "400ms should be blue")
assert.Equal(t, yellow, colorForLatency(time.Millisecond*600), "600ms should be yellow")
assert.Equal(t, magenta, colorForLatency(time.Millisecond*1500), "1.5s should be magenta")
assert.Equal(t, red, colorForLatency(time.Second*3), "other things should be red")
}
func TestResetColor(t *testing.T) {

View File

@ -13,6 +13,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func init() {
@ -145,6 +146,17 @@ func TestMarshalXMLforH(t *testing.T) {
assert.Error(t, e)
}
func TestMarshalXMLforHSuccess(t *testing.T) {
h := H{
"key1": "value1",
"key2": 123,
}
data, err := xml.Marshal(h)
require.NoError(t, err)
assert.Contains(t, string(data), "<key1>value1</key1>")
assert.Contains(t, string(data), "<key2>123</key2>")
}
func TestIsASCII(t *testing.T) {
assert.True(t, isASCII("test"))
assert.False(t, isASCII("🧡💛💚💙💜"))