Extraneous slashes in URL breaks things
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.7k
- Forks
- 2k
- Avg merge
- 18h 55m
- Merged PRs (30d)
- 35
Description
What happened?
When accessing a page via a URL that contains extraneous leading slashes (e.g. by following a link from within Home Assistant that takes you to e.g. http://z2m.lan:9000//#/device/0/0xa4c138d6xxxxxxxx/info), Zigbee2Mqtt redirects you to //#/devices. This page then displays no devices, and websocket fails to open as well as it's trying to access ws://ha1.lan:9000//api
While it may be an mistake on my part that I've configured the frontend url with a trailing slash (because there's nothing in the documentation indicating that I shouldn't use a full base URL), there are actual bugs at play here:
- If having a full base URL with trailing slash in the configuration is illegal, it shouldn't have been permitted.
- If it is permitted, it should have been normalised: the URL published in MQTT messages also contains two slashes.
- Z2M doesn't return a 404 for the invalid URL (which would have let me discover the issue earlier) and instead actually does try to display the device list (albeit empty) and attempts to connect to the wrong websocket URL.
Suggestion:
- If there is a trailing slash after the host and port in the configured frontend url, remove it OR at least error out.
- If there are extraneous leading slashes in the URL when routing a request, 301 redirect to the correct URL rather than just strip it and continue to produce more invalid URLs.
Also as an interesting aside (albeit a separate issue), visiting the correct URL directly http://z2m.lan:9000/#/device/0/0xa4c138d6xxxxxxxx/info does not display the device, it displays the device list, even though when you click on the device you wanted, the address bar changes to the exact same URL http://z2m.lan:9000//#/device/0/0xa4c138d6xxxxxxxx/info
What did you expect to happen?
No response
How to reproduce it (minimal and precise)
Note I have had to specify a URL because the default z2m port is in use by a different container, so I've mapped it to 9000 in Docker:
frontend:
enabled: true
port: 8080
url: http://z2m.lan:9000/
Zigbee2MQTT version
2.13.0
Adapter firmware version
n/a
Adapter
n/a
Setup
Docker container
Device database.db entry
No response
Debug log
No response
Notes
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the configured frontend URL with a trailing slash, then follow the frontend routing and WebSocket URL handling for requests containing duplicate slashes. Verify behavior for the provided device URL and MQTT-published URL; done means trailing slashes are normalized or rejected clearly, and invalid routed URLs do not load an empty device list or connect to an incorrect WebSocket path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100