We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Append of chunked upload processes raw data
**Version**
Please provide the versions of the pulpcore and plugin packages in use, and how they are installed.  If you are using Pulp via Katello, please provide the Katello version.

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:

**Expected behavior**
A clear and concise description of what you expected to happen.

**Additional context**
Add any other context about the problem here.  Please provide links to any previous discussions via Discourse or Bugzilla.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pulpcore/app/models/upload.py`
Content:
```
1 import hashlib
2 import os
3 
4 from django.core.files.base import ContentFile
5 from django.db import models
6 from django.db.models.signals import post_delete
7 from django.dispatch import receiver
8 from rest_framework import serializers
9 
10 from pulpcore.app.models import BaseModel, fields, storage
11 
12 
13 class Upload(BaseModel):
14     """
15     A chunked upload. Stores chunks until used to create an artifact, etc.
16 
17     Fields:
18 
19         size (models.BigIntegerField): The size of the file in bytes.
20     """
21 
22     size = models.BigIntegerField()
23 
24     def append(self, chunk, offset, sha256=None):
25         """
26         Append a chunk to an upload.
27 
28         Args:
29             chunk (File): Binary file to append to the upload file.
30             offset (int): First byte position to write chunk to.
31         """
32         chunk_read = chunk.read()
33         current_sha256 = hashlib.sha256(chunk_read).hexdigest()
34         if sha256 and sha256 != current_sha256:
35             raise serializers.ValidationError("Checksum does not match chunk upload.")
36 
37         upload_chunk = UploadChunk(upload=self, offset=offset, size=len(chunk))
38         filename = os.path.basename(upload_chunk.storage_path(""))
39         upload_chunk.file.save(filename, ContentFile(chunk_read))
40 
41 
42 class UploadChunk(BaseModel):
43     """
44     A chunk for an uploaded file.
45 
46     Fields:
47 
48         file (fields.FileField): A file where the uploaded chunk is stored.
49         upload (models.ForeignKey): Upload this chunk belongs to.
50         offset (models.BigIntegerField): Start of the chunk in bytes.
51         size (models.BigIntegerField): Size of the chunk in bytes.
52     """
53 
54     def storage_path(self, name):
55         """
56         Callable used by FileField to determine where the uploaded file should be stored.
57 
58         Args:
59             name (str): Original name of uploaded file. It is ignored by this method because the
60                 pulp_id is used to determine a file path instead.
61         """
62         return storage.get_upload_chunk_file_path(self.pulp_id)
63 
64     file = fields.FileField(null=False, upload_to=storage_path, max_length=255)
65     upload = models.ForeignKey(Upload, on_delete=models.CASCADE, related_name="chunks")
66     offset = models.BigIntegerField()
67     size = models.BigIntegerField()
68 
69 
70 @receiver(post_delete, sender=UploadChunk)
71 def upload_chunk_delete(instance, **kwargs):
72     instance.file.delete(save=False)
73
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pulpcore/app/models/upload.py b/pulpcore/app/models/upload.py
--- a/pulpcore/app/models/upload.py
+++ b/pulpcore/app/models/upload.py
@@ -1,6 +1,8 @@
 import hashlib
 import os
 
+from gettext import gettext as _
+
 from django.core.files.base import ContentFile
 from django.db import models
 from django.db.models.signals import post_delete
@@ -26,17 +28,18 @@
         Append a chunk to an upload.
 
         Args:
