Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add method of ignoring some fragments and pass them on to the client #7

Open
andersjanmyr opened this issue Jun 17, 2022 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@andersjanmyr
Copy link

We have the need for ignoring <esi:include>s for certain hostnames that cannot be handled. The only way I can do this is by hacking the parser. It would be nice to be able to tell the parser to skip some includes.

    match req.get_host() {
        // Tell parser to ignore this esi:include and pass it out as is.
        "host.to.ignore" => ErrSkip(),
        // It results in an infinite loop if pass  format!(r#"<esi:include onerror="continue" src="{}"></esi:include>"#, src);

        // Send all other fragment requests to the main origin
        // with a cache TTL of two minutes (120s)
        _ => Ok(req.with_ttl(120).send("origin_0")?)
      }
@andersjanmyr
Copy link
Author

I have a hacked solution for this that passes a function into the processor and parser.

    let esi_config = esi::Config {
        namespace: String::from("esi"),
        should_handle: &|src| {
            (src.starts_with("/") || src.contains(&config.host)) && s3_regex.is_match(src)
        },
    };
#[derive(Clone)]
pub struct Config<'a> {
    pub namespace: String,
    pub should_handle: &'a dyn Fn(&str) -> bool,
}

impl<'a> Default for Config<'a> {
    fn default() -> Self {
        Self {
            namespace: String::from("esi"),
            should_handle: &|src| true,
        }
    }
}

impl<'a> Config<'a> {
    /// Sets an alternative ESI namespace, which is used to identify ESI instructions.
    ///
    /// For example, setting this to `test` would cause the processor to only match tags like `<test:include>`.
    pub fn with_namespace(mut self, namespace: impl Into<String>) -> Self {
        self.namespace = namespace.into();
        self
    }

    pub fn with_should_handle(mut self, should_handle: &'a fn(src: &str) -> bool) -> Self {
        self.should_handle = should_handle;
        self
    }
}

@andersjanmyr
Copy link
Author

My solution for handling the requests is not optimal, but looks something like this.

            match event {
                Event::ESI(Tag::Include {
                    src,
                    alt,
                    continue_on_error,
                }) if (self.config.should_handle)(&src) => {
                }
                Event::ESI(Tag::Include {   src,   alt,  continue_on_error  }) => {
                   // ugly
                    let message = format!(r#"<esi:include onerror="continue" src="{}"></esi:include>"#, src);
                    xml_writer.write(message.as_bytes())?;
                    xml_writer.inner().flush().expect("failed to flush output");
                }
                Event::XML(event) => {

@kailan kailan self-assigned this Jul 7, 2022
@kailan kailan added this to the v0.4.0 milestone Jan 27, 2023
@kailan kailan added the enhancement New feature or request label Jan 27, 2023
@kailan kailan removed this from the v0.4.0 milestone Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants