diff --git a/.changesets/feat_feature_rhaiuriport.md b/.changesets/feat_feature_rhaiuriport.md new file mode 100644 index 0000000000..f010486e5b --- /dev/null +++ b/.changesets/feat_feature_rhaiuriport.md @@ -0,0 +1,11 @@ +### Add request.uri.port to rhai engine ([PR #6119](https://github.com/apollographql/router/pull/6119)) + +`request.uri.port` and `request.subgraph.uri.port` to rhai engine for both read and write. An example fo where this may be useful is if you need to dynamically change the uri of a subgraph call, including setting a port: + +```rhai +fn subgraph_request_callback (request) { + request.subgraph.uri.port = "4001"; +} +``` + +By [@andrewmcgivery](https://github.com/andrewmcgivery) in https://github.com/apollographql/router/pull/6119 diff --git a/apollo-router/src/plugins/rhai/engine.rs b/apollo-router/src/plugins/rhai/engine.rs index 1b6ad5d4a5..563f5f2d75 100644 --- a/apollo-router/src/plugins/rhai/engine.rs +++ b/apollo-router/src/plugins/rhai/engine.rs @@ -1147,6 +1147,22 @@ mod router_plugin { Ok(()) } + // Uri.port + #[rhai_fn(get = "port", pure, return_raw)] + pub(crate) fn uri_port_get(x: &mut Uri) -> Result> { + to_dynamic(x.port_u16().map(|port| port.to_string())) + } + + #[rhai_fn(set = "port", pure, return_raw)] + pub(crate) fn uri_port_set(x: &mut Uri, value: &str) -> Result<(), Box> { + let mut parts: Parts = x.clone().into_parts(); + let host = x.host().unwrap_or_default(); + parts.authority = + Some(Authority::from_str(&format!("{host}:{value}")).map_err(|e| e.to_string())?); + *x = Uri::from_parts(parts).map_err(|e| e.to_string())?; + Ok(()) + } + // Response.label #[rhai_fn(get = "label", pure)] pub(crate) fn response_label_get(x: &mut Response) -> Dynamic { diff --git a/apollo-router/src/plugins/rhai/tests.rs b/apollo-router/src/plugins/rhai/tests.rs index 11dc1d53f6..86d31b9a25 100644 --- a/apollo-router/src/plugins/rhai/tests.rs +++ b/apollo-router/src/plugins/rhai/tests.rs @@ -657,7 +657,7 @@ async fn it_can_process_string_subgraph_forbidden() { if let Err(error) = call_rhai_function("process_subgraph_response_string").await { let processed_error = process_error(error); assert_eq!(processed_error.status, StatusCode::INTERNAL_SERVER_ERROR); - assert_eq!(processed_error.message, Some("rhai execution error: 'Runtime error: I have raised an error (line 229, position 5)'".to_string())); + assert_eq!(processed_error.message, Some("rhai execution error: 'Runtime error: I have raised an error (line 232, position 5)'".to_string())); } else { // Test failed panic!("error processed incorrectly"); @@ -685,7 +685,7 @@ async fn it_cannot_process_om_subgraph_missing_message_and_body() { assert_eq!( processed_error.message, Some( - "rhai execution error: 'Runtime error: #{\"status\": 400} (line 240, position 5)'" + "rhai execution error: 'Runtime error: #{\"status\": 400} (line 243, position 5)'" .to_string() ) ); diff --git a/apollo-router/tests/fixtures/request_response_test.rhai b/apollo-router/tests/fixtures/request_response_test.rhai index 18ef52d56c..fcd74e390e 100644 --- a/apollo-router/tests/fixtures/request_response_test.rhai +++ b/apollo-router/tests/fixtures/request_response_test.rhai @@ -35,6 +35,9 @@ fn process_common_request(check_context_method_and_id, check_body, request) { if request.uri.path != "/" { throw(`query: expected: "/", actual: ${request.uri.path}`); } + if request.uri.port != () { + throw(`query: expected: (), actual: ${request.uri.host}`); + } } fn process_router_request(request){