diff --git a/CHANGELOG.md b/CHANGELOG.md index f75f825e6..f239246bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ This file is currently not maintained. See [release](https://github.com/maplibre ### Bug Fixes * fix invalid json escaping ([#224](https://github.com/maplibre/martin/issues/224)) (h/t [@gbip](https://github.com/gbip)) ([4994273](https://github.com/maplibre/martin/commit/49942734af5fcaffa4b4430e48600a0e4183d1bc)) -* fix tiles attribute in tilejson when using x-rewrite-url ([#266](https://github.com/maplibre/martin/issues/266)) ([f2d56c2](https://github.com/maplibre/martin/commit/f2d56c2f7d28d858c09cab90ff13789d595ba6da)) +* fix tiles attribute in tilejson when using `X-Rewrite-URL` ([#266](https://github.com/maplibre/martin/issues/266)) ([f2d56c2](https://github.com/maplibre/martin/commit/f2d56c2f7d28d858c09cab90ff13789d595ba6da)) [Unreleased]: https://github.com/maplibre/martin/compare/v0.5.0...HEAD @@ -94,7 +94,7 @@ This file is currently not maintained. See [release](https://github.com/maplibre - pass query string from tilejson endpoint to tiles ([ef7ddace](https://github.com/maplibre/martin/commit/ef7ddace17cc11433824942c2ae68ffecb00538a)) - add schema to function_sources ([a7092bc3](https://github.com/maplibre/martin/commit/a7092bc3b86c35c4f7d2d14d699e1239b19d875b)) - properly encode query as json into function_sources ([cc75ab4a](https://github.com/maplibre/martin/commit/cc75ab4a8e68c8291b33badb80fd8065ea4476d7)) -- handle x-rewrite-url header ([63c976e8](https://github.com/maplibre/martin/commit/63c976e8b9a598783150f9ef957e926d20ccf825)) +- handle `X-Rewrite-URL` header ([63c976e8](https://github.com/maplibre/martin/commit/63c976e8b9a598783150f9ef957e926d20ccf825)) - handle tables with no properties ([d6aee81b](https://github.com/maplibre/martin/commit/d6aee81b1bff47a7c3f46e4c26a07a2843a9c707)) - skip tables with SRID 0 ([241dda31](https://github.com/maplibre/martin/commit/241dda318453fb3bfc656793a1cef0fa6923114e)) - set default tile buffer to 64 ([612ecddb](https://github.com/maplibre/martin/commit/612ecddb99f33420077dcd3f1ca0ac9666e741b6)) diff --git a/martin/src/srv/tiles/metadata.rs b/martin/src/srv/tiles/metadata.rs index e8b15cb41..614dabfdb 100644 --- a/martin/src/srv/tiles/metadata.rs +++ b/martin/src/srv/tiles/metadata.rs @@ -36,7 +36,7 @@ async fn get_source_info( let sources = sources.get_sources(&path.source_ids, None)?.0; // Determine the path prefix for tile URLs in TileJSON responses - // Priority: base_path (explicit override) > route_prefix (where Martin is mounted) > x-rewrite-url header > request path + // Priority: base_path (explicit override) > route_prefix (where Martin is mounted) > X-Rewrite-URL header > request path let tiles_path = if let Some(base_path) = &srv_config.base_path { // If base_path is explicitly set, use it directly format!("{base_path}/{}", path.source_ids) @@ -44,9 +44,10 @@ async fn get_source_info( // If route_prefix is set, use it (Martin is mounted under a subpath) format!("{route_prefix}/{}", path.source_ids) } else { - // Fall back to x-rewrite-url header if present, otherwise use request path + // Fall back to X-Rewrite-URL header if present, otherwise use request path req.headers() - .get("x-rewrite-url") + .get("X-Rewrite-URL") + .or(req.headers().get("X-Forwarded-Prefix")) .and_then(|v| v.to_str().ok()) .and_then(|v| v.parse::().ok()) .map_or_else(|| req.path().to_string(), |v| v.path().to_string()) diff --git a/martin/tests/pg_server_test.rs b/martin/tests/pg_server_test.rs index 6d9b9c9d8..e3df26922 100644 --- a/martin/tests/pg_server_test.rs +++ b/martin/tests/pg_server_test.rs @@ -202,7 +202,7 @@ postgres: let req = TestRequest::get() .uri("/table_source?token=martin") - .insert_header(("x-rewrite-url", "/tiles/table_source?token=martin")) + .insert_header(("X-Rewrite-URL", "/tiles/table_source?token=martin")) .to_request(); let result: TileJSON = call_and_read_body_json(&app, req).await; assert_yaml_snapshot!(result, @r#" @@ -872,7 +872,7 @@ postgres: let req = TestRequest::get() .uri("/function_zxy_query?token=martin") - .insert_header(("x-rewrite-url", "/tiles/function_zxy_query?token=martin")) + .insert_header(("X-Rewrite-URL", "/tiles/function_zxy_query?token=martin")) .to_request(); let result: TileJSON = call_and_read_body_json(&app, req).await; assert_eq!( diff --git a/tests/expected/auto/tilejson_ignores_x_forwarded_for.json b/tests/expected/auto/tilejson_ignores_x_forwarded_for.json new file mode 100644 index 000000000..79f898d7a --- /dev/null +++ b/tests/expected/auto/tilejson_ignores_x_forwarded_for.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://localhost:3111/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_ignores_x_forwarded_for.json.headers b/tests/expected/auto/tilejson_ignores_x_forwarded_for.json.headers new file mode 100644 index 000000000..0fb16de3e --- /dev/null +++ b/tests/expected/auto/tilejson_ignores_x_forwarded_for.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"85-6Q4dOREWZNsdPdT5r-Pjvg==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_no_forwarded_headers.json b/tests/expected/auto/tilejson_no_forwarded_headers.json new file mode 100644 index 000000000..c8994d8a0 --- /dev/null +++ b/tests/expected/auto/tilejson_no_forwarded_headers.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://localhost/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_no_forwarded_headers.json.headers b/tests/expected/auto/tilejson_no_forwarded_headers.json.headers new file mode 100644 index 000000000..97bb9af28 --- /dev/null +++ b/tests/expected/auto/tilejson_no_forwarded_headers.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"80-ov0SCyAA-3Cf3_JgPvZxvQ==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_forwarded_host_only.json b/tests/expected/auto/tilejson_with_forwarded_host_only.json new file mode 100644 index 000000000..66274a6bc --- /dev/null +++ b/tests/expected/auto/tilejson_with_forwarded_host_only.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://tiles.example.com/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_forwarded_host_only.json.headers b/tests/expected/auto/tilejson_with_forwarded_host_only.json.headers new file mode 100644 index 000000000..51731b88c --- /dev/null +++ b/tests/expected/auto/tilejson_with_forwarded_host_only.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"88-4NeInzTwbUnMoT8DHd6w2w==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_forwarded_proto_and_host.json b/tests/expected/auto/tilejson_with_forwarded_proto_and_host.json new file mode 100644 index 000000000..c04ee3a67 --- /dev/null +++ b/tests/expected/auto/tilejson_with_forwarded_proto_and_host.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "https://tiles.example.com/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_forwarded_proto_and_host.json.headers b/tests/expected/auto/tilejson_with_forwarded_proto_and_host.json.headers new file mode 100644 index 000000000..92c378de5 --- /dev/null +++ b/tests/expected/auto/tilejson_with_forwarded_proto_and_host.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"89-I2QSzZaYUuhIqVyAcbeV0w==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_forwarded_proto_only.json b/tests/expected/auto/tilejson_with_forwarded_proto_only.json new file mode 100644 index 000000000..dde5e634d --- /dev/null +++ b/tests/expected/auto/tilejson_with_forwarded_proto_only.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "https://localhost:3111/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_forwarded_proto_only.json.headers b/tests/expected/auto/tilejson_with_forwarded_proto_only.json.headers new file mode 100644 index 000000000..e8dbfd7c0 --- /dev/null +++ b/tests/expected/auto/tilejson_with_forwarded_proto_only.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"86-avawaK9rjztofnjIGTH8tQ==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_host.json b/tests/expected/auto/tilejson_with_host.json new file mode 100644 index 000000000..ef86a6c3c --- /dev/null +++ b/tests/expected/auto/tilejson_with_host.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://example.com/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_host.json.headers b/tests/expected/auto/tilejson_with_host.json.headers new file mode 100644 index 000000000..ee2a34fca --- /dev/null +++ b/tests/expected/auto/tilejson_with_host.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"82-dXeZmjfhw0vSIzyrLrI2tQ==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_host_and_port.json b/tests/expected/auto/tilejson_with_host_and_port.json new file mode 100644 index 000000000..b5d7f1194 --- /dev/null +++ b/tests/expected/auto/tilejson_with_host_and_port.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://example.com:6000/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_host_and_port.json.headers b/tests/expected/auto/tilejson_with_host_and_port.json.headers new file mode 100644 index 000000000..906a00dfb --- /dev/null +++ b/tests/expected/auto/tilejson_with_host_and_port.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"87-SGblGUvNQ8cb-TAcYkikxA==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_x_forwarded_host.json b/tests/expected/auto/tilejson_with_x_forwarded_host.json new file mode 100644 index 000000000..66274a6bc --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_forwarded_host.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://tiles.example.com/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_x_forwarded_host.json.headers b/tests/expected/auto/tilejson_with_x_forwarded_host.json.headers new file mode 100644 index 000000000..51731b88c --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_forwarded_host.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"88-4NeInzTwbUnMoT8DHd6w2w==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_x_forwarded_prefix.json b/tests/expected/auto/tilejson_with_x_forwarded_prefix.json new file mode 100644 index 000000000..7ec8816c0 --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_forwarded_prefix.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://localhost:3111/tiles/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_x_forwarded_prefix.json.headers b/tests/expected/auto/tilejson_with_x_forwarded_prefix.json.headers new file mode 100644 index 000000000..56f7c2684 --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_forwarded_prefix.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"8b-aPZCJuN9gXKyxSjPdCb3Og==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_x_forwarded_proto_http.json b/tests/expected/auto/tilejson_with_x_forwarded_proto_http.json new file mode 100644 index 000000000..79f898d7a --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_forwarded_proto_http.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://localhost:3111/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_x_forwarded_proto_http.json.headers b/tests/expected/auto/tilejson_with_x_forwarded_proto_http.json.headers new file mode 100644 index 000000000..0fb16de3e --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_forwarded_proto_http.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"85-6Q4dOREWZNsdPdT5r-Pjvg==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_x_forwarded_proto_https.json b/tests/expected/auto/tilejson_with_x_forwarded_proto_https.json new file mode 100644 index 000000000..dde5e634d --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_forwarded_proto_https.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "https://localhost:3111/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_x_forwarded_proto_https.json.headers b/tests/expected/auto/tilejson_with_x_forwarded_proto_https.json.headers new file mode 100644 index 000000000..e8dbfd7c0 --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_forwarded_proto_https.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"86-avawaK9rjztofnjIGTH8tQ==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/expected/auto/tilejson_with_x_rewrite_url.json b/tests/expected/auto/tilejson_with_x_rewrite_url.json new file mode 100644 index 000000000..687560598 --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_rewrite_url.json @@ -0,0 +1,10 @@ +{ + "foo": { + "bar": "foo" + }, + "name": "function_zxy_query", + "tilejson": "3.0.0", + "tiles": [ + "http://localhost:3111/footiles/function_zxy_query/{z}/{x}/{y}" + ] +} diff --git a/tests/expected/auto/tilejson_with_x_rewrite_url.json.headers b/tests/expected/auto/tilejson_with_x_rewrite_url.json.headers new file mode 100644 index 000000000..f8b51f987 --- /dev/null +++ b/tests/expected/auto/tilejson_with_x_rewrite_url.json.headers @@ -0,0 +1,5 @@ +content-encoding: br +content-type: application/json +etag: W/"8e-cN5TSMZcyidSC58tIB_3kQ==" +transfer-encoding: chunked +vary: accept-encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers diff --git a/tests/test.sh b/tests/test.sh index 1a8f33278..022abf244 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -182,6 +182,16 @@ test_font() { clean_headers_dump "$FILENAME.headers" } +test_json_with_header() { + FILENAME="$TEST_OUT_DIR/$1.json" + URL="$MARTIN_URL/$2" + HEADER="$3" + + echo "Testing $(basename "$FILENAME") from $URL with header: $HEADER" + $CURL --dump-header "$FILENAME.headers" -H "$HEADER" "$URL" | jq --sort-keys > "$FILENAME" + clean_headers_dump "$FILENAME.headers" +} + test_redirect() { URL="$MARTIN_URL/$1" EXPECTED_LOCATION="$2" @@ -385,6 +395,24 @@ test_pbf cmp_14_14692_7645 table_source,points1,points2/14/14692/7645 test_pbf cmp_17_117542_61161 table_source,points1,points2/17/117542/61161 test_pbf cmp_18_235085_122323 table_source,points1,points2/18/235085/122323 +>&2 echo "***** Test header effects on tilejson *****" +test_json_with_header tilejson_no_forwarded_headers function_zxy_query "Host: localhost" +test_json_with_header tilejson_ignores_x_forwarded_for function_zxy_query "X-Forwarded-For: 192.168.1.100" +test_json_with_header tilejson_with_host function_zxy_query "Host: example.com" +test_json_with_header tilejson_with_host_and_port function_zxy_query "Host: example.com:6000" + +test_json_with_header tilejson_with_x_forwarded_proto_https function_zxy_query "X-Forwarded-Proto: https" +test_json_with_header tilejson_with_x_forwarded_proto_http function_zxy_query "X-Forwarded-Proto: http" + +test_json_with_header tilejson_with_x_forwarded_host function_zxy_query "X-Forwarded-Host: tiles.example.com" + +test_json_with_header tilejson_with_forwarded_proto_only function_zxy_query "Forwarded: proto=https" +test_json_with_header tilejson_with_forwarded_host_only function_zxy_query "Forwarded: host=tiles.example.com" +test_json_with_header tilejson_with_forwarded_proto_and_host function_zxy_query "Forwarded: proto=https;host=tiles.example.com" +test_json_with_header tilejson_with_x_forwarded_prefix function_zxy_query "X-Forwarded-Prefix: /tiles/function_zxy_query" +test_json_with_header tilejson_with_x_rewrite_url function_zxy_query "X-Rewrite-URL: /footiles/function_zxy_query" + + >&2 echo "***** Test server response for function source *****" test_jsn fnc function_zxy_query test_pbf fnc_0_0_0 function_zxy_query/0/0/0