diff --git a/go.mod b/go.mod index a421996..24404b9 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/goravel/fiber v1.18.1-0.20260901101548-72e06e6c5635 github.com/goravel/framework v1.18.1-0.20260925114822-dab1968caa54 github.com/goravel/gemini v1.18.0 - github.com/goravel/gin v1.18.1-0.20260901101851-2c895122597a + github.com/goravel/gin v1.18.1-0.20260926005436-467f03c48058 github.com/goravel/inertia v1.18.1-0.20260824090129-ac3d472d028c github.com/goravel/minio v1.18.0 github.com/goravel/mysql v1.18.0 @@ -70,9 +70,9 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.2 // indirect - github.com/bytedance/gopkg v0.1.3 // indirect - github.com/bytedance/sonic v1.15.0 // indirect - github.com/bytedance/sonic/loader v0.5.0 // indirect + github.com/bytedance/gopkg v0.1.4 // indirect + github.com/bytedance/sonic v1.15.2 // indirect + github.com/bytedance/sonic/loader v0.5.1 // indirect github.com/catppuccin/go v0.3.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -89,7 +89,7 @@ require ( github.com/clbanning/mxj v1.8.4 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect - github.com/cloudwego/base64x v0.1.6 // indirect + github.com/cloudwego/base64x v0.1.7 // indirect github.com/containerd/console v1.0.5 // indirect github.com/dave/dst v0.28.0 // indirect github.com/dromara/carbon/v2 v2.6.17 // indirect @@ -98,8 +98,8 @@ require ( github.com/felixge/httpsnoop v1.1.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gabriel-vasile/mimetype v1.4.15 // indirect - github.com/gin-contrib/sse v1.1.0 // indirect - github.com/gin-contrib/timeout v1.2.1 // indirect + github.com/gin-contrib/sse v1.1.1 // indirect + github.com/gin-contrib/timeout v1.2.2 // indirect github.com/gin-gonic/gin v1.12.0 // indirect github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -115,10 +115,10 @@ require ( github.com/go-openapi/swag/yamlutils v0.28.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.30.1 // indirect + github.com/go-playground/validator/v10 v10.30.3 // indirect github.com/go-sql-driver/mysql v1.9.1 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect - github.com/goccy/go-json v0.10.5 // indirect + github.com/goccy/go-json v0.10.6 // indirect github.com/goccy/go-yaml v1.19.2 // indirect github.com/gofiber/fiber/v3 v3.5.0 // indirect github.com/gofiber/schema v1.8.3 // indirect @@ -147,7 +147,7 @@ require ( github.com/jmoiron/sqlx v1.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.19.2 // indirect - github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/klauspost/cpuid/v2 v2.4.0 // indirect github.com/klauspost/crc32 v1.3.0 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect @@ -174,12 +174,12 @@ require ( github.com/ncruces/go-sqlite3/gormlite v0.24.0 // indirect github.com/ncruces/julianday v1.0.0 // indirect github.com/openai/openai-go/v3 v3.39.0 // indirect - github.com/pelletier/go-toml/v2 v2.3.1 // indirect + github.com/pelletier/go-toml/v2 v2.4.3 // indirect github.com/petaki/inertia-go v1.15.0 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/pterm/pterm v0.12.83 // indirect github.com/quic-go/qpack v0.6.0 // indirect - github.com/quic-go/quic-go v0.59.0 // indirect + github.com/quic-go/quic-go v0.60.0 // indirect github.com/redis/go-redis/v9 v9.21.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect @@ -218,7 +218,7 @@ require ( github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect - go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect + go.mongodb.org/mongo-driver/v2 v2.8.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.71.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.71.0 // indirect @@ -240,7 +240,7 @@ require ( go.opentelemetry.io/proto/otlp v1.11.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect - golang.org/x/arch v0.22.0 // indirect + golang.org/x/arch v0.29.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba // indirect golang.org/x/mod v0.41.0 // indirect diff --git a/go.sum b/go.sum index 5ae5a59..d89c8b5 100644 --- a/go.sum +++ b/go.sum @@ -119,12 +119,12 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= -github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= -github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= -github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= -github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= -github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/bytedance/gopkg v0.1.4 h1:oZnQwnX82KAIWb7033bEwtxvTqXcYMxDBaQxo5JJHWM= +github.com/bytedance/gopkg v0.1.4/go.mod h1:v1zWfPm21Fb+OsyXN2VAHdL6TBb2L88anLQgdyje6R4= +github.com/bytedance/sonic v1.15.2 h1:90H+rcF/FwLXwfB1cudOLq/je83n683Utf4Cbp0xHCo= +github.com/bytedance/sonic v1.15.2/go.mod h1:mT2NbXunuaEbnZ+mRIX/vYqKISmgEuHFDI4UzmKx2SA= +github.com/bytedance/sonic/loader v0.5.1 h1:Ygpfa9zwRCCKSlrp5bBP/b/Xzc3VxsAW+5NIYXrOOpI= +github.com/bytedance/sonic/loader v0.5.1/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY= github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= @@ -167,8 +167,8 @@ github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSE github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= -github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= -github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= +github.com/cloudwego/base64x v0.1.7 h1:NppS+Fgzg5ovhn4NkUXaDT3x9jldgH5ToMCqzBSi2zI= +github.com/cloudwego/base64x v0.1.7/go.mod h1:Cu1PV9zfrSf7ET2tIbWbbEy7jO7HHJ13q4X2SQ8aWYg= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.5 h1:R0ymNeydRqH2DmakFNdmjR2k0t7UPuiOV/N/27/qqsc= github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= @@ -205,10 +205,10 @@ github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gabriel-vasile/mimetype v1.4.15 h1:05iP/CYtZ/w455R/KZM6rZ5ieAdh99UPtd+d3YzLmaI= github.com/gabriel-vasile/mimetype v1.4.15/go.mod h1:azpTcoLcDZRNgFou5j+APrqQx9HqVPWa6ijYQIIVswQ= -github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= -github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= -github.com/gin-contrib/timeout v1.2.1 h1:vw+1K+rDo1M86G00A1RdQZDP9JJDcJjYj6+9ZVowjlk= -github.com/gin-contrib/timeout v1.2.1/go.mod h1:sUImmGGy/39JoCfTRnouXWJRVuUvR0DGcdRorXn7VdE= +github.com/gin-contrib/sse v1.1.1 h1:uGYpNwTacv5R68bSGMapo62iLTRa9l5zxGCps4hK6ko= +github.com/gin-contrib/sse v1.1.1/go.mod h1:QXzuVkA0YO7o/gun03UI1Q+FTI8ZV/n5t03kIQAI89s= +github.com/gin-contrib/timeout v1.2.2 h1:aGBV1d5V//xoZlunAAwyQhZ5VXg6BZE3epZdSSSykXA= +github.com/gin-contrib/timeout v1.2.2/go.mod h1:ug0OHKmhlukJGm2emdAScRg6XBnBrgpDzPbx08MtuRw= github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8= github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -250,8 +250,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.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= -github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= +github.com/go-playground/validator/v10 v10.30.3 h1:4MU6YkEwx7GbcPJOZxrtbu+QfF3pJLJuaYTeAH0DYy8= +github.com/go-playground/validator/v10 v10.30.3/go.mod h1:4Axh7oCNGcoGkqLoE4YWt6n20mcEIsPRlB7vPk3lpyc= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtSb/iI= github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= @@ -259,8 +259,8 @@ github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -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-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU= +github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/gofiber/fiber/v3 v3.5.0 h1:dk7TOUH6DXJGtOLsN2XEG+0ZML7cznzHILTVozbNEK8= @@ -321,8 +321,8 @@ github.com/goravel/framework v1.18.1-0.20260925114822-dab1968caa54 h1:3f7twoPYBZ github.com/goravel/framework v1.18.1-0.20260925114822-dab1968caa54/go.mod h1:7Phix1gVUYzA1muoX1o92AJszuDgBUgO31ICCCJ7+Xw= github.com/goravel/gemini v1.18.0 h1:Tv6IJ3KvBvH5QD7kAM3XFQR0g8IUfkqMbRGi7dtlWUo= github.com/goravel/gemini v1.18.0/go.mod h1:b4FueB0O0Qkz71eVWLiSaKghp+Eb/1hNNICkk7vMgrQ= -github.com/goravel/gin v1.18.1-0.20260901101851-2c895122597a h1:BXol6qwpZPFhSR/8vfkrBS2qhTZb3Dqi7Y+6w00lw1c= -github.com/goravel/gin v1.18.1-0.20260901101851-2c895122597a/go.mod h1:3gCPKtmGPLVLs2nod6cEjs9YBGLDNz4v2Eq7hhjlhyA= +github.com/goravel/gin v1.18.1-0.20260926005436-467f03c48058 h1:EId8wBSolUZQ00QQz4fyPrRWN+Tz/TZAw4u65XwSINY= +github.com/goravel/gin v1.18.1-0.20260926005436-467f03c48058/go.mod h1:14Ida0ONo/rCkg5uuglE7UrCPq9QyAurSsM/dxg2juk= github.com/goravel/inertia v1.18.1-0.20260824090129-ac3d472d028c h1:/tQABlAVdsM2q9Ts/B2lsfEzQ7YQvsMqDR+sDNi7OjU= github.com/goravel/inertia v1.18.1-0.20260824090129-ac3d472d028c/go.mod h1:JZ+9yNuVsLiNBdOeaby/hdaRd3svsZ9GeX3llrosNGI= github.com/goravel/minio v1.18.0 h1:+FSTAZWVFCngLKF+apo5Rglbo8Jt499LJmJiYC1QlFI= @@ -387,8 +387,8 @@ github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= -github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw= +github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU= github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM= github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -467,8 +467,8 @@ github.com/openai/openai-go/v3 v3.39.0 h1:WgLGgMOOdQDkZyo8YIhzUNXRXlEc+OJfU4EKP5 github.com/openai/openai-go/v3 v3.39.0/go.mod h1:cdufnVK14cWcT9qA1rRtrXx4FTRsgbDPW7Ia7SS5cZo= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc= -github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY= +github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/petaki/inertia-go v1.15.0 h1:0SVg1DWeKBAFwDFHklkwkyMm887ryhURXtTnrYJZ9Sc= github.com/petaki/inertia-go v1.15.0/go.mod h1:6GT2rzFfp54Z08aM24jjHLYwOCTyecjRp2BMW5LdU84= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= @@ -487,10 +487,12 @@ github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5b github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= github.com/pterm/pterm v0.12.83 h1:ie+YmGmA727VuhxBlyGr74Ks+7McV6kT99IB8EU80aA= github.com/pterm/pterm v0.12.83/go.mod h1:xlgc6bFWyJIMtmLJvGim+L7jhSReilOlOnodeIYe4Tk= +github.com/quic-go/go-ossfuzz-seeds v0.1.0 h1:APacT+iIaNF6fd8AGEiN3bT/Jtkd2jz4v4TzM7MFjy0= +github.com/quic-go/go-ossfuzz-seeds v0.1.0/go.mod h1:3IOHRbJIc+L6YKMwfDtJAM9Vj9k0YY4muhuyUYk5tbk= github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= -github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw= -github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= +github.com/quic-go/quic-go v0.60.0 h1:xcQioE8OM66UQLeUMHltK1CCcOu3JbVB4JAQdDQSB+0= +github.com/quic-go/quic-go v0.60.0/go.mod h1:wpKpjmPpftl30sL6pFh7REVpjbcCVy4zt2vDyK1TuJk= github.com/redis/go-redis/v9 v9.21.0 h1:FPBE4hhbAke+TLmcY3WkpbDffJEomdqPn3HYiqAtL9E= github.com/redis/go-redis/v9 v9.21.0/go.mod h1:v/M13XI1PVCDcm01VtPFOADfZtHf8YW3baQf57KlIkA= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -619,8 +621,8 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= -go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE= -go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= +go.mongodb.org/mongo-driver/v2 v2.8.0 h1:CxWDGQYY8QQwNjAl/aq2sfWakdnWZynnqJ9F4DhHbP8= +go.mongodb.org/mongo-driver/v2 v2.8.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.71.0 h1:B2h3uqicet1CT2N5TOFhS+Gq++9i0/CLmaxvhmhtP5s= @@ -679,8 +681,8 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= -golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI= -golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= +golang.org/x/arch v0.29.0 h1:8sSET5wB0+exBm0FGmOtdHMqjlRdV2DRD3/IV6OZgho= +golang.org/x/arch v0.29.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= diff --git a/tests/feature/fiber_test.go b/tests/feature/fiber_test.go index 9aa50f0..b304556 100644 --- a/tests/feature/fiber_test.go +++ b/tests/feature/fiber_test.go @@ -16,6 +16,7 @@ func TestFiberDriver(t *testing.T) { suite.Run(t, new(HttpTestSuite)) suite.Run(t, new(ViewTestSuite)) + suite.Run(t, new(HttpClientTestSuite)) facades.Config().Add("http.default", "gin") if err := facades.App().Restart(); err != nil { diff --git a/tests/feature/http_client_test.go b/tests/feature/http_client_test.go index 330e1cf..6468dd5 100644 --- a/tests/feature/http_client_test.go +++ b/tests/feature/http_client_test.go @@ -1,23 +1,58 @@ package feature import ( + "io" + nethttp "net/http" + "strings" "testing" + client "github.com/goravel/framework/contracts/http/client" + supporthttp "github.com/goravel/framework/support/http" "github.com/stretchr/testify/suite" "goravel/app/facades" "goravel/tests" ) +// smallBodyLimitKB keeps the over/under payloads tiny while still going through +// the real socket, so the client can read the 413 without an upload/close race. +const ( + smallBodyLimitKB = 1 + smallBodyLimitByte = smallBodyLimitKB << 10 +) + type HttpClientTestSuite struct { suite.Suite tests.TestCase + + scope *tests.ConfigScope } func TestHttpClientTestSuite(t *testing.T) { suite.Run(t, &HttpClientTestSuite{}) } +func (s *HttpClientTestSuite) SetupSuite() { + // Lower body_limit for the whole suite so the real-client over-limit cases + // send tiny bodies. OverrideConfig restarts the app, which also restarts the + // framework HTTP runner serving 127.0.0.1:8080. + scope, err := tests.OverrideConfig(map[string]any{ + "http.drivers.gin.body_limit": smallBodyLimitKB, + "http.drivers.fiber.body_limit": smallBodyLimitKB, + }) + s.scope = scope + if err != nil { + // Restore before failing: testify skips TearDownSuite when SetupSuite + // fails, and an unrestored 1 KiB limit would leak into later suites. + s.NoError(scope.Restore()) + s.Require().FailNow("failed to set body_limit: " + err.Error()) + } +} + +func (s *HttpClientTestSuite) TearDownSuite() { + s.NoError(s.scope.Restore()) +} + // SetupTest will run before each test in the suite. func (s *HttpClientTestSuite) SetupTest() { } @@ -31,3 +66,104 @@ func (s *HttpClientTestSuite) TestGet() { s.Require().NoError(err) s.Equal(200, response.Status()) } + +// TestBodyLimit verifies http.drivers..body_limit rejects an over-limit +// request with 413 before any handler runs (goravel/gin#247). It drives the +// app's real HTTP client against the live server on 127.0.0.1:8080, so both +// drivers answer over a real socket. +func (s *HttpClientTestSuite) TestBodyLimit() { + const jsonContentType = "application/json" + + s.Run("under the limit", func() { + resp, err := facades.Http().WithHeader("Content-Type", jsonContentType). + Post("/input-map", strings.NewReader(`{"test":{"key":"value"}}`)) + s.Require().NoError(err) + s.Equal(nethttp.StatusOK, resp.Status()) + + content, err := resp.Body() + s.Require().NoError(err) + s.Equal(`{"test":{"key":"value"}}`, content) + }) + + over := `{"test":"` + strings.Repeat("a", smallBodyLimitByte+1) + `"}` + formBody := "test=" + strings.Repeat("a", smallBodyLimitByte+1) + multipartBody, err := supporthttp.NewBody(supporthttp.BodyTypeMultipart). + SetField("test", strings.Repeat("a", smallBodyLimitByte+1)). + Build() + s.Require().NoError(err) + multipartPayload, err := io.ReadAll(multipartBody.Reader()) + s.Require().NoError(err) + + s.Run("at the limit", func() { + // Exactly smallBodyLimitByte bytes of valid JSON is accepted (strict >). + pad := smallBodyLimitByte - len(`{"test":""}`) + body := `{"test":"` + strings.Repeat("a", pad) + `"}` + s.Require().Len(body, smallBodyLimitByte) + + resp, err := facades.Http().WithHeader("Content-Type", jsonContentType). + Post("/input-map", strings.NewReader(body)) + s.Require().NoError(err) + s.Equal(nethttp.StatusOK, resp.Status()) + }) + + cases := []struct { + name string + path string + body string + contentType string + chunked bool + }{ + {name: "json", path: "/input-map", body: over, contentType: jsonContentType}, + {name: "json to an unmatched route", path: "/not-a-route", body: over, contentType: jsonContentType}, + {name: "form", path: "/input-map", body: formBody, contentType: "application/x-www-form-urlencoded"}, + {name: "multipart", path: "/input-map", body: string(multipartPayload), contentType: multipartBody.ContentType()}, + {name: "chunked", path: "/input-map", body: over, contentType: jsonContentType, chunked: true}, + } + + for _, test := range cases { + s.Run("over the limit "+test.name, func() { + var body io.Reader = strings.NewReader(test.body) + if test.chunked { + // io.NopCloser hides the concrete reader, so net/http sends + // Transfer-Encoding: chunked with no Content-Length. + body = io.NopCloser(strings.NewReader(test.body)) + } + + resp, err := facades.Http().WithHeader("Content-Type", test.contentType). + Post(test.path, body) + s.assertBodyTooLarge(resp, err) + }) + } +} + +// assertBodyTooLarge asserts the real wire response for an over-limit request. +func (s *HttpClientTestSuite) assertBodyTooLarge(resp client.Response, err error) { + s.T().Helper() + + s.Require().NoError(err) + s.Equal(nethttp.StatusRequestEntityTooLarge, resp.Status()) + s.Equal("text/plain; charset=utf-8", resp.Headers().Get("Content-Type")) + + content, err := resp.Body() + s.Require().NoError(err) + s.Equal("Request Entity Too Large", content) +} + +// TestBodyLimitDefaultFallback verifies body_limit 0 does not reject normal +// requests on either driver (gin maps <= 0 to the 4096 KiB default; fiber +// applies its own 4 MiB default). The 4 MiB boundary itself is not asserted +// here to avoid racing the server's Content-Length rejection during upload. +func (s *HttpClientTestSuite) TestBodyLimitDefaultFallback() { + scope, err := tests.OverrideConfig(map[string]any{ + "http.drivers.gin.body_limit": 0, + "http.drivers.fiber.body_limit": 0, + }) + s.Require().NoError(err) + defer func() { s.NoError(scope.Restore()) }() + + // 0 must not reject normal requests. + resp, err := facades.Http().WithHeader("Content-Type", "application/json"). + Post("/input-map", strings.NewReader(`{"test":{"key":"value"}}`)) + s.Require().NoError(err) + s.Equal(nethttp.StatusOK, resp.Status()) +}