apisix icon indicating copy to clipboard operation
apisix copied to clipboard

bug: golang plugin fails to get big body

Open cod-soap opened this issue 2 years ago • 9 comments

Current Behavior

在ext-plugin-post-resp 中注册了一个golang插件,来捕获下载请求,在下载文件较大时会报错,代码片段: (Registered a golang plugin in ext-plugin-post-resp to capture download requests and report errors when downloading large files, code snippet)

func (f FileRetentionPlugin) ResponseFilter(conf interface{}, w pkgHTTP.Response) {
	...
	retentionConfig := conf.(FileRetentionConfig)
	if !retentionConfig.Enable {
		return
	}

	contentType := w.Header().Get("Content-Type")
	w.Header().Set("X-Content-Type", contentType)

	body, err := w.ReadBody()
	if err != nil {
		log.Errorf("get body err:%v", err)
		return
	}
	if !ifDownload(contentType, body) {
		return
	}
	...
}

Expected Behavior

No response

Error Logs

2023-11-06T03:14:23.587Z INFO server/server.go:115 Client connected (unix) 2023-11-06T03:14:23.587Z INFO server/server.go:115 Client connected (unix) 2023-11-06T03:14:23.588Z INFO server/server.go:131 receive rpc type: 4 data length: 544 2023-11-06T03:14:23.588Z INFO plugin/plugin.go:185 run plugin file_retention_plugin 2023-11-06T03:14:23.693Z INFO http/response.go:97 receive rpc type: 3 data length: 5680672 2023-11-06T03:14:23.696Z ERROR util/msg.go:56 read: truncated, only get the first 219260 bytes github.com/apache/apisix-go-plugin-runner/internal/util.ReadErr F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/util/msg.go:56 github.com/apache/apisix-go-plugin-runner/internal/http.(*Response).askExtraInfo F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/http/response.go:101 github.com/apache/apisix-go-plugin-runner/internal/http.(*Response).ReadBody F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/http/response.go:182 asdsec.com/asec/platform/app/dynamic_strategy_engine/biz/download_retained.FileRetentionPlugin.ResponseFilter F:/code/go/src/asec-platform/asec-platform/app/dynamic_strategy_engine/biz/download_retained/retained_plugin.go:77 github.com/apache/apisix-go-plugin-runner/internal/plugin.(*responsePhase).filter F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/plugin/plugin.go:187 github.com/apache/apisix-go-plugin-runner/internal/plugin.HTTPRespCall F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/plugin/plugin.go:222 github.com/apache/apisix-go-plugin-runner/internal/server.glob..func3 F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/server/server.go:55 github.com/apache/apisix-go-plugin-runner/internal/server.dispatchRPC F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/server/server.go:85 github.com/apache/apisix-go-plugin-runner/internal/server.handleConn F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/server/server.go:139 2023-11-06T03:14:23.698Z ERROR download_retained/retained_plugin.go:79 get body err:The connection is closed asdsec.com/asec/platform/app/dynamic_strategy_engine/biz/download_retained.FileRetentionPlugin.ResponseFilter F:/code/go/src/asec-platform/asec-platform/app/dynamic_strategy_engine/biz/download_retained/retained_plugin.go:79 github.com/apache/apisix-go-plugin-runner/internal/plugin.(*responsePhase).filter F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/plugin/plugin.go:187 github.com/apache/apisix-go-plugin-runner/internal/plugin.HTTPRespCall F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/plugin/plugin.go:222 github.com/apache/apisix-go-plugin-runner/internal/server.glob..func3 F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/server/server.go:55 github.com/apache/apisix-go-plugin-runner/internal/server.dispatchRPC F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/server/server.go:85 github.com/apache/apisix-go-plugin-runner/internal/server.handleConn F:/code/go/pkg/mod/github.com/apache/[email protected]/internal/server/server.go:139

Steps to Reproduce

1.docker部署apisix 3.6.0 2.golang插件(0.5.0) 注册到路由 3.插件代码片段如上 4.在文件较小时,代码能够正常工作,文件较大时就会报错

(1.docker deployment apisix 3.6.0 2.golang plugin (0.5.0) register to the route 3.plugin code snippet as above 4. In the file is small, the code can work properly, when the file is large, it will report errors)

Environment

  • APISIX version (run apisix version):3.6.0
  • Operating system (run uname -a):Linux d58a11eab144 5.15.0-78-generic Ubuntu SMP Fri Jul 7 15:25:09 UTC 2023 x86_64 GNU/Linux
  • OpenResty / Nginx version (run openresty -V or nginx -V):
  • etcd version, if relevant (run curl http://127.0.0.1:9090/v1/server_info):
  • APISIX Dashboard version, if relevant:
  • Plugin runner version, for issues related to plugin runners:0.5.0
  • LuaRocks version, for installation issues (run luarocks --version):

cod-soap avatar Nov 06 '23 03:11 cod-soap

是不是分段传输chunk的原因? 我需要在插件代码中手动拼接chunk?但是golang插件中的Response接口没有提供任何拼接chunk的方法? (Is it the segmented transmission of chunks? I need to manually splice the chunks in the plugin code? but the Response interface in the golang plugin doesn't provide any method to splice the chunks?)

cod-soap avatar Nov 06 '23 08:11 cod-soap

@jiangfucheng please help to check

monkeyDluffy6017 avatar Dec 12 '23 09:12 monkeyDluffy6017

@cod-soap Hi, thanks for your report, but I can't reproduce this bug in my local env, can you provide detailed steps to reproduce this bug? (Include the go-plugin code, APISIX configuration, upstream server code, etc.)

jiangfucheng avatar Dec 12 '23 12:12 jiangfucheng

是不是分段传输chunk的原因? 我需要在插件代码中手动拼接chunk?但是golang插件中的Response接口没有提供任何拼接chunk的方法? (Is it the segmented transmission of chunks? I need to manually splice the chunks in the plugin code? but the Response interface in the golang plugin doesn't provide any method to splice the chunks?)

APISIX will auto-combine all chunks and then send them to the go-plugin-runner using one RPC call. You can read the related code in blew link if you are interested in it.

https://github.com/apache/apisix/blob/4db435ee38b425da6364ad41aa9c019046190d87/apisix/plugins/ext-plugin/init.lua#L317-L323

jiangfucheng avatar Dec 12 '23 12:12 jiangfucheng

I encountered the same problem. I looked at the code of the Lua plug-in. The body is read from ctx.body_reader, and my error location is because go-runner judges that the read is less than what needs to be read, and then an error is reported. Yes, did ctx.body_reader impose restrictions on the size of the body?

liyuq6 avatar Dec 27 '23 08:12 liyuq6

image

liyuq6 avatar Dec 27 '23 08:12 liyuq6

image

liyuq6 avatar Dec 27 '23 08:12 liyuq6

@jiangfucheng can you help to look at this issue

monkeyDluffy6017 avatar Jan 04 '24 02:01 monkeyDluffy6017

This is not a bug in APISIX, but a bug in the go-plugin-runner. It has already been fixed in https://github.com/apache/apisix-go-plugin-runner/pull/124

ccdeville avatar Dec 02 '25 13:12 ccdeville