Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions esi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ impl<W: Write> ElementHandler for DocumentHandler<'_, W> {
let dispatcher = self.dispatch_fragment_request;
let resp_handler = self.fragment_response_handler;
let mut isolated_processor = Processor::new(
Some(self.processor.ctx.get_request().clone_without_body()),
Some(fragment.req.clone_without_body()),
Comment thread
vagetman marked this conversation as resolved.
self.processor.configuration.clone(),
);
isolated_processor.include_depth = self.processor.include_depth + 1;
Expand Down Expand Up @@ -1760,6 +1760,7 @@ impl Processor {
body_bytes,
dca_mode,
&fragment_url,
&fragment.req,
output_writer,
dispatch_fragment_request,
process_fragment_response,
Expand Down Expand Up @@ -1792,6 +1793,7 @@ impl Processor {
body_bytes,
dca_mode,
&String::from_utf8_lossy(&alt_src),
&alt_req,
output_writer,
dispatch_fragment_request,
process_fragment_response,
Expand Down Expand Up @@ -1850,6 +1852,7 @@ impl Processor {
body_bytes: Vec<u8>,
dca_mode: DcaMode,
url: &str,
fragment_request: &Request,
output_writer: &mut impl Write,
dispatcher: &FragmentRequestDispatcher,
process_fragment_response: Option<&FragmentResponseProcessor>,
Expand Down Expand Up @@ -1882,7 +1885,7 @@ impl Processor {
// separate Processor also gives us a clean queue, preventing
// nested includes from escaping to the parent's slot scope.
let mut isolated_processor = Processor::new(
Some(self.ctx.get_request().clone_without_body()),
Some(fragment_request.clone_without_body()),
self.configuration.clone(),
);
isolated_processor.include_depth = self.include_depth + 1;
Expand Down
61 changes: 60 additions & 1 deletion esi/tests/dca_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,24 @@ use std::sync::Arc;
// ---------------------------------------------------------------------------

fn run<F>(input: &str, config: Configuration, dispatcher: &F) -> esi::Result<String>
where
F: Fn(Request, Option<u32>) -> esi::Result<esi::PendingFragmentContent> + 'static,
{
run_with_request(input, None, config, dispatcher)
}

fn run_with_request<F>(
input: &str,
request: Option<Request>,
config: Configuration,
dispatcher: &F,
) -> esi::Result<String>
where
F: Fn(Request, Option<u32>) -> esi::Result<esi::PendingFragmentContent> + 'static,
{
let reader = std::io::BufReader::new(std::io::Cursor::new(input.as_bytes()));
let mut output = Vec::new();
let mut processor = Processor::new(None, config);
let mut processor = Processor::new(request, config);
processor.process_stream(
reader,
&mut output,
Expand Down Expand Up @@ -486,3 +498,50 @@ fn test_inherit_on_eval_subtree() -> esi::Result<()> {
assert_eq!(result, "E0[88]");
Ok(())
}

// ===========================================================================
// 5. REQUEST_PATH / QUERY_STRING in nested dca=esi (issue #49)
// ===========================================================================

/// $(REQUEST_PATH) in a nested dca=esi fragment should reflect the fragment's
/// URL, not the top-level client request path.
#[test]
fn test_request_path_reflects_fragment_url_in_nested_dca_esi() -> esi::Result<()> {
let d = static_body(r#"<esi:vars>$(REQUEST_PATH)</esi:vars>"#);
let result = run_with_request(
r#"<esi:include src="/path/to/fragment" dca="esi"/>"#,
Some(Request::get("http://localhost/original")),
Configuration::default(),
&d,
)?;
assert_eq!(result, "/path/to/fragment");
Ok(())
}

/// $(QUERY_STRING) in a nested dca=esi fragment should reflect the fragment's
/// query string when the include src specifies one.
#[test]
fn test_query_string_reflects_fragment_url_in_nested_dca_esi() -> esi::Result<()> {
let d = static_body(r#"<esi:vars>$(QUERY_STRING{key})</esi:vars>"#);
let result = run_with_request(
r#"<esi:include src="/frag?key=from_fragment" dca="esi"/>"#,
Some(Request::get("http://localhost/original?key=from_parent")),
Configuration::default(),
&d,
)?;
assert_eq!(result, "from_fragment");
Ok(())
}

/// $(REQUEST_PATH) at top level still reflects the client request.
#[test]
fn test_request_path_top_level_unchanged() -> esi::Result<()> {
let result = run_with_request(
r#"<esi:vars>$(REQUEST_PATH)</esi:vars>"#,
Some(Request::get("http://localhost/original")),
Configuration::default(),
&|_req, _maxwait| unreachable!(),
)?;
assert_eq!(result, "/original");
Ok(())
}
Loading