Skip to content

Commit 60130d3

Browse files
andreipoenarujpbedeMartinHjelmare
authored
Add support for encoded URLs to RESTful Command (home-assistant#154957)
Co-authored-by: Jan-Philipp Benecke <[email protected]> Co-authored-by: Martin Hjelmare <[email protected]>
1 parent c45ede2 commit 60130d3

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

homeassistant/components/rest_command/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import aiohttp
1111
from aiohttp import hdrs
1212
import voluptuous as vol
13+
from yarl import URL
1314

1415
from homeassistant.const import (
1516
CONF_AUTHENTICATION,
@@ -51,6 +52,7 @@
5152

5253
CONF_CONTENT_TYPE = "content_type"
5354
CONF_INSECURE_CIPHER = "insecure_cipher"
55+
CONF_SKIP_URL_ENCODING = "skip_url_encoding"
5456

5557
COMMAND_SCHEMA = vol.Schema(
5658
{
@@ -69,6 +71,7 @@
6971
vol.Optional(CONF_CONTENT_TYPE): cv.string,
7072
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
7173
vol.Optional(CONF_INSECURE_CIPHER, default=False): cv.boolean,
74+
vol.Optional(CONF_SKIP_URL_ENCODING, default=False): cv.boolean,
7275
}
7376
)
7477

@@ -113,6 +116,7 @@ def async_register_rest_command(name: str, command_config: dict[str, Any]) -> No
113116
method = command_config[CONF_METHOD]
114117

115118
template_url = command_config[CONF_URL]
119+
skip_url_encoding = command_config[CONF_SKIP_URL_ENCODING]
116120

117121
auth = None
118122
digest_middleware = None
@@ -179,7 +183,7 @@ async def async_service_handler(service: ServiceCall) -> ServiceResponse:
179183
request_kwargs["middlewares"] = (digest_middleware,)
180184

181185
async with getattr(websession, method)(
182-
request_url,
186+
URL(request_url, encoded=skip_url_encoding),
183187
**request_kwargs,
184188
) as response:
185189
if response.status < HTTPStatus.BAD_REQUEST:

tests/components/rest_command/test_init.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import aiohttp
88
import pytest
9+
from yarl import URL
910

1011
from homeassistant.components.rest_command import DOMAIN
1112
from homeassistant.const import (
@@ -455,3 +456,34 @@ async def test_rest_command_response_iter_chunked(
455456

456457
# Verify iter_chunked was called with a chunk size
457458
assert mock_iter_chunked.called
459+
460+
461+
async def test_rest_command_skip_url_encoding(
462+
hass: HomeAssistant,
463+
setup_component: ComponentSetup,
464+
aioclient_mock: AiohttpClientMocker,
465+
) -> None:
466+
"""Check URL encoding."""
467+
config = {
468+
"skip_url_encoding_test": {
469+
"url": "0%2C",
470+
"method": "get",
471+
"skip_url_encoding": True,
472+
},
473+
"with_url_encoding_test": {
474+
"url": "1,",
475+
"method": "get",
476+
},
477+
}
478+
479+
await setup_component(config)
480+
481+
aioclient_mock.get(URL("0%2C", encoded=True), content=b"success")
482+
aioclient_mock.get(URL("1,"), content=b"success")
483+
484+
await hass.services.async_call(DOMAIN, "skip_url_encoding_test", {}, blocking=True)
485+
await hass.services.async_call(DOMAIN, "with_url_encoding_test", {}, blocking=True)
486+
487+
assert len(aioclient_mock.mock_calls) == 2
488+
assert str(aioclient_mock.mock_calls[0][1]) == "0%2C"
489+
assert str(aioclient_mock.mock_calls[1][1]) == "1,"

tests/test_util/aiohttp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ def match_request(self, method, url, params=None):
221221

222222
if (
223223
self._url.scheme != url.scheme
224-
or self._url.host != url.host
225-
or self._url.path != url.path
224+
or self._url.raw_host != url.raw_host
225+
or self._url.raw_path != url.raw_path
226226
):
227227
return False
228228

0 commit comments

Comments
 (0)