// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use proxy_wasm_experimental as proxy_wasm; use log::trace; use proxy_wasm::traits::*; use proxy_wasm::types::*; use std::time::Duration; #[no_mangle] pub fn _start() { proxy_wasm::set_log_level(LogLevel::Trace); proxy_wasm::set_http_context(|_, _| -> Box { Box::new(HttpAuthRandom) }); } struct HttpAuthRandom; impl HttpContext for HttpAuthRandom { fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action { self.dispatch_http_call( "httpbin", vec![ (":method", "GET"), (":path", "/bytes/1"), (":authority", "httpbin.org"), ], None, vec![], Duration::from_secs(5), ) .unwrap(); Action::Pause } fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action { self.set_http_response_header("Powered-By", Some("proxy-wasm")); Action::Continue } } impl Context for HttpAuthRandom { fn on_http_call_response(&mut self, _: u32, _: usize, body_size: usize, _: usize) { if let Some(body) = self.get_http_call_response_body(0, body_size) { if !body.is_empty() && body[0] % 2 == 0 { trace!("Access granted."); self.resume_http_request(); return; } } trace!("Access forbidden."); self.send_http_response( 403, vec![("Powered-By", "proxy-wasm")], Some(b"Access forbidden.\n"), ); } }