Skip to content

Commit df52ca3

Browse files
committed
fixes #93 Split HeaderMiddleware to request and response middleware handlers
1 parent de27ab4 commit df52ca3

File tree

10 files changed

+301
-139
lines changed

10 files changed

+301
-139
lines changed
Lines changed: 36 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,29 @@
11
package com.networknt.aws.lambda.handler.middleware.header;
22

3-
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
4-
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
5-
import com.networknt.aws.lambda.handler.MiddlewareHandler;
63
import com.networknt.aws.lambda.LightLambdaExchange;
4+
import com.networknt.aws.lambda.handler.MiddlewareHandler;
75
import com.networknt.config.Config;
86
import com.networknt.header.HeaderConfig;
97
import com.networknt.status.Status;
108
import com.networknt.utility.ModuleRegistry;
119
import org.slf4j.Logger;
1210
import org.slf4j.LoggerFactory;
1311

14-
import java.util.List;
15-
import java.util.Map;
16-
17-
public class HeaderMiddleware implements MiddlewareHandler {
12+
import java.util.*;
1813

19-
private static final String UNKNOWN_HEADER_OPERATION = "ERR14004";
20-
private static HeaderConfig CONFIG;
14+
public abstract class HeaderMiddleware implements MiddlewareHandler {
15+
static HeaderConfig CONFIG;
2116
private static final Logger LOG = LoggerFactory.getLogger(HeaderMiddleware.class);
2217

2318
public HeaderMiddleware() {
2419
CONFIG = HeaderConfig.load();
25-
LOG.info("HeaderMiddleware is constructed");
2620
}
2721

28-
/**
29-
* Constructor with configuration for testing purpose only
30-
* @param cfg HeaderConfig
31-
*/
3222
public HeaderMiddleware(HeaderConfig cfg) {
3323
CONFIG = cfg;
3424
LOG.info("HeaderMiddleware is constructed");
3525
}
3626

37-
@Override
38-
public Status execute(final LightLambdaExchange exchange) {
39-
if(LOG.isTraceEnabled()) LOG.trace("HeaderMiddleware.executeMiddleware starts.");
40-
if (!CONFIG.isEnabled()) {
41-
if(LOG.isTraceEnabled()) LOG.trace("HeaderMiddleware is not enabled.");
42-
return disabledMiddlewareStatus();
43-
}
44-
if(LOG.isTraceEnabled()) LOG.trace("HeaderMiddleware.executeMiddleware ends.");
45-
return this.handleHeaders(exchange);
46-
}
47-
48-
49-
private Status handleHeaders(LightLambdaExchange exchange) {
50-
// handle request headers
51-
if(exchange.isRequestInProgress()) {
52-
APIGatewayProxyRequestEvent requestEvent = exchange.getRequest();
53-
if(requestEvent != null) {
54-
if(LOG.isTraceEnabled()) LOG.trace("Request event is not null.");
55-
var requestHeaders = requestEvent.getHeaders();
56-
if(requestHeaders != null) {
57-
if(LOG.isTraceEnabled()) LOG.trace("Request headers is not null.");
58-
// handle all request header
59-
List<String> removeList = CONFIG.getRequestRemoveList();
60-
if (removeList != null) {
61-
if(LOG.isTraceEnabled()) LOG.trace("Request header removeList found.");
62-
removeList.forEach(requestHeaders::remove);
63-
}
64-
Map<String, Object> updateMap = CONFIG.getRequestUpdateMap();
65-
if(updateMap != null) {
66-
if(LOG.isTraceEnabled()) LOG.trace("Request header updateMap found.");
67-
updateMap.forEach((k, v) -> requestHeaders.put(k, (String) v));
68-
}
69-
70-
// handle per path prefix header if configured
71-
Map<String, Object> pathPrefixHeader = CONFIG.getPathPrefixHeader();
72-
if(pathPrefixHeader != null) {
73-
String path = exchange.getRequest().getPath();
74-
for (Map.Entry<String, Object> entry : pathPrefixHeader.entrySet()) {
75-
if(path.startsWith(entry.getKey())) {
76-
if(LOG.isTraceEnabled()) LOG.trace("Found path " + path + " with prefix " + entry.getKey());
77-
Map<String, Object> valueMap = (Map<String, Object>)entry.getValue();
78-
Map<String, Object> requestHeaderMap = (Map<String, Object>)valueMap.get(HeaderConfig.REQUEST);
79-
if(requestHeaderMap != null) {
80-
List<String> requestHeaderRemoveList = (List<String>)requestHeaderMap.get(HeaderConfig.REMOVE);
81-
if(requestHeaderRemoveList != null) {
82-
if(LOG.isTraceEnabled()) LOG.trace("Request header path prefix removeList found.");
83-
requestHeaderRemoveList.forEach(requestHeaders::remove);
84-
}
85-
Map<String, Object> requestHeaderUpdateMap = (Map<String, Object>)requestHeaderMap.get(HeaderConfig.UPDATE);
86-
if(requestHeaderUpdateMap != null) {
87-
if(LOG.isTraceEnabled()) LOG.trace("Request header path prefix updateMap found.");
88-
requestHeaderUpdateMap.forEach((k, v) -> requestHeaders.put(k, (String) v));
89-
}
90-
}
91-
}
92-
}
93-
}
94-
}
95-
}
96-
}
97-
if(exchange.isResponseInProgress()) {
98-
// handle response headers
99-
APIGatewayProxyResponseEvent responseEvent = exchange.getResponse();
100-
if(responseEvent != null) {
101-
if (LOG.isTraceEnabled()) LOG.trace("Response event is not null.");
102-
var responseHeaders = responseEvent.getHeaders();
103-
if (responseHeaders != null) {
104-
if (LOG.isTraceEnabled()) LOG.trace("Response headers is not null.");
105-
// handler all response header
106-
List<String> removeList = CONFIG.getResponseRemoveList();
107-
if(removeList != null) {
108-
if(LOG.isTraceEnabled()) LOG.trace("Response header removeList found.");
109-
removeList.forEach(responseHeaders::remove);
110-
}
111-
Map<String, Object> updateMap = CONFIG.getResponseUpdateMap();
112-
if(updateMap != null) {
113-
if(LOG.isTraceEnabled()) LOG.trace("Response header updateMap found.");
114-
updateMap.forEach((k, v) -> responseHeaders.put(k, (String) v));
115-
}
116-
// handle per path prefix header if configured
117-
Map<String, Object> pathPrefixHeader = CONFIG.getPathPrefixHeader();
118-
if(pathPrefixHeader != null) {
119-
String path = exchange.getRequest().getPath();
120-
for (Map.Entry<String, Object> entry : pathPrefixHeader.entrySet()) {
121-
if(path.startsWith(entry.getKey())) {
122-
if(LOG.isTraceEnabled()) LOG.trace("Found path " + path + " with prefix " + entry.getKey());
123-
Map<String, Object> valueMap = (Map<String, Object>)entry.getValue();
124-
Map<String, Object> responseHeaderMap = (Map<String, Object>)valueMap.get(HeaderConfig.RESPONSE);
125-
if(responseHeaderMap != null) {
126-
List<String> responseHeaderRemoveList = (List<String>)responseHeaderMap.get(HeaderConfig.REMOVE);
127-
if(responseHeaderRemoveList != null) {
128-
if(LOG.isTraceEnabled()) LOG.trace("Response header path prefix removeList found.");
129-
responseHeaderRemoveList.forEach(responseHeaders::remove);
130-
}
131-
Map<String, Object> responseHeaderUpdateMap = (Map<String, Object>)responseHeaderMap.get(HeaderConfig.UPDATE);
132-
if(responseHeaderUpdateMap != null) {
133-
if(LOG.isTraceEnabled()) LOG.trace("Response header path prefix updateMap found.");
134-
responseHeaderUpdateMap.forEach((k, v) -> responseHeaders.put(k, (String) v));
135-
}
136-
}
137-
}
138-
}
139-
}
140-
}
141-
}
142-
}
143-
return successMiddlewareStatus();
144-
}
145-
146-
@Override
147-
public void getCachedConfigurations() {
148-
}
149-
15027
@Override
15128
public boolean isEnabled() {
15229
return CONFIG.isEnabled();
@@ -167,6 +44,11 @@ public void reload() {
16744

16845
}
16946

47+
@Override
48+
public boolean isAsynchronous() {
49+
return false;
50+
}
51+
17052
@Override
17153
public boolean isContinueOnFailure() {
17254
return false;
@@ -178,8 +60,33 @@ public boolean isAudited() {
17860
}
17961

18062
@Override
181-
public boolean isAsynchronous() {
182-
return false;
63+
public void getCachedConfigurations() {
64+
18365
}
18466

67+
public void removeHeaders(List<String> removeList, Map<String, String> headers) {
68+
// convert the list to lower case.
69+
Set<String> lowercaseSet = new HashSet<>();
70+
for(String s: removeList) {
71+
lowercaseSet.add(s.toLowerCase());
72+
}
73+
// remove headers with keys in removeList
74+
headers.entrySet().removeIf(entry -> lowercaseSet.contains(entry.getKey().toLowerCase()));
75+
}
76+
77+
public void updateHeaders(Map<String, Object> updateMap, Map<String, String> headers) {
78+
// convert update map key to lowercase
79+
Map<String, Object> lowercaseUpdateMap = new HashMap<>();
80+
for (Map.Entry<String, Object> entry : updateMap.entrySet()) {
81+
lowercaseUpdateMap.put(entry.getKey().toLowerCase(), entry.getValue());
82+
}
83+
// Iterate over the original map and update values where keys match case-insensitively
84+
for (Map.Entry<String, String> entry : headers.entrySet()) {
85+
String lowercaseKey = entry.getKey().toLowerCase();
86+
if (lowercaseUpdateMap.containsKey(lowercaseKey)) {
87+
headers.put(entry.getKey(), (String)lowercaseUpdateMap.get(lowercaseKey));
88+
}
89+
}
90+
91+
}
18592
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.networknt.aws.lambda.handler.middleware.header;
2+
3+
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
4+
import com.networknt.aws.lambda.handler.MiddlewareHandler;
5+
import com.networknt.aws.lambda.LightLambdaExchange;
6+
import com.networknt.header.HeaderConfig;
7+
import com.networknt.status.Status;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
import java.util.List;
12+
import java.util.Map;
13+
14+
public class RequestHeaderMiddleware extends HeaderMiddleware implements MiddlewareHandler {
15+
private static final Logger LOG = LoggerFactory.getLogger(RequestHeaderMiddleware.class);
16+
17+
public RequestHeaderMiddleware() {
18+
super();
19+
LOG.info("RequestHeaderMiddleware is constructed");
20+
}
21+
22+
/**
23+
* Constructor with configuration for testing purpose only
24+
* @param cfg HeaderConfig
25+
*/
26+
public RequestHeaderMiddleware(HeaderConfig cfg) {
27+
super(cfg);
28+
LOG.info("RequestHeaderMiddleware is constructed");
29+
}
30+
31+
@Override
32+
public Status execute(final LightLambdaExchange exchange) {
33+
if(LOG.isTraceEnabled()) LOG.trace("RequestHeaderMiddleware.executeMiddleware starts.");
34+
if (!CONFIG.isEnabled()) {
35+
if(LOG.isTraceEnabled()) LOG.trace("RequestHeaderMiddleware is not enabled.");
36+
return disabledMiddlewareStatus();
37+
}
38+
APIGatewayProxyRequestEvent requestEvent = exchange.getRequest();
39+
if(requestEvent != null) {
40+
if(LOG.isTraceEnabled()) LOG.trace("Request event is not null.");
41+
var requestHeaders = requestEvent.getHeaders();
42+
if(requestHeaders != null) {
43+
if(LOG.isTraceEnabled()) LOG.trace("Request headers is not null.");
44+
// handle all request header
45+
List<String> removeList = CONFIG.getRequestRemoveList();
46+
if (removeList != null) {
47+
if(LOG.isTraceEnabled()) LOG.trace("Request header removeList found.");
48+
removeHeaders(removeList, requestHeaders);
49+
}
50+
Map<String, Object> updateMap = CONFIG.getRequestUpdateMap();
51+
if(updateMap != null) {
52+
if(LOG.isTraceEnabled()) LOG.trace("Request header updateMap found.");
53+
updateHeaders(updateMap, requestHeaders);
54+
}
55+
56+
// handle per path prefix header if configured
57+
Map<String, Object> pathPrefixHeader = CONFIG.getPathPrefixHeader();
58+
if(pathPrefixHeader != null) {
59+
String path = exchange.getRequest().getPath();
60+
for (Map.Entry<String, Object> entry : pathPrefixHeader.entrySet()) {
61+
if(path.startsWith(entry.getKey())) {
62+
if(LOG.isTraceEnabled()) LOG.trace("Found path " + path + " with prefix " + entry.getKey());
63+
Map<String, Object> valueMap = (Map<String, Object>)entry.getValue();
64+
Map<String, Object> requestHeaderMap = (Map<String, Object>)valueMap.get(HeaderConfig.REQUEST);
65+
if(requestHeaderMap != null) {
66+
List<String> requestHeaderRemoveList = (List<String>)requestHeaderMap.get(HeaderConfig.REMOVE);
67+
if(requestHeaderRemoveList != null) {
68+
if(LOG.isTraceEnabled()) LOG.trace("Request header path prefix removeList found.");
69+
removeHeaders(requestHeaderRemoveList, requestHeaders);
70+
}
71+
Map<String, Object> requestHeaderUpdateMap = (Map<String, Object>)requestHeaderMap.get(HeaderConfig.UPDATE);
72+
if(requestHeaderUpdateMap != null) {
73+
if(LOG.isTraceEnabled()) LOG.trace("Request header path prefix updateMap found.");
74+
updateHeaders(requestHeaderUpdateMap, requestHeaders);
75+
}
76+
}
77+
}
78+
}
79+
}
80+
}
81+
}
82+
if(LOG.isTraceEnabled()) LOG.trace("RequestHeaderMiddleware.executeMiddleware ends.");
83+
return successMiddlewareStatus();
84+
}
85+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.networknt.aws.lambda.handler.middleware.header;
2+
3+
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
4+
import com.networknt.aws.lambda.LightLambdaExchange;
5+
import com.networknt.aws.lambda.handler.MiddlewareHandler;
6+
import com.networknt.header.HeaderConfig;
7+
import com.networknt.status.Status;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
import java.util.HashSet;
12+
import java.util.HashMap;
13+
import java.util.List;
14+
import java.util.Map;
15+
import java.util.Set;
16+
17+
public class ResponseHeaderMiddleware extends HeaderMiddleware implements MiddlewareHandler {
18+
19+
private static final Logger LOG = LoggerFactory.getLogger(ResponseHeaderMiddleware.class);
20+
21+
public ResponseHeaderMiddleware() {
22+
super();
23+
LOG.info("ResponseHeaderMiddleware is constructed");
24+
}
25+
26+
/**
27+
* Constructor with configuration for testing purpose only
28+
* @param cfg HeaderConfig
29+
*/
30+
public ResponseHeaderMiddleware(HeaderConfig cfg) {
31+
super(cfg);
32+
LOG.info("ResponseHeaderMiddleware is constructed");
33+
}
34+
35+
@Override
36+
public Status execute(LightLambdaExchange exchange) {
37+
if(LOG.isTraceEnabled()) LOG.trace("ResponseHeaderMiddleware.executeMiddleware starts.");
38+
if (!CONFIG.isEnabled()) {
39+
if(LOG.isTraceEnabled()) LOG.trace("ResponseHeaderMiddleware is not enabled.");
40+
return disabledMiddlewareStatus();
41+
}
42+
APIGatewayProxyResponseEvent responseEvent = exchange.getResponse();
43+
if(responseEvent != null) {
44+
if (LOG.isTraceEnabled()) LOG.trace("Response event is not null.");
45+
var responseHeaders = responseEvent.getHeaders();
46+
if (responseHeaders != null) {
47+
if (LOG.isTraceEnabled()) LOG.trace("Response headers is not null.");
48+
// handler all response header
49+
List<String> removeList = CONFIG.getResponseRemoveList();
50+
if(removeList != null) {
51+
if(LOG.isTraceEnabled()) LOG.trace("Response header removeList found.");
52+
removeHeaders(removeList, responseHeaders);
53+
}
54+
Map<String, Object> updateMap = CONFIG.getResponseUpdateMap();
55+
if(updateMap != null) {
56+
if(LOG.isTraceEnabled()) LOG.trace("Response header updateMap found.");
57+
updateHeaders(updateMap, responseHeaders);
58+
}
59+
// handle per path prefix header if configured
60+
Map<String, Object> pathPrefixHeader = CONFIG.getPathPrefixHeader();
61+
if(pathPrefixHeader != null) {
62+
String path = exchange.getReadOnlyRequest().getPath();
63+
for (Map.Entry<String, Object> entry : pathPrefixHeader.entrySet()) {
64+
if(path.startsWith(entry.getKey())) {
65+
if(LOG.isTraceEnabled()) LOG.trace("Found path {} with prefix {}", path, entry.getKey());
66+
Map<String, Object> valueMap = (Map<String, Object>)entry.getValue();
67+
Map<String, Object> responseHeaderMap = (Map<String, Object>)valueMap.get(HeaderConfig.RESPONSE);
68+
if(responseHeaderMap != null) {
69+
List<String> responseHeaderRemoveList = (List<String>)responseHeaderMap.get(HeaderConfig.REMOVE);
70+
if(responseHeaderRemoveList != null) {
71+
if(LOG.isTraceEnabled()) LOG.trace("Response header path prefix removeList found.");
72+
removeHeaders(responseHeaderRemoveList, responseHeaders);
73+
}
74+
Map<String, Object> responseHeaderUpdateMap = (Map<String, Object>)responseHeaderMap.get(HeaderConfig.UPDATE);
75+
if(responseHeaderUpdateMap != null) {
76+
if(LOG.isTraceEnabled()) LOG.trace("Response header path prefix updateMap found.");
77+
updateHeaders(responseHeaderUpdateMap, responseHeaders);
78+
}
79+
}
80+
}
81+
}
82+
}
83+
}
84+
}
85+
if(LOG.isTraceEnabled()) LOG.trace("ResponseHeaderMiddleware.executeMiddleware ends.");
86+
return successMiddlewareStatus();
87+
}
88+
89+
@Override
90+
public boolean isResponseMiddleware() {
91+
return true;
92+
}
93+
}

0 commit comments

Comments
 (0)