There are many methods to limit the size of requests in APISIX:
- using a built-in plugin, such as
client-control
; - using APISIX configuration;
- making a custom plugin;
Since you want to enable it on a specific route (/file/upload/abcd.png
), the best approach would be to use a plugin.
NB: I'll provide examples using httpbin.org website and Admin APIs. I'll assume we have APISIX running and accessible at localhost:9080
and the Admin API are exposed and accessible without key authentication, at localhost:9180
. I'll also assume that we have 2 images in the current path:
abcd_small.png
, with lower size than 1 MB;abcd_large.png
, with higher size than 1 MB;
Solutions
1. Built-in Plugins: client-control
client-control
plugin can be used to limit the size of the body in client requests. From APISIX docs:
The
client-control
Plugin can be used to dynamically control the behavior of NGINX to handle a client request, by setting the max size of the request body.
You can enable it on the route which exposes endpoint /file/upload/abcd.png
and set max_body_size
attribute to your preferences.
Example (Admin API)
The following Admin API call enables the plugin client-control
on any route starting with /file/upload/
and limits the request body size to 1MB (1048576 Bytes). The proxy rewrite redirects the request to httpbin.org/post endpoint, which is used to send a POST request.
curl -s -X PUT -i "http://localhost:9180/apisix/admin/routes/client-control1" -d '{"uri": "/file/upload/*","plugins": {"client-control": {"max_body_size": 1048576 },"proxy-rewrite": {"method": "POST","uri": "/post" } },"upstream": {"type": "roundrobin","nodes": {"httpbin.org": 1 } }}'
We can test it with curl, by sending a request with a small image (< 1 MB) and with a large image (> 1 MB):
curl -s -i "localhost:9080/file/upload/abcd.png" -F "image=@./abcd_small.png" | grep HTTPHTTP/1.1 413 Request Entity Too Large
curl -s -i "localhost:9080/file/upload/abcd.png" -F "image=@./abcd_large.png" | grep HTTPHTTP/1.1 200 OK
2. Using APISIX Configuration
You can set nginx_config.http.client_max_body_size
in APISIX configuration file (check config.yaml.example for reference), to limit the maximum body size of client requests.
Example
Create a file config.yaml
with the following content:
nginx_config: http: client_max_body_size: 1048576
And mount it at ${apisix_root}/conf/config.yaml
. Then start APISIX or hot reload:
apisix reload
Then create a simple example route:
curl -s -X PUT -i "http://localhost:9180/apisix/admin/routes/apisix-config1" -d '{"uri": "/file/upload2/*","plugins": {"proxy-rewrite": {"method": "POST","uri": "/post" } },"upstream": {"type": "roundrobin","nodes": {"httpbin.org": 1 } }}'
We can test it with curl:
curl -s -i "localhost:9080/file/upload2/abcd.png" -F "image=@./abcd_small.png" | grep HTTPHTTP/1.1 413 Request Entity Too Large
curl -s -i "localhost:9080/file/upload2/abcd.png" -F "image=@./abcd_large.png" | grep HTTPHTTP/1.1 200 OK
3. Using Custom Plugin
You can make a custom Lua plugin (or an external plugin) and exploit, for example, the Content Lenght
header.
Example
Content of custom Lua plugin limit-upload-size.lua
:
local core = require("apisix.core")local ngx = ngxlocal schema = { type = "object", properties = { max_size = {type = "integer", minimum = 1}, }, required = {"max_size"},}local _M = { version = 0.1, priority = 10, name = "limit-upload-size", schema = schema,}function _M.check_schema(conf) return core.schema.check(schema, conf)endfunction _M.access(conf, ctx) local max_size = conf.max_size local content_length = tonumber(ngx.req.get_headers()["content-length"]) if content_length and content_length > max_size then return 413, { message = "Content cannot exceed " .. conf.max_size .. " Bytes" } endendreturn _M
We need to enable it by editing the APISIX configuration by appending the plugin name to the plugins list, under plugins
field; or by adding the plugin path to apisix.extra_lua_path
. Then we can enable it on a route like we did in other examples:
curl -s -X PUT -i "http://localhost:9180/apisix/admin/routes/limit-update-size1" -d '{"uri": "/file/upload3/*","plugins": {"limit-update-size": {"max_body_size": 1048576 },"proxy-rewrite": {"method": "POST","uri": "/post" } },"upstream": {"type": "roundrobin","nodes": {"httpbin.org": 1 } }}'
We can test it with curl:
curl -s -i "localhost:9080/file/upload3/abcd.png" -F "image=@./abcd_small.png" | grep HTTPHTTP/1.1 413 Request Entity Too Large
curl -s -i "localhost:9080/file/upload3/abcd.png" -F "image=@./abcd_large.png" | grep HTTPHTTP/1.1 200 OK