proxy-wasm-rust-sdk icon indicating copy to clipboard operation
proxy-wasm-rust-sdk copied to clipboard

how to modify and set http request body

Open xshadowlegendx opened this issue 3 years ago • 1 comments

hello, I am using rust proxy wasm with apisix wasm plugin, below is the sample code to get, modify and set http request body

use std::string;

use json;
use log::{warn};
use proxy_wasm;
use proxy_wasm::traits::Context;

struct RequestSignerHttpContext {
    context_id: u32,
    request_body_size: usize
}

struct RequestSignerRootContext;

proxy_wasm::main!{{
    proxy_wasm::set_log_level(proxy_wasm::types::LogLevel::Trace);

    proxy_wasm::set_root_context(|_| ->
        Box<dyn proxy_wasm::traits::RootContext> { Box::new(RequestSignerRootContext) });

    // proxy_wasm::set_http_context(|context_id, _| ->
    //     Box<dyn proxy_wasm::traits::HttpContext> { Box::new(RequestSignerHttpContext{ context_id, request_body_size: 0 }) });
}}

impl proxy_wasm::traits::Context for RequestSignerRootContext {}

impl proxy_wasm::traits::RootContext for RequestSignerRootContext {
    fn get_type(&self) -> Option<proxy_wasm::types::ContextType> {
        Some(proxy_wasm::types::ContextType::HttpContext)
    }

    fn create_http_context(&self, context_id: u32) -> Option<Box<dyn proxy_wasm::traits::HttpContext>> {
        Some(Box::new(RequestSignerHttpContext { context_id, request_body_size: 0 }))
    }
}

impl RequestSignerHttpContext {
    fn set_request_body_size(&mut self, size: usize) {
        self.request_body_size += size;
    }
}

impl proxy_wasm::traits::Context for RequestSignerHttpContext {}

impl proxy_wasm::traits::HttpContext for RequestSignerHttpContext {
    fn on_http_request_headers(&mut self, _: usize, _: bool) -> proxy_wasm::types::Action {
        self.set_property(vec!["wasm_process_req_body"], Some("true".as_bytes()));

        proxy_wasm::types::Action::Continue
    }

    fn on_http_request_body(&mut self, body_size: usize, end_of_stream: bool) -> proxy_wasm::types::Action {
        self.set_request_body_size(self.request_body_size + body_size);

        if !end_of_stream {
            return proxy_wasm::types::Action::Pause;
        }

        let body_str: string::String =
            match self.get_http_request_body(0, self.request_body_size) {
                Some(val) => {
                    match string::String::from_utf8(val) {
                        Ok(val) => val,
                        Err(_err) => String::from("")
                    }
                },
                None => String::from("")
            };

        let mut json_body =
            if body_str.is_empty() {
                json::parse("{}").unwrap()
            } else {
                match json::parse(&body_str) {
                    Ok(val) => val,
                    Err(_) => json::parse("{}").unwrap()
                }
            };

        json_body["newval"] = "testxx".into();

        let json_str: string::String = json::stringify(json_body.clone());

        let new_request_body_size: usize = json_str.len();

        self.set_http_request_body(0, new_request_body_size, json::stringify(json_body).as_bytes());

        self.resume_http_request();

        proxy_wasm::types::Action::Continue
    }
}

so when I try post request and the plugin run, it give these error

50#50: *6596 panicked at 'unexpected status: 12', /Users/xanonx/.cargo/registry/src/github.com-1ecc6299db9ec823/proxy-wasm-0.2.0/src/hostcalls.rs:135:23, client: 127.0.0.1, server: _, request: "POST /anything HTTP/1.1", host: "weby.local"
50#50: failed to call function: wasm trap: wasm `unreachable` instruction executed
50#50: *6596 [lua] wasm.lua:95: phase_func(): my-custom-plugin: failed to run wasm plugin: failed to run proxy_on_http_request_body, client: 127.0.0.1, server: _, request: "POST /anything HTTP/1.1", host: "weby.local"
50#50: *6596 [lua] plugin.lua:901: run_plugin(): my-custom-plugin exits with http status code 503, client: 127.0.0.1, server: _, request: "POST /anything HTTP/1.1", host: "weby.local"
50#50: *6596 panicked at 'already borrowed: BorrowMutError', /Users/xanonx/.cargo/registry/src/github.com-1ecc6299db9ec823/proxy-wasm-0.2.0/src/dispatcher.rs:370:54, client: 127.0.0.1, server: _, request: "POST /anything HTTP/1.1", host: "weby.local"
thread panicked while panicking. aborting.
50#50: failed to call function: wasm trap: wasm `unreachable` instruction executed
50#50: *6596 [lua] wasm.lua:112: phase_func(): my-custom-plugin: failed to run wasm plugin: failed to run proxy_on_http_response_headers, client: 127.0.0.1, server: _, request: "POST /anything HTTP/1.1", host: "weby.local"
thread panicked while processing panic. aborting.
50#50: failed to call function: wasm trap: wasm `unreachable` instruction executed
50#50: failed to mark context 2 as done, rc: -1
thread panicked while processing panic. aborting.
50#50: failed to call function: wasm trap: wasm `unreachable` instruction executed
50#50: failed to delete context 2, rc: -1

the error show that it is panicking from already borrowed: BorrowMutError error from proxy-wasm-0.2.0/src/dispatcher.rs:370:54. Does my set new request body code wasnt supposed to use set_http_request_body method or something is wrong with my code?

xshadowlegendx avatar Oct 03 '22 03:10 xshadowlegendx

Is there any new progress on this issue

Fengxq2014 avatar Sep 20 '23 06:09 Fengxq2014