17 Commits

Author SHA1 Message Date
5e677a1e05 fix(net/gclient): fix form field value truncation when uploading files (#4627)
## What does this PR do?

Fixes #4156

When posting form data with file upload, if a field value contains `=`
or `&`, the value was being truncated.

### Example

```go
data := g.Map{
    "file":      "@file:/path/to/file.txt",
    "fieldName": "aaa=1&b=2",
}
client.Post(ctx, "/upload", data)
```

**Expected**: Server receives `fieldName = "aaa=1&b=2"`
**Actual (before fix)**: Server receives `fieldName = "aaa"` (truncated)

## Root Cause Analysis

The issue was caused by three problems in the original code:

### Problem 1: Global URL encoding disable (httputils.go)

```go
// Original code - PROBLEMATIC
if urlEncode {
    for k, v := range m {
        if gstr.Contains(k, fileUploadingKey) || gstr.Contains(gconv.String(v), fileUploadingKey) {
            urlEncode = false  // Disables URL encoding for ALL values!
            break
        }
    }
}
```

When any value contained `@file:`, URL encoding was disabled for ALL
values, causing `"aaa=1&b=2"` to remain unencoded. The `&` character was
then treated as a parameter separator.

### Problem 2: Split on all `=` characters (gclient_request.go)

```go
// Original code - PROBLEMATIC
array := strings.Split(item, "=")  // Splits on ALL '=' characters
```

This caused `"fieldName=aaa=1"` to be split into `["fieldName", "aaa",
"1"]`.

### Problem 3: No URL decoding for field values

URL-encoded values were written directly to the multipart form without
decoding.

## Solution

### Fix 1: Remove global URL encoding disable

Only `@file:` prefixed values are kept unencoded for file upload
detection. Other values are properly URL-encoded.

### Fix 2: Use SplitN to limit split count

```go
array := strings.SplitN(item, "=", 2)  // Only split on first '='
```

### Fix 3: Add URL decoding for field values

```go
if v, err := gurl.Decode(fieldValue); err == nil {
    fieldValue = v
}
```

## Compatibility Analysis

| Scenario | Before | After | Compatible |
|----------|--------|-------|------------|
| Normal form POST (no file upload) |  Works |  Works |  Yes |
| File upload + normal field values |  Works |  Works |  Yes |
| File upload + field values containing `=` or `&` |  Truncated | 
Works |  Fixed |
| Field value is `@file:` (no path) |  Works |  Works |  Yes |
| Field value starts with `@file:` but file doesn't exist |  Error | 
Error |  Yes |
| User sends pre-encoded value like `"aaa%3D1"` |  Works |  Works | 
Yes |
| Content-Type: application/json |  Works |  Works |  Yes |
| Content-Type: application/xml |  Works |  Works |  Yes |

### Breaking Change Assessment

**No breaking changes.** The fix only affects the file upload scenario
where field values contain special characters (`=`, `&`). Previously
this scenario was broken, now it works correctly.

### Edge Cases

1. **Literal `@file:` value**: GoFrame treats `@file:` as a special
marker for file upload. This is a framework design decision and remains
unchanged.

2. **URL decode failure**: If URL decoding fails (e.g., invalid `%XX`
sequence), the original value is preserved.

## Test Coverage

Added comprehensive tests covering:

- `Test_Issue4156` - Basic fix verification
- `Test_Issue4156_MultipleSpecialChars` - Multiple `=`, `&`, `%`, `+`,
spaces
- `Test_Issue4156_MultipleFields` - Multiple fields with special
characters
- `Test_Issue4156_NoFileUpload` - Normal POST without file upload
- `Test_Issue4156_PreEncodedValue` - Pre-encoded values like `%3D`
- `Test_Issue4156_EmptyAndSpecialValues` - Edge cases (`=` at start/end,
only special chars)
- `TestBuildParams_*` - httputil.BuildParams comprehensive tests

All tests pass, including existing `Test_Issue3748` which tests the
`@file:` marker handling.

## Files Changed

- `internal/httputil/httputils.go` - Remove global URL encoding disable,
adjust `@file:` condition
- `internal/httputil/httputils_test.go` - Add comprehensive BuildParams
tests
- `net/gclient/gclient_request.go` - Use SplitN, add URL decoding
- `net/gclient/gclient_z_unit_issue_test.go` - Add Issue 4156 test cases
2026-01-19 13:05:44 +08:00
613
2744fe2212 fix(net/gclient): fix content-type 'application/json;charset=utf-8' … (#4369)
fix(net/gclient): fix content-type 'application/json;charset=utf-8' can
not match `application/json`

---------

Co-authored-by: houseme <housemecn@gmail.com>
2025-10-15 16:14:33 +08:00
ee24da4e72 refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.

**Type alias migration to `any`:**

* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)

**Generated code and templates:**

* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)

**Container and utility updates:**

* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)

These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
7ffdff37e4 chore: upgrade golangci-lint configuration and optimize codebase (#4236)
This PR includes the following changes:

- **Upgrade `.golangci.yml`**: Updated the configuration file to align
with the latest golangci-lint version, ensuring compatibility and
leveraging new features.
- **Refactor GitHub Action workflow**: Modified `golangci-lint.yml` in
the GitHub Actions workflow to reflect the updated configuration and
improve CI performance.
- **Codebase optimization**: Refactored code to address issues and
warnings raised by the updated golangci-lint rules, including:
  - Improved function length and complexity.
  - Enhanced error handling and variable naming conventions.
- Fixed minor issues such as unused imports and formatting
inconsistencies.

These changes aim to maintain code quality, ensure compatibility with
the latest tools, and improve overall maintainability.
2025-08-22 13:29:09 +08:00
76783fd72b fix(net/gclient): panic when containing @file: parameter value in json post request (#3775) 2024-09-25 10:37:32 +08:00
8669512f42 feat: add metric feature support in goframe (#3138) 2024-03-24 21:18:30 +08:00
33584506ab fix issue: request body was closed while retrying in callRequest method (#3199) 2023-12-14 14:18:31 +08:00
bb9cd37fab add SetNoUrlEncode/NoUrlEncode functions for gclient.Client (#3041) 2023-10-17 21:19:59 +08:00
53e5a04073 change minimum golang version from v1.15 to v1.18 (#2820) 2023-08-01 21:15:28 +08:00
80d57ed8f9 add postForm with multi data content type support (#2508) 2023-03-14 09:57:22 +08:00
1793bf0863 add golangci feature to guarantee codes quality (#2229) 2022-11-01 20:12:21 +08:00
6f5058c9b6 add x-url-path feature for ghttp.Server 2022-02-22 14:12:09 +08:00
7ac9c46f12 mark underlying PostForm function deprecated for gclient.Client 2022-01-25 23:01:35 +08:00
d4cb1666e5 improve package gclient for constants 2022-01-10 16:42:30 +08:00
fab17f89c4 fix issue in ut for package gsha1/gclient/ghttp/gregex 2021-12-23 00:34:02 +08:00
ce93b625d4 change errors wrapped by gerror.Wrap with error stack info for all packages 2021-12-21 22:59:14 +08:00
8de176d73f move package /net/ghttp/internal/client as /net/gclient 2021-12-03 23:32:00 +08:00