HttpClient – RESTful API / CRUD Operations, File Upload scheitert [ERLEDIGT]
Verfasst: Mo, 06. Mär 2023 13:59
Hallo!
Ich habe ein Problem mit einem File Upload beim Ansprechen einer (Google-gehosteten) RESTful API.
Ich hoffe, ich verwende die Begriffe einigermaßen korrekt, das ist Neuland für mich.
Grundsätzlich funktioniert das Ganze so:
(Doku: https://soundfile-abnahme.gema.de/api-documentation)
Zunächst erfolgt ein Login mit Benutzername und Passwort (als Json-String), zurück gibt es ein token.
Bei weiteren Abfragen wird das token im Header übergeben („Authorization“, „Bearer <token>“ )
Für den File-Upload wird zunächst ein Json-String mit Meta-Daten übertragen, zurück gibt es eine Upload-URL und eine File-ID (wird nur für spätere Abfragen des Status benötigt.)
Bis hierhin funktioniert alles.
Der nächste Schritt ist der Upload eines Soundfiles (wav/mp3 – der „Content-Type“ wird im Header zusätzlich zur Authorization angegeben.)
Ich hatte zunächst probiert, den Upload per HttpClient:httpRequest:setFileParameter Quelle und Ziel zu starten – was aber wohl ein Holzweg ist.
Korrekt ist m.E. die Quelldatei komplett als String einzulesen und als Content zu setzen(?)
(Die „Upload“-Methode habe ich angehängt – ist noch kein „ordentlicher“ Code, nur zum Testen.)
Die Rückmeldung für den Upload-Versuch habe ich unten angehängt.
…der Upload wird also wegen eines falschen Schlüssels abgelehnt. Der Schlüssel steht nach meinem Verständnis aber in der Upload-URL (siehe unten.)
Ich vermute, dass die Fehlermeldung "falsche Signatur" nicht der wahre Fehler ist.
Zum Testen habe ich mit den selben Daten (Upload-URL, Authorization im Header, Methode „PUT“) den Upload mit Insomnia (Utility zum API-Testen) durchgeführt und das funktoiniert. (Hier wähle ich die Option "binary file", dafür habe ich beim HttpClient() keine Entsprechnung gefunden.)
(Ich habe auch versucht den Datenverkehr mit Wireshark zu vergleichen, da scheitere ich aber daran, dass die Entschlüsselung scheinbar nicht so funktioniert, wie sie sollte. Oder ich bin zu blöd.)
Falls jemand eine Idee hat, was ich falsch mache, wäre das super – ich vermute ja, dass es irgendeine „Kleinigkeit“ ist, die ich vielleicht in der HttpClient() – Doku übersehen habe (die übrigens m.E. sehr knapp gehalten ist.)
Upload-URL ("h-ttps://" = "https//"):
-------------------------------------
h-ttps://storage.googleapis.com/abnahme-upload.soundfile.gema.de/tempApiSoundfiles/026326f1-43a6-4c84-97f8-4f7fb3042d8f/poke_321_track10.wav?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=cloud-run-api%40gema-soundfile-upload-abnahme.iam.gserviceaccount.com%2F20230306%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20230306T113155Z&X-Goog-Expires=86400&X-Goog-SignedHeaders=host&X-Goog-Signature=5720942e74c9d3a4aa6e1d73e681a1ba57be5b9d7af2a8ac2ad8ad52f89598ba57fc66ffd68e8f11d7550836ff0e15734155119c0e65df75b4ee3a6ca2cb79088f9a01611a7948fe25b198878ec6529a1cb92fda17817bf8f9708ce895b4448458b1961d4d12273addc1f570c938b33ad2487f97afd45b7ea3783e891823d0fca90dae28b616160c9319e1ec0e171257c8ac0e9316524fd681c40295e341a87d2809f1e2fceba6edefe3b10e7323de093253c04d2d6b11d21bc6d3bac40db95d81050d05981f0aa4e258b43d478a281200da14a897bec4e9e03899f7ebe0e6c4bffe595a5cb4c74949d7035a916d46677d366d73cb9bf53b357ed4a07b2ea736
Rückmeldung Upload-Versuch:
----------------------------------------------
<?xml version='1.0' encoding='UTF-8'?><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message><StringToSign>GOOG4-RSA-SHA256
20230306T113155Z
20230306/auto/storage/goog4_request
bc77ffa3c89e4ac40095227d084d28603f7bfc75ce488b83f3b5807f6aa23272</StringToSign><CanonicalRequest>PUT
/abnahme-upload.soundfile.gema.de/tempApiSoundfiles/026326f1-43a6-4c84-97f8-4f7fb3042d8f/poke_321_track10.wav
X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=cloud-run-api%40gema-soundfile-upload-abnahme.iam.gserviceaccount.com%2F20230306%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20230306T113155Z&X-Goog-Expires=86400&X-Goog-SignedHeaders=host
host:storage.googleapis.com
host
UNSIGNED-PAYLOAD</CanonicalRequest></Error>
Ich habe ein Problem mit einem File Upload beim Ansprechen einer (Google-gehosteten) RESTful API.
Ich hoffe, ich verwende die Begriffe einigermaßen korrekt, das ist Neuland für mich.
Grundsätzlich funktioniert das Ganze so:
(Doku: https://soundfile-abnahme.gema.de/api-documentation)
Zunächst erfolgt ein Login mit Benutzername und Passwort (als Json-String), zurück gibt es ein token.
Bei weiteren Abfragen wird das token im Header übergeben („Authorization“, „Bearer <token>“ )
Für den File-Upload wird zunächst ein Json-String mit Meta-Daten übertragen, zurück gibt es eine Upload-URL und eine File-ID (wird nur für spätere Abfragen des Status benötigt.)
Bis hierhin funktioniert alles.
Der nächste Schritt ist der Upload eines Soundfiles (wav/mp3 – der „Content-Type“ wird im Header zusätzlich zur Authorization angegeben.)
Ich hatte zunächst probiert, den Upload per HttpClient:httpRequest:setFileParameter Quelle und Ziel zu starten – was aber wohl ein Holzweg ist.
Korrekt ist m.E. die Quelldatei komplett als String einzulesen und als Content zu setzen(?)
(Die „Upload“-Methode habe ich angehängt – ist noch kein „ordentlicher“ Code, nur zum Testen.)
Die Rückmeldung für den Upload-Versuch habe ich unten angehängt.
…der Upload wird also wegen eines falschen Schlüssels abgelehnt. Der Schlüssel steht nach meinem Verständnis aber in der Upload-URL (siehe unten.)
Ich vermute, dass die Fehlermeldung "falsche Signatur" nicht der wahre Fehler ist.
Zum Testen habe ich mit den selben Daten (Upload-URL, Authorization im Header, Methode „PUT“) den Upload mit Insomnia (Utility zum API-Testen) durchgeführt und das funktoiniert. (Hier wähle ich die Option "binary file", dafür habe ich beim HttpClient() keine Entsprechnung gefunden.)
(Ich habe auch versucht den Datenverkehr mit Wireshark zu vergleichen, da scheitere ich aber daran, dass die Entschlüsselung scheinbar nicht so funktioniert, wie sie sollte. Oder ich bin zu blöd.)
Falls jemand eine Idee hat, was ich falsch mache, wäre das super – ich vermute ja, dass es irgendeine „Kleinigkeit“ ist, die ich vielleicht in der HttpClient() – Doku übersehen habe (die übrigens m.E. sehr knapp gehalten ist.)
Upload-URL ("h-ttps://" = "https//"):
-------------------------------------
h-ttps://storage.googleapis.com/abnahme-upload.soundfile.gema.de/tempApiSoundfiles/026326f1-43a6-4c84-97f8-4f7fb3042d8f/poke_321_track10.wav?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=cloud-run-api%40gema-soundfile-upload-abnahme.iam.gserviceaccount.com%2F20230306%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20230306T113155Z&X-Goog-Expires=86400&X-Goog-SignedHeaders=host&X-Goog-Signature=5720942e74c9d3a4aa6e1d73e681a1ba57be5b9d7af2a8ac2ad8ad52f89598ba57fc66ffd68e8f11d7550836ff0e15734155119c0e65df75b4ee3a6ca2cb79088f9a01611a7948fe25b198878ec6529a1cb92fda17817bf8f9708ce895b4448458b1961d4d12273addc1f570c938b33ad2487f97afd45b7ea3783e891823d0fca90dae28b616160c9319e1ec0e171257c8ac0e9316524fd681c40295e341a87d2809f1e2fceba6edefe3b10e7323de093253c04d2d6b11d21bc6d3bac40db95d81050d05981f0aa4e258b43d478a281200da14a897bec4e9e03899f7ebe0e6c4bffe595a5cb4c74949d7035a916d46677d366d73cb9bf53b357ed4a07b2ea736
Rückmeldung Upload-Versuch:
----------------------------------------------
<?xml version='1.0' encoding='UTF-8'?><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message><StringToSign>GOOG4-RSA-SHA256
20230306T113155Z
20230306/auto/storage/goog4_request
bc77ffa3c89e4ac40095227d084d28603f7bfc75ce488b83f3b5807f6aa23272</StringToSign><CanonicalRequest>PUT
/abnahme-upload.soundfile.gema.de/tempApiSoundfiles/026326f1-43a6-4c84-97f8-4f7fb3042d8f/poke_321_track10.wav
X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=cloud-run-api%40gema-soundfile-upload-abnahme.iam.gserviceaccount.com%2F20230306%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20230306T113155Z&X-Goog-Expires=86400&X-Goog-SignedHeaders=host
host:storage.googleapis.com
host
UNSIGNED-PAYLOAD</CanonicalRequest></Error>