Skip to content

Commit

Permalink
fix: image proxy on web ui (#154)
Browse files Browse the repository at this point in the history
I found that the image proxy is not applied when requested through web
ui. The cause is that the endpoint parameter is not extracted correctly,
such that the `base` field is always missing. This PR fixes the issue.

In addition I realized the app base inference logic doesn't match what's
defined in the documentation. I've updated the logic to match the
documentation.
  • Loading branch information
shouya authored Sep 28, 2024
1 parent 952e7da commit 49be74f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 22 deletions.
34 changes: 33 additions & 1 deletion src/server/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,21 @@ impl EndpointParam {
}

fn get_base(req: &Parts) -> Option<Url> {
if let Some(url) = Self::base_from_env().as_ref() {
return Some(url.clone());
}

if let Some(url) = Self::base_from_reverse_proxy(req) {
return Some(url);
}

Self::base_from_host(req)
}

fn base_from_reverse_proxy(req: &Parts) -> Option<Url> {
let host = req
.headers
.get("X-Forwarded-Host")
.or_else(|| req.headers.get(HOST))
.and_then(|x| x.to_str().ok())?;

let proto = req
Expand All @@ -204,6 +215,27 @@ impl EndpointParam {
let base = base.parse().ok()?;
Some(base)
}

fn base_from_host(req: &Parts) -> Option<Url> {
let host = req.headers.get(HOST)?.to_str().ok()?;
let base = format!("http://{}/", host);
let base = base.parse().ok()?;
Some(base)
}

fn base_from_env() -> &'static Option<Url> {
use std::env;
use std::sync::OnceLock;

static APP_BASE_URL: OnceLock<Option<Url>> = OnceLock::new();
APP_BASE_URL.get_or_init(|| {
let var = env::var("RSS_FUNNEL_APP_BASE").ok();
var.map(|v| {
v.parse()
.expect("Invalid base url specified in RSS_FUNNEL_APP_BASE")
})
})
}
}

impl Service<Request> for EndpointService {
Expand Down
5 changes: 2 additions & 3 deletions src/server/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod login;
use std::borrow::Cow;

use axum::{
extract::{rejection::QueryRejection, Path, Query},
extract::Path,
response::{IntoResponse, Redirect, Response},
routing, Extension, Router,
};
Expand Down Expand Up @@ -70,14 +70,13 @@ async fn handle_endpoint(
_: Auth,
Path(path): Path<String>,
Extension(service): Extension<FeedService>,
param: Result<Query<EndpointParam>, QueryRejection>,
param: EndpointParam,
) -> Result<Markup, Response> {
let endpoint = service.get_endpoint(&path).await.ok_or_else(|| {
(StatusCode::NOT_FOUND, format!("Endpoint {path} not found"))
.into_response()
})?;

let param = param.map(|q| q.0).map_err(|e| e.body_text());
Ok(endpoint::render_endpoint_page(endpoint, path, param).await)
}

Expand Down
28 changes: 10 additions & 18 deletions src/server/web/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,17 @@ use crate::{
pub async fn render_endpoint_page(
endpoint: EndpointService,
path: String,
param: Result<EndpointParam, String>,
param: EndpointParam,
) -> Markup {
// render source control
let source = source_control_fragment(&path, endpoint.source(), &param);

// render config
let config = render_config_fragment(&path, param.as_ref().ok(), &endpoint);
let config = render_config_fragment(&path, &param, &endpoint);
let config_tags = render_config_header_tags(&endpoint);

// render normalized feed
let feed = match param {
Ok(param) => fetch_and_render_feed(endpoint, param).await,
Err(e) => html! {
div .flash.error {
header { b { "Invalid request params" } }
p { (e) }
}
},
};
let feed = fetch_and_render_feed(endpoint, param).await;

html! {
(DOCTYPE)
Expand Down Expand Up @@ -91,7 +83,7 @@ pub async fn render_endpoint_page(
fn source_control_fragment(
path: &str,
source: &Source,
param: &Result<EndpointParam, String>,
param: &EndpointParam,
) -> Markup {
match source {
Source::Dynamic => html! {
Expand All @@ -100,7 +92,7 @@ fn source_control_fragment(
type="text"
name="source"
placeholder="Source URL"
value=[param.as_ref().ok().and_then(|p| p.source()).map(|url| url.as_str())]
value=[param.source().map(|url| url.as_str())]
hx-get=(format!("/_/endpoint/{path}"))
hx-trigger="keyup changed delay:500ms"
hx-push-url="true"
Expand All @@ -114,7 +106,7 @@ fn source_control_fragment(
Source::RelativeUrl(url) => html! {div title="Source" .source { (url) }},
Source::Templated(templated) => html! {
div .source-template-container {
@let queries = param.as_ref().ok().map(|p| p.extra_queries());
@let queries = param.extra_queries();
(source_template_fragment(templated, path, queries));
}
},
Expand Down Expand Up @@ -154,14 +146,14 @@ fn from_scratch_fragment(scratch: &FromScratch) -> Markup {
fn source_template_fragment(
templated: &crate::source::Templated,
path: &str,
queries: Option<&HashMap<String, String>>,
queries: &HashMap<String, String>,
) -> Markup {
html! {
@for fragment in templated.fragments() {
@match fragment {
Either::Left(plain) => span style="white-space: nowrap" { (plain) },
Either::Right((name, Some(placeholder))) => {
@let value=queries.and_then(|q| q.get(name));
@let value=queries.get(name);
@let default_value=placeholder.default.as_ref();
@let value=value.or(default_value);
@let validation=placeholder.validation.as_ref();
Expand Down Expand Up @@ -203,12 +195,12 @@ fn render_config_header_tags(endpoint: &EndpointService) -> Markup {

fn render_config_fragment(
path: &str,
param: Option<&EndpointParam>,
param: &EndpointParam,
endpoint: &EndpointService,
) -> Markup {
let config = endpoint.config();
let filter_enabled = |i| {
if let Some(f) = param.and_then(|p| p.filter_skip()) {
if let Some(f) = param.filter_skip() {
f.allows_filter(i) as u8
} else {
true as u8
Expand Down

0 comments on commit 49be74f

Please sign in to comment.