Skip to content

Commit b97714e

Browse files
authored
Merge pull request #398 from simonpoole/CORS
CORS added for cross-site requests and readme updated
2 parents 6f2e1a4 + 268e13a commit b97714e

File tree

6 files changed

+67
-8
lines changed

6 files changed

+67
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ To use an older version of ElasticSearch please download the data from [here](ht
5656

5757
Check the URL `http://localhost:2322/api?q=berlin` to see if photon is running without problems. You may want to use our [leaflet plugin](https://github.com/komoot/leaflet.photon) to see the results on a map.
5858

59+
To enable CORS (cross-site requests), use `-cors-any` to allow any origin or `-cors-origin` with a specific origin as the argument. By default, CORS support is disabled.
60+
5961
discover more of photon's feature with its usage `java -jar photon-*.jar -h`.
6062

6163

src/main/java/de/komoot/photon/App.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import de.komoot.photon.elasticsearch.Server;
77
import de.komoot.photon.nominatim.NominatimConnector;
88
import de.komoot.photon.nominatim.NominatimUpdater;
9+
import de.komoot.photon.utils.CorsFilter;
910
import lombok.extern.slf4j.Slf4j;
1011
import org.elasticsearch.client.Client;
1112
import spark.Request;
@@ -26,6 +27,9 @@ public static void main(String[] rawArgs) throws Exception {
2627
final JCommander jCommander = new JCommander(args);
2728
try {
2829
jCommander.parse(rawArgs);
30+
if (args.isCorsAnyOrigin() && args.getCorsOrigin() != null) { // these are mutually exclusive
31+
throw new ParameterException("Use only one cors configuration type");
32+
}
2933
} catch (ParameterException e) {
3034
log.warn("could not start photon: " + e.getMessage());
3135
jCommander.usage();
@@ -134,9 +138,18 @@ private static void startNominatimImport(CommandLineArgs args, Server esServer,
134138
* @param esNodeClient
135139
*/
136140
private static void startApi(CommandLineArgs args, Client esNodeClient) {
137-
setPort(args.getListenPort());
138-
setIpAddress(args.getListenIp());
139-
141+
port(args.getListenPort());
142+
ipAddress(args.getListenIp());
143+
144+
String allowedOrigin = args.isCorsAnyOrigin() ? "*" : args.getCorsOrigin();
145+
if (allowedOrigin != null) {
146+
CorsFilter.enableCORS(allowedOrigin, "get", "*");
147+
} else {
148+
before((request, response) -> {
149+
response.type("application/json"); // in the other case set by enableCors
150+
});
151+
}
152+
140153
// setup search API
141154
get("api", new SearchRequestHandler("api", esNodeClient, args.getLanguages()));
142155
get("api/", new SearchRequestHandler("api/", esNodeClient, args.getLanguages()));

src/main/java/de/komoot/photon/CommandLineArgs.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ public class CommandLineArgs {
5656
@Parameter(names = "-listen-ip", description = "listen to address (default '0.0.0.0')")
5757
private String listenIp = "0.0.0.0";
5858

59+
@Parameter(names = "-cors-any", description = "enable cross-site resource sharing foe any origin ((default CORS not supported)")
60+
private boolean corsAnyOrigin = false;
61+
62+
@Parameter(names = "-cors-origin", description = "enable cross-site resource sharing for the specified origin (default CORS not supported)")
63+
private String corsOrigin = null;
64+
5965
@Parameter(names = "-h", description = "show help / usage")
6066
private boolean usage = false;
6167
}

src/main/java/de/komoot/photon/ReverseSearchRequestHandler.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ public String handle(Request request, Response response) {
4949
ReverseRequestHandler<R> handler = requestHandlerFactory.createHandler(photonRequest);
5050
List<JSONObject> results = handler.handle(photonRequest);
5151
JSONObject geoJsonResults = geoJsonConverter.convert(results);
52-
response.type("application/json; charset=utf-8");
53-
response.header("Access-Control-Allow-Origin", "*");
5452
if (request.queryParams("debug") != null)
5553
return geoJsonResults.toString(4);
5654

src/main/java/de/komoot/photon/SearchRequestHandler.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ public String handle(Request request, Response response) {
4949
PhotonRequestHandler<R> handler = requestHandlerFactory.createHandler(photonRequest);
5050
List<JSONObject> results = handler.handle(photonRequest);
5151
JSONObject geoJsonResults = geoJsonConverter.convert(results);
52-
response.type("application/json; charset=utf-8");
53-
response.header("Access-Control-Allow-Origin", "*");
5452
if (request.queryParams("debug") != null)
5553
return geoJsonResults.toString(4);
5654

5755
return geoJsonResults.toString();
5856
}
59-
}
57+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package de.komoot.photon.utils;
2+
3+
import static spark.Spark.before;
4+
import static spark.Spark.options;
5+
6+
public class CorsFilter {
7+
8+
//
9+
/**
10+
* Enables CORS on requests. This method is an initialization method and should be called once.
11+
*
12+
* As a side effect this sets the content type for the response to "application/json"
13+
*
14+
* @param origin permitted origin
15+
* @param methods permitted methods comma separated
16+
* @param headers permitted headers comma separated
17+
*/
18+
public static void enableCORS(final String origin, final String methods, final String headers) {
19+
20+
options("/*", (request, response) -> {
21+
22+
String accessControlRequestHeaders = request.headers("Access-Control-Request-Headers");
23+
if (accessControlRequestHeaders != null) {
24+
response.header("Access-Control-Allow-Headers", accessControlRequestHeaders);
25+
}
26+
27+
String accessControlRequestMethod = request.headers("Access-Control-Request-Method");
28+
if (accessControlRequestMethod != null) {
29+
response.header("Access-Control-Allow-Methods", accessControlRequestMethod);
30+
}
31+
32+
return "OK";
33+
});
34+
35+
before((request, response) -> {
36+
response.header("Access-Control-Allow-Origin", origin);
37+
response.header("Access-Control-Request-Method", methods);
38+
response.header("Access-Control-Allow-Headers", headers);
39+
response.type("application/json");
40+
});
41+
}
42+
}

0 commit comments

Comments
 (0)