Why is a file generated every time a meta url is refreshed?
Why is a file generated every time a meta url is refreshed?

url：
http://127.0.0.1:8888/unsafe/meta/http://127.0.0.1:9999/test/5d8cce994c0190cbdb2f1e0914286c0a

These files are all from the same meta url.

Shouldn't only one file be correct?

![example](https://github.com/thumbor/thumbor/assets/17996289/a4da8be6-59d6-48bc-9987-e43af76ab883)

diff --git a/tests/handlers/test_base_handler_with_result_storage.py b/tests/handlers/test_base_handler_with_result_storage.py
index a799ea4..2a7de3b 100644
--- a/tests/handlers/test_base_handler_with_result_storage.py
+++ b/tests/handlers/test_base_handler_with_result_storage.py
@@ -8,6 +8,7 @@
 # http://www.opensource.org/licenses/mit-license
 # Copyright (c) 2011 globo.com thumbor@googlegroups.com
 
+import json
 import os
 from os.path import dirname
 from shutil import which
@@ -77,6 +78,34 @@ class ImageOperationsWithResultStorageTestCase(BaseImagingTestCase):
         expect(expected_path).to_exist()
         expect(response.body).to_be_similar_to(animated_image())
 
+    @patch("tornado.ioloop.IOLoop.instance")
+    @gen_test
+    async def test_saves_meta_to_result_storage(self, instance_mock):
+        instance_mock.return_value = self.io_loop
+        response = await self.async_fetch(
+            "/oGi9XL4nHJKGEKVHjHEp1Jg1KpM=/meta/animated.gif"
+        )
+        expect(response.code).to_equal(200)
+
+        self.context.request = Mock(
+            accepts_webp=False,
+        )
+        expected_path = self.result_storage.normalize_path(
+            "/oGi9XL4nHJKGEKVHjHEp1Jg1KpM=/meta/animated.gif"
+        )
+        expect(expected_path).to_exist()
+
+        expected_source = {
+            "frameCount": 2,
+            "height": 100,
+            "url": "animated.gif",
+            "width": 100,
+        }
+        metadata = json.loads(response.body)
+        expect(metadata).to_include("thumbor")
+        expect(metadata["thumbor"]).to_include("source")
+        expect(metadata["thumbor"]["source"]).to_be_like(expected_source)
+
 
 class ImageOperationsResultStorageOnlyTestCase(BaseImagingTestCase):
     def get_context(self):
diff --git a/thumbor/handlers/__init__.py b/thumbor/handlers/__init__.py
index 72ee807..b7d5558 100644
--- a/thumbor/handlers/__init__.py
+++ b/thumbor/handlers/__init__.py
@@ -660,11 +660,17 @@ class BaseHandler(tornado.web.RequestHandler):
         await self._write_results_to_client(results, content_type)
 
         if should_store:
+            results = self._ensure_bytes(results)
             await self._store_results(result_storage, metrics, results)
 
         # can't cleanup before storing results as the storage requires context
         self._cleanup()
 
+    def _ensure_bytes(self, results):
+        if isinstance(results, str):
+            return results.encode()
+        return results
+
     def _cleanup(self):
         self.context.request_handler = None
 
['thumbor/handlers/__init__.py', 'tests/handlers/test_base_handler_with_result_storage.py']