Skip to content

including header for application/json responses #2435

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cors/src/main/java/com/networknt/cors/CorsHttpHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class CorsHttpHandler implements MiddlewareHandler {
public static CorsConfig config;
private List<String> allowedOrigins;
private List<String> allowedMethods;
private boolean isNonPreflightReqAllowed = true;

private volatile HttpHandler next;
/** Default max age **/
Expand Down Expand Up @@ -77,6 +78,7 @@ public CorsHttpHandler(String configName) {
public void handleRequest(HttpServerExchange exchange) throws Exception {
if(logger.isDebugEnabled()) logger.debug("CorsHttpHandler.handleRequest starts.");
HeaderMap headers = exchange.getRequestHeaders();
isNonPreflightReqAllowed = true;
if (isCorsRequest(headers)) {
// cors headers available in the request. Set the allowedOrigins and allowedMethods based on the
// path prefix if it is configured. Otherwise, use the global configuration set in the constructor.
Expand All @@ -101,7 +103,8 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
setCorsResponseHeaders(exchange, allowedOrigins, allowedMethods);
}
if(logger.isDebugEnabled()) logger.debug("CorsHttpHandler.handleRequest ends.");
Handler.next(exchange, next);
if(isNonPreflightReqAllowed) Handler.next(exchange, next);
else return;
}

private void handlePreflightRequest(HttpServerExchange exchange, List<String> allowedOrigins, List<String> allowedMethods) throws Exception {
Expand Down Expand Up @@ -194,6 +197,7 @@ public static String matchOrigin(HttpServerExchange exchange, Collection<String>
}
logger.debug("Request rejected due to HOST/ORIGIN mis-match.");
ResponseCodeHandler.HANDLE_403.handleRequest(exchange);
isNonPreflightReqAllowed = false;
return null;
}

Expand Down
28 changes: 28 additions & 0 deletions cors/src/test/java/com/networknt/cors/CorsHttpHandlerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,34 @@ static RoutingHandler getTestHandler() {
});
}

@Test
public void testRegularWrongOrigin() throws Exception {
String url = "http://localhost:7080";
Http2Client client = Http2Client.getInstance();
final CountDownLatch latch = new CountDownLatch(1);
final ClientConnection connection;
try {
connection = client.connect(new URI(url), Http2Client.WORKER, Http2Client.SSL, Http2Client.BUFFER_POOL, OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).get();
} catch (Exception e) {
throw new ClientException(e);
}
final AtomicReference<ClientResponse> reference = new AtomicReference<>();
try {
ClientRequest request = new ClientRequest().setPath("/").setMethod(Methods.GET);
request.getRequestHeaders().put(Headers.HOST, "localhost");
request.getRequestHeaders().put(new HttpString("Origin"), "http://example.com");
connection.sendRequest(request, client.createClientCallback(reference, latch));
latch.await();
} catch (Exception e) {
logger.error("Exception: ", e);
throw new ClientException(e);
} finally {
IoUtils.safeClose(connection);
}
int statusCode = reference.get().getResponseCode();
Assert.assertEquals(403, statusCode);
}

@Test
public void testOptionsWrongOrigin() throws Exception {
String url = "http://localhost:7080";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class TokenLimitHandler implements MiddlewareHandler {
static final String AUTHORIZATION_CODE = "authorization_code";
static final String CLIENT_ID = "client_id";
static final String CLIENT_SECRET = "client_secret";
static final String SCOPE = "scope";
static final String SCOPE = "scope";
static final String CODE = "code";
static final String TOKEN_LIMIT_ERROR = "ERR10091";

Expand Down
2 changes: 1 addition & 1 deletion token-limit/src/main/resources/config/token-limit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ duplicateLimit: ${token-limit.duplicateLimit:2}
# - /oauth2/(?<instanceId>[^/]+)/v1/token
# - /oauth2/(?<instanceId>[^/]+)/token
tokenPathTemplates: ${token-limit.tokenPathTemplates:}
# List of ClientID that should be treated as Legacy and thus excluded from the token limit rules.
# List of ClientID that should be treated as Legacy and thus excluded from the token limit rules.
# This should only be used by approved legacy clients. The client ID is case insensitive.
# token-limit.legacyClient:
# - 5oa66u56irXiekTUF1d6
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public String callNonLegacyClient() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
SimpleConnectionHolder.ConnectionToken connectionToken = null;
final AtomicReference<ClientResponse> reference = new AtomicReference<>();

try {
if(enableHttps) {
connectionToken = client.borrow(new URI(url), Http2Client.WORKER, client.getDefaultXnioSsl(), Http2Client.BUFFER_POOL, enableHttp2 ? OptionMap.create(UndertowOptions.ENABLE_HTTP2, true): OptionMap.EMPTY);
Expand Down
4 changes: 2 additions & 2 deletions token-limit/src/test/resources/config/values.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ token-limit.errorOnLimit: true
token-limit.duplicateLimit: 2
token-limit.tokenPathTemplates:
- /oauth2/(?<instanceId>[^/]+)/v1/token
token-limit.legacyClient:
token-limit.legacyClient:
- legacyClient

# cache.yml
Expand All @@ -45,4 +45,4 @@ cache.caches:
maxSize: 1000
- cacheName: token-limit
expiryInMinutes: 15
maxSize: 1000
maxSize: 1000