Guohao1020 opened a new issue, #10069:
URL: https://github.com/apache/apisix/issues/10069
### Current Behavior
When the java plug-in ext-plugin-post-resp is used, API disabled occurs when
the response body is large. in the context of body_filter_by_lua*, however,
there is no problem on the local computer. Deploy the program to the server and
it will appear.
Error message:
```
lua entry thread aborted: runtime error:
/usr/local/apisix/apisix/plugins/ext-plugin-post-resp.lua:109: API disabled in
the context of body_filter_by_lua*
stack traceback:
coroutine 0:
[C]: in function 'ngx_print'
/usr/local/apisix/apisix/plugins/ext-plugin-post-resp.lua:109: in function
'send_chunk'
/usr/local/apisix/apisix/plugins/ext-plugin-post-resp.lua:132: in function
'send_response'
/usr/local/apisix/apisix/plugins/ext-plugin-post-resp.lua:171: in function
'phase_func'
/usr/local/apisix/apisix/plugin.lua:1097: in function 'common_phase'
/usr/local/apisix/apisix/init.lua:507: in function 'handle_upstream'
/usr/local/apisix/apisix/init.lua:669: in function 'http_access_phase'
access_by_lua(nginx.conf:334):2: in main chunk, client: 11.18.1.47, server:
_, request: "POST /1122/o8k8yu/jrsoap/soa/TradeInfoService HTTP/1.1"
```
Plug-in code:
```
package cn.devops.plugin.filter;
import cn.devops.plugin.constant.CacheNameTimeConstant;
import cn.devops.plugin.constant.GatewayConstants;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.apisix.plugin.runner.HttpRequest;
import org.apache.apisix.plugin.runner.HttpResponse;
import org.apache.apisix.plugin.runner.PostRequest;
import org.apache.apisix.plugin.runner.PostResponse;
import org.apache.apisix.plugin.runner.filter.PluginFilterChain;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
public class WebServiceResponseRewritePluginFilter extends
BaseGatewayPluginFilter {
@Resource
private CacheManager cacheManager;
@Resource(name = "gatewayRedisTemplate")
private RedisTemplate<String, Object> gatewayRedisTemplate;
@Override
public String name() {
return "web-service-response-rewrite";
}
@Override
public void filter(HttpRequest request, HttpResponse response,
PluginFilterChain chain) {
String host = request.getHeader("host");
String requestId = request.getVars("request_id");
gatewayRedisTemplate.opsForValue().set(GatewayConstants.getGatewayRequestHostKey(requestId),
host, 30, TimeUnit.MINUTES);
Cache cache =
cacheManager.getCache(CacheNameTimeConstant.CACHE_REQUEST_HOST);
if (ObjectUtil.isNotNull(cache)) {
cache.put(requestId, host);
}
chain.filter(request, response);
}
@Override
public void postFilter(PostRequest request, PostResponse response,
PluginFilterChain chain) {
String requestId = request.getVars("request_id");
boolean isWsdlXml = false;
String requestUri = request.getVars("request_uri");
if (StrUtil.contains(requestUri, "wsdl")) {
isWsdlXml = true;
}
if (!isWsdlXml) {
chain.postFilter(request, response);
return;
}
String host = null;
Cache cache =
cacheManager.getCache(CacheNameTimeConstant.CACHE_REQUEST_HOST);
if (ObjectUtil.isNotNull(cache)) {
host = cache.get(requestId, String.class);
}
if (StrUtil.isBlank(host)) {
host = (String) gatewayRedisTemplate.opsForValue()
.get(GatewayConstants.getGatewayRequestHostKey(requestId));
}
if (StrUtil.isBlank(host)) {
chain.postFilter(request, response);
return;
}
String newLocation = StrUtil.subBefore(requestUri, "?", false);
try {
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
InputSource inputSource = new InputSource(new
StringReader(request.getBody()));
Document doc = dBuilder.parse(inputSource);
NodeList soapAddressList =
doc.getElementsByTagName("soap:address");
if (soapAddressList.getLength() > 0) {
for (int i = 0; i < soapAddressList.getLength(); i++) {
Element soapAddressElement = (Element)
soapAddressList.item(i);
String location =
soapAddressElement.getAttribute("location");
URL url = new URL(location);
soapAddressElement.setAttribute("location",
url.getProtocol() + "://" + host + newLocation);
}
} else {
chain.postFilter(request, response);
return;
}
javax.xml.transform.TransformerFactory transformerFactory =
javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer transformer =
transformerFactory.newTransformer();
javax.xml.transform.dom.DOMSource source = new
javax.xml.transform.dom.DOMSource(doc);
java.io.StringWriter writer = new java.io.StringWriter();
javax.xml.transform.stream.StreamResult result = new
javax.xml.transform.stream.StreamResult(writer);
transformer.transform(source, result);
String updatedXml = writer.toString();
response.setBody(updatedXml);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
response.setHeader("Content-Type", "text/xml;charset=UTF-8");
chain.postFilter(request, response);
}
@Override
public List<String> requiredVars() {
List<String> vars = new ArrayList<>();
vars.add("remote_addr");
vars.add("server_port");
vars.add("request_id");
vars.add("request_uri");
vars.add("request_method");
vars.add("request_length");
vars.add("status");
return vars;
}
@Override
public Boolean requiredBody() {
return true;
}
@Override
public Boolean requiredRespBody() {
return true;
}
}
```
### Expected Behavior
The upstream request response body was returned, but after using the
plug-in, the request response body was truncated, and I suspect this error
caused the data transfer to be interrupted
### Error Logs
```
2023/08/22 10:34:27 [error] 65#65: *34548 lua entry thread aborted: runtime
error: /usr/local/apisix/apisix/plugins/ext-plugin-post-resp.lua:109: API
disabled in the context of body_filter_by_lua*
stack traceback:
coroutine 0:
[C]: in function 'ngx_print'
/usr/local/apisix/apisix/plugins/ext-plugin-post-resp.lua:109: in function
'send_chunk'
/usr/local/apisix/apisix/plugins/ext-plugin-post-resp.lua:132: in function
'send_response'
/usr/local/apisix/apisix/plugins/ext-plugin-post-resp.lua:171: in function
'phase_func'
/usr/local/apisix/apisix/plugin.lua:1097: in function 'common_phase'
/usr/local/apisix/apisix/init.lua:507: in function 'handle_upstream'
/usr/local/apisix/apisix/init.lua:669: in function 'http_access_phase'
access_by_lua(nginx.conf:334):2: in main chunk, client: 11.18.1.47, server:
_, request: "POST /1122/o8k8yu/jrsoap/soa/TradeInfoService HTTP/1.1", host:
"xx.xxx.xx.xxx:10003"
11.18.1.47 - - [22/Aug/2023:10:34:27 +0800] xx.xxx.xx.xxx:10003 "POST
/1122/o8k8yu/jrsoap/soa/TradeInfoService HTTP/1.1" 200 166436 0.757 "-"
"PostmanRuntime-ApipostRuntime/1.1.0" - - -
"http://xx.xxx.xx.xxx:10003/jrsoap/soa/TradeInfoService"
```
### Steps to Reproduce
1. Create a running apisix image based on the official apisix image, and add
the java plug-in jar package to the image.
2. Run the apisix docker image.
3. Configure routes and add the java ext-plugin-post-resp plugin.
4. Call the interface, simulate the request needs to return a relatively
large packet, about about 1m.
5. The response is truncated, and the apisix log output an error log.
### Environment
- APISIX version (run `apisix version`): 3.3.0
- Operating system (run `uname -a`): Linux apisix-v1-765cb69475-8s4xq
3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 GNU/Linux
- OpenResty / Nginx version (run `openresty -V` or `nginx -V`):
openresty/1.21.4.1
- etcd version, if relevant (run `curl
http://127.0.0.1:9090/v1/server_info`):
{"hostname":"apisix-v1-765cb69475-8s4xq","version":"3.3.0","etcd_version":"3.5.0","id":"cb46e64f-3cf9-47ad-819c-42183c9593e3","boot_time":1692671574}
- APISIX Dashboard version, if relevant: 3.0.1
- Plugin runner version, for issues related to plugin runners: 0.4.0 for java
- LuaRocks version, for installation issues (run `luarocks --version`):
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]