-            chunk (File): Binary file to append to the upload file.
+            chunk (File): Binary data to append to the upload file.
             offset (int): First byte position to write chunk to.
         """
-        chunk_read = chunk.read()
-        current_sha256 = hashlib.sha256(chunk_read).hexdigest()
-        if sha256 and sha256 != current_sha256:
-            raise serializers.ValidationError("Checksum does not match chunk upload.")
+        chunk = chunk.read()
+        if sha256:
+            current_sha256 = hashlib.sha256(chunk).hexdigest()
+            if sha256 != current_sha256:
+                raise serializers.ValidationError(_("Checksum does not match chunk upload."))
 
         upload_chunk = UploadChunk(upload=self, offset=offset, size=len(chunk))
         filename = os.path.basename(upload_chunk.storage_path(""))
-        upload_chunk.file.save(filename, ContentFile(chunk_read))
+        upload_chunk.file.save(filename, ContentFile(chunk))
 
 
 class UploadChunk(BaseModel):

{"golden_diff": "diff --git a/pulpcore/app/models/upload.py b/pulpcore/app/models/upload.py\n--- a/pulpcore/app/models/upload.py\n+++ b/pulpcore/app/models/upload.py\n@@ -1,6 +1,8 @@\n import hashlib\n import os\n \n+from gettext import gettext as _\n+\n from django.core.files.base import ContentFile\n from django.db import models\n from django.db.models.signals import post_delete\n@@ -26,17 +28,18 @@\n         Append a chunk to an upload.\n \n         Args:\n-            chunk (File): Binary file to append to the upload file.\n+            chunk (File): Binary data to append to the upload file.\n             offset (int): First byte position to write chunk to.\n         \"\"\"\n-        chunk_read = chunk.read()\n-        current_sha256 = hashlib.sha256(chunk_read).hexdigest()\n-        if sha256 and sha256 != current_sha256:\n-            raise serializers.ValidationError(\"Checksum does not match chunk upload.\")\n+        chunk = chunk.read()\n+        if sha256:\n+            current_sha256 = hashlib.sha256(chunk).hexdigest()\n+            if sha256 != current_sha256:\n+                raise serializers.ValidationError(_(\"Checksum does not match chunk upload.\"))\n \n         upload_chunk = UploadChunk(upload=self, offset=offset, size=len(chunk))\n         filename = os.path.basename(upload_chunk.storage_path(\"\"))\n-        upload_chunk.file.save(filename, ContentFile(chunk_read))\n+        upload_chunk.file.save(filename, ContentFile(chunk))\n \n \n class UploadChunk(BaseModel):\n", "issue": "Append of chunked upload processes raw data\n**Version**\r\nPlease provide the versions of the pulpcore and plugin packages in use, and how they are installed.  If you are using Pulp via Katello, please provide the Katello version.\r\n\r\n**Describe the bug**\r\nA clear and concise description of what the bug is.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n\r\n**Expected behavior**\r\nA clear and concise description of what you expected to happen.\r\n\r\n**Additional context**\r\nAdd any other context about the problem here.  Please provide links to any previous discussions via Discourse or Bugzilla.\r\n\n", "before_files": [{"content": "import hashlib\nimport os\n\nfrom django.core.files.base import ContentFile\nfrom django.db import models\nfrom django.db.models.signals import post_delete\nfrom django.dispatch import receiver\nfrom rest_framework import serializers\n\nfrom pulpcore.app.models import BaseModel, fields, storage\n\n\nclass Upload(BaseModel):\n    \"\"\"\n    A chunked upload. Stores chunks until used to create an artifact, etc.\n\n    Fields:\n\n        size (models.BigIntegerField): The size of the file in bytes.\n    \"\"\"\n\n    size = models.BigIntegerField()\n\n    def append(self, chunk, offset, sha256=None):\n        \"\"\"\n        Append a chunk to an upload.\n\n        Args:\n            chunk (File): Binary file to append to the upload file.\n            offset (int): First byte position to write chunk to.\n        \"\"\"\n        chunk_read = chunk.read()\n        current_sha256 = hashlib.sha256(chunk_read).hexdigest()\n        if sha256 and sha256 != current_sha256:\n            raise serializers.ValidationError(\"Checksum does not match chunk upload.\")\n\n        upload_chunk = UploadChunk(upload=self, offset=offset, size=len(chunk))\n        filename = os.path.basename(upload_chunk.storage_path(\"\"))\n        upload_chunk.file.save(filename, ContentFile(chunk_read))\n\n\nclass UploadChunk(BaseModel):\n    \"\"\"\n    A chunk for an uploaded file.\n\n    Fields:\n\n        file (fields.FileField): A file where the uploaded chunk is stored.\n        upload (models.ForeignKey): Upload this chunk belongs to.\n        offset (models.BigIntegerField): Start of the chunk in bytes.\n        size (models.BigIntegerField): Size of the chunk in bytes.\n    \"\"\"\n\n    def storage_path(self, name):\n        \"\"\"\n        Callable used by FileField to determine where the uploaded file should be stored.\n\n        Args:\n            name (str): Original name of uploaded file. It is ignored by this method because the\n                pulp_id is used to determine a file path instead.\n        \"\"\"\n        return storage.get_upload_chunk_file_path(self.pulp_id)\n\n    file = fields.FileField(null=False, upload_to=storage_path, max_length=255)\n    upload = models.ForeignKey(Upload, on_delete=models.CASCADE, related_name=\"chunks\")\n    offset = models.BigIntegerField()\n    size = models.BigIntegerField()\n\n\n@receiver(post_delete, sender=UploadChunk)\ndef upload_chunk_delete(instance, **kwargs):\n    instance.file.delete(save=False)\n", "path": "pulpcore/app/models/upload.py"}], "after_files": [{"content": "import hashlib\nimport os\n\nfrom gettext import gettext as _\n\nfrom django.core.files.base import ContentFile\nfrom django.db import models\nfrom django.db.models.signals import post_delete\nfrom django.dispatch import receiver\nfrom rest_framework import serializers\n\nfrom pulpcore.app.models import BaseModel, fields, storage\n\n\nclass Upload(BaseModel):\n    \"\"\"\n    A chunked upload. Stores chunks until used to create an artifact, etc.\n\n    Fields:\n\n        size (models.BigIntegerField): The size of the file in bytes.\n    \"\"\"\n\n    size = models.BigIntegerField()\n\n    def append(self, chunk, offset, sha256=None):\n        \"\"\"\n        Append a chunk to an upload.\n\n        Args:\n            chunk (File): Binary data to append to the upload file.\n            offset (int): First byte position to write chunk to.\n        \"\"\"\n        chunk = chunk.read()\n        if sha256:\n            current_sha256 = hashlib.sha256(chunk).hexdigest()\n            if sha256 != current_sha256:\n                raise serializers.ValidationError(_(\"Checksum does not match chunk upload.\"))\n\n        upload_chunk = UploadChunk(upload=self, offset=offset, size=len(chunk))\n        filename = os.path.basename(upload_chunk.storage_path(\"\"))\n        upload_chunk.file.save(filename, ContentFile(chunk))\n\n\nclass UploadChunk(BaseModel):\n    \"\"\"\n    A chunk for an uploaded file.\n\n    Fields:\n\n        file (fields.FileField): A file where the uploaded chunk is stored.\n        upload (models.ForeignKey): Upload this chunk belongs to.\n        offset (models.BigIntegerField): Start of the chunk in bytes.\n        size (models.BigIntegerField): Size of the chunk in bytes.\n    \"\"\"\n\n    def storage_path(self, name):\n        \"\"\"\n        Callable used by FileField to determine where the uploaded file should be stored.\n\n        Args:\n            name (str): Original name of uploaded file. It is ignored by this method because the\n                pulp_id is used to determine a file path instead.\n        \"\"\"\n        return storage.get_upload_chunk_file_path(self.pulp_id)\n\n    file = fields.FileField(null=False, upload_to=storage_path, max_length=255)\n    upload = models.ForeignKey(Upload, on_delete=models.CASCADE, related_name=\"chunks\")\n    offset = models.BigIntegerField()\n    size = models.BigIntegerField()\n\n\n@receiver(post_delete, sender=UploadChunk)\ndef upload_chunk_delete(instance, **kwargs):\n    instance.file.delete(save=False)\n", "path": "pulpcore/app/models/upload.py"}]}