Skip to content

Conversation

@Eeshu-Yadav
Copy link
Contributor

fixes : #93

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @Eeshu-Yadav, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the request handling capabilities by introducing a flexible mechanism for rewriting the authority (host and port) of incoming HTTP requests. This feature allows for dynamic adjustment of the Host header and URI authority based on predefined rules, including an automatic option to match the upstream service, thereby improving routing accuracy and compatibility with various backend configurations.

Highlights

  • New AutoHostRewrite Functionality: Introduced a new AutoHostRewrite option within the AuthorityRewriteSpecifier to automatically set the request's authority to the upstream service's authority.
  • Enhanced Authority Rewriting Logic: Implemented a comprehensive apply method for AuthorityRewriteSpecifier that supports rewriting the authority based on a specific value, a request header, or a regular expression, in addition to the new auto-host rewrite.
  • Integration into Request Handling: Modified the HTTP connection manager's request handling to apply the configured authority rewrite rules, ensuring that the URI's authority and the Host header are correctly updated before forwarding the request upstream.
  • New Unit Tests: Added dedicated unit tests to validate the correct behavior of the new AuthorityRewriteSpecifier and its various rewrite options, including AutoHostRewrite.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces AutoHostRewrite functionality for request authority rewriting. The implementation is sound and includes good test coverage. My review focuses on a performance improvement to avoid cloning request parts on the hot path, and a minor readability enhancement. The changes are well-contained and address the intended feature.

