This is an automated email from the ASF dual-hosted git repository.
nic-6443 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 5f345688b revert: drop configurable request JSON libraries (#13449)
5f345688b is described below
commit 5f345688b449f7537e6d029664ef61734dc425a6
Author: Nic <[email protected]>
AuthorDate: Mon Jun 1 16:28:41 2026 +0800
revert: drop configurable request JSON libraries (#13449)
---
.devcontainer/Dockerfile | 2 +-
Makefile | 11 +-
apisix-master-0.rockspec | 2 -
apisix/cli/config.lua | 1 -
apisix/cli/schema.lua | 4 -
apisix/core/request.lua | 4 +-
apisix/core/request_json.lua | 98 ------------
apisix/plugins/ai-transport/auth-aws.lua | 4 +-
apisix/plugins/ai-transport/http.lua | 3 +-
ci/common.sh | 13 +-
ci/linux_apisix_current_luarocks_runner.sh | 4 -
conf/config.yaml.example | 4 -
docker/debian-dev/Dockerfile | 4 -
docs/en/latest/plugins/ai-proxy.md | 23 ---
docs/zh/latest/plugins/ai-proxy.md | 23 ---
t/chaos/utils/Dockerfile | 2 -
t/core/config-default.t | 2 -
t/core/request.t | 248 +----------------------------
t/plugin/ai-proxy-multi.t | 4 +-
t/plugin/ai-proxy.t | 4 +-
utils/install-dependencies.sh | 8 -
utils/install-rust-toolchain.sh | 149 -----------------
22 files changed, 16 insertions(+), 601 deletions(-)
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 9ae08b865..4402db7e8 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -21,7 +21,7 @@ RUN apt update && export DEBIAN_FRONTEND=noninteractive \
&& apt install -y sudo git make gcc tini
COPY Makefile .requirements apisix-master-0.rockspec ./
-COPY utils/install-dependencies.sh utils/install-rust-toolchain.sh
utils/linux-install-luarocks.sh utils/
+COPY utils/install-dependencies.sh utils/linux-install-luarocks.sh utils/
RUN make install-runtime
diff --git a/Makefile b/Makefile
index 24a160a2c..5e56349cc 100644
--- a/Makefile
+++ b/Makefile
@@ -137,16 +137,7 @@ deps: install-runtime
$(ENV_LUAROCKS) config $(ENV_LUAROCKS_FLAG_LOCAL)
variables.OPENSSL_LIBDIR $(addprefix $(ENV_OPENSSL_PREFIX), /lib); \
$(ENV_LUAROCKS) config $(ENV_LUAROCKS_FLAG_LOCAL)
variables.OPENSSL_INCDIR $(addprefix $(ENV_OPENSSL_PREFIX), /include); \
$(ENV_LUAROCKS) config $(ENV_LUAROCKS_FLAG_LOCAL)
variables.YAML_DIR $(ENV_LIBYAML_INSTALL_PREFIX); \
- rustup_home=$${RUSTUP_HOME:-}; \
- cargo_home=$${CARGO_HOME:-}; \
- if [ -z "$$rustup_home" ]; then \
- if [ -d /usr/local/rustup ] && [ -w /usr/local/rustup
]; then rustup_home=/usr/local/rustup; else rustup_home=$$HOME/.rustup; fi; \
- fi; \
- if [ -z "$$cargo_home" ]; then \
- if [ -d /usr/local/cargo ] && [ -w /usr/local/cargo ];
then cargo_home=/usr/local/cargo; else cargo_home=$$HOME/.cargo; fi; \
- fi; \
- RUSTUP_HOME=$$rustup_home CARGO_HOME=$$cargo_home
PATH=$$cargo_home/bin:$$PATH \
- $(ENV_LUAROCKS) install apisix-master-0.rockspec --tree
deps --only-deps $(ENV_LUAROCKS_SERVER_OPT); \
+ $(ENV_LUAROCKS) install apisix-master-0.rockspec --tree deps
--only-deps $(ENV_LUAROCKS_SERVER_OPT); \
else \
$(call func_echo_warn_status, "WARNING: You're not using
LuaRocks 3.x; please remove the luarocks and reinstall it via
https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh");
\
exit 1; \
diff --git a/apisix-master-0.rockspec b/apisix-master-0.rockspec
index 283d4b961..2279f3767 100644
--- a/apisix-master-0.rockspec
+++ b/apisix-master-0.rockspec
@@ -87,8 +87,6 @@ dependencies = {
"api7-lua-resty-aws == 2.0.2-1",
"multipart = 0.5.11-1",
"luautf8 = 0.2.0-1",
- "lua-qjson = 0.1.0-1",
- "api7-lua-resty-simdjson = 0.1.1-1",
}
build = {
diff --git a/apisix/cli/config.lua b/apisix/cli/config.lua
index 8088f1bdc..479712b37 100644
--- a/apisix/cli/config.lua
+++ b/apisix/cli/config.lua
@@ -29,7 +29,6 @@ local _M = {
enable_server_tokens = true,
extra_lua_path = "",
extra_lua_cpath = "",
- request_body_json_lib = "simdjson",
proxy_cache = {
cache_ttl = "10s",
zones = {
diff --git a/apisix/cli/schema.lua b/apisix/cli/schema.lua
index 2d9ed30a2..8a70bda8b 100644
--- a/apisix/cli/schema.lua
+++ b/apisix/cli/schema.lua
@@ -92,10 +92,6 @@ local config_schema = {
},
}
},
- request_body_json_lib = {
- enum = {"cjson", "simdjson", "qjson"},
- default = "simdjson",
- },
proxy_cache = {
type = "object",
properties = {
diff --git a/apisix/core/request.lua b/apisix/core/request.lua
index c07422873..9989d955e 100644
--- a/apisix/core/request.lua
+++ b/apisix/core/request.lua
@@ -21,7 +21,7 @@
local lfs = require("lfs")
local log = require("apisix.core.log")
-local request_json = require("apisix.core.request_json")
+local json = require("apisix.core.json")
local io = require("apisix.core.io")
local multipart = require("multipart")
local core_str = require("apisix.core.string")
@@ -362,7 +362,7 @@ local function get_request_body_table(ctx, content_type)
if not body then
return nil, "could not get body: " .. (body_err or "request body
is empty")
end
- result, err = request_json.decode(body)
+ result, err = json.decode(body)
if not result then
return nil, "could not parse JSON request body: " .. (err or
"invalid JSON")
end
diff --git a/apisix/core/request_json.lua b/apisix/core/request_json.lua
deleted file mode 100644
index d635681f6..000000000
--- a/apisix/core/request_json.lua
+++ /dev/null
@@ -1,98 +0,0 @@
---
--- Licensed to the Apache Software Foundation (ASF) under one or more
--- contributor license agreements. See the NOTICE file distributed with
--- this work for additional information regarding copyright ownership.
--- The ASF licenses this file to You under the Apache License, Version 2.0
--- (the "License"); you may not use this file except in compliance with
--- the License. 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.
---
-
-local config_local = require("apisix.core.config_local")
-local core_json = require("apisix.core.json")
-local qjson = require("qjson")
-local simdjson = require("resty.simdjson")
-local pcall = pcall
-local tostring = tostring
-
-
-local simdjson_parser, simdjson_err = simdjson.new()
-assert(simdjson_parser, simdjson_err)
-local configured_name
-
-local _M = {}
-
-
-local function qjson_decode(str)
- local ok, decoded, err = pcall(qjson.decode, str)
- if not ok then
- return nil, tostring(decoded)
- end
-
- if decoded == nil then
- return nil, err
- end
-
- ok, decoded, err = pcall(qjson.materialize, decoded)
- if not ok then
- return nil, tostring(decoded)
- end
-
- if decoded == nil then
- return nil, err
- end
-
- return decoded
-end
-
-
-local function qjson_encode(data)
- local ok, encoded, err = pcall(qjson.encode, data)
- if not ok then
- return nil, tostring(encoded)
- end
-
- return encoded, err
-end
-
-
-function _M.decode(str)
- if not configured_name then
- configured_name =
config_local.local_conf().apisix.request_body_json_lib
- end
-
- local name = configured_name
- if name == "cjson" then
- return core_json.decode(str)
- end
-
- if name == "simdjson" then
- return simdjson_parser:decode(str)
- end
-
- return qjson_decode(str)
-end
-
-
-function _M.encode(data)
- if not configured_name then
- configured_name =
config_local.local_conf().apisix.request_body_json_lib
- end
-
- if configured_name == "qjson" then
- return qjson_encode(data)
- end
-
- -- simdjson encode is slower than cjson, so simdjson mode only uses it for
decode.
- return core_json.encode(data)
-end
-
-
-return _M
diff --git a/apisix/plugins/ai-transport/auth-aws.lua
b/apisix/plugins/ai-transport/auth-aws.lua
index ae01c0cd4..83594d3d7 100644
--- a/apisix/plugins/ai-transport/auth-aws.lua
+++ b/apisix/plugins/ai-transport/auth-aws.lua
@@ -20,7 +20,7 @@
require("resty.aws.config") -- reads env vars before init
local aws = require("resty.aws")
-local request_json = require("apisix.core.request_json")
+local core = require("apisix.core")
local signer = require("resty.aws.request.sign")
local ngx = ngx
local ngx_escape_uri = ngx.escape_uri
@@ -81,7 +81,7 @@ function _M.sign_request(params, aws_conf, region)
-- Serialize body to JSON string (SigV4 signs the exact bytes)
if type(params.body) == "table" then
- local body_str, err = request_json.encode(params.body)
+ local body_str, err = core.json.encode(params.body)
if not body_str then
return "failed to encode body: " .. (err or "")
end
diff --git a/apisix/plugins/ai-transport/http.lua
b/apisix/plugins/ai-transport/http.lua
index 242efa1ad..bf8a06c1a 100644
--- a/apisix/plugins/ai-transport/http.lua
+++ b/apisix/plugins/ai-transport/http.lua
@@ -19,7 +19,6 @@
-- Provides HTTP client lifecycle management for AI provider requests.
local core = require("apisix.core")
-local request_json = require("apisix.core.request_json")
local http = require("resty.http")
local ngx_now = ngx.now
local pairs = pairs
@@ -108,7 +107,7 @@ function _M.request(params, timeout)
req_json = params.body
else
local err
- req_json, err = request_json.encode(params.body)
+ req_json, err = core.json.encode(params.body)
if not req_json then
httpc:close()
return nil, "encode body: " .. (err or "unknown"), {
diff --git a/ci/common.sh b/ci/common.sh
index 30ea4a46f..b99819b5e 100644
--- a/ci/common.sh
+++ b/ci/common.sh
@@ -17,11 +17,6 @@
set -ex
-_APISIX_UTILS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/utils"
-# shellcheck source=../utils/install-rust-toolchain.sh
-. "${_APISIX_UTILS_DIR}/install-rust-toolchain.sh"
-unset _APISIX_UTILS_DIR
-
export_version_info() {
source ./.requirements
}
@@ -37,10 +32,6 @@ export_or_prefix() {
create_lua_deps() {
echo "Create lua deps"
- export RUSTUP_HOME="${RUSTUP_HOME:-/usr/local/rustup}"
- export CARGO_HOME="${CARGO_HOME:-/usr/local/cargo}"
- export PATH="${CARGO_HOME}/bin:${PATH}"
-
make deps
# just for jwt-auth test
@@ -186,15 +177,13 @@ GRPC_SERVER_EXAMPLE_VER=20210819
linux_get_dependencies () {
apt update
- apt install -y cargo cpanminus build-essential libncurses5-dev
libreadline-dev libssl-dev perl libpcre3 libpcre3-dev libpcre2-dev xz-utils
redis-tools
- install_rust_toolchain
+ apt install -y cpanminus build-essential libncurses5-dev libreadline-dev
libssl-dev perl libpcre3 libpcre3-dev libpcre2-dev xz-utils redis-tools
apt remove -y curl
apt-get install -y libyaml-dev
wget
https://github.com/mikefarah/yq/releases/download/3.4.1/yq_linux_amd64 -O
/usr/bin/yq && sudo chmod +x /usr/bin/yq
# install curl with http3 support
install_curl
-
}
function start_grpc_server_example() {
diff --git a/ci/linux_apisix_current_luarocks_runner.sh
b/ci/linux_apisix_current_luarocks_runner.sh
index 8a8f44514..94abcd466 100755
--- a/ci/linux_apisix_current_luarocks_runner.sh
+++ b/ci/linux_apisix_current_luarocks_runner.sh
@@ -43,10 +43,6 @@ script() {
sudo rm -rf /usr/local/share/lua/5.1/apisix
- export RUSTUP_HOME="${RUSTUP_HOME:-/usr/local/rustup}"
- export CARGO_HOME="${CARGO_HOME:-/usr/local/cargo}"
- export PATH="${CARGO_HOME}/bin:${PATH}"
-
# install APISIX with local version
luarocks install apisix-master-0.rockspec --only-deps > build.log 2>&1 ||
(cat build.log && exit 1)
luarocks make apisix-master-0.rockspec > build.log 2>&1 || (cat build.log
&& exit 1)
diff --git a/conf/config.yaml.example b/conf/config.yaml.example
index 3a29d3dc0..f092b6bf5 100644
--- a/conf/config.yaml.example
+++ b/conf/config.yaml.example
@@ -44,10 +44,6 @@ apisix:
enable_server_tokens: true # If true, show APISIX version in the
`Server` response header.
extra_lua_path: "" # Extend lua_package_path to load
third-party code.
extra_lua_cpath: "" # Extend lua_package_cpath to load
third-party code.
- request_body_json_lib: simdjson # JSON library used to decode request
bodies parsed by core.request.
- # Also controls AI upstream request
body encoding.
- # The value is resolved per worker.
Reload or restart workers after changing it.
- # Can be cjson, simdjson, or qjson.
qjson is experimental.
# lua_module_hook: "my_project.my_hook" # Hook module used to inject
third-party code into APISIX.
proxy_cache: # Proxy Caching configuration
diff --git a/docker/debian-dev/Dockerfile b/docker/debian-dev/Dockerfile
index 7b3487e3d..60bc8b1f3 100644
--- a/docker/debian-dev/Dockerfile
+++ b/docker/debian-dev/Dockerfile
@@ -21,9 +21,6 @@ ARG CODE_PATH
ENV DEBIAN_FRONTEND=noninteractive
ENV ENV_INST_LUADIR=/usr/local/apisix
-ENV RUSTUP_HOME=/usr/local/rustup
-ENV CARGO_HOME=/usr/local/cargo
-ENV PATH=/usr/local/cargo/bin:$PATH
COPY ${CODE_PATH} /apisix
@@ -45,7 +42,6 @@ RUN set -x \
pkg-config \
libssl-dev \
zlib1g-dev \
- && bash -c '. ./utils/install-rust-toolchain.sh && install_rust_toolchain'
\
&& ls -al \
&& make deps \
&& mkdir -p ${ENV_INST_LUADIR} \
diff --git a/docs/en/latest/plugins/ai-proxy.md
b/docs/en/latest/plugins/ai-proxy.md
index e3e1b593a..cb7347a8a 100644
--- a/docs/en/latest/plugins/ai-proxy.md
+++ b/docs/en/latest/plugins/ai-proxy.md
@@ -42,29 +42,6 @@ The `ai-proxy` Plugin simplifies access to LLM and embedding
models by transform
In addition, the Plugin also supports logging LLM request information in the
access log, such as token usage, model, time to the first response, and more.
These log entries are also consumed by logging plugins such as `http-logger`
and `kafka-logger`. These options do not affect `error.log`.
-## Request Body JSON Library
-
-APISIX uses `apisix.request_body_json_lib` to select the JSON library for
request body parsing through `core.request.get_request_body_table`. This is a
core request helper, so the setting affects every Plugin that reads JSON
request bodies through this API, including `ai-proxy` and other AI Plugins. It
also controls JSON encoding for AI upstream request bodies.
-
-```yaml title="conf/config.yaml"
-apisix:
- request_body_json_lib: simdjson
-```
-
-Valid values are `cjson`, `simdjson`, and `qjson`. The default is `simdjson`.
When `simdjson` is configured, APISIX uses `simdjson` to decode request bodies
and `cjson` to encode AI upstream request bodies. `qjson` is available as an
experimental option for users who want to explicitly opt in to the
highest-throughput path.
-
-The value is resolved per worker. Reload or restart APISIX workers after
changing it.
-
-The following benchmark data was measured with large OpenAI chat completion
payloads and `post_arg.model` route matching, which triggers request body JSON
parsing during route matching. The `qjson` result uses qjson for both request
body decode and AI upstream request body encode.
-
-| Payload | `cjson` QPS | `simdjson` QPS | `qjson` QPS | `simdjson` vs `cjson`
| `qjson` vs `cjson` |
-|---------|-------------|----------------|-------------|------------------------|--------------------|
-| 1 MB | 173 | 250 | 604 | 1.45x
| 3.41x |
-| 5 MB | 38 | 48-54 | 146-147 | 1.24x
| 3.85x |
-| 10 MB | 17.4 | 27.4 | 77.9 | 1.58x
| 4.48x |
-
-Use `simdjson` when you want to accelerate request body decoding while keeping
`cjson` encoding semantics for AI upstream request bodies. `qjson` showed the
best throughput in this benchmark, but it is experimental and should be
selected explicitly after evaluating compatibility for your workloads.
-
## Request Format
| Name | Type | Required | Description
|
diff --git a/docs/zh/latest/plugins/ai-proxy.md
b/docs/zh/latest/plugins/ai-proxy.md
index ba01056c7..8d7b18102 100644
--- a/docs/zh/latest/plugins/ai-proxy.md
+++ b/docs/zh/latest/plugins/ai-proxy.md
@@ -42,29 +42,6 @@ import TabItem from '@theme/TabItem';
此外,该插件还支持在访问日志中记录 LLM 请求信息,如令牌使用量、模型、首次响应时间等。这些日志条目也会被
`http-logger`、`kafka-logger` 等日志插件消费。这些选项不影响 `error.log`。
-## 请求体 JSON 库
-
-APISIX 使用 `apisix.request_body_json_lib` 选择
`core.request.get_request_body_table` 解析请求体时使用的 JSON
库。该入口是核心请求辅助接口,因此该配置会影响所有通过此接口读取 JSON 请求体的插件,包括 `ai-proxy` 和其他 AI 插件。该配置也会控制 AI
上游请求体的 JSON 编码。
-
-```yaml title="conf/config.yaml"
-apisix:
- request_body_json_lib: simdjson
-```
-
-有效值为 `cjson`、`simdjson` 和 `qjson`,默认值为 `simdjson`。当配置为 `simdjson` 时,APISIX 使用
`simdjson` 解码请求体,并使用 `cjson` 编码 AI 上游请求体。`qjson`
作为实验性选项提供,适合希望显式选择最高吞吐路径的用户自行评估后启用。
-
-该配置值按 worker 解析。修改后需要 reload 或 restart APISIX worker 才会生效。
-
-以下性能数据来自使用大 OpenAI chat completion 请求体和 `post_arg.model` 路由匹配的
benchmark,因此路由匹配阶段也会触发请求体 JSON 解析。`qjson` 结果表示请求体解码和 AI 上游请求体编码都使用 qjson。
-
-| 请求体大小 | `cjson` QPS | `simdjson` QPS | `qjson` QPS | `simdjson` 相对 `cjson` |
`qjson` 相对 `cjson` |
-|------------|-------------|----------------|-------------|--------------------------|----------------------|
-| 1 MB | 173 | 250 | 604 | 1.45x
| 3.41x |
-| 5 MB | 38 | 48-54 | 146-147 | 1.24x
| 3.85x |
-| 10 MB | 17.4 | 27.4 | 77.9 | 1.58x
| 4.48x |
-
-如果希望加速请求体解码,同时保持 AI 上游请求体使用 `cjson` 编码语义,可以使用 `simdjson`。`qjson` 在该 benchmark
中吞吐最高,但仍是实验性选项,建议用户基于自身负载评估兼容性后显式启用。
-
## 请求格式
| 名称 | 类型 | 必选项 | 描述 |
diff --git a/t/chaos/utils/Dockerfile b/t/chaos/utils/Dockerfile
index 99c0c733d..a3159437d 100644
--- a/t/chaos/utils/Dockerfile
+++ b/t/chaos/utils/Dockerfile
@@ -27,7 +27,6 @@ RUN set -x \
&& apk add --no-cache --virtual .builddeps \
automake \
autoconf \
- cargo \
g++ \
libtool \
pkgconfig \
@@ -35,7 +34,6 @@ RUN set -x \
git \
openldap-dev \
pcre-dev \
- rust \
sudo \
&& cd apisix \
&& git config --global url.https://github.com/.insteadOf git://github.com/
\
diff --git a/t/core/config-default.t b/t/core/config-default.t
index 1fe3c0a2b..f19392d24 100644
--- a/t/core/config-default.t
+++ b/t/core/config-default.t
@@ -31,7 +31,6 @@ __DATA__
local config = require("apisix.core").config.local_conf()
ngx.say("node_listen: ", config.apisix.node_listen)
- ngx.say("request_body_json_lib: ",
config.apisix.request_body_json_lib)
ngx.say("stream_proxy: ", encode_json(config.apisix.stream_proxy))
ngx.say("admin_key: ",
encode_json(config.deployment.admin.admin_key))
}
@@ -40,7 +39,6 @@ __DATA__
GET /t
--- response_body
node_listen: 1984
-request_body_json_lib: simdjson
stream_proxy: {"tcp":[9100]}
admin_key: null
diff --git a/t/core/request.t b/t/core/request.t
index d0d4c145f..14c2e901e 100644
--- a/t/core/request.t
+++ b/t/core/request.t
@@ -494,20 +494,17 @@ apisix
=== TEST 17: get_json_request_body_table caches result and re-decodes after
set_body_data
---- yaml_config
-apisix:
- request_body_json_lib: cjson
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
- local request_json = require("apisix.core.request_json")
+ local json = require("apisix.core.json")
ngx.ctx.api_ctx = {}
local decode_count = 0
- local orig_decode = request_json.decode
- request_json.decode = function(str)
+ local orig_decode = json.decode
+ json.decode = function(str)
decode_count = decode_count + 1
return orig_decode(str)
end
@@ -528,7 +525,7 @@ apisix:
-- cache cleared, must re-decode
local t4 = core.request.get_json_request_body_table()
- request_json.decode = orig_decode
+ json.decode = orig_decode
ngx.say("after set_body model: ", t4 and t4.model)
ngx.say("decode_count: ", decode_count)
@@ -545,240 +542,3 @@ same table: true
decode_count: 1
after set_body model: claude
decode_count: 2
-
-
-
-=== TEST 18: request_json selects configured JSON library
---- config
- location /t {
- content_by_lua_block {
- local config_local = require("apisix.core.config_local")
- local orig_local_conf = config_local.local_conf
- local orig_qjson = package.loaded["qjson"]
- local orig_preload_qjson = package.preload["qjson"]
- local orig_simdjson = package.loaded["resty.simdjson"]
- local orig_preload_simdjson = package.preload["resty.simdjson"]
- local orig_request_json =
package.loaded["apisix.core.request_json"]
-
- package.loaded["qjson"] = {
- decode = function()
- return {lib = "qjson", lazy = true}
- end,
- materialize = function(data)
- data.lazy = false
- return data
- end,
- encode = function(data)
- return "qjson:" .. data.lib
- end,
- }
-
- package.loaded["resty.simdjson"] = {
- new = function()
- return {
- decode = function()
- return {lib = "simdjson"}
- end,
- }
- end,
- }
-
- local function load_with(lib)
- config_local.local_conf = function()
- return {apisix = {request_body_json_lib = lib}}
- end
- package.loaded["apisix.core.request_json"] = nil
- return require("apisix.core.request_json")
- end
-
- local request_json = load_with("qjson")
- local decoded = request_json.decode("{}")
- local encoded = request_json.encode({lib = "body"})
- ngx.say("qjson decode: ", decoded.lib)
- ngx.say("qjson materialized: ", not decoded.lazy)
- ngx.say("qjson encode: ", encoded)
-
- request_json = load_with("simdjson")
- decoded = request_json.decode("{}")
- encoded = request_json.encode({lib = "body"})
- ngx.say("simdjson decode: ", decoded.lib)
- ngx.say("simdjson encode: ", encoded)
-
- request_json = load_with("cjson")
- decoded = request_json.decode('{"lib":"cjson"}')
- encoded = request_json.encode({lib = "body"})
- ngx.say("cjson decode: ", decoded.lib)
- ngx.say("cjson encode: ", encoded)
-
- config_local.local_conf = orig_local_conf
- package.loaded["apisix.core.request_json"] = orig_request_json
- package.loaded["qjson"] = orig_qjson
- package.preload["qjson"] = orig_preload_qjson
- package.loaded["resty.simdjson"] = orig_simdjson
- package.preload["resty.simdjson"] = orig_preload_simdjson
- }
- }
---- response_body
-qjson decode: qjson
-qjson materialized: true
-qjson encode: qjson:body
-simdjson decode: simdjson
-simdjson encode: {"lib":"body"}
-cjson decode: cjson
-cjson encode: {"lib":"body"}
-
-
-
-=== TEST 19: qjson decode and encode errors are returned
---- yaml_config
-apisix:
- request_body_json_lib: qjson
---- config
- location /t {
- content_by_lua_block {
- local core = require("apisix.core")
- local request_json = require("apisix.core.request_json")
-
- ngx.ctx.api_ctx = {}
-
- local body, body_err = core.request.get_json_request_body_table()
- ngx.say("body nil: ", body == nil)
- ngx.say("body error: ", body_err and body_err.message and
- body_err.message:find("could not parse JSON request
body:", 1, true) == 1)
-
- local decoded, decode_err = request_json.decode("{")
- ngx.say("decode nil: ", decoded == nil)
- ngx.say("decode error: ", type(decode_err) == "string" and
#decode_err > 0)
-
- local encoded, encode_err = request_json.encode({bad = function()
end})
- ngx.say("encode nil: ", encoded == nil)
- ngx.say("encode error: ", type(encode_err) == "string" and
#encode_err > 0)
- }
- }
---- request
-POST /t
-{
---- more_headers
-Content-Type: application/json
---- response_body
-body nil: true
-body error: true
-decode nil: true
-decode error: true
-encode nil: true
-encode error: true
---- no_error_log
-[error]
-
-
-
-=== TEST 20: simdjson preserves empty arrays for cjson encoding
---- yaml_config
-apisix:
- request_body_json_lib: simdjson
---- config
- location /t {
- content_by_lua_block {
- local core_json = require("apisix.core.json")
- local request_json = require("apisix.core.request_json")
-
- local decoded =
request_json.decode('{"messages":[],"metadata":{"tags":[]}}')
- local encoded = request_json.encode(decoded)
- local round_trip = core_json.decode(encoded)
-
- ngx.say("messages array: ", getmetatable(round_trip.messages) ==
core_json.array_mt)
- ngx.say("tags array: ", getmetatable(round_trip.metadata.tags) ==
core_json.array_mt)
- }
- }
---- response_body
-messages array: true
-tags array: true
-
-
-
-=== TEST 21: ai transport encoders use request_json
---- config
- location /t {
- content_by_lua_block {
- local request_json = require("apisix.core.request_json")
- local orig_encode = request_json.encode
- local orig_request_json =
package.loaded["apisix.core.request_json"]
- local orig_http = package.loaded["resty.http"]
- local orig_aws_config = package.loaded["resty.aws.config"]
- local orig_aws = package.loaded["resty.aws"]
- local orig_sign = package.loaded["resty.aws.request.sign"]
- local orig_transport =
package.loaded["apisix.plugins.ai-transport.http"]
- local orig_auth_aws =
package.loaded["apisix.plugins.ai-transport.auth-aws"]
- request_json.encode = function()
- return "encoded-by-request-json"
- end
-
- package.loaded["resty.http"] = {
- new = function()
- return {
- set_timeout = function() end,
- connect = function() return true end,
- request = function(_, params)
- ngx.say("http body: ", params.body)
- return {headers = {}, status = 200}
- end,
- close = function() end,
- }
- end,
- }
-
- package.loaded["apisix.plugins.ai-transport.http"] = nil
- local transport = require("apisix.plugins.ai-transport.http")
- local res, err = transport.request({
- host = "127.0.0.1",
- port = 80,
- path = "/",
- body = {model = "test"},
- }, 1000)
- if not res then
- ngx.say(err)
- end
-
- package.loaded["resty.aws.config"] = {}
- package.loaded["resty.aws"] = function()
- return {
- Credentials = function(_, opts)
- return opts
- end,
- }
- end
- package.loaded["resty.aws.request.sign"] = function(_, req)
- ngx.say("aws body: ", req.body)
- return {headers = {Authorization = "signed"}}
- end
-
- package.loaded["apisix.plugins.ai-transport.auth-aws"] = nil
- local auth_aws = require("apisix.plugins.ai-transport.auth-aws")
- local sign_err = auth_aws.sign_request({
- method = "POST",
- host = "bedrock-runtime.us-east-1.amazonaws.com",
- port = 443,
- path = "/model/test/converse",
- headers = {},
- body = {model = "test"},
- }, {
- access_key_id = "ak",
- secret_access_key = "sk",
- }, "us-east-1")
- if sign_err then
- ngx.say(sign_err)
- end
-
- request_json.encode = orig_encode
- package.loaded["resty.http"] = orig_http
- package.loaded["resty.aws.config"] = orig_aws_config
- package.loaded["resty.aws"] = orig_aws
- package.loaded["resty.aws.request.sign"] = orig_sign
- package.loaded["apisix.core.request_json"] = orig_request_json
- package.loaded["apisix.plugins.ai-transport.http"] = orig_transport
- package.loaded["apisix.plugins.ai-transport.auth-aws"] =
orig_auth_aws
- }
- }
---- response_body
-http body: encoded-by-request-json
-aws body: encoded-by-request-json
diff --git a/t/plugin/ai-proxy-multi.t b/t/plugin/ai-proxy-multi.t
index 081184faa..c2ecdcd4f 100644
--- a/t/plugin/ai-proxy-multi.t
+++ b/t/plugin/ai-proxy-multi.t
@@ -260,8 +260,8 @@ qr/\{ "content": "1 \+ 1 = 2\.", "role": "assistant" \}/
GET /anything
{}"messages": [ { "role": "system", "cont
--- error_code: 400
---- response_body eval
-qr/^\{"message":"could not parse JSON request body: .+"\}\n?$/
+--- response_body
+{"message":"could not parse JSON request body: Expected the end but found
T_STRING at character 3"}
diff --git a/t/plugin/ai-proxy.t b/t/plugin/ai-proxy.t
index 0a18db577..e73e41a86 100644
--- a/t/plugin/ai-proxy.t
+++ b/t/plugin/ai-proxy.t
@@ -234,8 +234,8 @@ qr/\{ "content": "1 \+ 1 = 2\.", "role": "assistant" \}/
GET /anything
{}"messages": [ { "role": "system", "cont
--- error_code: 400
---- response_body eval
-qr/^\{"message":"could not parse JSON request body: .+"\}\n?$/
+--- response_body
+{"message":"could not parse JSON request body: Expected the end but found
T_STRING at character 3"}
diff --git a/utils/install-dependencies.sh b/utils/install-dependencies.sh
index a2e19802d..34e4d5fb9 100755
--- a/utils/install-dependencies.sh
+++ b/utils/install-dependencies.sh
@@ -19,11 +19,6 @@
set -ex
-_APISIX_UTILS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-# shellcheck source=utils/install-rust-toolchain.sh
-. "${_APISIX_UTILS_DIR}/install-rust-toolchain.sh"
-unset _APISIX_UTILS_DIR
-
function detect_aur_helper() {
if [[ $(command -v yay) ]]; then
AUR_HELPER=yay
@@ -39,7 +34,6 @@ function install_dependencies_with_aur() {
detect_aur_helper
$AUR_HELPER -S openresty --noconfirm
sudo pacman -S openssl base-devel git --noconfirm
- install_rust_toolchain
export OPENRESTY_PREFIX=/opt/openresty
@@ -63,7 +57,6 @@ function install_dependencies_with_yum() {
gcc gcc-c++ curl wget unzip xz gnupg perl-ExtUtils-Embed cpanminus
patch libyaml-devel \
perl perl-devel pcre pcre-devel pcre2 pcre2-devel openldap-devel \
openresty-zlib-devel openresty-pcre-devel libxml2-devel libxslt-devel
zlib-devel
- install_rust_toolchain
}
# Install dependencies on ubuntu and debian
@@ -86,7 +79,6 @@ function install_dependencies_with_apt() {
# install some compilation tools
sudo apt-get install -y curl make gcc g++ cpanminus libpcre3 libpcre3-dev
libpcre2-dev libyaml-dev unzip openresty-zlib-dev openresty-pcre-dev
libxml2-dev libxslt-dev zlib1g-dev
- install_rust_toolchain
}
# Identify the different distributions and call the corresponding function
diff --git a/utils/install-rust-toolchain.sh b/utils/install-rust-toolchain.sh
deleted file mode 100755
index a2351d2cf..000000000
--- a/utils/install-rust-toolchain.sh
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/env bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. 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.
-#
-
-function rustc_meets_minimum_version() {
- if ! command -v rustc >/dev/null 2>&1; then
- return 1
- fi
-
- local version major minor
- version=$(rustc --version | awk '{print $2}')
- if [[ ! "$version" =~ ^[0-9]+\.[0-9]+ ]]; then
- return 1
- fi
-
- major=${version%%.*}
- minor=${version#*.}
- minor=${minor%%.*}
-
- [ "$major" -gt 1 ] || { [ "$major" -eq 1 ] && [ "$minor" -ge 77 ]; }
-}
-
-function run_as_root() {
- if [ "$(id -u)" -eq 0 ]; then
- "$@"
- else
- sudo "$@"
- fi
-}
-
-function install_rustup_toolchain() {
- local version target checksum tmp_dir tmp rustup_home cargo_home base_path
- version="1.28.2"
- rustup_home="${RUSTUP_HOME:-/usr/local/rustup}"
- cargo_home="${CARGO_HOME:-/usr/local/cargo}"
- base_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- case "$(uname -m)" in
- x86_64|amd64)
- target="x86_64-unknown-linux-gnu"
-
checksum="20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c"
- ;;
- aarch64|arm64)
- target="aarch64-unknown-linux-gnu"
-
checksum="e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c"
- ;;
- *)
- echo "unsupported architecture for rustup-init: $(uname -m)"
- exit 1
- ;;
- esac
-
- tmp_dir=$(mktemp -d) || return 1
- (
- set -euo pipefail
- trap 'rm -rf "${tmp_dir}"' EXIT
- tmp="${tmp_dir}/rustup-init"
- curl -fsSLo "$tmp"
"https://static.rust-lang.org/rustup/archive/${version}/${target}/rustup-init"
- echo "${checksum} ${tmp}" | sha256sum -c -
- chmod +x "$tmp"
- run_as_root mkdir -p "$rustup_home" "$cargo_home"
- run_as_root env RUSTUP_HOME="$rustup_home" CARGO_HOME="$cargo_home"
PATH="$base_path" \
- "$tmp" -y --profile minimal --default-toolchain stable
--no-modify-path
- run_as_root env RUSTUP_HOME="$rustup_home" CARGO_HOME="$cargo_home"
PATH="${cargo_home}/bin:${base_path}" \
- "${cargo_home}/bin/rustup" default stable
- ) || return 1
- export RUSTUP_HOME="$rustup_home"
- export CARGO_HOME="$cargo_home"
- export PATH="${cargo_home}/bin:${PATH}"
- if [[ -n "${GITHUB_ENV:-}" ]]; then
- {
- echo "RUSTUP_HOME=${rustup_home}"
- echo "CARGO_HOME=${cargo_home}"
- } >> "$GITHUB_ENV"
- fi
- if [[ -n "${GITHUB_PATH:-}" ]]; then
- echo "${cargo_home}/bin" >> "$GITHUB_PATH"
- fi
- run_as_root ln -sf "${cargo_home}/bin/cargo" /usr/local/bin/cargo
- run_as_root ln -sf "${cargo_home}/bin/rustc" /usr/local/bin/rustc
-}
-
-function install_rust_toolchain() {
- if rustc_meets_minimum_version; then
- return
- fi
-
- if command -v brew >/dev/null 2>&1; then
- brew install rust
- if rustc_meets_minimum_version; then
- return
- fi
- echo "installed rustc is older than 1.77"
- exit 1
- fi
-
- if command -v curl >/dev/null 2>&1 && command -v sha256sum >/dev/null
2>&1; then
- install_rustup_toolchain
- if rustc_meets_minimum_version; then
- return
- fi
- echo "installed rustc is older than 1.77"
- exit 1
- fi
-
- if command -v apt-get >/dev/null 2>&1; then
- run_as_root apt-get install -y cargo
- if rustc_meets_minimum_version; then
- return
- fi
- echo "installed rustc is older than 1.77"
- exit 1
- fi
-
- if command -v yum >/dev/null 2>&1; then
- run_as_root yum install -y cargo rust
- if rustc_meets_minimum_version; then
- return
- fi
- echo "installed rustc is older than 1.77"
- exit 1
- fi
-
- if command -v pacman >/dev/null 2>&1; then
- run_as_root pacman -S rust --noconfirm
- if rustc_meets_minimum_version; then
- return
- fi
- echo "installed rustc is older than 1.77"
- exit 1
- fi
-
- echo "No supported Rust package manager found"
- exit 1
-}