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

feat: add request size limit plugin #528

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions plugins/wasm-go/extensions/request-size-limit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 功能说明
`request-size-limit` 插件实现了限制请求 body 大小的作用,可以用于防止请求 body 过大的请求对网关及上游服务造成影响。

# 配置字段

| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-------------|--------|---------------------------------------------|-----|----------------|
| requestSize | string | 需填写允许的请求体最大大小,单位为 B、KB、MB 或 GB。例如 1KB,2MB 等 | 1MB | 配置允许通过的请求体最大大小 |

# 配置示例

## 限制请求 body 超过 5B 的请求

```yaml
requestSize: 5B
```
配置完毕之后,下列请求将被禁止访问:

```bash
curl -d "123456" http://example.com
```
1 change: 1 addition & 0 deletions plugins/wasm-go/extensions/request-size-limit/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0
19 changes: 19 additions & 0 deletions plugins/wasm-go/extensions/request-size-limit/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module github.com/alibaba/higress/plugins/wasm-go/extensions/request-size-limit

go 1.19

replace github.com/alibaba/higress/plugins/wasm-go => ../..

require (
github.com/alibaba/higress/plugins/wasm-go v0.0.0
github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c
github.com/tidwall/gjson v1.14.3
)

require (
github.com/google/uuid v1.3.0 // indirect
github.com/magefile/mage v1.14.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/wasilibs/nottinygc v0.3.0 // indirect
)
18 changes: 18 additions & 0 deletions plugins/wasm-go/extensions/request-size-limit/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c h1:OCUFXVGixHLfNjg6/QYEhv+jHJ5mRGhpEUVFv9eWPJE=
github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c/go.mod h1:5t/pWFNJ9eMyu/K/Z+OeGhDJ9sN9eCo8fc2pyM/Qjg4=
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/wasilibs/nottinygc v0.3.0 h1:0L1jsJ1MsyN5tdinmFbLfuEA0TnHRcqaBM9pDTJVJmU=
github.com/wasilibs/nottinygc v0.3.0/go.mod h1:oDcIotskuYNMpqMF23l7Z8uzD4TC0WXHK8jetlB3HIo=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
71 changes: 71 additions & 0 deletions plugins/wasm-go/extensions/request-size-limit/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"errors"
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
"github.com/tidwall/gjson"
"regexp"
"strconv"
"strings"
)

func main() {
wrapper.SetCtx(
"request-size-limit",
wrapper.ParseConfigBy(parseConfig),
wrapper.ProcessRequestBodyBy(onHttpRequestBody),
)
}

type RequestSizeLimitConfig struct {
requestSize int64
}

func parseConfig(json gjson.Result, config *RequestSizeLimitConfig, log wrapper.Log) error {
sizeStr := json.Get("requestSize").String()
sizeStr = strings.TrimSpace(sizeStr)
re := regexp.MustCompile("^([+\\-]?\\d+)([a-zA-Z]{0,2})$")
submatchs := re.FindStringSubmatch(sizeStr)
if len(submatchs) == 0 {
config.requestSize = 1024 * 1024
return nil
}
amount, _ := strconv.ParseInt(submatchs[1], 10, 64)
unitStr := submatchs[2]
if len(unitStr) == 0 {
config.requestSize = amount
} else {
unitSizeMap := map[string]int64{
"B": 1,
"KB": 1024,
"MB": 1024 * 1024,
"GB": 1024 * 1024 * 1024,
}
unit, ok := unitSizeMap[unitStr]
if !ok {
return errors.New("Invalid unit size: " + unitStr)
}
config.requestSize = amount * unit
}
return nil
}

func onHttpRequestBody(ctx wrapper.HttpContext, config RequestSizeLimitConfig, body []byte, log wrapper.Log) types.Action {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这样实现是有问题的,这里只能拿到第一段body的length,要实现这个功能需要sdk支持流式处理body,这个还需要改进下才能支持,我先把PR标记为draft了

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这样实现是有问题的,这里只能拿到第一段body的length,要实现这个功能需要sdk支持流式处理body,这个还需要改进下才能支持,我先把PR标记为draft了

了解了,sdk支持流式处理body目前有排期计划支持吗?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if int64(len(body)) > config.requestSize {
proxywasm.SendHttpResponse(413, nil, []byte("The request body is too large"), -1)
return types.ActionContinue
}
return types.ActionContinue
}