[git-bridge] add CORS support (#23892)

GitOrigin-RevId: 9e3d85e479746affd047434ec9ce2588b60ca76c
This commit is contained in:
Jakob Ackermann
2025-02-28 08:02:51 +00:00
committed by Copybot
parent 85d3af6dc5
commit a7de1de23c
9 changed files with 149 additions and 3 deletions
@@ -26,6 +26,7 @@ public class Config implements JSONSource {
config.bindIp,
config.idleTimeout,
config.rootGitDirectory,
config.allowedCorsOrigins,
config.apiBaseURL,
config.postbackURL,
config.serviceName,
@@ -41,6 +42,7 @@ public class Config implements JSONSource {
private String bindIp;
private int idleTimeout;
private String rootGitDirectory;
private String[] allowedCorsOrigins;
private String apiBaseURL;
private String postbackURL;
private String serviceName;
@@ -64,6 +66,7 @@ public class Config implements JSONSource {
String bindIp,
int idleTimeout,
String rootGitDirectory,
String[] allowedCorsOrigins,
String apiBaseURL,
String postbackURL,
String serviceName,
@@ -77,6 +80,7 @@ public class Config implements JSONSource {
this.bindIp = bindIp;
this.idleTimeout = idleTimeout;
this.rootGitDirectory = rootGitDirectory;
this.allowedCorsOrigins = allowedCorsOrigins;
this.apiBaseURL = apiBaseURL;
this.postbackURL = postbackURL;
this.serviceName = serviceName;
@@ -101,6 +105,13 @@ public class Config implements JSONSource {
}
this.apiBaseURL = apiBaseURL;
serviceName = getElement(configObject, "serviceName").getAsString();
final String rawAllowedCorsOrigins =
getOptionalString(configObject, "allowedCorsOrigins").trim();
if (rawAllowedCorsOrigins.isEmpty()) {
allowedCorsOrigins = new String[] {};
} else {
allowedCorsOrigins = rawAllowedCorsOrigins.split(",");
}
postbackURL = getElement(configObject, "postbackBaseUrl").getAsString();
if (!postbackURL.endsWith("/")) {
postbackURL += "/";
@@ -139,6 +150,10 @@ public class Config implements JSONSource {
return this.sqliteHeapLimitBytes;
}
public String[] getAllowedCorsOrigins() {
return allowedCorsOrigins;
}
public String getAPIBaseURL() {
return apiBaseURL;
}
@@ -0,0 +1,47 @@
package uk.ac.ic.wlgitbridge.server;
import java.io.IOException;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import uk.ac.ic.wlgitbridge.util.Log;
public class CORSHandler extends AbstractHandler {
private final Set<String> allowedCorsOrigins;
public CORSHandler(String[] allowedCorsOrigins) {
this.allowedCorsOrigins = Set.of(allowedCorsOrigins);
}
@Override
public void handle(
String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException {
String origin = request.getHeader("Origin");
if (origin == null) {
return; // Not a CORS request
}
final boolean ok = allowedCorsOrigins.contains(origin);
if (ok) {
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, PUT, POST, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
response.setHeader("Access-Control-Max-Age", "86400"); // cache for 24h
}
String method = baseRequest.getMethod();
if ("OPTIONS".equals(method)) {
Log.debug("OPTIONS <- {}", target);
baseRequest.setHandled(true);
if (ok) {
response.setStatus(200);
} else {
response.setStatus(403);
}
}
}
}
@@ -110,6 +110,7 @@ public class GitBridgeServer {
this.jettyServer.addConnector(connector);
HandlerCollection handlers = new HandlerList();
handlers.addHandler(new CORSHandler(config.getAllowedCorsOrigins()));
handlers.addHandler(initApiHandler());
handlers.addHandler(initBaseHandler());
handlers.addHandler(initGitHandler(config, repoStore, snapshotApi));