Repository: pimcore/pimcore (language: php)

Issue:
[Bug]: Generating Checksum on Azure May Fail After Upload
### Pimcore version

11.3.1

### Steps to reproduce

Upload certain asset files, in this case the file is > 44MBs. Certain files reliably trigger the issue.
I was able to get this to trigger with a file generated using `mkfile -n 44m ~/Downloads/44mb` (on MacOS)

### Actual Behavior

Get error message like:
![image](https://github.com/user-attachments/assets/aa14f5b2-f10b-4f18-9348-2a46d8116226)
file is uploaded to Blob but not shown in Pimcore.

### Expected Behavior

We try to get the checksum right after uploading: https://github.com/pimcore/pimcore/blob/9f901b1d3056239258a0416cc2506348bf2f743a/models/Asset.php#L737-L738

however that checksum might not be available on Azure:
https://github.com/thephpleague/flysystem-azure-blob-storage/blob/7856cc57ae74b0cf673b924e05c236c4f5dbdcb0/AzureBlobStorageAdapter.php#L365-L367

I suggest that the `UnableToProvideChecksum` exception is caught and we fallback to the old behavior of just not saving the checksum.


Discussion / hints:
This SO post indicates a 32MB threshold https://stackoverflow.com/questions/42229153/how-to-check-azure-storage-blob-file-uploaded-correctly/69319211#69319211 corresponding to the chunk size. This can be raised programmatically up to 256MB. 
The other solution that can be done is to calculate checksum when file arrives on server prior to including flysystem and pass it to Asset::create method and store it on Asset because Azure will eventually fail at some point because of the size limit and possible other services.

This way md5 will always be present, which is ok, as checksum now is just set, it's not checked by the system in any other way to confirm successful upload.
The new Azure Blob PHP library is taking that approach: https://github.com/Azure-OSS/azure-storage-php/pull/36. There is an associated flysystem that will use this library: https://github.com/Azure-OSS/azure-storage-php-adapter-flysystem.
so, would it be possible to use that https://github.com/Azure-OSS/azure-storage-php-adapter-flysystem adapter for Azure instead? 
I do think Pimcore side should not fail if the checksum cannot be resolved. (1) Pimcore does not actually _need_ the checksum (and in fact there is even a script to back populate) and (2) historically (until recently) it didn't call checkum when pushing Assets.

The adapter can be investigated; however, it is VERY new (the team behind it just open sourced it) and would prefer to not be forced to move to it.
One thing to consider: IF Pimcore cares about the checksum, we'd need to save the origin of the checksum along with the actual checksum, because they can be different depending on the origin 🤔 
So I'm afraid that just handling the checksum generation internally when the Flysystem adapter fails, is not  💯% the solution. 
>handling the checksum generation internally when the Flysystem adapter fails,

The specific adapters may be able to take the approach (of handling locally) if they understand the idiosyncrasies of their backend.
e.g. Azure makes clear they use md5: https://github.com/microsoft/azure-blob-checksum-verification so it would be safe for that adapter to perform md5. I agree that _Pimcore_ should not assume md5 is right checksum.

>we'd need to save the origin of the checksum along with the actual checksum, because they can be different depending on the origin

This is actually important for the `pimcore:migrate:storage` which should probably not copy over the checksums if the backend is changing. 

 👍agree, just wanted to clarify that Pimcore should handle this in a generic way and not to handle different Flysystem adapters individually 😉 
anyone willing to contribute? 

Fix patch:
diff --git a/models/Asset.php b/models/Asset.php
index f1c2cd73fb3..f4252db5bcb 100644
--- a/models/Asset.php
+++ b/models/Asset.php
@@ -22,6 +22,7 @@
 use League\Flysystem\FilesystemException;
 use League\Flysystem\FilesystemOperator;
 use League\Flysystem\UnableToMoveFile;
+use League\Flysystem\UnableToProvideChecksum;
 use League\Flysystem\UnableToRetrieveMetadata;
 use Pimcore;
 use Pimcore\Cache;
@@ -1144,7 +1145,8 @@ public function getChecksum(): string
             $checksum = $this->getCustomSetting('checksum');
         }
 
-        return $checksum;
+        // generateChecksum may fail to set the checksum, in which case we fall back to empty string.
+        return $checksum ?? '';
     }
 
     /**
@@ -1152,7 +1154,15 @@ public function getChecksum(): string
      */
     public function generateChecksum(): void
     {
-        $this->setCustomSetting('checksum', Storage::get('asset')->checksum($this->getRealFullPath()));
+        try {
+            $this->setCustomSetting('checksum', Storage::get('asset')->checksum($this->getRealFullPath()));
+        } catch (UnableToProvideChecksum $e) {
+            // There are circumstances in which the adapter is unable to calculate the checksum for a given file.
+            // In those cases, we ignore the exception.
+            Logger::error((string) $e);
+
+            return;
+        }
         $this->getDao()->updateCustomSettings();
     }
 


Test patch: