mirror of
https://github.com/maplibre/martin.git
synced 2024-12-19 21:01:45 +03:00
fix: tiles attribute in tilejson with x-rewrite-url (#266)
This commit is contained in:
parent
194a83e63f
commit
f2d56c2f7d
@ -615,7 +615,7 @@ If you are running martin behind Nginx proxy, you may want to rewrite the reques
|
|||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
location ~ /tiles/(?<fwd_path>.*) {
|
location ~ /tiles/(?<fwd_path>.*) {
|
||||||
proxy_set_header X-Rewrite-URL $request_uri;
|
proxy_set_header X-Rewrite-URL $uri;
|
||||||
proxy_set_header X-Forwarded-Host $host:$server_port;
|
proxy_set_header X-Forwarded-Host $host:$server_port;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
@ -640,7 +640,7 @@ http {
|
|||||||
server {
|
server {
|
||||||
...
|
...
|
||||||
location ~ /tiles/(?<fwd_path>.*) {
|
location ~ /tiles/(?<fwd_path>.*) {
|
||||||
proxy_set_header X-Rewrite-URL $request_uri;
|
proxy_set_header X-Rewrite-URL $uri;
|
||||||
proxy_set_header X-Forwarded-Host $host:$server_port;
|
proxy_set_header X-Forwarded-Host $host:$server_port;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
@ -56,7 +56,7 @@ http {
|
|||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
proxy_set_header X-Rewrite-URL $request_uri;
|
proxy_set_header X-Rewrite-URL $uri;
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
|
||||||
proxy_connect_timeout 15m;
|
proxy_connect_timeout 15m;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use serde::Deserialize;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@ -6,9 +5,11 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use actix::{Actor, Addr, SyncArbiter, SystemRunner};
|
use actix::{Actor, Addr, SyncArbiter, SystemRunner};
|
||||||
use actix_cors::Cors;
|
use actix_cors::Cors;
|
||||||
|
use actix_web::http::Uri;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
error, http, middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer, Result,
|
error, middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer, Result,
|
||||||
};
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::composite_source::CompositeSource;
|
use crate::composite_source::CompositeSource;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
@ -19,6 +20,7 @@ use crate::function_source::FunctionSources;
|
|||||||
use crate::messages;
|
use crate::messages;
|
||||||
use crate::source::{Source, Xyz};
|
use crate::source::{Source, Xyz};
|
||||||
use crate::table_source::{TableSource, TableSources};
|
use crate::table_source::{TableSource, TableSources};
|
||||||
|
use crate::utils::parse_x_rewrite_url;
|
||||||
use crate::worker_actor::WorkerActor;
|
use crate::worker_actor::WorkerActor;
|
||||||
|
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
@ -126,30 +128,28 @@ async fn get_composite_source(
|
|||||||
let tiles_path = req
|
let tiles_path = req
|
||||||
.headers()
|
.headers()
|
||||||
.get("x-rewrite-url")
|
.get("x-rewrite-url")
|
||||||
.map_or(Ok(req.path().trim_end_matches(".json")), |header| {
|
.and_then(parse_x_rewrite_url)
|
||||||
let header_str = header.to_str()?;
|
.unwrap_or_else(|| req.path().trim_end_matches(".json").to_owned());
|
||||||
Ok(header_str.trim_end_matches(".json"))
|
|
||||||
})
|
|
||||||
.map_err(|e: http::header::ToStrError| {
|
|
||||||
error::ErrorBadRequest(format!("Can't build TileJSON: {}", e))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let (sep, query) = if req.query_string().is_empty() {
|
|
||||||
("", "")
|
|
||||||
} else {
|
|
||||||
("?", req.query_string())
|
|
||||||
};
|
|
||||||
|
|
||||||
let connection_info = req.connection_info();
|
let connection_info = req.connection_info();
|
||||||
|
|
||||||
let tiles_url = format!(
|
let path_and_query = if req.query_string().is_empty() {
|
||||||
"{}://{}{}/{{z}}/{{x}}/{{y}}.pbf{}{}",
|
format!("{}/{{z}}/{{x}}/{{y}}.pbf", tiles_path)
|
||||||
connection_info.scheme(),
|
} else {
|
||||||
connection_info.host(),
|
format!(
|
||||||
|
"{}/{{z}}/{{x}}/{{y}}.pbf?{}",
|
||||||
tiles_path,
|
tiles_path,
|
||||||
sep,
|
req.query_string()
|
||||||
query
|
)
|
||||||
);
|
};
|
||||||
|
|
||||||
|
let tiles_url = Uri::builder()
|
||||||
|
.scheme(connection_info.scheme())
|
||||||
|
.authority(connection_info.host())
|
||||||
|
.path_and_query(path_and_query)
|
||||||
|
.build()
|
||||||
|
.map(|tiles_url| tiles_url.to_string())
|
||||||
|
.map_err(|e| error::ErrorBadRequest(format!("Can't build tiles URL: {}", e)))?;
|
||||||
|
|
||||||
tilejson.tiles = vec![tiles_url];
|
tilejson.tiles = vec![tiles_url];
|
||||||
Ok(HttpResponse::Ok().json(tilejson))
|
Ok(HttpResponse::Ok().json(tilejson))
|
||||||
@ -266,30 +266,28 @@ async fn get_function_source(
|
|||||||
let tiles_path = req
|
let tiles_path = req
|
||||||
.headers()
|
.headers()
|
||||||
.get("x-rewrite-url")
|
.get("x-rewrite-url")
|
||||||
.map_or(Ok(req.path().trim_end_matches(".json")), |header| {
|
.and_then(parse_x_rewrite_url)
|
||||||
let header_str = header.to_str()?;
|
.unwrap_or_else(|| req.path().trim_end_matches(".json").to_owned());
|
||||||
Ok(header_str.trim_end_matches(".json"))
|
|
||||||
})
|
|
||||||
.map_err(|e: http::header::ToStrError| {
|
|
||||||
error::ErrorBadRequest(format!("Can't build TileJSON: {}", e))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let (sep, query) = if req.query_string().is_empty() {
|
|
||||||
("", "")
|
|
||||||
} else {
|
|
||||||
("?", req.query_string())
|
|
||||||
};
|
|
||||||
|
|
||||||
let connection_info = req.connection_info();
|
let connection_info = req.connection_info();
|
||||||
|
|
||||||
let tiles_url = format!(
|
let path_and_query = if req.query_string().is_empty() {
|
||||||
"{}://{}{}/{{z}}/{{x}}/{{y}}.pbf{}{}",
|
format!("{}/{{z}}/{{x}}/{{y}}.pbf", tiles_path)
|
||||||
connection_info.scheme(),
|
} else {
|
||||||
connection_info.host(),
|
format!(
|
||||||
|
"{}/{{z}}/{{x}}/{{y}}.pbf?{}",
|
||||||
tiles_path,
|
tiles_path,
|
||||||
sep,
|
req.query_string()
|
||||||
query
|
)
|
||||||
);
|
};
|
||||||
|
|
||||||
|
let tiles_url = Uri::builder()
|
||||||
|
.scheme(connection_info.scheme())
|
||||||
|
.authority(connection_info.host())
|
||||||
|
.path_and_query(path_and_query)
|
||||||
|
.build()
|
||||||
|
.map(|tiles_url| tiles_url.to_string())
|
||||||
|
.map_err(|e| error::ErrorBadRequest(format!("Can't build tiles URL: {}", e)))?;
|
||||||
|
|
||||||
tilejson.tiles = vec![tiles_url];
|
tilejson.tiles = vec![tiles_url];
|
||||||
Ok(HttpResponse::Ok().json(tilejson))
|
Ok(HttpResponse::Ok().json(tilejson))
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::source::{Query, Xyz};
|
use crate::source::{Query, Xyz};
|
||||||
|
use actix_web::http;
|
||||||
use postgis::{ewkb, LineString, Point, Polygon};
|
use postgis::{ewkb, LineString, Point, Polygon};
|
||||||
use postgres::types::Json;
|
use postgres::types::Json;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@ -92,3 +93,11 @@ pub fn polygon_to_bbox(polygon: ewkb::Polygon) -> Option<Vec<f32>> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_x_rewrite_url(header: &http::HeaderValue) -> Option<String> {
|
||||||
|
header
|
||||||
|
.to_str()
|
||||||
|
.ok()
|
||||||
|
.and_then(|header| header.parse::<http::Uri>().ok())
|
||||||
|
.map(|uri| uri.path().trim_end_matches(".json").to_owned())
|
||||||
|
}
|
||||||
|
@ -82,17 +82,19 @@ async fn test_get_table_source_ok() {
|
|||||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||||
|
|
||||||
let req = test::TestRequest::get()
|
let req = test::TestRequest::get()
|
||||||
.uri("/public.table_source.json")
|
.uri("/public.table_source.json?token=martin")
|
||||||
|
.header(
|
||||||
|
"x-rewrite-url",
|
||||||
|
"/tiles/public.table_source.json?token=martin",
|
||||||
|
)
|
||||||
.to_request();
|
.to_request();
|
||||||
|
|
||||||
let result: TileJSON = test::read_response_json(&mut app, req).await;
|
let result: TileJSON = test::read_response_json(&mut app, req).await;
|
||||||
|
|
||||||
println!("{:?}", result);
|
|
||||||
|
|
||||||
assert_eq!(result.name, Some(String::from("public.table_source")));
|
assert_eq!(result.name, Some(String::from("public.table_source")));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.tiles,
|
result.tiles,
|
||||||
vec!["http://localhost:8080/public.table_source/{z}/{x}/{y}.pbf"]
|
vec!["http://localhost:8080/tiles/public.table_source/{z}/{x}/{y}.pbf?token=martin"]
|
||||||
);
|
);
|
||||||
assert_eq!(result.minzoom, Some(0));
|
assert_eq!(result.minzoom, Some(0));
|
||||||
assert_eq!(result.maxzoom, Some(30));
|
assert_eq!(result.maxzoom, Some(30));
|
||||||
@ -504,6 +506,21 @@ async fn test_get_function_source_ok() {
|
|||||||
|
|
||||||
let response = test::call_service(&mut app, req).await;
|
let response = test::call_service(&mut app, req).await;
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
|
let req = test::TestRequest::get()
|
||||||
|
.uri("/rpc/public.function_source.json?token=martin")
|
||||||
|
.header(
|
||||||
|
"x-rewrite-url",
|
||||||
|
"/tiles/rpc/public.function_source.json?token=martin",
|
||||||
|
)
|
||||||
|
.to_request();
|
||||||
|
|
||||||
|
let result: TileJSON = test::read_response_json(&mut app, req).await;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
result.tiles,
|
||||||
|
vec!["http://localhost:8080/tiles/rpc/public.function_source/{z}/{x}/{y}.pbf?token=martin"]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
|
Loading…
Reference in New Issue
Block a user