Repository: deepset-ai/haystack

Issue:
`FileTypeRouter` should get mime type from `ByteStream` mime type attribute instead of `meta
**Describe the bug**
Looking at this code [here](https://github.com/deepset-ai/haystack/blob/201db5b28813d25066f60e0e710d501623f79682/haystack/components/routers/file_type_router.py#L89):

[The `ByteStream` class has an attribute `mime_type`](https://github.com/deepset-ai/haystack/blob/fe0ac5c4a280b6196fc984d580d3dd2675f893ae/haystack/dataclasses/byte_stream.py#L14). We should rather using this than using the metadata for this.

**Error message**
None

**Expected behavior**
Use `mime_type` field instead of meta (or make this configurable)

**Additional context**
Add any other context about the problem here, like document types / preprocessing steps / settings of reader etc.

**To Reproduce**
Steps to reproduce the behavior

**FAQ Check**
- [x] Have you had a look at [our new FAQ page](https://docs.haystack.deepset.ai/docs/faq)?

**System:**
 - OS:
 - GPU/CPU:
 - Haystack version (commit or version number): 2
 - DocumentStore:
 - Reader:
 - Retriever:



Discussion:

Patch:
diff --git a/haystack/components/fetchers/link_content.py b/haystack/components/fetchers/link_content.py
index 00cbdeb667..0d86ff8529 100644
--- a/haystack/components/fetchers/link_content.py
+++ b/haystack/components/fetchers/link_content.py
@@ -151,6 +151,7 @@ def run(self, urls: List[str]):
             for stream_metadata, stream in results:  # type: ignore
                 if stream_metadata is not None and stream is not None:
                     stream.meta.update(stream_metadata)
+                    stream.mime_type = stream.meta.get("content_type", None)
                     streams.append(stream)
 
         return {"streams": streams}
diff --git a/haystack/components/routers/file_type_router.py b/haystack/components/routers/file_type_router.py
index 08c615c7e1..fdf8830c9f 100644
--- a/haystack/components/routers/file_type_router.py
+++ b/haystack/components/routers/file_type_router.py
@@ -90,7 +90,7 @@ def run(self, sources: List[Union[str, Path, ByteStream]]) -> Dict[str, List[Uni
             if isinstance(source, Path):
                 mime_type = self._get_mime_type(source)
             elif isinstance(source, ByteStream):
-                mime_type = source.meta.get("content_type", None)
+                mime_type = source.mime_type
             else:
                 raise ValueError(f"Unsupported data source type: {type(source).__name__}")
 
diff --git a/releasenotes/notes/enhanced-mime-type-handling-182fb64a0f5fb852.yaml b/releasenotes/notes/enhanced-mime-type-handling-182fb64a0f5fb852.yaml
new file mode 100644
index 0000000000..c0e7d07445
--- /dev/null
+++ b/releasenotes/notes/enhanced-mime-type-handling-182fb64a0f5fb852.yaml
@@ -0,0 +1,4 @@
+---
+enhancements:
+ - |
+   Improved MIME type management by directly setting MIME types on ByteStreams, enhancing the overall handling and routing of different file types. This update makes MIME type data more consistently accessible and simplifies the process of working with various document formats.


Test patch:
diff --git a/test/components/routers/test_file_router.py b/test/components/routers/test_file_router.py
index b64be66336..32d1e99dd1 100644
--- a/test/components/routers/test_file_router.py
+++ b/test/components/routers/test_file_router.py
@@ -50,7 +50,7 @@ def test_run_with_bytestreams(self, test_files_path):
         byte_streams = []
         for path, mime_type in zip(file_paths, mime_types):
             stream = ByteStream(path.read_bytes())
-            stream.meta["content_type"] = mime_type
+            stream.mime_type = mime_type
             byte_streams.append(stream)
 
         # add unclassified ByteStream
@@ -81,7 +81,7 @@ def test_run_with_bytestreams_and_file_paths(self, test_files_path):
         byte_stream_sources = []
         for path, mime_type in zip(file_paths, mime_types):
             stream = ByteStream(path.read_bytes())
-            stream.meta["content_type"] = mime_type
+            stream.mime_type = mime_type
             byte_stream_sources.append(stream)
 
         mixed_sources = file_paths[:2] + byte_stream_sources[2:]
@@ -165,9 +165,12 @@ def test_exact_mime_type_matching(self, mock_file):
         """
         Test if the component correctly matches mime types exactly, without regex patterns.
         """
-        txt_stream = ByteStream(io.BytesIO(b"Text file content"), meta={"content_type": "text/plain"})
-        jpg_stream = ByteStream(io.BytesIO(b"JPEG file content"), meta={"content_type": "image/jpeg"})
-        mp3_stream = ByteStream(io.BytesIO(b"MP3 file content"), meta={"content_type": "audio/mpeg"})
+        txt_stream = ByteStream(io.BytesIO(b"Text file content").read())
+        txt_stream.mime_type = "text/plain"
+        jpg_stream = ByteStream(io.BytesIO(b"JPEG file content").read())
+        jpg_stream.mime_type = "image/jpeg"
+        mp3_stream = ByteStream(io.BytesIO(b"MP3 file content").read())
+        mp3_stream.mime_type = "audio/mpeg"
 
         byte_streams = [txt_stream, jpg_stream, mp3_stream]