@abtnode/router-provider 1.16.43-beta-20250425-130658-8da18f4d → 1.16.43-beta-20250427-132304-6da95c55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/nginx/index.js +67 -6
  2. package/package.json +6 -6
@@ -23,6 +23,8 @@ const {
23
23
  USER_AVATAR_PATH_PREFIX,
24
24
  LOG_RETAIN_IN_DAYS,
25
25
  ROUTER_CACHE_GROUPS,
26
+ GATEWAY_RATE_LIMIT_GLOBAL,
27
+ GATEWAY_RATE_LIMIT,
26
28
  } = require('@abtnode/constant');
27
29
 
28
30
  const promiseRetry = require('promise-retry');
@@ -122,6 +124,7 @@ class NginxProvider extends BaseProvider {
122
124
  this.capabilities = this._checkCapabilities();
123
125
 
124
126
  this.conf = null; // nginx `conf` object
127
+ this.requestLimit = null;
125
128
 
126
129
  logger.info('nginx provider config', {
127
130
  configDir,
@@ -207,6 +210,7 @@ class NginxProvider extends BaseProvider {
207
210
  this._addCommonResHeaders(conf.nginx.http, commonHeaders);
208
211
  this._addExposeServices(conf, services);
209
212
  if (requestLimit && requestLimit.enabled) {
213
+ this.requestLimit = requestLimit;
210
214
  this.addRequestLimiting(conf.nginx.http, requestLimit);
211
215
  }
212
216
  if (blockPolicy && blockPolicy?.enabled) {
@@ -274,6 +278,8 @@ class NginxProvider extends BaseProvider {
274
278
  this._addDefaultServer(conf, nodeInfo.port);
275
279
  }
276
280
 
281
+ this._addStubStatusLocation(conf);
282
+
277
283
  conf.flush();
278
284
  });
279
285
  });
@@ -367,7 +373,7 @@ class NginxProvider extends BaseProvider {
367
373
  _checkCapabilities() {
368
374
  const config = this.readNginxConfigParams();
369
375
 
370
- const capabilities = ['http_v2', 'http_geoip'].reduce((acc, key) => {
376
+ const capabilities = ['http_v2', 'http_geoip', 'http_stub_status'].reduce((acc, key) => {
371
377
  const arg = `with-${key}_module`;
372
378
  const capability = camelCase(key);
373
379
 
@@ -797,14 +803,43 @@ class NginxProvider extends BaseProvider {
797
803
  location._add('add_header', 'X-Request-ID $request_id');
798
804
  }
799
805
 
806
+ _addStubStatusLocation(conf) {
807
+ if (!conf?.nginx?.http?.server) {
808
+ return;
809
+ }
810
+
811
+ if (!this.capabilities?.httpStubStatus) {
812
+ return;
813
+ }
814
+
815
+ const servers = Array.isArray(conf.nginx.http.server) ? conf.nginx.http.server : [conf.nginx.http.server];
816
+ const server = servers.find((x) => x.server_name._value === '127.0.0.1');
817
+ if (!server) {
818
+ return;
819
+ }
820
+
821
+ server._add('location', '/__nginx_status');
822
+ const location = this._getLastLocation(server);
823
+ location._add('stub_status', 'on');
824
+ location._add('access_log', 'off');
825
+ location._add('allow', '127.0.0.1');
826
+ location._add('deny', 'all');
827
+ }
828
+
800
829
  _getLastServer(conf) {
801
830
  return conf.nginx.http.server.length
802
831
  ? conf.nginx.http.server[conf.nginx.http.server.length - 1]
803
832
  : conf.nginx.http.server;
804
833
  }
805
834
 
806
- _getLastLocation(serverConf) {
807
- return serverConf.location.length ? serverConf.location[serverConf.location.length - 1] : serverConf.location;
835
+ _getLastLocation(server) {
836
+ const location = server.location.length ? server.location[server.location.length - 1] : server.location;
837
+ if (location && this.requestLimit?.enabled && !location.toString().includes('limit_req')) {
838
+ location._add('limit_req', `zone=ip_rate_limit burst=${this.requestLimit.burst} delay=10`);
839
+ location._add('limit_req', `zone=global_rate_limit burst=${this.requestLimit.burstGlobal} nodelay`);
840
+ }
841
+
842
+ return location;
808
843
  }
809
844
 
810
845
  _getLastStreamServer(conf) {
@@ -849,7 +884,7 @@ class NginxProvider extends BaseProvider {
849
884
  locations.forEach((x) => this._addReverseProxy({ server: httpsServerUnit, ...x, serverName, corsAllowedOrigins, commonHeaders, blockletDid })); // prettier-ignore
850
885
  }
851
886
 
852
- _addHttpServerUnit({ conf, serverName, port }) {
887
+ _addHttpServerUnit({ conf, serverName, port = '' }) {
853
888
  let listen = port || this.httpPort;
854
889
  if (serverName === '_') {
855
890
  listen = `${listen} default_server`;
@@ -975,8 +1010,34 @@ class NginxProvider extends BaseProvider {
975
1010
  }
976
1011
 
977
1012
  addRequestLimiting(block, limit) {
978
- block._add('limit_req_zone', `$binary_remote_addr zone=req_limit_per_ip:20m rate=${limit.rate || 5}r/s`);
979
- block._add('limit_req', `zone=req_limit_per_ip burst=${limit.maxInstantRate || 30} delay=10`);
1013
+ if (!limit?.enabled) {
1014
+ return;
1015
+ }
1016
+
1017
+ const resourceExts =
1018
+ 'jpg|jpeg|png|gif|webp|svg|ico|css|js|jsx|ts|tsx|mjs|woff|woff2|ttf|eot|otf|json|bmp|avif|wasm|xml|txt';
1019
+
1020
+ // limit by global
1021
+ block._addVerbatimBlock(
1022
+ 'map $request_uri $global_rate_limit_key',
1023
+ `${os.EOL}${[`~*\\.(${resourceExts})$ "";`, 'default global_rate_limit;'].join(os.EOL)}${os.EOL}`
1024
+ );
1025
+
1026
+ // limit by ip
1027
+ block._addVerbatimBlock(
1028
+ 'map $request_uri:$request_method $ip_rate_limit_key',
1029
+ `${os.EOL}${[`~*\\.(${resourceExts})(\\?.*)?: "";`, `~*:(${limit.methods.join('|')})$ ip_rate_limit;`, 'default "";'].join(os.EOL)}${os.EOL}`
1030
+ );
1031
+
1032
+ // link: https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone
1033
+ block._add(
1034
+ 'limit_req_zone',
1035
+ `$global_rate_limit_key zone=global_rate_limit:128k rate=${limit.global || GATEWAY_RATE_LIMIT_GLOBAL.min}r/s`
1036
+ );
1037
+ block._add(
1038
+ 'limit_req_zone',
1039
+ `$ip_rate_limit_key zone=ip_rate_limit:5m rate=${limit.rate || GATEWAY_RATE_LIMIT.min}r/s`
1040
+ );
980
1041
  block._add('limit_req_status', 429);
981
1042
  }
982
1043
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abtnode/router-provider",
3
- "version": "1.16.43-beta-20250425-130658-8da18f4d",
3
+ "version": "1.16.43-beta-20250427-132304-6da95c55",
4
4
  "description": "Routing engine implementations for abt node",
5
5
  "author": "polunzh <polunzh@gmail.com>",
6
6
  "homepage": "https://github.com/ArcBlock/blocklet-server#readme",
@@ -32,10 +32,10 @@
32
32
  "url": "https://github.com/ArcBlock/blocklet-server/issues"
33
33
  },
34
34
  "dependencies": {
35
- "@abtnode/constant": "1.16.43-beta-20250425-130658-8da18f4d",
36
- "@abtnode/logger": "1.16.43-beta-20250425-130658-8da18f4d",
37
- "@abtnode/router-templates": "1.16.43-beta-20250425-130658-8da18f4d",
38
- "@abtnode/util": "1.16.43-beta-20250425-130658-8da18f4d",
35
+ "@abtnode/constant": "1.16.43-beta-20250427-132304-6da95c55",
36
+ "@abtnode/logger": "1.16.43-beta-20250427-132304-6da95c55",
37
+ "@abtnode/router-templates": "1.16.43-beta-20250427-132304-6da95c55",
38
+ "@abtnode/util": "1.16.43-beta-20250427-132304-6da95c55",
39
39
  "@arcblock/http-proxy": "^1.19.1",
40
40
  "@arcblock/is-valid-domain": "^1.0.5",
41
41
  "axios": "^1.7.9",
@@ -61,5 +61,5 @@
61
61
  "bluebird": "^3.7.2",
62
62
  "fs-extra": "^11.2.0"
63
63
  },
64
- "gitHead": "b5195a0290d5ced00bb716a709548b1a56356134"
64
+ "gitHead": "9df10dcb3135a528912241e7fc1ed54171bfeb03"
65
65
  }