pub struct Processor { /* private fields */ }Expand description
A processor for handling ESI responses
The Processor maintains state and configuration for processing ESI directives in HTML/XML content. It handles fragment inclusion, variable substitution, and conditional processing according to the ESI specification.
§Fields
original_request_metadata- Optional original client request data used for fragment requestsconfiguration- Configuration settings controlling ESI processing behavior
§Example
use esi::{Processor, Configuration};
use fastly::Request;
// Create a configuration (assuming Configuration implements Default)
let config = Configuration::default();
// Optionally, create a Request (assuming Request can be constructed or mocked)
let request = Request::get("http://example.com/");
// Initialize the Processor with optional request metadata
let processor = Processor::new(Some(request), config);Implementations§
Source§impl Processor
impl Processor
pub const fn new( original_request_metadata: Option<Request>, configuration: Configuration, ) -> Self
Sourcepub fn process_response(
self,
src_document: &mut Response,
client_response_metadata: Option<Response>,
dispatch_fragment_request: Option<&dyn Fn(Request) -> Result<PendingFragmentContent>>,
process_fragment_response: Option<&dyn Fn(&mut Request, Response) -> Result<Response>>,
) -> Result<()>
pub fn process_response( self, src_document: &mut Response, client_response_metadata: Option<Response>, dispatch_fragment_request: Option<&dyn Fn(Request) -> Result<PendingFragmentContent>>, process_fragment_response: Option<&dyn Fn(&mut Request, Response) -> Result<Response>>, ) -> Result<()>
Process a response body as an ESI document. Consumes the response body.
This method processes ESI directives in the response body while streaming the output to the client, minimizing memory usage for large responses. It handles ESI includes, conditionals, and variable substitution according to the ESI specification.
§Arguments
src_document- Source HTTP response containing ESI markup to processclient_response_metadata- Optional response metadata (headers, status) to send to clientdispatch_fragment_request- Optional callback for customizing fragment request handlingprocess_fragment_response- Optional callback for processing fragment responses
§Returns
Result<()>- Ok if processing completed successfully, Error if processing failed
§Example
use fastly::Response;
use esi::{Processor, Configuration};
// Create a processor
let processor = Processor::new(None, Configuration::default());
// Create a response with ESI markup
let mut response = Response::new();
response.set_body("<esi:include src='http://example.com/header.html'/>");
// Define a simple fragment dispatcher
fn default_fragment_dispatcher(req: fastly::Request) -> esi::Result<esi::PendingFragmentContent> {
Ok(esi::PendingFragmentContent::CompletedRequest(
fastly::Response::from_body("Fragment content")
))
}
// Process the response, streaming the resulting document directly to the client
processor.process_response(
&mut response,
None,
Some(&default_fragment_dispatcher),
None
)?;§Errors
Returns error if:
- ESI processing fails
- Stream writing fails
- Fragment requests fail
Sourcepub fn process_parsed_document(
self,
src_events: VecDeque<Event<'_>>,
output_writer: &mut Writer<impl Write>,
dispatch_fragment_request: Option<&dyn Fn(Request) -> Result<PendingFragmentContent>>,
process_fragment_response: Option<&dyn Fn(&mut Request, Response) -> Result<Response>>,
) -> Result<()>
pub fn process_parsed_document( self, src_events: VecDeque<Event<'_>>, output_writer: &mut Writer<impl Write>, dispatch_fragment_request: Option<&dyn Fn(Request) -> Result<PendingFragmentContent>>, process_fragment_response: Option<&dyn Fn(&mut Request, Response) -> Result<Response>>, ) -> Result<()>
Process an ESI document that has already been parsed into a queue of events.
Takes a queue of already parsed ESI events and processes them, writing the output to the provided writer. This method is used internally after parsing but can also be called directly if you have pre-parsed events.
§Arguments
src_events- Queue of parsed ESI events to processoutput_writer- Writer to stream processed output todispatch_fragment_request- Optional handler for fragment requestsprocess_fragment_response- Optional processor for fragment responses
§Returns
Result<()>- Ok if processing completed successfully
§Example
use std::io::Cursor;
use std::collections::VecDeque;
use esi::{Event, Reader, Writer, Processor, Configuration};
use quick_xml::events::Event as XmlEvent;
let events = VecDeque::from([Event::Content(XmlEvent::Empty(
quick_xml::events::BytesStart::new("div")
))]);
let mut writer = Writer::new(Cursor::new(Vec::new()));
let processor = Processor::new(None, esi::Configuration::default());
processor.process_parsed_document(
events,
&mut writer,
None,
None
)?;§Errors
Returns error if:
- Event processing fails
- Writing to output fails
- Fragment request/response processing fails
Sourcepub fn process_document(
self,
src_document: Reader<impl BufRead>,
output_writer: &mut Writer<impl Write>,
dispatch_fragment_request: Option<&dyn Fn(Request) -> Result<PendingFragmentContent>>,
process_fragment_response: Option<&dyn Fn(&mut Request, Response) -> Result<Response>>,
) -> Result<()>
pub fn process_document( self, src_document: Reader<impl BufRead>, output_writer: &mut Writer<impl Write>, dispatch_fragment_request: Option<&dyn Fn(Request) -> Result<PendingFragmentContent>>, process_fragment_response: Option<&dyn Fn(&mut Request, Response) -> Result<Response>>, ) -> Result<()>
Process an ESI document from a Reader, handling includes and directives
Processes ESI directives while streaming content to the output writer. Handles:
- ESI includes with fragment fetching
- Variable substitution
- Conditional processing
- Try/except blocks
§Arguments
src_document- Reader containing source XML/HTML with ESI markupoutput_writer- Writer to stream processed output todispatch_fragment_request- Optional handler for fragment requestsprocess_fragment_response- Optional processor for fragment responses
§Returns
Result<()>- Ok if processing completed successfully
§Example
use esi::{Reader, Writer, Processor, Configuration};
use std::io::Cursor;
let xml = r#"<esi:include src="http://example.com/header.html"/>"#;
let reader = Reader::from_str(xml);
let mut writer = Writer::new(Cursor::new(Vec::new()));
let processor = Processor::new(None, Configuration::default());
// Define a simple fragment dispatcher
fn default_fragment_dispatcher(req: fastly::Request) -> esi::Result<esi::PendingFragmentContent> {
Ok(esi::PendingFragmentContent::CompletedRequest(
fastly::Response::from_body("Fragment content")
))
}
processor.process_document(
reader,
&mut writer,
Some(&default_fragment_dispatcher),
None
)?;§Errors
Returns error if:
- ESI markup parsing fails
- Fragment requests fail
- Output writing fails
Auto Trait Implementations§
impl !Freeze for Processor
impl !RefUnwindSafe for Processor
impl !Send for Processor
impl !Sync for Processor
impl Unpin for Processor
impl !UnwindSafe for Processor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more