mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-11 17:56:37 +08:00
fix(access-logs): 修复概览域名筛选参数 hosts[] 被 Gin 忽略
Axios 默认序列化为 hosts[]=,Gin QueryArray("hosts") 读不到导致筛选失效;
后端兼容 hosts/hosts[],前端改为重复键序列化。
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package observability
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestReadQueryStringArrayAcceptsHostsBracketForm(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
url string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "axios brackets form",
|
||||
url: "/overview?hours=168&hosts%5B%5D=gist.arctel.de",
|
||||
want: []string{"gist.arctel.de"},
|
||||
},
|
||||
{
|
||||
name: "repeated hosts keys",
|
||||
url: "/overview?hosts=a.example&hosts=b.example",
|
||||
want: []string{"a.example", "b.example"},
|
||||
},
|
||||
{
|
||||
name: "single hosts key",
|
||||
url: "/overview?hosts=gist.arctel.de",
|
||||
want: []string{"gist.arctel.de"},
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
url: "/overview?hours=24",
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req, err := http.NewRequest(http.MethodGet, tc.url, nil)
|
||||
require.NoError(t, err)
|
||||
c.Request = req
|
||||
|
||||
got := readQueryStringArray(c, "hosts")
|
||||
require.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ func GetAccessLogOverviewHandler(c *gin.Context) {
|
||||
result, err := GetAccessLogOverview(c.Request.Context(), AccessLogOverviewQuery{
|
||||
NodeID: c.Query("node_id"),
|
||||
Host: c.Query("host"),
|
||||
Hosts: c.QueryArray("hosts"),
|
||||
Hosts: readQueryStringArray(c, "hosts"),
|
||||
Hours: readQueryInt(c, "hours"),
|
||||
})
|
||||
if apiutil.AbortBadRequestOnError(c, err) {
|
||||
@@ -279,3 +279,15 @@ func readQueryInt(c *gin.Context, key string) int {
|
||||
value, _ := strconv.Atoi(c.DefaultQuery(key, "0"))
|
||||
return value
|
||||
}
|
||||
|
||||
// readQueryStringArray reads repeated query values for key, and also accepts
|
||||
// the Axios/jQuery bracket form key[] / key%5B%5D which Gin does not map to key.
|
||||
func readQueryStringArray(c *gin.Context, key string) []string {
|
||||
if values := c.QueryArray(key); len(values) > 0 {
|
||||
return values
|
||||
}
|
||||
if values := c.QueryArray(key + "[]"); len(values) > 0 {
|
||||
return values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user