Repository: Avaiga/taipy

Issue:
[🐛 BUG] Problem with file_download when file name has spaces
### What went wrong? 🤔

I have a problem with the `file_download` selector, the problem only happens when the file name has spaces. In that case, I can download a file, but it's a `.htm` file that says "The requested URL was not found on the server. If you entered the URL manually, please check your spelling and try again."

This happens when using Windows (I haven't tested with other OS). 

### Expected Behavior

URLs should handle file names with spaces (or at minimum, the documentation should specify not to include spaces, but that would be sub-optimum in my opinion). 

### Steps to Reproduce Issue

In the same directory, I create 2 .txt files:
* `sample_file.txt`
* `sample file.txt` <-- Note the space

They both have this content:
This is a sample file

In the same directory, I create the following app. Note the commented code; you can switch comments to reproduce the issue or to see the version that works (the one with an underscore):

```python
import taipy.gui.builder as tgb
from taipy import Gui

with tgb.Page() as test_page:

    tgb.text("# Test Download button", mode="md")
    tgb.file_download(
        # content="sample_file.txt", # This works (if the file's name is that, of course!)
        content="sample file.txt", # This doesn't work (even if that's the file's name...)
        label="Download File",
    )
if __name__ == "__main__":
    gui = Gui(page=test_page)
    gui.run(
        title="Test download",
        use_reloader=True,
    )
```

### Browsers

Brave

### OS

Windows

### Version of Taipy

- 3.0
- 3.1
- 4.0.2

### Additional Context

```bash

```

### Acceptance Criteria

- [ ] A unit test reproducing the bug is added.
- [ ] Any new code is covered by a unit tested.
- [ ] Check code coverage is at least 90%.
- [ ] The bug reporter validated the fix.
- [ ] Related issue(s) in taipy-doc are created for documentation and Release Notes are updated.


### Code of Conduct

- [x] I have checked the [existing issues](https://github.com/Avaiga/taipy/issues?q=is%3Aissue+).
- [ ] I am willing to work on this issue (optional)

Discussion:
@pranshugupta01: hey there, I would like to help with this issue if possible!@CaptHeisenberg: I'd love to help @FlorianJacta: I have assigned it to you @pranshugupta01 @pranshugupta01: @FlorianJacta i have linked a PR for this issue , please check it out 

Solution patch:
diff --git a/taipy/gui/data/content_accessor.py b/taipy/gui/data/content_accessor.py
index 33abc23fc..1e8d105fe 100644
--- a/taipy/gui/data/content_accessor.py
+++ b/taipy/gui/data/content_accessor.py
@@ -113,7 +113,7 @@ class _ContentAccessor:
             self.__content_paths[url_path] = dir_path
             file_url = f"{url_path}/{path.name}"
             self.__url_is_image[file_url] = image
-            return (urllib.parse.quote_plus(file_url, safe="/"),)
+            return (urllib.parse.quote(file_url, safe="/"),)
         elif _has_magic_module:
             try:
                 mime = magic.from_buffer(value, mime=True)


Test patch:
diff --git a/tests/gui/control/test_file_download.py b/tests/gui/control/test_file_download.py
index ac157af0b..aeff818d7 100644
--- a/tests/gui/control/test_file_download.py
+++ b/tests/gui/control/test_file_download.py
@@ -50,6 +50,26 @@ def test_file_download_path_md(gui: Gui, test_client, helpers):
     helpers.test_control_md(gui, md_string, expected_list)
 
 
+def test_file_download_with_spaces_path_md(gui: Gui, test_client, helpers):
+    resources_dir = pathlib.Path(__file__).parent.parent / "resources"
+    test_file_path = resources_dir / "test file with spaces.txt"
+
+    try:
+        with open(test_file_path, "w") as f:
+            f.write("Test content")
+
+        gui._bind_var_val("content", str(test_file_path.resolve()))
+        md_string = "<|{content}|file_download|>"
+        expected_list = [
+            "<FileDownload",
+            'defaultContent="/taipy-content/taipyStatic0/test%20file%20with%20spaces.txt"',
+        ]
+        helpers.test_control_md(gui, md_string, expected_list)
+    finally:
+        if test_file_path.exists():
+            test_file_path.unlink()
+
+
 def test_file_download_any_file_md(gui: Gui, test_client, helpers):
     with open(os.path.abspath(__file__), "rb") as content:
         gui._bind_var_val("content", content.read())