This is an automated email from the ASF dual-hosted git repository.
liuhongyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 5cdc8582c6 [type:fix] fix duplicate header for request plugin (#5846)
5cdc8582c6 is described below
commit 5cdc8582c68b815b495a1fbd4ce3a3b4f9ce604c
Author: moremind <[email protected]>
AuthorDate: Sat Dec 14 13:37:40 2024 +0800
[type:fix] fix duplicate header for request plugin (#5846)
* [type:fix] fix client register validation
* [type:fix] fix rqeuest header
* [type:fix] fix rqeuest header
* [type:fix] fix rqeuest header
* [type:fix] fix duplicate header for request plugin
* [type:fix] fix duplicate header for request plugin
* [type:fix] fix duplicate header for request plugin
* [type:fix] fix duplicate header for request plugin
---
db/init/mysql/schema.sql | 7 ++
db/init/ob/schema.sql | 8 +-
db/init/og/create-table.sql | 7 ++
db/init/oracle/schema.sql | 22 +++++
db/init/pg/create-table.sql | 7 ++
db/upgrade/2.6.1-upgrade-2.7.0-mysql.sql | 9 +-
db/upgrade/2.6.1-upgrade-2.7.0-og.sql | 8 +-
db/upgrade/2.6.1-upgrade-2.7.0-oracle.sql | 22 +++++
db/upgrade/2.6.1-upgrade-2.7.0-pg.sql | 7 ++
.../src/main/resources/sql-script/h2/schema.sql | 5 +
.../src/main/resources/application.yml | 4 -
.../apache/shenyu/common/constant/Constants.java | 5 +
.../common/dto/convert/rule/RequestHandle.java | 101 +++++++++++++++++++++
.../common/enums/HeaderUniqueStrategyEnum.java | 39 ++++++++
.../shenyu/common/enums/UniqueHeaderEnum.java | 41 +++++++++
.../httpclient/AbstractHttpClientPlugin.java | 22 ++++-
.../plugin/httpclient/NettyHttpClientPlugin.java | 34 +++----
.../shenyu/plugin/httpclient/WebClientPlugin.java | 32 +++----
.../config/DuplicateResponseHeaderProperties.java | 90 ------------------
.../httpclient/NettyHttpClientPluginTest.java | 3 +-
.../plugin/httpclient/WebClientPluginTest.java | 11 +--
.../shenyu/plugin/request/RequestPlugin.java | 17 +++-
.../httpclient/HttpClientPluginConfiguration.java | 22 +----
23 files changed, 355 insertions(+), 168 deletions(-)
diff --git a/db/init/mysql/schema.sql b/db/init/mysql/schema.sql
index 041e0cdd65..1d88800a6e 100644
--- a/db/init/mysql/schema.sql
+++ b/db/init/mysql/schema.sql
@@ -1293,6 +1293,11 @@ INSERT INTO `plugin_handle` VALUES
('1722804548510507023', '3', 'rewriteMetaData
INSERT INTO `plugin_handle` VALUES ('1722804548510507024', '8',
'registerType', 'registerType', 2, 3, 1, NULL, '2024-08-24 09:40:03.293',
'2024-08-24 21:52:27.920');
INSERT INTO `plugin_handle` VALUES ('1722804548510507025', '8', 'serverLists',
'serverLists', 2, 3, 2, NULL, '2024-08-24 21:52:51.179', '2024-08-24
21:53:27.483');
INSERT INTO `plugin_handle` VALUES ('1722804548510507026', '8', 'props',
'props', 4, 3, 3, NULL, '2024-08-24 21:53:25.764', '2024-08-24 21:53:30.255');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507027', '20',
'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}', '2024-12-05 22:00:02.251',
'2024-12-05 22:00:02.251');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507028', '20',
'requestHeaderUniqueStrategy', 'requestHeaderUniqueStrategy', 2, 2, 1,
'{"required":"0","rule":""}', '2024-12-13 22:36:54.299', '2024-12-13
22:36:54.299');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507029', '20',
'requestUniqueHeaders', 'requestUniqueHeaders', 2, 2, 2,
'{"required":"0","rule":""}', '2024-12-13 22:37:29.959', '2024-12-13
22:37:29.959');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507030', '20',
'respHeaderUniqueStrategy', 'respHeaderUniqueStrategy', 2, 2, 3,
'{"required":"0","rule":""}', '2024-12-13 22:37:48.239', '2024-12-13
22:37:48.239');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507031', '20',
'respUniqueHeaders', 'respUniqueHeaders', 2, 2, 4,
'{"required":"0","rule":""}', '2024-12-13 22:38:05.726', '2024-12-13
22:38:05.726');
-- ----------------------------
-- Table structure for resource
@@ -2079,6 +2084,8 @@ INSERT INTO `shenyu_dict` VALUES ('1679002911061737474',
'discoveryMode', 'DISCO
INSERT INTO `shenyu_dict` VALUES ('1679002911061737475', 'discoveryMode',
'DISCOVERY_MODE', 'eureka', '{"eurekaClientRefreshInterval": "10",
"eurekaClientRegistryFetchIntervalSeconds": "10"}', 'discoery mode to link
eureka', 0, 1,'2023-03-01 10:48:49', '2023-03-01 10:48:49');
INSERT INTO `shenyu_dict` VALUES ('1679002911061737478', 'rewriteMetaData',
'REWRITE_META_DATA', 'true', 'true', '', 4, 1, '2024-02-07 14:31:49',
'2024-02-07 14:31:49');
INSERT INTO `shenyu_dict` VALUES ('1679002911061737479', 'rewriteMetaData',
'REWRITE_META_DATA', 'false', 'false', '', 4, 1, '2024-02-07 14:31:49',
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737480', 'preserveHost',
'PRESERVE_HOST', 'true', 'true', '', 0, 1, '2024-12-05 22:00:46.416',
'2024-12-05 22:00:46.416');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737481', 'preserveHost',
'PRESERVE_HOST', 'false', 'false', '', 1, 1, '2024-12-05 22:01:13.396',
'2024-12-05 22:01:13.396');
-- ----------------------------
-- Table structure for user_role
diff --git a/db/init/ob/schema.sql b/db/init/ob/schema.sql
index cd6ff2b36c..cf0790759a 100644
--- a/db/init/ob/schema.sql
+++ b/db/init/ob/schema.sql
@@ -1286,6 +1286,11 @@ INSERT INTO `plugin_handle` VALUES
('1722804548510507023', '3', 'rewriteMetaData
INSERT INTO `plugin_handle` VALUES ('1722804548510507024', '8',
'registerType', 'registerType', 2, 3, 1, NULL, '2024-08-24 09:40:03.293',
'2024-08-24 21:52:27.920');
INSERT INTO `plugin_handle` VALUES ('1722804548510507025', '8', 'serverLists',
'serverLists', 2, 3, 2, NULL, '2024-08-24 21:52:51.179', '2024-08-24
21:53:27.483');
INSERT INTO `plugin_handle` VALUES ('1722804548510507026', '8', 'props',
'props', 4, 3, 3, NULL, '2024-08-24 21:53:25.764', '2024-08-24 21:53:30.255');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507027', '20',
'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}', '2024-12-05 22:00:02.251',
'2024-12-05 22:00:02.251');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507028', '20',
'requestHeaderUniqueStrategy', 'requestHeaderUniqueStrategy', 2, 2, 1,
'{"required":"0","rule":""}', '2024-12-13 22:36:54.299', '2024-12-13
22:36:54.299');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507029', '20',
'requestUniqueHeaders', 'requestUniqueHeaders', 2, 2, 2,
'{"required":"0","rule":""}', '2024-12-13 22:37:29.959', '2024-12-13
22:37:29.959');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507030', '20',
'respHeaderUniqueStrategy', 'respHeaderUniqueStrategy', 2, 2, 3,
'{"required":"0","rule":""}', '2024-12-13 22:37:48.239', '2024-12-13
22:37:48.239');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507031', '20',
'respUniqueHeaders', 'respUniqueHeaders', 2, 2, 4,
'{"required":"0","rule":""}', '2024-12-13 22:38:05.726', '2024-12-13
22:38:05.726');
-- ----------------------------
-- Table structure for resource
@@ -2066,7 +2071,8 @@ INSERT INTO `shenyu_dict` VALUES ('1679002911061737474',
'discoveryMode', 'DISCO
INSERT INTO `shenyu_dict` VALUES ('1679002911061737475', 'discoveryMode',
'DISCOVERY_MODE', 'eureka', '{"eurekaClientRefreshInterval": "10",
"eurekaClientRegistryFetchIntervalSeconds": "10"}', 'discoery mode to link
eureka', 0, 1,'2023-03-01 10:48:49', '2023-03-01 10:48:49');
INSERT INTO `shenyu_dict` VALUES ('1679002911061737478', 'rewriteMetaData',
'REWRITE_META_DATA', 'true', 'true', '', 4, 1, '2024-02-07 14:31:49',
'2024-02-07 14:31:49');
INSERT INTO `shenyu_dict` VALUES ('1679002911061737479', 'rewriteMetaData',
'REWRITE_META_DATA', 'false', 'false', '', 4, 1, '2024-02-07 14:31:49',
'2024-02-07 14:31:49');
-
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737480', 'preserveHost',
'PRESERVE_HOST', 'true', 'true', '', 0, 1, '2024-12-05 22:00:46.416',
'2024-12-05 22:00:46.416');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737481', 'preserveHost',
'PRESERVE_HOST', 'false', 'false', '', 1, 1, '2024-12-05 22:01:13.396',
'2024-12-05 22:01:13.396');
-- ----------------------------
-- Table structure for user_role
-- ----------------------------
diff --git a/db/init/og/create-table.sql b/db/init/og/create-table.sql
index 74576c5ecf..4fed467321 100644
--- a/db/init/og/create-table.sql
+++ b/db/init/og/create-table.sql
@@ -1370,6 +1370,11 @@ INSERT INTO "public"."plugin_handle" VALUES
('1722804548510507023', '3', 'rewrit
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507024', '8',
'registerType', 'registerType', 2, 3, 1, NULL, '2024-08-24 09:40:03.293',
'2024-08-24 21:52:27.920');
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507025', '8',
'serverLists', 'serverLists', 2, 3, 2, NULL, '2024-08-24 21:52:51.179',
'2024-08-24 21:53:27.483');
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507026', '8',
'props', 'props', 4, 3, 3, NULL, '2024-08-24 21:53:25.764', '2024-08-24
21:53:30.255');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507027', '20',
'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}', '2024-12-05 22:00:02.251',
'2024-12-05 22:00:02.251');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507028', '20',
'requestHeaderUniqueStrategy', 'requestHeaderUniqueStrategy', 2, 2, 1,
'{"required":"0","rule":""}', '2024-12-13 22:36:54.299', '2024-12-13
22:36:54.299');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507029', '20',
'requestUniqueHeaders', 'requestUniqueHeaders', 2, 2, 2,
'{"required":"0","rule":""}', '2024-12-13 22:37:29.959', '2024-12-13
22:37:29.959');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507030', '20',
'respHeaderUniqueStrategy', 'respHeaderUniqueStrategy', 2, 2, 3,
'{"required":"0","rule":""}', '2024-12-13 22:37:48.239', '2024-12-13
22:37:48.239');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507031', '20',
'respUniqueHeaders', 'respUniqueHeaders', 2, 2, 4,
'{"required":"0","rule":""}', '2024-12-13 22:38:05.726', '2024-12-13
22:38:05.726');
-- ----------------------------
-- Table structure for resource
@@ -2152,6 +2157,8 @@ INSERT INTO "public"."shenyu_dict" VALUES
('1679002911061737474', 'discoveryMode
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737475',
'discoveryMode', 'DISCOVERY_MODE', 'eureka', '{"eurekaClientRefreshInterval":
"10", "eurekaClientRegistryFetchIntervalSeconds": "10"}', 'discoery mode to
link eureka', 0, 1,'2023-03-01 10:48:49', '2023-03-01 10:48:49');
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737478',
'rewriteMetaData', 'REWRITE_META_DATA', 'true', 'true', '', 4, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737479',
'rewriteMetaData', 'REWRITE_META_DATA', 'false', 'false', '', 4, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737480',
'preserveHost', 'PRESERVE_HOST', 'true', 'true', '', 0, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737481',
'preserveHost', 'PRESERVE_HOST', 'false', 'false', '', 1, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
-- ----------------------------
-- Table structure for user_role
diff --git a/db/init/oracle/schema.sql b/db/init/oracle/schema.sql
index 1ec2dde1cf..22463a224e 100644
--- a/db/init/oracle/schema.sql
+++ b/db/init/oracle/schema.sql
@@ -2176,6 +2176,23 @@ values ('1722804548510507025', '8', 'serverLists',
'serverLists', 2, 3, 2, NULL)
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
values ('1722804548510507026', '8', 'props', 'props', 4, 3, 3, NULL);
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507027', '20', 'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}');
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507028', '20', 'requestHeaderUniqueStrategy',
'requestHeaderUniqueStrategy', 2, 2, 1, '{"required":"0","rule":""}');
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507029', '20', 'requestUniqueHeaders',
'requestUniqueHeaders', 2, 2, 2, '{"required":"0","rule":""}');
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507030', '20', 'respHeaderUniqueStrategy',
'respHeaderUniqueStrategy', 2, 2, 3, '{"required":"0","rule":""}');
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507031', '20', 'respUniqueHeaders', 'respUniqueHeaders',
2, 2, 4, '{"required":"0","rule":""}');
+
+
+
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
VALUES ('1529402613195784272', 'securityProtocol', 'SECURITY_PROTOCOL',
'PLAINTEXT', 'PLAINTEXT', '', 1, 1);
@@ -2245,6 +2262,11 @@ VALUES ('1679002911061737474', 'discoveryMode',
'DISCOVERY_MODE', 'nacos', '{"gr
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
VALUES ('1679002911061737475', 'discoveryMode', 'DISCOVERY_MODE', 'eureka',
'{"eurekaClientRefreshInterval": "10",
"eurekaClientRegistryFetchIntervalSeconds": "10"}', 'discoery mode to link
eureka', 0, 1);
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
+VALUES ('1679002911061737480', 'preserveHost', 'PRESERVE_HOST', 'true',
'true', '', 0, 1);
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
+VALUES('1679002911061737481', 'preserveHost', 'PRESERVE_HOST', 'false',
'false', '', 1, 1);
/** insert resource for resource */
diff --git a/db/init/pg/create-table.sql b/db/init/pg/create-table.sql
index 8d4ba5008f..b49dc04cc5 100644
--- a/db/init/pg/create-table.sql
+++ b/db/init/pg/create-table.sql
@@ -1430,6 +1430,11 @@ INSERT INTO "public"."plugin_handle" VALUES
('1722804548510507023', '3', 'rewrit
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507024', '8',
'registerType', 'registerType', 2, 3, 1, NULL, '2024-08-24 09:40:03.293',
'2024-08-24 21:52:27.920');
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507025', '8',
'serverLists', 'serverLists', 2, 3, 2, NULL, '2024-08-24 21:52:51.179',
'2024-08-24 21:53:27.483');
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507026', '8',
'props', 'props', 4, 3, 3, NULL, '2024-08-24 21:53:25.764', '2024-08-24
21:53:30.255');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507027', '20',
'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}', '2024-12-05 22:00:02.251',
'2024-12-05 22:00:02.251');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507028', '20',
'requestHeaderUniqueStrategy', 'requestHeaderUniqueStrategy', 2, 2, 1,
'{"required":"0","rule":""}', '2024-12-13 22:36:54.299', '2024-12-13
22:36:54.299');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507029', '20',
'requestUniqueHeaders', 'requestUniqueHeaders', 2, 2, 2,
'{"required":"0","rule":""}', '2024-12-13 22:37:29.959', '2024-12-13
22:37:29.959');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507030', '20',
'respHeaderUniqueStrategy', 'respHeaderUniqueStrategy', 2, 2, 3,
'{"required":"0","rule":""}', '2024-12-13 22:37:48.239', '2024-12-13
22:37:48.239');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507031', '20',
'respUniqueHeaders', 'respUniqueHeaders', 2, 2, 4,
'{"required":"0","rule":""}', '2024-12-13 22:38:05.726', '2024-12-13
22:38:05.726');
-- ----------------------------
-- Table structure for resource
@@ -2279,6 +2284,8 @@ INSERT INTO "public"."shenyu_dict" VALUES
('1679002911061737474', 'discoveryMode
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737475',
'discoveryMode', 'DISCOVERY_MODE', 'eureka', '{"eurekaClientRefreshInterval":
"10", "eurekaClientRegistryFetchIntervalSeconds": "10"}', 'discoery mode to
link eureka', 0, 1,'2023-03-17 10:15:16.846', '2023-03-07 10:15:16.846');
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737478',
'rewriteMetaData', 'REWRITE_META_DATA', 'true', 'true', '', 4, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737479',
'rewriteMetaData', 'REWRITE_META_DATA', 'false', 'false', '', 4, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737480',
'preserveHost', 'PRESERVE_HOST', 'true', 'true', '', 0, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737481',
'preserveHost', 'PRESERVE_HOST', 'false', 'false', '', 1, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
-- ----------------------------
-- Table structure for user_role
diff --git a/db/upgrade/2.6.1-upgrade-2.7.0-mysql.sql
b/db/upgrade/2.6.1-upgrade-2.7.0-mysql.sql
index 54845ebd1f..df100e302f 100755
--- a/db/upgrade/2.6.1-upgrade-2.7.0-mysql.sql
+++ b/db/upgrade/2.6.1-upgrade-2.7.0-mysql.sql
@@ -23,9 +23,16 @@ INSERT INTO `plugin_handle` VALUES ('1722804548510507024',
'8', 'registerType',
INSERT INTO `plugin_handle` VALUES ('1722804548510507025', '8', 'serverLists',
'serverLists', 2, 3, 2, NULL, '2024-08-24 21:52:51.179', '2024-08-24
21:53:27.483');
INSERT INTO `plugin_handle` VALUES ('1722804548510507026', '8', 'props',
'props', 4, 3, 3, NULL, '2024-08-24 21:53:25.764', '2024-08-24 21:53:30.255');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507027', '20',
'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}', '2024-12-05 22:00:02.251',
'2024-12-05 22:00:02.251');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507028', '20',
'requestHeaderUniqueStrategy', 'requestHeaderUniqueStrategy', 2, 2, 1,
'{"required":"0","rule":""}', '2024-12-13 22:36:54.299', '2024-12-13
22:36:54.299');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507029', '20',
'requestUniqueHeaders', 'requestUniqueHeaders', 2, 2, 2,
'{"required":"0","rule":""}', '2024-12-13 22:37:29.959', '2024-12-13
22:37:29.959');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507030', '20',
'respHeaderUniqueStrategy', 'respHeaderUniqueStrategy', 2, 2, 3,
'{"required":"0","rule":""}', '2024-12-13 22:37:48.239', '2024-12-13
22:37:48.239');
+INSERT INTO `plugin_handle` VALUES ('1722804548510507031', '20',
'respUniqueHeaders', 'respUniqueHeaders', 2, 2, 4,
'{"required":"0","rule":""}', '2024-12-13 22:38:05.726', '2024-12-13
22:38:05.726');
+
INSERT INTO `shenyu_dict` VALUES ('1679002911061737478', 'rewriteMetaData',
'REWRITE_META_DATA', 'true', 'true', '', 4, 1, '2024-02-07 14:31:49',
'2024-02-07 14:31:49');
INSERT INTO `shenyu_dict` VALUES ('1679002911061737479', 'rewriteMetaData',
'REWRITE_META_DATA', 'false', 'false', '', 4, 1, '2024-02-07 14:31:49',
'2024-02-07 14:31:49');
-
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737480', 'preserveHost',
'PRESERVE_HOST', 'true', 'true', '', 0, 1, '2024-12-05 22:00:46.416',
'2024-12-05 22:00:46.416');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737481', 'preserveHost',
'PRESERVE_HOST', 'false', 'false', '', 1, 1, '2024-12-05 22:01:13.396',
'2024-12-05 22:01:13.396');
-- ----------------------------
-- Table structure for sheny_lock
-- ----------------------------
diff --git a/db/upgrade/2.6.1-upgrade-2.7.0-og.sql
b/db/upgrade/2.6.1-upgrade-2.7.0-og.sql
index ab092557bd..1f27167d0b 100644
--- a/db/upgrade/2.6.1-upgrade-2.7.0-og.sql
+++ b/db/upgrade/2.6.1-upgrade-2.7.0-og.sql
@@ -21,10 +21,16 @@ INSERT INTO "public"."plugin_handle" VALUES
('1722804548510507022', '3', 'rewrit
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507024', '8',
'registerType', 'registerType', 2, 3, 1, NULL, '2024-08-24 09:40:03.293',
'2024-08-24 21:52:27.920');
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507025', '8',
'serverLists', 'serverLists', 2, 3, 2, NULL, '2024-08-24 21:52:51.179',
'2024-08-24 21:53:27.483');
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507026', '8',
'props', 'props', 4, 3, 3, NULL, '2024-08-24 21:53:25.764', '2024-08-24
21:53:30.255');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507027', '20',
'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}', '2024-12-05 22:00:02.251',
'2024-12-05 22:00:02.251');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507028', '20',
'requestHeaderUniqueStrategy', 'requestHeaderUniqueStrategy', 2, 2, 1,
'{"required":"0","rule":""}', '2024-12-13 22:36:54.299', '2024-12-13
22:36:54.299');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507029', '20',
'requestUniqueHeaders', 'requestUniqueHeaders', 2, 2, 2,
'{"required":"0","rule":""}', '2024-12-13 22:37:29.959', '2024-12-13
22:37:29.959');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507030', '20',
'respHeaderUniqueStrategy', 'respHeaderUniqueStrategy', 2, 2, 3,
'{"required":"0","rule":""}', '2024-12-13 22:37:48.239', '2024-12-13
22:37:48.239');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507031', '20',
'respUniqueHeaders', 'respUniqueHeaders', 2, 2, 4,
'{"required":"0","rule":""}', '2024-12-13 22:38:05.726', '2024-12-13
22:38:05.726');
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737478',
'rewriteMetaData', 'REWRITE_META_DATA', 'true', 'true', '', 4, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737479',
'rewriteMetaData', 'REWRITE_META_DATA', 'false', 'false', '', 4, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
-
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737480',
'preserveHost', 'PRESERVE_HOST', 'true', 'true', '', 0, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737481',
'preserveHost', 'PRESERVE_HOST', 'false', 'false', '', 1, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
-- ----------------------------
-- Table structure for shenyu_lock
-- ----------------------------
diff --git a/db/upgrade/2.6.1-upgrade-2.7.0-oracle.sql
b/db/upgrade/2.6.1-upgrade-2.7.0-oracle.sql
index cf86c37039..03bf078847 100755
--- a/db/upgrade/2.6.1-upgrade-2.7.0-oracle.sql
+++ b/db/upgrade/2.6.1-upgrade-2.7.0-oracle.sql
@@ -21,6 +21,12 @@ VALUES ('1679002911061737478', 'rewriteMetaData',
'REWRITE_META_DATA', 'true', '
INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ INTO SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
VALUES ('1679002911061737479', 'rewriteMetaData', 'REWRITE_META_DATA',
'false', 'false', '', 4, 1);
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
+VALUES ('1679002911061737480', 'preserveHost', 'PRESERVE_HOST', 'true',
'true', '', 0, 1);
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
+VALUES('1679002911061737481', 'preserveHost', 'PRESERVE_HOST', 'false',
'false', '', 1, 1);
+
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
values ('1722804548510507020', '14', 'rewriteContextPath',
'rewriteContextPath', 2, 2, 2, '{"required":"0","defaultValue":""}');
@@ -39,6 +45,22 @@ values ('1722804548510507025', '8', 'serverLists',
'serverLists', 2, 3, 2, NULL)
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
values ('1722804548510507026', '8', 'props', 'props', 4, 3, 3, NULL);
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507027', '20', 'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}');
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507028', '20', 'requestHeaderUniqueStrategy',
'requestHeaderUniqueStrategy', 2, 2, 1, '{"required":"0","rule":""}');
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507029', '20', 'requestUniqueHeaders',
'requestUniqueHeaders', 2, 2, 2, '{"required":"0","rule":""}');
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507030', '20', 'respHeaderUniqueStrategy',
'respHeaderUniqueStrategy', 2, 2, 3, '{"required":"0","rule":""}');
+
+insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(plugin_id, field, type))
*/ into plugin_handle (ID, PLUGIN_ID, FIELD, LABEL, DATA_TYPE, TYPE, SORT,
EXT_OBJ)
+values ('1722804548510507031', '20', 'respUniqueHeaders', 'respUniqueHeaders',
2, 2, 4, '{"required":"0","rule":""}');
+
+
-- ----------------------------
-- Table structure for SHENYU_LOCK
-- ----------------------------
diff --git a/db/upgrade/2.6.1-upgrade-2.7.0-pg.sql
b/db/upgrade/2.6.1-upgrade-2.7.0-pg.sql
index d834e9a3e4..71c2ca5c3a 100755
--- a/db/upgrade/2.6.1-upgrade-2.7.0-pg.sql
+++ b/db/upgrade/2.6.1-upgrade-2.7.0-pg.sql
@@ -21,9 +21,16 @@ INSERT INTO "public"."plugin_handle" VALUES
('1722804548510507022', '3', 'rewrit
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507024', '8',
'registerType', 'registerType', 2, 3, 1, NULL, '2024-08-24 09:40:03.293',
'2024-08-24 21:52:27.920');
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507025', '8',
'serverLists', 'serverLists', 2, 3, 2, NULL, '2024-08-24 21:52:51.179',
'2024-08-24 21:53:27.483');
INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507026', '8',
'props', 'props', 4, 3, 3, NULL, '2024-08-24 21:53:25.764', '2024-08-24
21:53:30.255');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507027', '20',
'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}', '2024-12-05 22:00:02.251',
'2024-12-05 22:00:02.251');
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737478',
'rewriteMetaData', 'REWRITE_META_DATA', 'true', 'true', '', 4, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737479',
'rewriteMetaData', 'REWRITE_META_DATA', 'false', 'false', '', 4, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737480',
'preserveHost', 'PRESERVE_HOST', 'true', 'true', '', 0, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737481',
'preserveHost', 'PRESERVE_HOST', 'false', 'false', '', 1, 1, '2024-02-07
14:31:49', '2024-02-07 14:31:49');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507028', '20',
'requestHeaderUniqueStrategy', 'requestHeaderUniqueStrategy', 2, 2, 1,
'{"required":"0","rule":""}', '2024-12-13 22:36:54.299', '2024-12-13
22:36:54.299');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507029', '20',
'requestUniqueHeaders', 'requestUniqueHeaders', 2, 2, 2,
'{"required":"0","rule":""}', '2024-12-13 22:37:29.959', '2024-12-13
22:37:29.959');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507030', '20',
'respHeaderUniqueStrategy', 'respHeaderUniqueStrategy', 2, 2, 3,
'{"required":"0","rule":""}', '2024-12-13 22:37:48.239', '2024-12-13
22:37:48.239');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507031', '20',
'respUniqueHeaders', 'respUniqueHeaders', 2, 2, 4,
'{"required":"0","rule":""}', '2024-12-13 22:38:05.726', '2024-12-13
22:38:05.726');
-- ----------------------------
-- Table structure for shenyu_lock
diff --git a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
index efe0acebc2..38c16b23ae 100755
--- a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
+++ b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
@@ -918,6 +918,11 @@ INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,
INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES
('1722804548510507024', '8', 'registerType', 'registerType', 2, 3, 1, NULL);
INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES
('1722804548510507025', '8', 'serverLists', 'serverLists', 2, 3, 2, NULL);
INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES
('1722804548510507026', '8', 'props', 'props', 4, 3, 3, NULL);
+INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES
('1722804548510507027', '20', 'preserveHost', 'preserveHost', 3, 2, 0,
'{"required":"0","defaultValue":"false","rule":""}');
+INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES
('1722804548510507028', '20', 'requestHeaderUniqueStrategy',
'requestHeaderUniqueStrategy', 2, 2, 1, '{"required":"0","rule":""}');
+INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES
('1722804548510507029', '20', 'requestUniqueHeaders', 'requestUniqueHeaders',
2, 2, 2, '{"required":"0","rule":""}');
+INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES
('1722804548510507030', '20', 'respHeaderUniqueStrategy',
'respHeaderUniqueStrategy', 2, 2, 3, '{"required":"0","rule":""}');
+INSERT IGNORE INTO plugin_handle (`id`,
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES
('1722804548510507031', '8', '20', 'respUniqueHeaders', 'respUniqueHeaders', 2,
2, 4, '{"required":"0","rule":""}');
/** insert resource for resource */
INSERT IGNORE INTO `resource` (`id`, `parent_id`, `title`, `name`, `url`,
`component`, `resource_type`, `sort`, `icon`, `is_leaf`, `is_route`, `perms`,
`status`)
VALUES('1346775491550474240','','SHENYU.MENU.PLUGIN.LIST','plug','/plug','PluginList','0','0','dashboard','0','0','','1');
diff --git a/shenyu-bootstrap/src/main/resources/application.yml
b/shenyu-bootstrap/src/main/resources/application.yml
index 18fbbf7880..f852f0c14a 100644
--- a/shenyu-bootstrap/src/main/resources/application.yml
+++ b/shenyu-bootstrap/src/main/resources/application.yml
@@ -193,10 +193,6 @@ shenyu:
# selectCount: 1
# workerCount: 8
# daemon: true
- duplicate-response-header:
- strategy: RETAIN_FIRST
- headers:
- - Access-Control-Allow-Origin
register:
enabled: false
registerType: zookeeper #etcd #consul
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
index 77b0251588..3cd0c7d16f 100644
---
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
@@ -925,6 +925,11 @@ public interface Constants {
* The constant EVENT_NAME_REGISTER.
*/
String HTTP_PATH = "shenyu.httpPath";
+
+ /**
+ * The constant preserve host.
+ */
+ String PRESERVE_HOST = "preserveHost";
/**
* String q.
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/RequestHandle.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/RequestHandle.java
index 97b5872517..e53a9cb141 100644
---
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/RequestHandle.java
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/RequestHandle.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.common.dto.convert.rule;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
+import org.apache.shenyu.common.enums.HeaderUniqueStrategyEnum;
import java.util.Map;
import java.util.Objects;
@@ -35,6 +36,16 @@ public class RequestHandle {
private ShenyuCookie cookie;
+ private Boolean preserveHost = Boolean.FALSE;
+
+ private HeaderUniqueStrategyEnum requestHeaderUniqueStrategy =
HeaderUniqueStrategyEnum.RETAIN_FIRST;
+
+ private String requestUniqueHeaders;
+
+ private HeaderUniqueStrategyEnum respHeaderUniqueStrategy =
HeaderUniqueStrategyEnum.RETAIN_FIRST;
+
+ private String respUniqueHeaders;
+
/**
* get header.
*
@@ -89,6 +100,96 @@ public class RequestHandle {
this.cookie = cookie;
}
+ /**
+ * get preserveHost.
+ *
+ * @return preserveHost
+ */
+ public Boolean getPreserveHost() {
+ return preserveHost;
+ }
+
+ /**
+ * set preserveHost.
+ *
+ * @param preserveHost preserveHost
+ */
+ public void setPreserveHost(final Boolean preserveHost) {
+ this.preserveHost = preserveHost;
+ }
+
+ /**
+ * get headerUniqueStrategy.
+ *
+ * @return headerUniqueStrategy
+ */
+ public HeaderUniqueStrategyEnum getRequestHeaderUniqueStrategy() {
+ return requestHeaderUniqueStrategy;
+ }
+
+ /**
+ * set headerUniqueStrategy.
+ *
+ * @param requestHeaderUniqueStrategy requestHeaderUniqueStrategy
+ */
+ public void setRequestHeaderUniqueStrategy(final HeaderUniqueStrategyEnum
requestHeaderUniqueStrategy) {
+ this.requestHeaderUniqueStrategy = requestHeaderUniqueStrategy;
+ }
+
+ /**
+ * get uniqueHeader.
+ *
+ * @return uniqueHeader
+ */
+ public String getRequestUniqueHeaders() {
+ return requestUniqueHeaders;
+ }
+
+ /**
+ * set uniqueHeader.
+ *
+ * @param requestUniqueHeaders requestUniqueHeaders
+ */
+ public void setRequestUniqueHeaders(final String requestUniqueHeaders) {
+ this.requestUniqueHeaders = requestUniqueHeaders;
+ }
+
+ /**
+ * get respHeaderUniqueStrategy.
+ *
+ * @return respHeaderUniqueStrategy
+ */
+ public HeaderUniqueStrategyEnum getRespHeaderUniqueStrategy() {
+ return respHeaderUniqueStrategy;
+ }
+
+ /**
+ * set respHeaderUniqueStrategy.
+ *
+ * @param respHeaderUniqueStrategy respHeaderUniqueStrategy
+ */
+ public void setRespHeaderUniqueStrategy(final HeaderUniqueStrategyEnum
respHeaderUniqueStrategy) {
+ this.respHeaderUniqueStrategy = respHeaderUniqueStrategy;
+ }
+
+ /**
+ * get respUniqueHeaders.
+ *
+ * @return respUniqueHeaders
+ */
+ public String getRespUniqueHeaders() {
+ return respUniqueHeaders;
+ }
+
+ /**
+ * set respUniqueHeaders.
+ *
+ * @param respUniqueHeaders respUniqueHeaders
+ */
+ public void setRespUniqueHeaders(final String respUniqueHeaders) {
+ this.respUniqueHeaders = respUniqueHeaders;
+ }
+
@Override
public boolean equals(final Object o) {
if (this == o) {
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/enums/HeaderUniqueStrategyEnum.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/HeaderUniqueStrategyEnum.java
new file mode 100644
index 0000000000..4ed8b119f6
--- /dev/null
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/HeaderUniqueStrategyEnum.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.common.enums;
+
+/**
+ * Gets duplicate response headers handle strategy.
+ */
+public enum HeaderUniqueStrategyEnum {
+
+ /**
+ * Default: Retain the first value only.
+ */
+ RETAIN_FIRST,
+
+ /**
+ * Retain the last value only.
+ */
+ RETAIN_LAST,
+
+ /**
+ * Retain all unique values in the order of their first encounter.
+ */
+ RETAIN_UNIQUE
+}
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/enums/UniqueHeaderEnum.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/UniqueHeaderEnum.java
new file mode 100644
index 0000000000..cc06680d5e
--- /dev/null
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/UniqueHeaderEnum.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.common.enums;
+
+public enum UniqueHeaderEnum {
+ REQ_UNIQUE_HEADER("requestUniqueHeaders", "requestHeaderUniqueStrategy"),
+
+ RESP_UNIQUE_HEADER("responseUniqueHeaders",
"responseHeaderUniqueStrategy");
+
+ private final String name;
+
+ private final String strategy;
+
+ UniqueHeaderEnum(final String name, final String strategy) {
+ this.name = name;
+ this.strategy = strategy;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getStrategy() {
+ return strategy;
+ }
+}
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/AbstractHttpClientPlugin.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/AbstractHttpClientPlugin.java
index a7e3befe9a..69ba3c364a 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/AbstractHttpClientPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/AbstractHttpClientPlugin.java
@@ -21,8 +21,11 @@ import com.google.common.collect.Sets;
import io.netty.channel.ConnectTimeoutException;
import io.netty.handler.timeout.ReadTimeoutException;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.enums.HeaderUniqueStrategyEnum;
import org.apache.shenyu.common.enums.RetryEnum;
+import org.apache.shenyu.common.enums.UniqueHeaderEnum;
import org.apache.shenyu.common.exception.ShenyuException;
import org.apache.shenyu.common.utils.LogUtils;
import org.apache.shenyu.loadbalancer.cache.UpstreamCacheManager;
@@ -35,7 +38,6 @@ import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
import org.apache.shenyu.plugin.api.result.ShenyuResultWrap;
import org.apache.shenyu.plugin.api.utils.RequestUrlUtils;
import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
-import
org.apache.shenyu.plugin.httpclient.config.DuplicateResponseHeaderProperties.DuplicateResponseHeaderStrategy;
import org.apache.shenyu.plugin.httpclient.exception.ShenyuTimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -52,6 +54,7 @@ import reactor.util.retry.RetryBackoffSpec;
import java.net.URI;
import java.time.Duration;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
@@ -171,8 +174,23 @@ public abstract class AbstractHttpClientPlugin<R>
implements ShenyuPlugin {
*/
protected abstract Mono<R> doRequest(ServerWebExchange exchange, String
httpMethod,
URI uri, Flux<DataBuffer> body);
+
+ protected void duplicateHeaders(final ServerWebExchange exchange, final
HttpHeaders headers, final UniqueHeaderEnum uniqueHeaderEnum) {
+ final String duplicateHeader =
exchange.getAttribute(uniqueHeaderEnum.getName());
+ if (StringUtils.isEmpty(duplicateHeader)) {
+ return;
+ }
+ List<String> duplicateHeaderList =
Arrays.asList(StringUtils.split(duplicateHeader, Constants.SEPARATOR_CHARS));
+ if (CollectionUtils.isEmpty(duplicateHeaderList)) {
+ return;
+ }
+ HeaderUniqueStrategyEnum strategy =
exchange.getAttributeOrDefault(uniqueHeaderEnum.getStrategy(),
HeaderUniqueStrategyEnum.RETAIN_FIRST);
+ for (String headerKey : duplicateHeaderList) {
+ this.duplicate(headers, headerKey, strategy);
+ }
+ }
- protected void duplicateHeaders(final HttpHeaders headers, final String
header, final DuplicateResponseHeaderStrategy strategy) {
+ protected void duplicate(final HttpHeaders headers, final String header,
final HeaderUniqueStrategyEnum strategy) {
List<String> headerValues = headers.get(header);
if (Objects.isNull(headerValues) || headerValues.size() <= 1) {
return;
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
index 528878e3ba..a0c135ebc7 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
@@ -18,17 +18,17 @@
package org.apache.shenyu.plugin.httpclient;
import io.netty.handler.codec.http.HttpMethod;
-import org.apache.commons.collections4.CollectionUtils;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.common.enums.PluginEnum;
-import
org.apache.shenyu.plugin.httpclient.config.DuplicateResponseHeaderProperties;
-import
org.apache.shenyu.plugin.httpclient.config.DuplicateResponseHeaderProperties.DuplicateResponseHeaderStrategy;
+import org.apache.shenyu.common.enums.UniqueHeaderEnum;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.NettyDataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.AbstractServerHttpResponse;
+import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
@@ -37,7 +37,6 @@ import reactor.netty.http.client.HttpClient;
import reactor.netty.http.client.HttpClientResponse;
import java.net.URI;
-import java.util.List;
import java.util.Objects;
/**
@@ -47,25 +46,28 @@ public class NettyHttpClientPlugin extends
AbstractHttpClientPlugin<HttpClientRe
private final HttpClient httpClient;
- private final DuplicateResponseHeaderProperties properties;
-
/**
* Instantiates a new Netty http client plugin.
*
* @param httpClient the http client
- * @param properties proerties
*/
- public NettyHttpClientPlugin(final HttpClient httpClient, final
DuplicateResponseHeaderProperties properties) {
+ public NettyHttpClientPlugin(final HttpClient httpClient) {
this.httpClient = httpClient;
- this.properties = properties;
}
@Override
protected Mono<HttpClientResponse> doRequest(final ServerWebExchange
exchange, final String httpMethod,
final URI uri, final
Flux<DataBuffer> body) {
+ ServerHttpRequest request = exchange.getRequest();
+ final HttpHeaders httpHeaders = new HttpHeaders(request.getHeaders());
+ this.duplicateHeaders(exchange, httpHeaders,
UniqueHeaderEnum.REQ_UNIQUE_HEADER);
return Mono.from(httpClient.headers(headers -> {
- exchange.getRequest().getHeaders().forEach(headers::add);
+ httpHeaders.forEach(headers::set);
headers.remove(HttpHeaders.HOST);
+ Boolean preserveHost =
exchange.getAttributeOrDefault(Constants.PRESERVE_HOST, Boolean.FALSE);
+ if (preserveHost) {
+ headers.add(HttpHeaders.HOST,
request.getHeaders().getFirst(HttpHeaders.HOST));
+ }
}).request(HttpMethod.valueOf(httpMethod)).uri(uri.toASCIIString())
.send((req, nettyOutbound) ->
nettyOutbound.send(body.map(dataBuffer -> ((NettyDataBuffer)
dataBuffer).getNativeBuffer())))
.responseConnection((res, connection) -> {
@@ -74,7 +76,7 @@ public class NettyHttpClientPlugin extends
AbstractHttpClientPlugin<HttpClientRe
final ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = new HttpHeaders();
res.responseHeaders().forEach(entry ->
headers.add(entry.getKey(), entry.getValue()));
- this.duplicate(headers);
+ this.duplicateHeaders(exchange, httpHeaders,
UniqueHeaderEnum.RESP_UNIQUE_HEADER);
String contentTypeValue =
headers.getFirst(HttpHeaders.CONTENT_TYPE);
if (StringUtils.isNotBlank(contentTypeValue)) {
exchange.getAttributes().put(Constants.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR,
contentTypeValue);
@@ -92,16 +94,6 @@ public class NettyHttpClientPlugin extends
AbstractHttpClientPlugin<HttpClientRe
}));
}
- private void duplicate(final HttpHeaders headers) {
- List<String> duplicateHeaders = properties.getHeaders();
- if (CollectionUtils.isEmpty(duplicateHeaders)) {
- return;
- }
- DuplicateResponseHeaderStrategy strategy = properties.getStrategy();
- for (String headerKey : duplicateHeaders) {
- duplicateHeaders(headers, headerKey, strategy);
- }
- }
@Override
public int getOrder() {
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
index b12cd81169..0e8d6a545a 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
@@ -17,26 +17,24 @@
package org.apache.shenyu.plugin.httpclient;
-import org.apache.commons.collections4.CollectionUtils;
import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.common.enums.PluginEnum;
import org.apache.shenyu.common.enums.ResultEnum;
+import org.apache.shenyu.common.enums.UniqueHeaderEnum;
import org.apache.shenyu.plugin.base.utils.MediaTypeUtils;
-import
org.apache.shenyu.plugin.httpclient.config.DuplicateResponseHeaderProperties;
-import
org.apache.shenyu.plugin.httpclient.config.DuplicateResponseHeaderProperties.DuplicateResponseHeaderStrategy;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
+import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.net.URI;
-import java.util.List;
/**
* The type Web client plugin.
@@ -44,18 +42,14 @@ import java.util.List;
public class WebClientPlugin extends
AbstractHttpClientPlugin<ResponseEntity<Flux<DataBuffer>>> {
private final WebClient webClient;
-
- private final DuplicateResponseHeaderProperties properties;
/**
* Instantiates a new Web client plugin.
*
* @param webClient the web client
- * @param properties properties
*/
- public WebClientPlugin(final WebClient webClient, final
DuplicateResponseHeaderProperties properties) {
+ public WebClientPlugin(final WebClient webClient) {
this.webClient = webClient;
- this.properties = properties;
}
@Override
@@ -64,10 +58,17 @@ public class WebClientPlugin extends
AbstractHttpClientPlugin<ResponseEntity<Flu
// springWebflux5.3 mark #exchange() deprecated. because #echange
maybe make memory leak.
// https://github.com/spring-projects/spring-framework/issues/25751
// exchange is deprecated, so change to {@link
WebClient.RequestHeadersSpec#exchangeToMono(Function)}
+ ServerHttpRequest request = exchange.getRequest();
+ final HttpHeaders httpHeaders = new HttpHeaders(request.getHeaders());
+ this.duplicateHeaders(exchange, httpHeaders,
UniqueHeaderEnum.REQ_UNIQUE_HEADER);
final WebClient.ResponseSpec responseSpec =
webClient.method(HttpMethod.valueOf(httpMethod)).uri(uri)
.headers(headers -> {
headers.addAll(exchange.getRequest().getHeaders());
headers.remove(HttpHeaders.HOST);
+ Boolean preserveHost =
exchange.getAttributeOrDefault(Constants.PRESERVE_HOST, Boolean.FALSE);
+ if (preserveHost) {
+ headers.add(HttpHeaders.HOST,
request.getHeaders().getFirst(HttpHeaders.HOST));
+ }
})
.body((outputMessage, context) -> {
MediaType mediaType =
exchange.getRequest().getHeaders().getContentType();
@@ -89,24 +90,13 @@ public class WebClientPlugin extends
AbstractHttpClientPlugin<ResponseEntity<Flu
}
HttpHeaders headers = new HttpHeaders();
headers.addAll(fluxResponseEntity.getHeaders());
- this.duplicate(headers);
+ this.duplicateHeaders(exchange, headers,
UniqueHeaderEnum.RESP_UNIQUE_HEADER);
exchange.getResponse().getHeaders().putAll(headers);
exchange.getResponse().setStatusCode(fluxResponseEntity.getStatusCode());
exchange.getAttributes().put(Constants.CLIENT_RESPONSE_ATTR,
fluxResponseEntity);
return Mono.just(fluxResponseEntity);
});
}
-
- private void duplicate(final HttpHeaders headers) {
- List<String> duplicateHeaders = properties.getHeaders();
- if (CollectionUtils.isEmpty(duplicateHeaders)) {
- return;
- }
- DuplicateResponseHeaderStrategy strategy = properties.getStrategy();
- for (String headerKey : duplicateHeaders) {
- duplicateHeaders(headers, headerKey, strategy);
- }
- }
@Override
public int getOrder() {
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/DuplicateResponseHeaderProperties.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/DuplicateResponseHeaderProperties.java
deleted file mode 100644
index 3dbbdfc610..0000000000
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/DuplicateResponseHeaderProperties.java
+++ /dev/null
@@ -1,90 +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.
- */
-
-package org.apache.shenyu.plugin.httpclient.config;
-
-import java.util.List;
-
-public class DuplicateResponseHeaderProperties {
-
- /**
- * Duplicate response headers.
- */
- private List<String> headers;
-
- /**
- * Duplicate response headers handle strategy.
- */
- private DuplicateResponseHeaderStrategy strategy =
DuplicateResponseHeaderStrategy.RETAIN_FIRST;
-
- /**
- * Gets duplicate response headers.
- *
- * @return duplicate response headers
- */
- public List<String> getHeaders() {
- return headers;
- }
-
- /**
- * Sets duplicate response headers.
- *
- * @param headers duplicate response headers
- */
- public void setHeaders(final List<String> headers) {
- this.headers = headers;
- }
-
- /**
- * Gets duplicate response headers handle strategy.
- *
- * @return duplicate response headers handle strategy
- */
- public DuplicateResponseHeaderStrategy getStrategy() {
- return strategy;
- }
-
- /**
- * Sets duplicate response headers handle strategy.
- *
- * @param strategy strategy
- */
- public void setStrategy(final DuplicateResponseHeaderStrategy strategy) {
- this.strategy = strategy;
- }
-
- /**
- * Gets duplicate response headers handle strategy.
- */
- public enum DuplicateResponseHeaderStrategy {
-
- /**
- * Default: Retain the first value only.
- */
- RETAIN_FIRST,
-
- /**
- * Retain the last value only.
- */
- RETAIN_LAST,
-
- /**
- * Retain all unique values in the order of their first encounter.
- */
- RETAIN_UNIQUE
- }
-}
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPluginTest.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPluginTest.java
index 77b7386f7e..aeac9d5318 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPluginTest.java
@@ -26,7 +26,6 @@ import org.apache.shenyu.plugin.api.ShenyuPluginChain;
import org.apache.shenyu.plugin.api.context.ShenyuContext;
import org.apache.shenyu.plugin.api.result.ShenyuResult;
import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
-import
org.apache.shenyu.plugin.httpclient.config.DuplicateResponseHeaderProperties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -69,7 +68,7 @@ public final class NettyHttpClientPluginTest {
chain = mock(ShenyuPluginChain.class);
when(chain.execute(any())).thenReturn(Mono.empty());
HttpClient httpClient = HttpClient.create();
- nettyHttpClientPlugin = new NettyHttpClientPlugin(httpClient, new
DuplicateResponseHeaderProperties());
+ nettyHttpClientPlugin = new NettyHttpClientPlugin(httpClient);
}
/**
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/WebClientPluginTest.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/WebClientPluginTest.java
index 204c43d554..2b26962a8a 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/WebClientPluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/WebClientPluginTest.java
@@ -24,7 +24,6 @@ import org.apache.shenyu.plugin.api.ShenyuPluginChain;
import org.apache.shenyu.plugin.api.context.ShenyuContext;
import org.apache.shenyu.plugin.api.result.ShenyuResult;
import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
-import
org.apache.shenyu.plugin.httpclient.config.DuplicateResponseHeaderProperties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -78,7 +77,7 @@ public final class WebClientPluginTest {
when(context.getBean(ShenyuResult.class)).thenReturn(mock(ShenyuResult.class));
WebClient webClient = mockWebClientOK();
- webClientPlugin = new WebClientPlugin(webClient, new
DuplicateResponseHeaderProperties());
+ webClientPlugin = new WebClientPlugin(webClient);
}
/**
@@ -91,7 +90,7 @@ public final class WebClientPluginTest {
ServerWebExchange exchangeNoPathTest = MockServerWebExchange
.from(MockServerHttpRequest.get("/test").build());
exchangeNoPathTest.getAttributes().put(Constants.CONTEXT,
mock(ShenyuContext.class));
- WebClientPlugin webClientPluginNoPathTest = new
WebClientPlugin(webClientNoPathTest, new DuplicateResponseHeaderProperties());
+ WebClientPlugin webClientPluginNoPathTest = new
WebClientPlugin(webClientNoPathTest);
Mono<Void> monoNoPathTest =
webClientPluginNoPathTest.execute(exchangeNoPathTest, chainNoPathTest);
StepVerifier.create(monoNoPathTest).expectSubscription().verifyComplete();
@@ -101,19 +100,19 @@ public final class WebClientPluginTest {
.from(MockServerHttpRequest.post("/test123?param=1").build());
exchangePostTest.getAttributes().put(Constants.CONTEXT,
mock(ShenyuContext.class));
exchangePostTest.getAttributes().put(Constants.HTTP_URI,
URI.create("/test123?param=1"));
- WebClientPlugin webClientPluginPostTest = new
WebClientPlugin(webClientPostTest, new DuplicateResponseHeaderProperties());
+ WebClientPlugin webClientPluginPostTest = new
WebClientPlugin(webClientPostTest);
Mono<Void> monoPostTest =
webClientPluginPostTest.execute(exchangePostTest, chainPostTest);
StepVerifier.create(monoPostTest).expectSubscription().verifyError();
final ShenyuPluginChain chainOkTest = mock(ShenyuPluginChain.class);
final WebClient webClientOkTest = mockWebClientOK();
- WebClientPlugin webClientPluginOkTest = new
WebClientPlugin(webClientOkTest, new DuplicateResponseHeaderProperties());
+ WebClientPlugin webClientPluginOkTest = new
WebClientPlugin(webClientOkTest);
Mono<Void> monoOkTest =
webClientPluginOkTest.execute(generateServerWebExchange(), chainOkTest);
StepVerifier.create(monoOkTest).expectSubscription().verifyError();
final ShenyuPluginChain chainErrorTest = mock(ShenyuPluginChain.class);
final WebClient webClientErrorTest = mockWebClientError();
- WebClientPlugin webClientPluginErrorTest = new
WebClientPlugin(webClientErrorTest, new DuplicateResponseHeaderProperties());
+ WebClientPlugin webClientPluginErrorTest = new
WebClientPlugin(webClientErrorTest);
Mono<Void> monoErrorTest =
webClientPluginErrorTest.execute(generateServerWebExchange(), chainErrorTest);
StepVerifier.create(monoErrorTest).expectSubscription().verifyError();
}
diff --git
a/shenyu-plugin/shenyu-plugin-request/src/main/java/org/apache/shenyu/plugin/request/RequestPlugin.java
b/shenyu-plugin/shenyu-plugin-request/src/main/java/org/apache/shenyu/plugin/request/RequestPlugin.java
index bc30d525cd..0d3cef6a5e 100644
---
a/shenyu-plugin/shenyu-plugin-request/src/main/java/org/apache/shenyu/plugin/request/RequestPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-request/src/main/java/org/apache/shenyu/plugin/request/RequestPlugin.java
@@ -20,10 +20,12 @@ package org.apache.shenyu.plugin.request;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.common.dto.RuleData;
import org.apache.shenyu.common.dto.SelectorData;
import org.apache.shenyu.common.dto.convert.rule.RequestHandle;
import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.enums.UniqueHeaderEnum;
import org.apache.shenyu.plugin.api.ShenyuPluginChain;
import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
@@ -56,10 +58,23 @@ public class RequestPlugin extends AbstractShenyuPlugin {
protected Mono<Void> doExecute(final ServerWebExchange exchange, final
ShenyuPluginChain chain, final SelectorData selector,
final RuleData rule) {
RequestHandle requestHandle =
RequestPluginHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
- if (Objects.isNull(requestHandle) || requestHandle.isEmptyConfig()) {
+ if (Objects.isNull(requestHandle)) {
LOG.error("request handler can not configuration:{}",
requestHandle);
return chain.execute(exchange);
}
+ exchange.getAttributes().put(Constants.PRESERVE_HOST,
requestHandle.getPreserveHost());
+ if (Objects.nonNull(requestHandle.getRequestHeaderUniqueStrategy()) &&
StringUtils.isNotEmpty(requestHandle.getRequestUniqueHeaders())) {
+
exchange.getAttributes().put(UniqueHeaderEnum.REQ_UNIQUE_HEADER.getStrategy(),
requestHandle.getRequestHeaderUniqueStrategy());
+
exchange.getAttributes().put(UniqueHeaderEnum.REQ_UNIQUE_HEADER.getName(),
requestHandle.getRequestUniqueHeaders());
+ }
+ if (Objects.nonNull(requestHandle.getRequestHeaderUniqueStrategy()) &&
StringUtils.isNotEmpty(requestHandle.getRespUniqueHeaders())) {
+
exchange.getAttributes().put(UniqueHeaderEnum.RESP_UNIQUE_HEADER.getStrategy(),
requestHandle.getRespHeaderUniqueStrategy());
+
exchange.getAttributes().put(UniqueHeaderEnum.RESP_UNIQUE_HEADER.getName(),
requestHandle.getRespUniqueHeaders());
+ }
+ if (requestHandle.isEmptyConfig()) {
+ LOG.warn("request handler configuration is empty:{}",
requestHandle);
+ return chain.execute(exchange);
+ }
ServerHttpRequest request = exchange.getRequest();
ServerWebExchange modifiedExchange = exchange.mutate()
.request(originalRequest -> originalRequest.uri(
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfiguration.java
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfiguration.java
index c889a90e3a..cbd6b83765 100644
---
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfiguration.java
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfiguration.java
@@ -21,7 +21,6 @@ import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.plugin.api.ShenyuPlugin;
import org.apache.shenyu.plugin.httpclient.NettyHttpClientPlugin;
import org.apache.shenyu.plugin.httpclient.WebClientPlugin;
-import
org.apache.shenyu.plugin.httpclient.config.DuplicateResponseHeaderProperties;
import org.apache.shenyu.plugin.httpclient.config.HttpClientProperties;
import org.springframework.beans.factory.ObjectProvider;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -54,17 +53,6 @@ public class HttpClientPluginConfiguration {
public HttpClientProperties httpClientProperties() {
return new HttpClientProperties();
}
-
- /**
- * http response duplicate response headers config.
- *
- * @return the duplicate response header properties
- */
- @Bean
- @ConfigurationProperties(prefix = "shenyu.duplicate-response-header")
- public DuplicateResponseHeaderProperties responseHeaderProperties() {
- return new DuplicateResponseHeaderProperties();
- }
/**
* Http client loop resource.
@@ -113,8 +101,7 @@ public class HttpClientPluginConfiguration {
@Bean
public ShenyuPlugin webClientPlugin(
final HttpClientProperties properties,
- final ObjectProvider<HttpClient> httpClient,
- final DuplicateResponseHeaderProperties
responseHeaderProperties) {
+ final ObjectProvider<HttpClient> httpClient) {
WebClient webClient = WebClient.builder()
// fix Exceeded limit on max bytes to buffer
// detail see
https://stackoverflow.com/questions/59326351/configure-spring-codec-max-in-memory-size-when-using-reactiveelasticsearchclient
@@ -123,7 +110,7 @@ public class HttpClientPluginConfiguration {
.build())
.clientConnector(new
ReactorClientHttpConnector(Objects.requireNonNull(httpClient.getIfAvailable())))
.build();
- return new WebClientPlugin(webClient, responseHeaderProperties);
+ return new WebClientPlugin(webClient);
}
}
@@ -141,9 +128,8 @@ public class HttpClientPluginConfiguration {
* @return the shenyu plugin
*/
@Bean
- public ShenyuPlugin nettyHttpClientPlugin(final
ObjectProvider<HttpClient> httpClient,
- final
DuplicateResponseHeaderProperties responseHeaderProperties) {
- return new NettyHttpClientPlugin(httpClient.getIfAvailable(),
responseHeaderProperties);
+ public ShenyuPlugin nettyHttpClientPlugin(final
ObjectProvider<HttpClient> httpClient) {
+ return new NettyHttpClientPlugin(httpClient.getIfAvailable());
}
}
}