![]() |
Nach einem redirect 301 wird POST wird durch GET überschrieben
Hallo alle zusammen!
Ich habe einen REST-Server und einen REST-Client mit dem DMVC von Daniele Teti geschrieben. Die Filter-Parameter für die Abfrage GetHistorie() werden als JSON im Body übergeben. Mit POST wird die Abfrage ausgeführt.
Delphi-Quellcode:
Die Produktiv-Umgebung läuft über einen Reverse-Proxy mit NGINX und Let's encrypt.
[MVCPath('/historie')]
[MVCConsumes(TMVCMediaType.APPLICATION_JSON)] [MVCProduces(TMVCMediaType.APPLICATION_JSON)] [MVCHTTPMethod([httpPOST])] procedure GetHistorie([MVCFromBody] Filter: TFltHistorie); Wenn die Abfrage über HTTPS geht ist alles ok, die POST-Methode wird ausgeführt. Wenn die Abfrage über HTTP gestartet wird, erfolgt durch NGINX eine Umleitung auf HTTPS.
Code:
Diese Umleitung mit dem Code 301 bewirkt im REST-Server in der Funktion
...
return 301 https://$server_name$request_uri; ... System.Net.HttpClient.IsAutoRedirectWithGET(..) ein Überschreiben der POST-Methode durch eine GET-Methode. Das hat zur Folge, dass der Client als Antwort ein 404 erhält, da Funktion GetHistorie() als HTTP-POST und nicht als HTTP-GET definiert ist. Ok, Lösung: gleich das HTTPS Protkoll verwenden. Jetzt die Fragen: Warum wird, wie es aussieht standardmäßig, nach einem redirect 301 ein POST durch ein GET ersetzt? Kann man dieses Verhalten abstellen? Alex |
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Ist wohl abhängig von der verwendeten Client-Library Implementierung:
Zitat:
|
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Hhmm,
das heißt, dass diese Funktion einfach nur ein Fehler ist? :-D unit System.Net.HttpClient:
Delphi-Quellcode:
function THTTPClient.IsAutoRedirectWithGET(const ARequest: THTTPRequest; const AResponse: THTTPResponse): Boolean;
var LRedirWithGet: THTTPRedirectsWithGET; LMethod: string; begin // POST: // * 303 must be redirected to GET according spec // * 301, 302, 307 erroneously may be redirected to GET too // PUT, DELETE: // * 303 must be redirected to GET according spec Result := False; if not IsAutoRedirect(AResponse) then Exit; LRedirWithGet := RedirectsWithGET; LMethod := ARequest.GetMethodString; if SameText(LMethod, sHTTPMethodPost) then case AResponse.GetStatusCode of 301: Result := THTTPRedirectWithGET.Post301 in LRedirWithGet; 302: Result := THTTPRedirectWithGET.Post302 in LRedirWithGet; 303: Result := THTTPRedirectWithGET.Post303 in LRedirWithGet; 307: Result := THTTPRedirectWithGET.Post307 in LRedirWithGet; 308: Result := THTTPRedirectWithGET.Post308 in LRedirWithGet; end else if SameText(LMethod, sHTTPMethodPut) then case AResponse.GetStatusCode of 301: Result := THTTPRedirectWithGET.Put301 in LRedirWithGet; 302: Result := THTTPRedirectWithGET.Put302 in LRedirWithGet; 303: Result := THTTPRedirectWithGET.Put303 in LRedirWithGet; 307: Result := THTTPRedirectWithGET.Put307 in LRedirWithGet; 308: Result := THTTPRedirectWithGET.Put308 in LRedirWithGet; end else if SameText(LMethod, sHTTPMethodDelete) then case AResponse.GetStatusCode of 301: Result := THTTPRedirectWithGET.Delete301 in LRedirWithGet; 302: Result := THTTPRedirectWithGET.Delete302 in LRedirWithGet; 303: Result := THTTPRedirectWithGET.Delete303 in LRedirWithGet; 307: Result := THTTPRedirectWithGET.Delete307 in LRedirWithGet; 308: Result := THTTPRedirectWithGET.Delete308 in LRedirWithGet; end; end; |
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Nein das ist so schon richtig. Das Problem ist, dass du garnicht erst ein Post auf eine URL ausführen solltest, die ein 301 liefert. Die Daten werden im Content an den Server geschickt und bei einem 301 würdest du diese Daten verlieren, da du nur die neue URL retour bekommst, aber nicht die im Content geschickten Daten. Eventuell irre ich mich da auch, aber ich glaube eine 301 sendet kein Content.
|
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Ok, das mit dem fehlenden Content wäre eine Erklärung.
Wobei sich die Frage stellt, was das Sinnvolles rauskommen soll, wenn ein POST/PUT/DELETE in ein GET umgewandelt wird. Und es bliebe noch der Hinweis aus der RFC, dass das Umwandeln nur fälschlicherweise durch einige Clients ausgeführt wird. Aber gut, ich werde den Zugriff per HTTP abstellen und immer gleich HTTPS verwenden. Alex |
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Auf das Redirekt reagieren, die Zugangsdaten in der Komponente anpassen und es nochmal senden?
|
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Naja, ich bekomme als Fehler nur die 404 "Not found" zurück
und das kann ja verschiedene Gründe haben. Außerdem gehe ich in der Produktiv-Umgebung sowieso über HTTPS und komme damit nicht in den "Genuss" des Redirects. Meine Frage war eher aus Interesse, warum man überhaupt sowas, für meine Begriffe, unsinniges macht. alex |
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Wenn du statt 301 ein 308 als Antwort lieferst, dann sollte die Umleitung so funktionieren, dass das POST erhalten bleibt, siehe
![]() |
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Das 301 sagt Dir, dass es nun wo anders zufinden ist ... du (bzw. die verwendete Komponente) kann nun einen Fehler werfen, weil Umleitungen z.B. aus Sicherheitsgründen verboten sind (Hacker hat Kontrolle bekommen und leitet alles an seine Server weiter) oder man wendet sich eben an die neue Adresse (hier vielleicht die Redirects mitzählen und begrenzen, damit man nicht in einer Endlosschleife landen kann.
Der Server könnte natürlich auch intern die Anfrage direkt weiterleiten, anstatt einem 301/308, wenn er wöllte, und du bekommst davon dann nichts mit und es läuft so weiter, wie bisher. |
AW: Nach einem redirect 301 wird POST wird durch GET überschrieben
Erstmal danke für den
![]() Ein POST/PUT/DELETE wird auch bei einem redirect 308 in der unit System.Net.HttpClient auf ein GET umgeleitet und ich hatte nicht vor an den Delphi-Quelltexten Änderungen zu machen. Den redirect 301 verwende ich im nginx dazu den Client zum Wechsel von HTTP zu HTTPS zu zwingen. Da aber auch die Client-Software von mir ist, kann ich auch gleich das richtige Protokoll verwenden. Bei HTTP gibt es ein 403 zurück. Ist auch der Sicherheit zuträglicher. :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz