Skip to content

[servicebus] Strip port and path from fully_qualified_namespace (#44034)#48062

Open
pranz1996 wants to merge 4 commits into
Azure:mainfrom
pranz1996:fix/strip-port-from-namespace-44034
Open

[servicebus] Strip port and path from fully_qualified_namespace (#44034)#48062
pranz1996 wants to merge 4 commits into
Azure:mainfrom
pranz1996:fix/strip-port-from-namespace-44034

Conversation

@pranz1996

Copy link
Copy Markdown
Member

Description

Fixes #44034.

ServiceBusClient (sync + async) and the base handler normalize the caller's fully_qualified_namespace through strip_protocol_from_uri. Previously that helper stripped only the scheme (http://, sb://), leaving any port and trailing path in place. When a caller passes the endpoint that Azure returns when provisioning a namespace — https://<namespace>.servicebus.windows.net:443/ — the :443/ survived normalization and corrupted both consumers of the value:

  • the AMQP connection host (create_connection(host=...)), and
  • the CBS token audience (_auth_uri = sb://<host>), which the service validates.

The result was ServiceBusAuthenticationError (amqp:client-error), even though the bare-host form worked. The .NET and JavaScript SDKs already normalize this format; Python was the outlier (confirmed by @eerhardt and @sebastienros on the issue).

Fix

strip_protocol_from_uri now reduces the input to its bare host — removing scheme, port, and path — so the value is valid as both the socket target and the token audience. The change only removes characters that are invalid in a hostname; every already-clean input (bare host, scheme-only, sovereign clouds, connection strings) is byte-identical to before.

Verification

  • New regression test test_strip_protocol_from_uri_normalizes_to_bare_host (fails on the old code, passes on the new): covers scheme × port × trailing-slash, including the exact https://<ns>:443/ form.
  • Verified end-to-end against a live namespace with DefaultAzureCredential: the :443/ form failed before the fix (ServiceBusAuthenticationError) and connects + receives after; the bare-host path is unchanged.

Additional test-infra fixes (surfaced while adding the test)

The test_connection_string_parser.py test class was never collected by pytest (its name didn't match the default Test* pattern and its base is not a unittest.TestCase), so all 14 of its tests silently never ran. This PR:

  • renames ServiceBusConnectionStringParserTestsTestServiceBusConnectionStringParser so pytest collects it,
  • fixes 3 stale endpoint assertions in test_sb_parse_emulator_string (the parser has appended a trailing / since [SB] combine conn str parser logic in base handler and _common #16464, consistent with every sibling test), and
  • de-duplicates two methods that shared a name (one was shadowed).

Result: the file went from 0 collected to 16 passing.

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

…e#44034)

strip_protocol_from_uri now reduces the namespace to its bare host, removing any port (e.g. :443) and trailing path in addition to the scheme. This accepts the https://<ns>.servicebus.windows.net:443/ form that Azure returns when provisioning a namespace, matching the .NET and JavaScript SDKs. Previously the retained port/path corrupted both the AMQP connection host and the CBS token audience, raising ServiceBusAuthenticationError.

Also enables the previously-uncollected connection-string parser test class (renamed to Test* so pytest collects it), fixes 3 stale emulator assertions, and de-duplicates a shadowed test method.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes Service Bus namespace normalization for Azure-provided endpoints.

Changes:

  • Removes schemes, ports, and paths from namespace URIs.
  • Adds regression coverage and restores test collection.
  • Updates release notes.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
azure/servicebus/_common/utils.py Normalizes namespace URIs.
tests/test_connection_string_parser.py Restores collection and adds regression tests.
CHANGELOG.md Documents the fix.

Comment thread sdk/servicebus/azure-servicebus/azure/servicebus/_common/utils.py Outdated
…ure#44034)

Address PR review: strip_protocol_from_uri truncated bracketed IPv6 hosts (e.g. [fe80::1]) at the first colon inside the address. Port stripping now only applies after the closing ']' for bracketed literals, matching the AMQP transport's to_host_port handling. Added IPv6 regression cases.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

@pranz1996
pranz1996 marked this pull request as ready for review July 15, 2026 02:06
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@SwayGom SwayGom 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.

The core fix for #44034 is sound, and the latest IPv6 handling plus the test-collection cleanup look good. I found one blocking regression, though.

strip_protocol_from_uri now removes the port from every input. For an emulator connection string such as Endpoint=sb://localhost:5673;...;UseDevelopmentEmulator=true, _parse_conn_str preserves localhost:5673 and sets use_tls=False, but the client constructor then normalizes fully_qualified_namespace to localhost. PyAMQP consequently builds amqp://localhost and falls back to port 5672 instead of the requested 5673. There is no alternate connection-string field later in the sync or async path that restores the port; direct sender/receiver factories are affected as well.

Could we keep the bare namespace/token-audience normalization separate from the socket endpoint (or otherwise preserve the emulator port), and add sync and async regression coverage for a non-default emulator port? All current checks are green, but they only exercise portless/default-port emulator endpoints, so they do not catch this behavior change.

Pranjal Patel added 2 commits July 15, 2026 15:51
…namespace (Azure#44034)

Address PR review: the Azure#44034 port strip dropped the development emulator's non-default port (e.g. localhost:5673 -> localhost), causing pyamqp to fall back to 5672. strip_protocol_from_uri now takes a strip_port keyword; the four client/base-handler constructors pass strip_port=use_tls so the emulator (use_tls=False) keeps its port while real namespaces are still reduced to a bare host. Added sync and async regression tests for a non-default emulator port.
…amespace-44034

# Conflicts:
#	sdk/servicebus/azure-servicebus/CHANGELOG.md
@pranz1996

Copy link
Copy Markdown
Member Author

Thanks for the review @SwayGom

Good catch — fixed. The port is now only stripped for real (TLS) namespaces; the development emulator keeps its non-default port, so it connects on the right port again. Added sync and async regression tests covering a non-default emulator port.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@j7nw4r
j7nw4r enabled auto-merge (squash) July 16, 2026 20:58

@j7nw4r j7nw4r 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.

lgtm

@j7nw4r
j7nw4r requested a review from SwayGom July 16, 2026 20:59
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.

Strip port from strip_protocol_from_uri

4 participants