Skip to content

fix(http): improve parameters name decoding precision and span lifecycle - #822

Merged
Vincent Biret (baywet) merged 4 commits into
microsoft:mainfrom
hardikkaurani:fix/parameters-name-decoding-robustness
Oct 21, 2026
Merged

Vincent Biret (baywet) merged 4 commits into
microsoft:mainfrom
hardikkaurani:fix/parameters-name-decoding-robustness

Conversation

@hardikkaurani

Copy link
Copy Markdown
Contributor

Summary

In ParametersNameDecodingHandler (microsoft-kiota-http), there were four issues in parameter decoding, URL manipulation, and telemetry:

  1. Parameter Value Corruption: decode_uri_encoded_string decoded parameters by calling original.replace(parameter, new_parameter) on the whole query string. If a query parameter's value happened to contain an encoded parameter name (e.g., query=%24select&$select=1), the value was erroneously decoded (query=$select), corrupting query parameter values.
  2. Case Sensitivity: Percent-encoding was generated using uppercase hex only (f"%{ord(x):X}"), failing to decode standard lowercase percent-encoding (such as %2d, %2e, %7e).
  3. URL Path Corruption Risk: original_url.replace(query_params, decoded_query_parameters_string) replaced the first occurrence in the entire URL, corrupting paths that contain identical substrings. Replacing query via request.url.copy_with(query=...) safely updates only the query component.
  4. Span Lifecycle & Null Check:
    • Validates if request is None: raise TypeError("request cannot be null") matching other middleware.
    • Ends observability span in finally over the super().send call instead of ending prematurely before the request is sent.

Changes

  • Updated decode_uri_encoded_string to split query parameters and decode exclusively parameter names (supporting both uppercase and lowercase hex), leaving parameter values untouched.
  • Replaced URL string replacement with request.url.copy_with(query=...).
  • Wrapped super().send() in try ... finally: span.end() and added request is None guard check.
  • Added comprehensive unit tests in test_parameters_name_decoding_handler.py.

Copilot AI balanced review requested due to automatic review settings October 21, 2026 06:21
@hardikkaurani
Hardik K (hardikkaurani) requested a review from a team as a code owner October 21, 2026 06:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hardikkaurani

Copy link
Copy Markdown
Contributor Author

Hi Vincent Biret (@baywet)! This PR refines ParametersNameDecodingHandler by decoding parameter names on split query segments instead of doing a global string replace (which inadvertently decoded parameter values containing encoded names), supports lowercase percent-encoding, uses request.url.copy_with to protect paths from string replacement collisions, adds a null check, and keeps the observability span active across the send execution. Unit tests covering all scenarios are included. Whenever convenient, please take a look. Thank you!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The span-lifecycle change needs regression coverage for successful and failing transport execution.

1 open issue

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 21, 2026 13:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hardikkaurani

Copy link
Copy Markdown
Contributor Author

Hi Vincent Biret (@baywet),

I have updated the PR to address the feedback regarding span lifecycle coverage:

  • Added est_span_lifecycle_active_during_send_and_ends_on_success: verifies that span.end() has not been called while the downstream transport call is in flight, and is called exactly once after send() successfully completes.
  • Added est_span_lifecycle_ends_and_exception_propagates_on_transport_failure: verifies that span.end() has not been called while transport is in flight, verifies that the transport exception propagates, and confirms that span.end() is invoked in the inally: block.
  • Positioned the ry: block immediately after _create_observability_span(...) in ParametersNameDecodingHandler.send() to guarantee span closure across all paths.
  • Added explicit typing for query decoding collections to pass mypy without warnings or type mismatches.
  • Verified all code formatting (yapf), import ordering (isort), linting (pylint), type checking (mypy), and the full pytest suite (all 186 tests passing).

The PR is ready for review. Thank you!

@baywet
Vincent Biret (baywet) requested a balanced review from Copilot October 21, 2026 16:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

No blocking defects remain; the suggested path-regression test improvement is nonblocking.

2 open issues

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 21, 2026 17:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused changes address the reported defects, with targeted regression coverage and no unresolved findings.

1 open issue
1 resolved since last review

Review effort: Balanced

@hardikkaurani

Copy link
Copy Markdown
Contributor Author

Hi Vincent Biret (@baywet),

I have addressed the review comment in commit 6d506cb.

test_decoding_preserves_url_path has been updated so that the URL path contains the full query parameter substring (%24select=name in https://example.com/api/%24select=name/items?%24select=name). The test verifies that the path remains fully encoded (%24select=name) in both str(resp.request.url) and resp.request.url.raw_path, while the query parameter is properly decoded to $select=name.

All formatting, lint checks, static type checks (mypy), unit tests, and CI workflows have passed. Ready for review!

@baywet Vincent Biret (baywet) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution!

@github-project-automation github-project-automation Bot moved this to In Progress 🚧 in Kiota Oct 21, 2026
Copilot AI balanced review requested due to automatic review settings October 21, 2026 17:43
@baywet
Vincent Biret (baywet) force-pushed the fix/parameters-name-decoding-robustness branch from 6d506cb to 4689c5e Compare October 21, 2026 17:43
auto-merge was automatically disabled October 21, 2026 17:43

Head branch was pushed to by a user without write access

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@sonarqubecloud

Copy link
Copy Markdown

@baywet
Vincent Biret (baywet) merged commit 806a09d into microsoft:main Oct 21, 2026
134 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress 🚧 to Done ✔️ in Kiota Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done ✔️

Development

Successfully merging this pull request may close these issues.

3 participants