Comment on lines 135 to 173
pub fn apply<B>(
&self,
request: &Request<B>,
upstream_authority: &Authority,
) -> Result<Option<Authority>, InvalidUri> {
match self {
AuthorityRewriteSpecifier::Authority(authority) => Ok(Some(authority.clone())),

AuthorityRewriteSpecifier::Header(header_name) => {
if let Some(header_value) = request.headers().get(header_name.as_str()) {
if let Ok(header_str) = header_value.to_str() {
Authority::from_str(header_str)
.map(Some)
.map_err(|e| e.into())
} else {
Ok(None)
}
} else {
Ok(None)
}
},

AuthorityRewriteSpecifier::Regex(regex) => {
let current_authority = request.uri().authority()
.map(Authority::as_str)
.or_else(|| {
request.headers().get(http::header::HOST)
.and_then(|h| h.to_str().ok())
})
.unwrap_or_default();

let replacement = regex.pattern.replace_all(current_authority, regex.substitution.as_str());
if let std::borrow::Cow::Borrowed(_) = replacement {
Ok(None)
} else {
Authority::from_str(&replacement)
.map(Some)
.map_err(|e| e.into())
}
},

AuthorityRewriteSpecifier::AutoHostRewrite => Ok(Some(upstream_authority.clone())),
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The apply method currently takes a &Request<B>, which necessitates an expensive clone of http::request::Parts at the call site in orion-lib. To improve performance, this method can be refactored to accept only the parts it needs: the URI and headers.

This change will also require updating the tests for this function to pass the URI and headers instead of a full request.

I've also taken the opportunity to simplify the logic in the Header match arm for better readability.

    pub fn apply(
        &self,
        uri: &http::Uri,
        headers: &http::HeaderMap,
        upstream_authority: &Authority,
    ) -> Result<Option<Authority>, InvalidUri> {
        match self {
            AuthorityRewriteSpecifier::Authority(authority) => Ok(Some(authority.clone())),
            
            AuthorityRewriteSpecifier::Header(header_name) => {
                let Some(header_value) = headers.get(header_name.as_str()) else {
                    return Ok(None);
                };
                let Ok(header_str) = header_value.to_str() else {
                    return Ok(None);
                };
                Authority::from_str(header_str)
                    .map(Some)
                    .map_err(|e| e.into())
            },
            
            AuthorityRewriteSpecifier::Regex(regex) => {
                let current_authority = uri.authority()
                    .map(Authority::as_str)
                    .or_else(|| {
                        headers.get(http::header::HOST)
                            .and_then(|h| h.to_str().ok())
                    })
                    .unwrap_or_default();
                
                let replacement = regex.pattern.replace_all(current_authority, regex.substitution.as_str());
                if let std::borrow::Cow::Borrowed(_) = replacement {
                    Ok(None)
                } else {
                    Authority::from_str(&replacement)
                        .map(Some)
                        .map_err(|e| e.into())
                }
            },
            
            AuthorityRewriteSpecifier::AutoHostRewrite => Ok(Some(upstream_authority.clone())),
        }
    }
}

Comment on lines 101 to 107
let authority_replacement = if let Some(authority_rewrite) = &self.authority_rewrite {
let original_request = Request::from_parts(parts.clone(), ());
authority_rewrite
.apply(&original_request, &svc_channel.upstream_authority)
.with_context_msg("invalid authority after rewrite")?
} else {
None
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Cloning http::request::Parts via parts.clone() on every request with an authority rewrite can be a performance bottleneck, as it involves cloning the entire set of headers. This is done to construct a temporary Request object for AuthorityRewriteSpecifier::apply.

To improve performance, you can refactor AuthorityRewriteSpecifier::apply to accept &http::Uri and &http::HeaderMap instead of &Request<B>, as it only needs access to these parts. This avoids the expensive clone.

I've added a suggestion on orion-configuration/src/config/network_filters/http_connection_manager/route.rs to refactor apply. With that change, you can update this block to avoid the clone.

                    let authority_replacement = if let Some(authority_rewrite) = &self.authority_rewrite {
                        authority_rewrite
                            .apply(&parts.uri, &parts.headers, &svc_channel.upstream_authority)
                            .with_context_msg("invalid authority after rewrite")?
                    } else {
                        None
                    };

@Eeshu-Yadav Eeshu-Yadav force-pushed the fix/implement-auto-host-rewrite branch from f71c2e3 to 5ad97fc Compare September 11, 2025 22:50
This commit implements the missing AutoHostRewrite functionality that was
configured but not actually used during request processing. The implementation
adds support for all AuthorityRewriteSpecifier variants:

- AutoHostRewrite: Uses upstream cluster's authority
- Authority: Uses a specific authority
- Header: Uses value from a request header
- Regex: Applies regex transformation to current authority

Both the request URI authority and Host header are updated when authority
rewriting is applied, ensuring consistent behavior across the request.

Fixes the issue mentioned in PR kmesh-net#86 review where autorewrite configuration
was parsed but not executed during request handling.

Signed-off-by: Eeshu-Yadav <eeshuyadav123@gmail.com>
@Eeshu-Yadav Eeshu-Yadav force-pushed the fix/implement-auto-host-rewrite branch from 5ad97fc to 9121161 Compare September 11, 2025 22:53

let result = authority_rewrite.apply(&uri, &headers, &upstream_authority).unwrap();
assert_eq!(result, Some(Authority::from_str("api.rewritten.com").unwrap()));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a error case that we don't host in headers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rest is LGTM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

This commit adds a test case to cover the edge case where there's no Host
header in the request headers.

The test verifies that the regex-based authority rewrite handles gracefully
when both the URI has no authority and there's no Host header in the headers,
ensuring robust behavior in all scenarios.

Test: test_authority_rewrite_regex_no_host_header

Signed-off-by: Eeshu-Yadav <eeshuyadav123@gmail.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements AutoHostRewrite functionality in request handling, allowing automatic rewriting of the authority (host) portion of HTTP requests to match upstream targets.

  • Adds authority rewriting capability with support for multiple rewrite strategies including AutoHostRewrite
  • Modifies request handling to apply both path and authority rewrites when processing HTTP requests
  • Updates Host header to reflect authority changes when authority rewriting occurs

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
orion-lib/src/listeners/http_connection_manager/route.rs Integrates authority rewriting into request processing pipeline
orion-configuration/src/config/network_filters/http_connection_manager/route.rs Implements AuthorityRewriteSpecifier with apply method and comprehensive test coverage

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

if path_and_query_replacement.is_some() || authority_replacement.is_some() {
parts.uri = {
let UriParts { scheme, authority, path_and_query: _, .. } = parts.uri.into_parts();
let UriParts { scheme, authority, path_and_query, .. } = parts.uri.into_parts();
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The destructuring pattern now ignores the original path_and_query value but still extracts it. Since path_and_query is used in the fallback logic on line 115, removing the underscore suffix makes the code clearer about its intended use.

Copilot uses AI. Check for mistakes.
let Ok(header_str) = header_value.to_str() else {
return Ok(None);
};
Authority::from_str(header_str).map(Some).map_err(|e| e.into())
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error conversion |e| e.into() is redundant. The ? operator can handle the conversion automatically: Authority::from_str(header_str).map(Some)

Suggested change
Authority::from_str(header_str).map(Some).map_err(|e| e.into())
Authority::from_str(header_str).map(Some)

Copilot uses AI. Check for mistakes.
if let std::borrow::Cow::Borrowed(_) = replacement {
Ok(None)
} else {
Authority::from_str(&replacement).map(Some).map_err(|e| e.into())
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error conversion |e| e.into() is redundant. The ? operator can handle the conversion automatically: Authority::from_str(&replacement).map(Some)

Suggested change
Authority::from_str(&replacement).map(Some).map_err(|e| e.into())
Authority::from_str(&replacement).map(Some)

Copilot uses AI. Check for mistakes.
Copy link
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM

uri: &http::Uri,
headers: &http::HeaderMap,
upstream_authority: &Authority,
) -> Result<Option<Authority>, InvalidUri> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: InvalidUri seems redudant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

- Remove unnecessary .map_err(|e| e.into()) calls
- The ? operator handles error conversion automatically for Authority::from_str
- Remove redundant InvalidUri error type
Signed-off-by: Eeshu-Yadav <eeshuyadav123@gmail.com>
Copy link
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@kmesh-bot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: hzxuzhonghu

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kmesh-bot kmesh-bot merged commit 3e9820e into kmesh-net:main Sep 22, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement AutoHostRewrite functionality in request handling

4 participants