forked from Deuxfleurs/garage
Merge pull request 'api_server.rs: Adapted to use query string per Caddy upstream change' (#491) from jpds/garage:fix-caddy-ask-domain-query-string into main
Reviewed-on: Deuxfleurs/garage#491
This commit is contained in:
commit
4d3a5f29e0
2 changed files with 82 additions and 37 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -81,29 +82,32 @@ impl AdminApiServer {
|
||||||
&self,
|
&self,
|
||||||
req: Request<Body>,
|
req: Request<Body>,
|
||||||
) -> Result<Response<Body>, Error> {
|
) -> Result<Response<Body>, Error> {
|
||||||
let has_domain_header = req.headers().contains_key("domain");
|
let query_params: HashMap<String, String> = req
|
||||||
|
.uri()
|
||||||
|
.query()
|
||||||
|
.map(|v| {
|
||||||
|
url::form_urlencoded::parse(v.as_bytes())
|
||||||
|
.into_owned()
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.unwrap_or_else(HashMap::new);
|
||||||
|
|
||||||
if !has_domain_header {
|
let has_domain_key = query_params.contains_key("domain");
|
||||||
return Err(Error::bad_request("No domain header found"));
|
|
||||||
|
if !has_domain_key {
|
||||||
|
return Err(Error::bad_request("No domain query string found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let domain = &req
|
let domain = query_params
|
||||||
.headers()
|
|
||||||
.get("domain")
|
.get("domain")
|
||||||
.ok_or_internal_error("Could not parse domain header")?;
|
.ok_or_internal_error("Could not parse domain query string")?;
|
||||||
|
|
||||||
let domain_string = String::from(
|
|
||||||
domain
|
|
||||||
.to_str()
|
|
||||||
.ok_or_bad_request("Invalid characters found in domain header")?,
|
|
||||||
);
|
|
||||||
|
|
||||||
let bucket_id = self
|
let bucket_id = self
|
||||||
.garage
|
.garage
|
||||||
.bucket_helper()
|
.bucket_helper()
|
||||||
.resolve_global_bucket_name(&domain_string)
|
.resolve_global_bucket_name(&domain)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(HelperError::NoSuchBucket(domain_string))?;
|
.ok_or(HelperError::NoSuchBucket(domain.to_string()))?;
|
||||||
|
|
||||||
let bucket = self
|
let bucket = self
|
||||||
.garage
|
.garage
|
||||||
|
@ -115,12 +119,16 @@ impl AdminApiServer {
|
||||||
let bucket_website_config = bucket_state.website_config.get();
|
let bucket_website_config = bucket_state.website_config.get();
|
||||||
|
|
||||||
match bucket_website_config {
|
match bucket_website_config {
|
||||||
Some(_v) => Ok(Response::builder()
|
Some(_v) => {
|
||||||
|
Ok(Response::builder()
|
||||||
.status(StatusCode::OK)
|
.status(StatusCode::OK)
|
||||||
.body(Body::from("Bucket authorized for website hosting"))?),
|
.body(Body::from(format!(
|
||||||
None => Err(Error::bad_request(
|
"Bucket '{domain}' is authorized for website hosting"
|
||||||
"Bucket is not authorized for website hosting",
|
)))?)
|
||||||
)),
|
}
|
||||||
|
None => Err(Error::bad_request(format!(
|
||||||
|
"Bucket '{domain}' is not authorized for website hosting"
|
||||||
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,11 @@ async fn test_website() {
|
||||||
let admin_req = || {
|
let admin_req = || {
|
||||||
Request::builder()
|
Request::builder()
|
||||||
.method("GET")
|
.method("GET")
|
||||||
.uri(format!("http://127.0.0.1:{}/check", ctx.garage.admin_port))
|
.uri(format!(
|
||||||
.header("domain", BCKT_NAME.to_string())
|
"http://127.0.0.1:{0}/check?domain={1}",
|
||||||
|
ctx.garage.admin_port,
|
||||||
|
BCKT_NAME.to_string()
|
||||||
|
))
|
||||||
.body(Body::empty())
|
.body(Body::empty())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
@ -69,7 +72,7 @@ async fn test_website() {
|
||||||
res_body,
|
res_body,
|
||||||
json!({
|
json!({
|
||||||
"code": "InvalidRequest",
|
"code": "InvalidRequest",
|
||||||
"message": "Bad request: Bucket is not authorized for website hosting",
|
"message": "Bad request: Bucket 'my-website' is not authorized for website hosting",
|
||||||
"region": "garage-integ-test",
|
"region": "garage-integ-test",
|
||||||
"path": "/check",
|
"path": "/check",
|
||||||
})
|
})
|
||||||
|
@ -91,8 +94,11 @@ async fn test_website() {
|
||||||
let admin_req = || {
|
let admin_req = || {
|
||||||
Request::builder()
|
Request::builder()
|
||||||
.method("GET")
|
.method("GET")
|
||||||
.uri(format!("http://127.0.0.1:{}/check", ctx.garage.admin_port))
|
.uri(format!(
|
||||||
.header("domain", BCKT_NAME.to_string())
|
"http://127.0.0.1:{0}/check?domain={1}",
|
||||||
|
ctx.garage.admin_port,
|
||||||
|
BCKT_NAME.to_string()
|
||||||
|
))
|
||||||
.body(Body::empty())
|
.body(Body::empty())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
@ -101,7 +107,7 @@ async fn test_website() {
|
||||||
assert_eq!(admin_resp.status(), StatusCode::OK);
|
assert_eq!(admin_resp.status(), StatusCode::OK);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_bytes(admin_resp.body_mut()).await.unwrap().as_ref(),
|
to_bytes(admin_resp.body_mut()).await.unwrap().as_ref(),
|
||||||
b"Bucket authorized for website hosting"
|
format!("Bucket '{BCKT_NAME}' is authorized for website hosting").as_bytes()
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.garage
|
ctx.garage
|
||||||
|
@ -120,8 +126,11 @@ async fn test_website() {
|
||||||
let admin_req = || {
|
let admin_req = || {
|
||||||
Request::builder()
|
Request::builder()
|
||||||
.method("GET")
|
.method("GET")
|
||||||
.uri(format!("http://127.0.0.1:{}/check", ctx.garage.admin_port))
|
.uri(format!(
|
||||||
.header("domain", BCKT_NAME.to_string())
|
"http://127.0.0.1:{0}/check?domain={1}",
|
||||||
|
ctx.garage.admin_port,
|
||||||
|
BCKT_NAME.to_string()
|
||||||
|
))
|
||||||
.body(Body::empty())
|
.body(Body::empty())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
@ -133,7 +142,7 @@ async fn test_website() {
|
||||||
res_body,
|
res_body,
|
||||||
json!({
|
json!({
|
||||||
"code": "InvalidRequest",
|
"code": "InvalidRequest",
|
||||||
"message": "Bad request: Bucket is not authorized for website hosting",
|
"message": "Bad request: Bucket 'my-website' is not authorized for website hosting",
|
||||||
"region": "garage-integ-test",
|
"region": "garage-integ-test",
|
||||||
"path": "/check",
|
"path": "/check",
|
||||||
})
|
})
|
||||||
|
@ -408,7 +417,7 @@ async fn test_website_check_website_enabled() {
|
||||||
res_body,
|
res_body,
|
||||||
json!({
|
json!({
|
||||||
"code": "InvalidRequest",
|
"code": "InvalidRequest",
|
||||||
"message": "Bad request: No domain header found",
|
"message": "Bad request: No domain query string found",
|
||||||
"region": "garage-integ-test",
|
"region": "garage-integ-test",
|
||||||
"path": "/check",
|
"path": "/check",
|
||||||
})
|
})
|
||||||
|
@ -417,8 +426,34 @@ async fn test_website_check_website_enabled() {
|
||||||
let admin_req = || {
|
let admin_req = || {
|
||||||
Request::builder()
|
Request::builder()
|
||||||
.method("GET")
|
.method("GET")
|
||||||
.uri(format!("http://127.0.0.1:{}/check", ctx.garage.admin_port))
|
.uri(format!(
|
||||||
.header("domain", "foobar")
|
"http://127.0.0.1:{}/check?domain=",
|
||||||
|
ctx.garage.admin_port
|
||||||
|
))
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let admin_resp = client.request(admin_req()).await.unwrap();
|
||||||
|
assert_eq!(admin_resp.status(), StatusCode::NOT_FOUND);
|
||||||
|
let res_body = json_body(admin_resp).await;
|
||||||
|
assert_json_eq!(
|
||||||
|
res_body,
|
||||||
|
json!({
|
||||||
|
"code": "NoSuchBucket",
|
||||||
|
"message": "Bucket not found: ",
|
||||||
|
"region": "garage-integ-test",
|
||||||
|
"path": "/check",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let admin_req = || {
|
||||||
|
Request::builder()
|
||||||
|
.method("GET")
|
||||||
|
.uri(format!(
|
||||||
|
"http://127.0.0.1:{}/check?domain=foobar",
|
||||||
|
ctx.garage.admin_port
|
||||||
|
))
|
||||||
.body(Body::empty())
|
.body(Body::empty())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
@ -439,20 +474,22 @@ async fn test_website_check_website_enabled() {
|
||||||
let admin_req = || {
|
let admin_req = || {
|
||||||
Request::builder()
|
Request::builder()
|
||||||
.method("GET")
|
.method("GET")
|
||||||
.uri(format!("http://127.0.0.1:{}/check", ctx.garage.admin_port))
|
.uri(format!(
|
||||||
.header("domain", "☹")
|
"http://127.0.0.1:{}/check?domain=%E2%98%B9",
|
||||||
|
ctx.garage.admin_port
|
||||||
|
))
|
||||||
.body(Body::empty())
|
.body(Body::empty())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let admin_resp = client.request(admin_req()).await.unwrap();
|
let admin_resp = client.request(admin_req()).await.unwrap();
|
||||||
assert_eq!(admin_resp.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(admin_resp.status(), StatusCode::NOT_FOUND);
|
||||||
let res_body = json_body(admin_resp).await;
|
let res_body = json_body(admin_resp).await;
|
||||||
assert_json_eq!(
|
assert_json_eq!(
|
||||||
res_body,
|
res_body,
|
||||||
json!({
|
json!({
|
||||||
"code": "InvalidRequest",
|
"code": "NoSuchBucket",
|
||||||
"message": "Bad request: Invalid characters found in domain header: failed to convert header to a str",
|
"message": "Bucket not found: ☹",
|
||||||
"region": "garage-integ-test",
|
"region": "garage-integ-test",
|
||||||
"path": "/check",
|
"path": "/check",
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue