Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge from main #2

Merged
merged 40 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
bdde009
chore(deps): bump golang.org/x/net from 0.14.0 to 0.18.0 (#3774)
dependabot[bot] Nov 16, 2023
0aeac86
chore(deps): bump github.com/go-playground/validator/v10 from 10.15.1…
dependabot[bot] Nov 16, 2023
49f45a5
docs: remove redundant comments (#3765)
WeiTheShinobi Nov 16, 2023
44d0dd7
fix: Add pointer support for url query params (#3659) (#3666)
omkar-foss Nov 16, 2023
386d244
fix(tree): correctly expand the capacity of params (#3502)
georgijd-form3 Dec 7, 2023
081b36e
chore(deps): bump actions/setup-go from 4 to 5 (#3798)
dependabot[bot] Dec 13, 2023
811f271
chore(deps): bump goreleaser/goreleaser-action from 4 to 5 (#3721)
dependabot[bot] Dec 13, 2023
53fbf4d
chore(deps): bump github.com/pelletier/go-toml/v2 from 2.0.8 to 2.1.1…
dependabot[bot] Dec 13, 2023
160c173
chore: update GitHub Actions configuration (#3792)
appleboy Jan 18, 2024
857db39
chore(deps): bump github/codeql-action from 2 to 3 (#3806)
dependabot[bot] Jan 19, 2024
4a40f8f
fix(sec): upgrade golang.org/x/crypto to 0.17.0 (#3832)
chncaption Feb 1, 2024
8ab47c6
ci(lint): update tooling and workflows for consistency (#3834)
appleboy Feb 1, 2024
a64286a
chore(deps): update dependencies to latest versions (#3835)
appleboy Feb 1, 2024
c6ae2e6
feat(logger): ability to skip logs based on user-defined logic (#3593)
palvaneh Feb 2, 2024
9f598a3
fix(router): catch-all conflicting wildcard (#3812)
FirePing32 Feb 4, 2024
3dc1cd6
fix(binding): binding error while not upload file (#3819) (#3820)
clearcodecn Feb 5, 2024
e957d1a
chore(deps): bump codecov/codecov-action from 3 to 4 (#3838)
dependabot[bot] Feb 6, 2024
86ff4a6
fix(header): Allow header according to RFC 7231 (HTTP 405) (#3759)
Crocmagnon Feb 6, 2024
82bcd6d
fix(binding): dereference pointer to struct (#3199)
echovl Feb 7, 2024
bb3519d
chore(IP): add TrustedPlatform constant for Fly.io. (#3839)
ab Feb 7, 2024
000fdb3
ci(testing): add go1.22 version (#3842)
appleboy Feb 18, 2024
ecdbbbe
chore: refactor CI and update dependencies (#3848)
appleboy Feb 19, 2024
739d2d9
chore(perf): Optimize the Copy method of the Context struct (#3859)
1911860538 Mar 5, 2024
ae15646
test(http): use constant instead of numeric literal (#3863)
testwill Mar 5, 2024
9c61295
chore(header): Add support for RFC 9512: application/yaml (#3851)
vincentbernat Mar 5, 2024
f75144a
docs: fix typo in comment (#3868)
testwill Mar 5, 2024
09f8224
fix(route): Add fullPath in context copy (#3784)
KarthikReddyPuli Mar 6, 2024
3ea8bd9
chore(refactor): modify interface check way (#3855)
demoManito Mar 6, 2024
97eab7d
test(git): gitignore add develop tools (#3370)
demoManito Mar 8, 2024
5f458dd
feat(auth): add proxy-server authentication (#3877)
EndlessParadox1 Mar 11, 2024
646312a
fix: protect Context.Keys map when call Copy method (#3873)
kingcanfish Mar 11, 2024
83fc767
docs: fix typo in function documentation (#3872)
TotomiEcio Mar 11, 2024
ac5e84d
feat(engine): Added `OptionFunc` and `With` (#3572)
flc1125 Mar 11, 2024
1b3c085
chore(debug): add ability to override the debugPrint statement (#2337)
josegonzalez Mar 11, 2024
ab8042e
chore(request): check reader if it's nil before reading (#3419)
noahyao1024 Mar 11, 2024
f70dd00
fix(engine): fix unit test (#3878)
flc1125 Mar 12, 2024
861ffb9
docs(middleware): comments to function `BasicAuthForProxy` (#3881)
EndlessParadox1 Mar 12, 2024
990c44a
docs(context): Added deprecation comments to BindWith (#3880)
flc1125 Mar 12, 2024
ee70b30
docs: Add document to constant `AuthProxyUserKey` and `BasicAuthFor…
EndlessParadox1 Mar 13, 2024
fd60a24
test(path): Optimize unit test execution results (#3883)
flc1125 Mar 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ name: "CodeQL"

on:
push:
branches: [ master ]
branches: [master]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
branches: [master]
schedule:
- cron: '0 17 * * 5'
- cron: "0 17 * * 5"

jobs:
analyze:
Expand All @@ -29,15 +29,15 @@ jobs:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
# TODO: Enable for javascript later
language: [ 'go']
language: ["go"]

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -46,4 +46,4 @@ jobs:
# queries: ./path/to/local/query, your-org/your-repo/queries@main

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
31 changes: 18 additions & 13 deletions .github/workflows/gin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,28 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Setup go
uses: actions/setup-go@v4
with:
go-version: '^1.18'
- name: Checkout repository
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
check-latest: true
- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v3.7.0
uses: golangci/golangci-lint-action@v4
with:
version: v1.52.2
version: v1.56.2
args: --verbose
test:
needs: lint
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
go: ['1.18', '1.19', '1.20']
test-tags: ['', '-tags nomsgpack', '-tags "sonic avx"', '-tags go_json']
go: ["1.18", "1.19", "1.20", "1.21", "1.22"]
test-tags:
["", "-tags nomsgpack", '-tags "sonic avx"', "-tags go_json", "-race"]
include:
- os: ubuntu-latest
go-build: ~/.cache/go-build
Expand All @@ -46,16 +50,17 @@ jobs:
GOPROXY: https://proxy.golang.org
steps:
- name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
cache: false

- name: Checkout Code
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
${{ matrix.go-build }}
Expand All @@ -68,10 +73,10 @@ jobs:
run: make test

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
flags: ${{ matrix.os }},go-${{ matrix.go }},${{ matrix.test-tags }}

- name: Format
if: matrix.go-version == '1.20.x'
if: matrix.go-version == '1.22.x'
run: diff -u <(echo -n) <(gofmt -d .)
17 changes: 7 additions & 10 deletions .github/workflows/goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Goreleaser
on:
push:
tags:
- '*'
- "*"

permissions:
contents: write
Expand All @@ -12,19 +12,16 @@ jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
-
name: Checkout
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.20
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
go-version: "^1"
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ count.out
test
profile.out
tmp.out

# Develop tools
.idea/
.vscode/
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ run:
linters:
enable:
- asciicheck
- depguard
- dogsled
- durationcheck
- errcheck
Expand Down
25 changes: 25 additions & 0 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import (
// AuthUserKey is the cookie name for user credential in basic auth.
const AuthUserKey = "user"

// AuthProxyUserKey is the cookie name for proxy_user credential in basic auth for proxy.
const AuthProxyUserKey = "proxy_user"

// Accounts defines a key/value for user/pass list of authorized logins.
type Accounts map[string]string

Expand Down Expand Up @@ -89,3 +92,25 @@ func authorizationHeader(user, password string) string {
base := user + ":" + password
return "Basic " + base64.StdEncoding.EncodeToString(bytesconv.StringToBytes(base))
}

// BasicAuthForProxy returns a Basic HTTP Proxy-Authorization middleware.
// If the realm is empty, "Proxy Authorization Required" will be used by default.
func BasicAuthForProxy(accounts Accounts, realm string) HandlerFunc {
if realm == "" {
realm = "Proxy Authorization Required"
}
realm = "Basic realm=" + strconv.Quote(realm)
pairs := processAccounts(accounts)
return func(c *Context) {
proxyUser, found := pairs.searchCredential(c.requestHeader("Proxy-Authorization"))
if !found {
// Credentials doesn't match, we return 407 and abort handlers chain.
c.Header("Proxy-Authenticate", realm)
c.AbortWithStatus(http.StatusProxyAuthRequired)
return
}
// The proxy_user credentials was found, set proxy_user's id to key AuthProxyUserKey in this context, the proxy_user's id can be read later using
// c.MustGet(gin.AuthProxyUserKey).
c.Set(AuthProxyUserKey, proxyUser)
}
}
37 changes: 37 additions & 0 deletions auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,40 @@ func TestBasicAuth401WithCustomRealm(t *testing.T) {
assert.Equal(t, http.StatusUnauthorized, w.Code)
assert.Equal(t, "Basic realm=\"My Custom \\\"Realm\\\"\"", w.Header().Get("WWW-Authenticate"))
}

func TestBasicAuthForProxySucceed(t *testing.T) {
accounts := Accounts{"admin": "password"}
router := New()
router.Use(BasicAuthForProxy(accounts, ""))
router.Any("/*proxyPath", func(c *Context) {
c.String(http.StatusOK, c.MustGet(AuthProxyUserKey).(string))
})

w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/test", nil)
req.Header.Set("Proxy-Authorization", authorizationHeader("admin", "password"))
router.ServeHTTP(w, req)

assert.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, "admin", w.Body.String())
}

func TestBasicAuthForProxy407(t *testing.T) {
called := false
accounts := Accounts{"foo": "bar"}
router := New()
router.Use(BasicAuthForProxy(accounts, ""))
router.Any("/*proxyPath", func(c *Context) {
called = true
c.String(http.StatusOK, c.MustGet(AuthProxyUserKey).(string))
})

w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/test", nil)
req.Header.Set("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("admin:password")))
router.ServeHTTP(w, req)

assert.False(t, called)
assert.Equal(t, http.StatusProxyAuthRequired, w.Code)
assert.Equal(t, "Basic realm=\"Proxy Authorization Required\"", w.Header().Get("Proxy-Authenticate"))
}
3 changes: 2 additions & 1 deletion binding/binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (
MIMEMSGPACK = "application/x-msgpack"
MIMEMSGPACK2 = "application/msgpack"
MIMEYAML = "application/x-yaml"
MIMEYAML2 = "application/yaml"
MIMETOML = "application/toml"
)

Expand Down Expand Up @@ -102,7 +103,7 @@ func Default(method, contentType string) Binding {
return ProtoBuf
case MIMEMSGPACK, MIMEMSGPACK2:
return MsgPack
case MIMEYAML:
case MIMEYAML, MIMEYAML2:
return YAML
case MIMETOML:
return TOML
Expand Down
3 changes: 2 additions & 1 deletion binding/binding_nomsgpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
MIMEMultipartPOSTForm = "multipart/form-data"
MIMEPROTOBUF = "application/x-protobuf"
MIMEYAML = "application/x-yaml"
MIMEYAML2 = "application/yaml"
MIMETOML = "application/toml"
)

Expand Down Expand Up @@ -96,7 +97,7 @@ func Default(method, contentType string) Binding {
return XML
case MIMEPROTOBUF:
return ProtoBuf
case MIMEYAML:
case MIMEYAML, MIMEYAML2:
return YAML
case MIMEMultipartPOSTForm:
return FormMultipart
Expand Down
2 changes: 2 additions & 0 deletions binding/binding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ func TestBindingDefault(t *testing.T) {

assert.Equal(t, YAML, Default("POST", MIMEYAML))
assert.Equal(t, YAML, Default("PUT", MIMEYAML))
assert.Equal(t, YAML, Default("POST", MIMEYAML2))
assert.Equal(t, YAML, Default("PUT", MIMEYAML2))

assert.Equal(t, TOML, Default("POST", MIMETOML))
assert.Equal(t, TOML, Default("PUT", MIMETOML))
Expand Down
5 changes: 4 additions & 1 deletion binding/default_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ func (v *defaultValidator) ValidateStruct(obj any) error {
value := reflect.ValueOf(obj)
switch value.Kind() {
case reflect.Ptr:
return v.ValidateStruct(value.Elem().Interface())
if value.Elem().Kind() != reflect.Struct {
return v.ValidateStruct(value.Elem().Interface())
}
return v.validateStruct(obj)
case reflect.Struct:
return v.validateStruct(obj)
case reflect.Slice, reflect.Array:
Expand Down
8 changes: 8 additions & 0 deletions binding/form_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package binding
import (
"errors"
"fmt"
"mime/multipart"
"reflect"
"strconv"
"strings"
Expand Down Expand Up @@ -235,10 +236,17 @@ func setWithProperType(val string, value reflect.Value, field reflect.StructFiel
switch value.Interface().(type) {
case time.Time:
return setTimeField(val, field, value)
case multipart.FileHeader:
return nil
}
return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface())
case reflect.Map:
return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface())
case reflect.Ptr:
if !value.Elem().IsValid() {
value.Set(reflect.New(value.Type().Elem()))
}
return setWithProperType(val, value.Elem(), field)
default:
return errUnknownType
}
Expand Down
35 changes: 35 additions & 0 deletions binding/form_mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package binding

import (
"mime/multipart"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -43,6 +44,7 @@ func TestMappingBaseTypes(t *testing.T) {
{"zero value", struct{ F uint }{}, "", uint(0)},
{"zero value", struct{ F bool }{}, "", false},
{"zero value", struct{ F float32 }{}, "", float32(0)},
{"file value", struct{ F *multipart.FileHeader }{}, "", &multipart.FileHeader{}},
} {
tp := reflect.TypeOf(tt.value)
testName := tt.name + ":" + tp.Field(0).Type.String()
Expand Down Expand Up @@ -269,6 +271,39 @@ func TestMappingStructField(t *testing.T) {
assert.Equal(t, 9, s.J.I)
}

func TestMappingPtrField(t *testing.T) {
type ptrStruct struct {
Key int64 `json:"key"`
}

type ptrRequest struct {
Items []*ptrStruct `json:"items" form:"items"`
}

var err error

// With 0 items.
var req0 ptrRequest
err = mappingByPtr(&req0, formSource{}, "form")
assert.NoError(t, err)
assert.Empty(t, req0.Items)

// With 1 item.
var req1 ptrRequest
err = mappingByPtr(&req1, formSource{"items": {`{"key": 1}`}}, "form")
assert.NoError(t, err)
assert.Len(t, req1.Items, 1)
assert.EqualValues(t, 1, req1.Items[0].Key)

// With 2 items.
var req2 ptrRequest
err = mappingByPtr(&req2, formSource{"items": {`{"key": 1}`, `{"key": 2}`}}, "form")
assert.NoError(t, err)
assert.Len(t, req2.Items, 2)
assert.EqualValues(t, 1, req2.Items[0].Key)
assert.EqualValues(t, 2, req2.Items[1].Key)
}

func TestMappingMapField(t *testing.T) {
var s struct {
M map[string]int
Expand Down
Loading
Loading