Skip to content

Fix context not preserved when doing an http_call from an on_tick - #385

Open
balbifm wants to merge 1 commit into
proxy-wasm:mainfrom
balbifm:add-info-logging
Open

Fix context not preserved when doing an http_call from an on_tick#385
balbifm wants to merge 1 commit into
proxy-wasm:mainfrom
balbifm:add-info-logging

Conversation

@balbifm

@balbifm balbifm commented Jul 31, 2026

Copy link
Copy Markdown

When trying to perform an HTTP Call from an on_tick, as part of a paused HTTP Request, the response is processed by the Root context instead of the HTTP context. Which prevents setting stream properties while processing the HTTP Call response.

Example of what can not be currently done:

use std::cell::Cell;
use std::rc::Rc;
use std::time::Duration;

use log::info;
use proxy_wasm::hostcalls;
use proxy_wasm::traits::{Context, HttpContext, RootContext};
use proxy_wasm::types::{Action, ContextType, LogLevel};

proxy_wasm::main! {{
    proxy_wasm::set_log_level(LogLevel::Info);
    proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> {
        Box::new(FilterRoot {
            pending: Rc::new(Cell::new(None)),
        })
    });
}}

struct FilterRoot {
    pending: Rc<Cell<Option<u32>>>,
}

impl Context for FilterRoot {
    fn on_http_call_response(&mut self, _t: u32, _nh: usize, _bs: usize, _nt: usize) {
        panic!("Callback arriving to root context instead of http context");
    }
}

impl RootContext for FilterRoot {
    fn on_configure(&mut self, _plugin_configuration_size: usize) -> bool {
        self.set_tick_period(Duration::from_millis(500));
        true
    }

    fn create_http_context(&self, context_id: u32) -> Option<Box<dyn HttpContext>> {
        Some(Box::new(HttpFilter {
            context_id,
            pending: self.pending.clone(),
        }))
    }

    fn get_type(&self) -> Option<ContextType> {
        Some(ContextType::HttpContext)
    }

    fn on_tick(&mut self) {
        let Some(context_id) = self.pending.get() else {
            return;
        };
        self.pending.set(None); // unflag1

        let _ = hostcalls::set_effective_context(context_id);

        match self.dispatch_http_call(
            "ingress-http-upstream.default.svc",
            vec![
                (":method", "GET"),
                (":path", "/get"),
                (":authority", "backend"),
            ],
            None,
            vec![],
            Duration::from_secs(5),
        ) {
            Ok(token) => info!("dispatched http call (token {token}) for context {context_id}"),
            Err(status) => info!("dispatch_http_call failed: {:?}", status),
        }
    }
}

struct HttpFilter {
    context_id: u32,
    pending: Rc<Cell<Option<u32>>>,
}

impl Context for HttpFilter {
    fn on_http_call_response(&mut self, _t: u32, _nh: usize, _bs: usize, _nt: usize) {
        let status = self
            .get_http_call_response_header(":status")
            .unwrap_or_else(|| "unknown".to_string());
        
        info!("on_http_call_response: upstream call returned status {status}",);

        self.set_property(
            vec!["access_log_custom", "upstream_status"],
            Some(status.as_bytes()),
        );

        let _ = hostcalls::resume_http_request();
    }
}

impl HttpContext for HttpFilter {
    fn on_http_request_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action {
        self.pending.set(Some(self.context_id)); // set flag1
        Action::Pause
    }
}

@balbifm
balbifm requested a review from PiotrSikora as a code owner July 31, 2026 14:21
@google-cla

google-cla Bot commented Jul 31, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@balbifm
balbifm force-pushed the add-info-logging branch 3 times, most recently from 5bb05c9 to 0c00548 Compare July 31, 2026 17:26
@balbifm balbifm changed the title Test Fix context not preserved when doing an http_call from an on_tick Jul 31, 2026
@balbifm
balbifm force-pushed the add-info-logging branch from 0c00548 to 7b5e094 Compare July 31, 2026 17:31
Signed-off-by: Federico Balbi <fbalbi@salesforce.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant