alibaba / higress

🤖 AI Gateway | AI Native API Gateway
https://higress.io
Apache License 2.0
3.18k stars 503 forks source link

wasm插件中onHttpRequestBody方法似乎没有被调用 #1467

Closed xunull closed 3 hours ago

xunull commented 4 hours ago

If you are reporting any crash or any potential security issue, do not open an issue in this repo. Please report the issue via ASRC(Alibaba Security Response Center) where the issue will be triaged appropriately.

Ⅰ. Issue Description

我把https://higress.cn/docs/ebook/wasm14/ 这里的一个easy-logger的wasm代码进行了一次本地环境的测试 插件中实现了onHttpRequestHeaders,onHttpRequestBody,onHttpResponseHeaders,onHttpResponseBody四个方法 但是我观察一个请求过去后 只有三个方法输出了日志onHttpRequestHeaders onHttpResponseHeaders onHttpResponseBody onHttpRequestBody 并没有输出日志 看起来像是没有被调用

Ⅱ. Describe what happened

image

Ⅳ. How to reproduce it (as minimally and precisely as possible)

使用的main.go

package main

import (
    "github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
    "github.com/higress-group/proxy-wasm-go-sdk/proxywasm/types"
    "github.com/tidwall/gjson"
)

func main() {
    wrapper.SetCtx(
        // 插件名称
        "easy-logger",
        // 设置自定义函数解析插件配置
        wrapper.ParseConfigBy(parseConfig),
        // 设置自定义函数处理请求头
        wrapper.ProcessRequestHeadersBy(onHttpRequestHeaders),
        // 设置自定义函数处理请求体
        wrapper.ProcessRequestBodyBy(onHttpRequestBody),
        // 设置自定义函数处理响应头
        wrapper.ProcessResponseHeadersBy(onHttpResponseHeaders),
        // 设置自定义函数处理响应体
        wrapper.ProcessResponseBodyBy(onHttpResponseBody),
        // 设置自定义函数处理流式请求体
        //wrapper.ProcessStreamingRequestBodyBy(onHttpStreamingRequestBody),
        // 设置自定义函数处理流式响应体
        //wrapper.ProcessStreamingResponseBodyBy(onHttpStreamingResponseBody),
    )
}

// 自定义插件配置
type LoggerConfig struct {
    // 是否打印请求
    request bool
    // 是否打印响应
    response bool
    // 打印响应状态码,* 表示打印所有状态响应,500,502,503 表示打印 HTTP 500、502、503 状态响应,默认是 *
    responseStatusCodes string
}

func parseConfig(json gjson.Result, config *LoggerConfig, log wrapper.Log) error {
    log.Debugf("parseConfig()")
    config.request = json.Get("request").Bool()
    config.response = json.Get("response").Bool()
    config.responseStatusCodes = json.Get("responseStatusCodes").String()
    if config.responseStatusCodes == "" {
        config.responseStatusCodes = "*"
    }
    log.Debugf("parse config:%v", config)
    return nil
}

func onHttpRequestHeaders(ctx wrapper.HttpContext, config LoggerConfig, log wrapper.Log) types.Action {
    log.Debugf("onHttpRequestHeaders()")
    return types.ActionContinue
}

func onHttpRequestBody(ctx wrapper.HttpContext, config LoggerConfig, body []byte, log wrapper.Log) types.Action {
    log.Debugf("onHttpRequestBody()")
    return types.ActionContinue
}

func onHttpResponseBody(ctx wrapper.HttpContext, config LoggerConfig, body []byte, log wrapper.Log) types.Action {
    log.Debugf("onHttpResponseBody()")
    return types.ActionContinue
}

func onHttpResponseHeaders(ctx wrapper.HttpContext, config LoggerConfig, log wrapper.Log) types.Action {
    log.Debugf("onHttpResponseHeaders()")
    return types.ActionContinue
}

使用的docker-compose.yaml

version: '3.7'
services:
  envoy:
    image: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/gateway:v1.4.0-rc.1
    entrypoint: /usr/local/bin/envoy
    # 注意这里对wasm开启了debug级别日志,正式部署时则默认info级别
    command: -c /etc/envoy/envoy.yaml --component-log-level wasm:debug
    depends_on:
      - httpbin
    networks:
      - wasmtest
    ports:
      - "12355:10000"
    volumes:
      - ./envoy.yaml:/etc/envoy/envoy.yaml
      - ./main.wasm:/etc/envoy/main.wasm

  httpbin:
    image: kennethreitz/httpbin:latest
    networks:
      - wasmtest
    ports:
      - "12345:80"

networks:
  wasmtest: {}

使用的envoy.yaml

admin:
  address:
    socket_address:
      protocol: TCP
      address: 0.0.0.0
      port_value: 9901
static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 10000
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                scheme_header_transformation:
                  scheme_to_overwrite: https
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: local_service
                      domains: ["*"]
                      routes:
                        - match:
                            prefix: "/"
                          route:
                            cluster: httpbin
                http_filters:
                  - name: wasmdemo
                    typed_config:
                      "@type": type.googleapis.com/udpa.type.v1.TypedStruct
                      type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
                      value:
                        config:
                          name: wasmdemo
                          vm_config:
                            runtime: envoy.wasm.runtime.v8
                            code:
                              local:
                                filename: /etc/envoy/main.wasm
                          configuration:
                            "@type": "type.googleapis.com/google.protobuf.StringValue"
                            value: |
                              {
                                "request": true,
                                "response": true,
                                "responseStatusCodes": "200,500,502,503"
                              }
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  clusters:
    - name: httpbin
      connect_timeout: 30s
      type: LOGICAL_DNS
      # Comment out the following line to test on v6 networks
      dns_lookup_family: V4_ONLY
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: httpbin
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: httpbin
                      port_value: 80

使用的编译命令: tinygo build -o main.wasm -scheduler=none -target=wasi -gc=custom -tags="custommalloc nottinygc_finalizer" ./

Ⅵ. Environment:

johnlanni commented 3 hours ago

只有存在请求body时,才会进到onHttpRequestBody的