mirror of
https://github.com/maplibre/martin.git
synced 2024-12-18 20:31:54 +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
|
||||
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-Proto $scheme;
|
||||
proxy_redirect off;
|
||||
@ -640,7 +640,7 @@ http {
|
||||
server {
|
||||
...
|
||||
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-Proto $scheme;
|
||||
proxy_redirect off;
|
||||
|
@ -56,7 +56,7 @@ http {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
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_connect_timeout 15m;
|
||||
|
@ -1,4 +1,3 @@
|
||||
use serde::Deserialize;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
@ -6,9 +5,11 @@ use std::rc::Rc;
|
||||
|
||||
use actix::{Actor, Addr, SyncArbiter, SystemRunner};
|
||||
use actix_cors::Cors;
|
||||
use actix_web::http::Uri;
|
||||
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::config::Config;
|
||||
@ -19,6 +20,7 @@ use crate::function_source::FunctionSources;
|
||||
use crate::messages;
|
||||
use crate::source::{Source, Xyz};
|
||||
use crate::table_source::{TableSource, TableSources};
|
||||
use crate::utils::parse_x_rewrite_url;
|
||||
use crate::worker_actor::WorkerActor;
|
||||
|
||||
pub struct AppState {
|
||||
@ -126,30 +128,28 @@ async fn get_composite_source(
|
||||
let tiles_path = req
|
||||
.headers()
|
||||
.get("x-rewrite-url")
|
||||
.map_or(Ok(req.path().trim_end_matches(".json")), |header| {
|
||||
let header_str = header.to_str()?;
|
||||
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())
|
||||
};
|
||||
.and_then(parse_x_rewrite_url)
|
||||
.unwrap_or_else(|| req.path().trim_end_matches(".json").to_owned());
|
||||
|
||||
let connection_info = req.connection_info();
|
||||
|
||||
let tiles_url = format!(
|
||||
"{}://{}{}/{{z}}/{{x}}/{{y}}.pbf{}{}",
|
||||
connection_info.scheme(),
|
||||
connection_info.host(),
|
||||
tiles_path,
|
||||
sep,
|
||||
query
|
||||
);
|
||||
let path_and_query = if req.query_string().is_empty() {
|
||||
format!("{}/{{z}}/{{x}}/{{y}}.pbf", tiles_path)
|
||||
} else {
|
||||
format!(
|
||||
"{}/{{z}}/{{x}}/{{y}}.pbf?{}",
|
||||
tiles_path,
|
||||
req.query_string()
|
||||
)
|
||||
};
|
||||
|
||||
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];
|
||||
Ok(HttpResponse::Ok().json(tilejson))
|
||||
@ -266,30 +266,28 @@ async fn get_function_source(
|
||||
let tiles_path = req
|
||||
.headers()
|
||||
.get("x-rewrite-url")
|
||||
.map_or(Ok(req.path().trim_end_matches(".json")), |header| {
|
||||
let header_str = header.to_str()?;
|
||||
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())
|
||||
};
|
||||
.and_then(parse_x_rewrite_url)
|
||||
.unwrap_or_else(|| req.path().trim_end_matches(".json").to_owned());
|
||||
|
||||
let connection_info = req.connection_info();
|
||||
|
||||
let tiles_url = format!(
|
||||
"{}://{}{}/{{z}}/{{x}}/{{y}}.pbf{}{}",
|
||||
connection_info.scheme(),
|
||||
connection_info.host(),
|
||||
tiles_path,
|
||||
sep,
|
||||
query
|
||||
);
|
||||
let path_and_query = if req.query_string().is_empty() {
|
||||
format!("{}/{{z}}/{{x}}/{{y}}.pbf", tiles_path)
|
||||
} else {
|
||||
format!(
|
||||
"{}/{{z}}/{{x}}/{{y}}.pbf?{}",
|
||||
tiles_path,
|
||||
req.query_string()
|
||||
)
|
||||
};
|
||||
|
||||
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];
|
||||
Ok(HttpResponse::Ok().json(tilejson))
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::source::{Query, Xyz};
|
||||
use actix_web::http;
|
||||
use postgis::{ewkb, LineString, Point, Polygon};
|
||||
use postgres::types::Json;
|
||||
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);
|
||||
|
||||
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();
|
||||
|
||||
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.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.maxzoom, Some(30));
|
||||
@ -504,6 +506,21 @@ async fn test_get_function_source_ok() {
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
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]
|
||||
|
Loading…
Reference in New Issue
Block a user