
Connexus-Helfer (Teil 5): HTTP-Methoden und Status Codes
Einführung
Dieser Artikel ist die Fortsetzung einer Reihe von Artikeln, in denen wir eine Bibliothek namens Connexus aufbauen werden. Im ersten Artikel haben wir die grundlegende Funktionsweise der Funktion WebRequest verstanden, jeden ihrer Parameter kennengelernt und auch einen Beispielcode erstellt, der die Verwendung dieser Funktion und ihre Schwierigkeiten demonstriert. Im letzten Artikel haben wir verstanden, wie eine Anfrage funktioniert, was der Body einer Anfrage ist und wie man Daten an den Server sendet, und schließlich haben wir Unterstützung für Anfragen mit einem Body entwickelt.
In diesem fünften Artikel der Serie über den Aufbau der Connexus-Bibliothek werden wir einen wesentlichen Aspekt des HTTP-Protokolls behandeln: Methoden und Status-Codes. Das Verständnis der Funktionsweise der einzelnen HTTP-Verben und der Handhabung von Status-Codes ist entscheidend für die Schaffung zuverlässiger Interaktionen zwischen Clients und Servern. Los geht's!
HTTP-Methoden
HTTP-Methoden sind die Aktionen, mit denen wir den Server beauftragen. Wenn Sie eine HTTP-Anfrage stellen, z. B. um eine Seite aufzurufen oder Daten zu senden, „sprechen“ Sie mit dem Server mit Hilfe dieser Verben. Hier sind die wichtigsten davon:
- GET: Das ist das gute alte „Gib mir das“. Der Browser möchte etwas auf dem Server sehen, sei es eine Seite, ein Bild oder eine Datei. Es werden nur die Informationen abgerufen, ohne etwas zu verändern. Als ob man nach der Speisekarte eines Restaurants fragt, nur um zu sehen, was angeboten wird.
- POST: POST ist der Mann, der ein Paket ausliefert. Hier senden Sie Daten an den Server. Dies ist bei Formularen üblich, z. B. wenn Sie sich auf einer Website registrieren. Stellen Sie sich vor, Sie würden einen Brief verschicken: Sie warten, bis er am Zielort ankommt und tun dort etwas, z. B. sich anmelden.
- PUT: Wenn Sie PUT verwenden, sagen Sie im Grunde: „Ändere dies, hier für diese neue Version“. Sie wird verwendet, um eine bestehende Ressource zu aktualisieren. Das ist wie ein Ölwechsel bei Ihrem Auto – es ist dasselbe Auto, aber jetzt mit etwas Neuem.
- DELETE: Ziemlich einfach, oder? Es heißt: „Nimm das weg“. Sie fordern den Server auf, etwas zu löschen. Auf Wiedersehen, wir sehen es nie wieder.
- PATCH: PATCH ist etwas heikler. Es wird nur ein Teil der Ressource verändert. Es ist, als würde man ein kaputtes Teil eines Spielzeugs reparieren – man muss nicht alles ändern, sondern nur das anpassen, was kaputt ist.
- HEAD: Dies ist GET, aber ohne den Hauptteil (body). Sie wollen nur die Kopfdaten, nicht den Inhalt. Es ist, als würde man den Titel eines Buches lesen, ohne die Seiten aufzuschlagen.
Es gibt noch andere Methoden wie CONNECT, OPTIONS und TRACE, die aber in der täglichen Arbeit von Entwicklern selten verwendet werden. Ich werde hier nicht auf die Details der einzelnen Methoden eingehen, aber mein Ziel ist es, dass die Bibliothek alle HTTP-Methoden unterstützt. Wenn Sie mehr über alle HTTP-Methoden erfahren möchten, finden Sie hier die vollständige Protokolldokumentation. Aber glauben Sie mir, die gängigsten Anfragen bei der täglichen Arbeit von Entwicklern, wie GET, POST und DELETE, reichen für die meisten Probleme aus.
Ich möchte betonen, dass wir nur eine Methode pro Anfrage verwenden, d.h. eine Anfrage kann nicht gleichzeitig vom Typ GET und POST sein.
Erstellen der Klasse CHttpMethod
Da wir nun die einzelnen HTTP-Methoden kennen, wissen, wofür sie gedacht sind und wann sie zu verwenden sind, können wir direkt mit dem Code beginnen. Wir werden in Connexus eine Klasse implementieren, die für die Speicherung der HTTP-Methode zuständig ist, mit der die Anfragen gestellt werden. Es handelt sich um einen sehr einfachen Kurs, bei dem Sie unabhängig von Ihren Programmierkenntnissen das meiste verstehen werden, was passiert. Der Zweck der Klasse ist nur die Speicherung der verwendeten Methode, aber da wir uns in einer Klasse befinden, werden wir weitere Funktionen hinzufügen, um es dem Endnutzer der Connexus-Bibliothek so einfach wie möglich zu machen.
Beginnen wir mit der Erstellung eines neuen Ordners mit dem Namen Constants, in dem wir eine neue Datei mit dem Namen CHttpMethod erstellen, die am Ende wie folgt aussehen wird Include/Constants/HttpMethod.mqh . In dieser neuen Datei erstellen wir die Klasse CHttpMethod:
//+------------------------------------------------------------------+ //| HttpMethods.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| class : CHttpMethods | //| | //| [PROPERTY] | //| Name : CHttpMethods | //| Heritage : No heritage | //| Description : Saved http method. | //| | //+------------------------------------------------------------------+ class CHttpMethod { public: CHttpMethod(void); ~CHttpMethod(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpMethod::CHttpMethod(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpMethod::~CHttpMethod(void) { } //+------------------------------------------------------------------+
Um alle möglichen http-Methoden zu erfassen, erstellen wir ein Enum, das alle möglichen Methoden einer http-Anfrage enthält. Außerdem fügen wir der Klasse eine neue Variable vom Typ ENUM_HTTP_METHOD mit der Bezeichnung m_method hinzu:
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_HTTP_METHOD { HTTP_METHOD_NULL = 0, // [0] Null HTTP_METHOD_CONNECT, // [1] Connect HTTP_METHOD_DELETE, // [2] Delete HTTP_METHOD_GET, // [3] Get HTTP_METHOD_HEAD, // [4] Head HTTP_METHOD_OPTION, // [5] Option HTTP_METHOD_PATCH, // [6] Patch HTTP_METHOD_POST, // [7] Post HTTP_METHOD_PUT, // [8] Put HTTP_METHOD_TRACE, // [9] Trace }; //+------------------------------------------------------------------+ //| class : CHttpMethods | //| | //| [PROPERTY] | //| Name : CHttpMethods | //| Heritage : No heritage | //| Description : Saved http method. | //| | //+------------------------------------------------------------------+ class CHttpMethod { private: ENUM_HTTP_METHOD m_method; // Stores the method that will be used }; //+------------------------------------------------------------------+
Da wir nun die Variable haben, die für die Speicherung verwendet wird, müssen wir Hilfsmethoden erstellen, um die HTTP-Methode zu definieren und abzurufen, und den Operator „=“ überladen, um die Verwendung der Hauptfunktionen zu erleichtern:
- Zuweisungsoperator „=“: Er ermöglicht Ihnen, die HTTP-Methode direkt mit dem Operator „=“ zu definieren.
- SetMethod(ENUM_HTTP_METHOD) und SetMethod(string): Damit wird die HTTP-Methode als Enum oder Zeichenkette. Wenn der Parameter vom Typ „string“ ist, wird die Funktion StringToUpper() verwendet, um die Zeichenkette korrekt zu bilden.
- GetMethod() und GetMethodDescription(): So erhält man die HTTP-Methode und ihre textliche Beschreibung.
- void operator=(ENUM_HTTP_METHOD method): Hierbei handelt es sich um eine überladene Operation, die, vereinfacht ausgedrückt, dazu dient, die HTTP-Methode mit dem Operator „=“ zu definieren. Hier ist ein Beispiel für diesen Operator in der Praxis:
CHttpMethod method; method = HTTP_METHOD_POST;
- Überprüfungsfunktionen (IsPost(), IsGet(), usw.): Sie erleichtern die Überprüfung der Methode, machen den Code lesbarer und vereinfachen ihn. Ein Beispiel dafür, wie diese Funktionen uns helfen können.
CHttpMethod method; method.SetMethod("POST") if(method.GetMethod() == HTTP_METHOD_POST) { //--- Action } //--- Or if(method.IsPost()) { //--- Action }
Auf diese Weise vermeiden wir explizite Methodenvergleiche.
//+------------------------------------------------------------------+ //| class : CHttpMethod | //| | //| [PROPERTY] | //| Name : CHttpMethod | //| Heritage : No heritage | //| Description : Saved http method. | //| | //+------------------------------------------------------------------+ class CHttpMethod { private: ENUM_HTTP_METHOD m_method; // Stores the method that will be used public: CHttpMethod(void); ~CHttpMethod(void); //--- Get and set void operator=(ENUM_HTTP_METHOD method); void Set(ENUM_HTTP_METHOD method); bool Set(string method); ENUM_HTTP_METHOD Get(void); string GetAsString(void); //--- Check method bool IsConnect(void); bool IsGet(void); bool IsPost(void); bool IsPut(void); bool IsDelete(void); bool IsPatch(void); bool IsHead(void); bool IsOption(void); bool IsTrace(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpMethod::CHttpMethod(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpMethod::~CHttpMethod(void) { } //+------------------------------------------------------------------+ //| Defines the http method | //+------------------------------------------------------------------+ void CHttpMethod::operator=(ENUM_HTTP_METHOD method) { m_method = method; } //+------------------------------------------------------------------+ //| Defines the http method | //+------------------------------------------------------------------+ void CHttpMethod::Set(ENUM_HTTP_METHOD method) { m_method = method; } //+------------------------------------------------------------------+ //| Defines the http method | //+------------------------------------------------------------------+ bool CHttpMethod::Set(string method) { string method_upper = method; StringToUpper(method_upper); if(method_upper == "CONNECT") { m_method = HTTP_METHOD_CONNECT; return(true); } else if(method_upper == "DELETE") { m_method = HTTP_METHOD_DELETE; return(true); } else if(method_upper == "GET") { m_method = HTTP_METHOD_GET; return(true); } else if(method_upper == "HEAD") { m_method = HTTP_METHOD_HEAD; return(true); } else if(method_upper == "OPTIONS") { m_method = HTTP_METHOD_OPTION; return(true); } else if(method_upper == "PATCH") { m_method = HTTP_METHOD_PATCH; return(true); } else if(method_upper == "POST") { m_method = HTTP_METHOD_POST; return(true); } else if(method_upper == "PUT") { m_method = HTTP_METHOD_PUT; return(true); } else if(method_upper == "TRACE") { m_method = HTTP_METHOD_TRACE; return(true); } return(false); } //+------------------------------------------------------------------+ //| Get http method | //+------------------------------------------------------------------+ ENUM_HTTP_METHOD CHttpMethod::Get(void) { return(m_method); } //+------------------------------------------------------------------+ //| Get the description of the selected http method | //+------------------------------------------------------------------+ string CHttpMethod::GetAsString(void) { switch(m_method) { case HTTP_METHOD_NULL: return "NULL"; case HTTP_METHOD_CONNECT: return "CONNECT"; case HTTP_METHOD_DELETE: return "DELETE"; case HTTP_METHOD_GET: return "GET"; case HTTP_METHOD_HEAD: return "HEAD"; case HTTP_METHOD_OPTION: return "OPTIONS"; case HTTP_METHOD_PATCH: return "PATCH"; case HTTP_METHOD_POST: return "POST"; case HTTP_METHOD_PUT: return "PUT"; case HTTP_METHOD_TRACE: return "TRACE"; default: return "Unknown HTTP Method"; } } //+------------------------------------------------------------------+ //| Check if method is connect | //+------------------------------------------------------------------+ bool CHttpMethod::IsConnect(void) { return(m_method == HTTP_METHOD_CONNECT); } //+------------------------------------------------------------------+ //| Check if method is get | //+------------------------------------------------------------------+ bool CHttpMethod::IsGet(void) { return(m_method == HTTP_METHOD_GET); } //+------------------------------------------------------------------+ //| Check if method is post | //+------------------------------------------------------------------+ bool CHttpMethod::IsPost(void) { return(m_method == HTTP_METHOD_POST); } //+------------------------------------------------------------------+ //| Check if method is put | //+------------------------------------------------------------------+ bool CHttpMethod::IsPut(void) { return(m_method == HTTP_METHOD_PUT); } //+------------------------------------------------------------------+ //| Check if method is delete | //+------------------------------------------------------------------+ bool CHttpMethod::IsDelete(void) { return(m_method == HTTP_METHOD_DELETE); } //+------------------------------------------------------------------+ //| Check if method is patch | //+------------------------------------------------------------------+ bool CHttpMethod::IsPatch(void) { return(m_method == HTTP_METHOD_PATCH); } //+------------------------------------------------------------------+ //| Check if method is head | //+------------------------------------------------------------------+ bool CHttpMethod::IsHead(void) { return(m_method == HTTP_METHOD_HEAD); } //+------------------------------------------------------------------+ //| Check if method is option | //+------------------------------------------------------------------+ bool CHttpMethod::IsOption(void) { return(m_method == HTTP_METHOD_OPTION); } //+------------------------------------------------------------------+ //| Check if method is trace | //+------------------------------------------------------------------+ bool CHttpMethod::IsTrace(void) { return(m_method == HTTP_METHOD_TRACE); } //+------------------------------------------------------------------+
Damit ist die Klasse abgeschlossen, die für die Speicherung der verwendeten HTTP-Methode zuständig ist. Wir haben einige Hilfsfunktionen, um in Zukunft etwas Code zu sparen. Kommen wir nun zur nächsten Hilfsklasse.
Status Code
Die Status-Codes sind ganz einfach Zahlen. Diese Nummer ist standardisiert und wird vom Server nach der Bearbeitung einer Anfrage an den Client gesendet. Jeder Code besteht aus drei Ziffern, von denen die erste die Kategorie angibt, zu der der Status gehört (1xx, 2xx, 3xx, 4xx und 5xx). Dieser Code sagt Ihnen einfach, was das Ergebnis der Anfrage war, ob sie erfolgreich abgeschlossen wurde, ob auf der Serverseite ein Fehler aufgetreten ist oder ob die Anfrage fehlerhaft gesendet wurde. Es gibt mehrere Status-Codes. Diese Zahl kann zwischen 100 und 599 variieren und wird in 5 Kategorien eingeteilt. Um herauszufinden, zu welcher Kategorie der Code gehört, müssen Sie nur feststellen, in welchem Bereich er sich befindet, siehe die Tabelle mit den Werten:
Status-Code des Bereichs | Beschreibung |
---|---|
100-199 | Das ist nicht sehr häufig zu sehen. Es handelt sich um Antworten wie „Ich arbeite, bitte warten“. Das ist die Meldung des Servers, dass er Ihre Anfrage bearbeitet, aber noch nicht fertig ist. |
200-299 | Das ist die Antwort, die uns am besten gefällt! Es bedeutet, dass alles gut gelaufen ist. Die berühmteste ist die 200 OK – ein Zeichen dafür, dass „alles gut gelaufen ist“. Sie haben gefragt, es hat geantwortet. So einfach ist das. |
300-399 | Der Server sagt Ihnen im Grunde: „Ups, Sie sind am falschen Ort, gehen Sie dorthin“. 301 ist eine permanente Umleitung, während 302 eine temporäre Umleitung ist – so etwas wie: „Ich werde gerade renoviert, aber Sie können das vorübergehend hier finden“. |
400-499 | Dies sind die berüchtigten Fehler, die wir als Nutzer oft verursachen. Die bekannteste ist 404 Not Found, wenn die gesuchte Seite einfach nicht existiert. Es ist, als ob man an einer Adresse ankommt und feststellt, dass das Gebäude abgerissen worden ist. |
500-599 | Wenn nun das Problem auf der anderen Seite liegt, wird der Server verantwortlich gemacht. Der berühmte 500 (Internal Server Error) bedeutet, dass der Server die Hände in den Schoß legt und sagt: „Hier ist etwas schief gelaufen“. |
Es gibt mehrere mögliche Codes, ich werde sie nicht alle aufzählen, um den Artikel nicht zu lang werden zu lassen. Wenn Sie mehr über die möglichen Werte erfahren möchten, lesen Sie hier. Dort wird jeder mögliche Code detailliert erklärt, und die Lektüre lohnt sich, wenn Sie mehr über das HTTP-Protokoll erfahren möchten. Im Alltag eines Entwicklers werden nur wenige Codes verwendet, und die meisten von ihnen sind nur selten im Internet zu finden. Ich werde die häufigsten aufzählen:
1xx: Informativ
- 100 Weiter: Der Server hat die Kopfzeilen erhalten, und der Client kann mit dem Senden des Anfragekörpers fortfahren.
- 101 Vermittlungsprotokolle: Der Client beantragte eine Protokolländerung, die der Server akzeptierte.
2xx: Erfolg
- 200 OK: Die Anfrage war erfolgreich.
- 201 Erstellt: Die Anfrage war erfolgreich und eine neue Ressource wurde erstellt. - 204 Kein Inhalt: Die Anfrage war erfolgreich, aber es gibt keinen Inhalt im Hauptteil der Antwort.
3xx: Umleitung
- 301 Dauerhaft verschoben: Die Ressource wurde dauerhaft auf eine neue URL verschoben.
- 302 Gefunden: Die Ressource wurde vorübergehend auf eine neue URL verschoben.
- 304 Nicht geändert: Die Ressource wurde seit der letzten Anfrage nicht geändert, sodass der Client die im Cache gespeicherte Version verwenden kann.
4xx: Client-Fehler
- 400 Schlechte Anfrage: Die Anfrage ist ungültig oder fehlerhaft geformt.
- 401 Nicht autorisiert: Der Zugriff ist nicht autorisiert; eine Authentifizierung ist erforderlich.
- 403 Verboten: Der Server hat die Anfrage verstanden, verweigert aber den Zugriff.
- 404 Nicht gefunden: Die angeforderte Ressource wurde nicht gefunden.
- 405 Nicht erlaubte Methode: Die verwendete HTTP-Methode ist für die angeforderte Ressource nicht zulässig.
5xx: Server-Fehler
- 500 Interner Serverfehler: Auf dem Server ist ein allgemeiner Fehler aufgetreten.
- 502 Schlechtes Gateway: Der Server hat beim Versuch, die Anfrage zu erfüllen, eine ungültige Antwort erhalten.
- 503 Dienst nicht verfügbar: Der Server ist vorübergehend nicht verfügbar, in der Regel aufgrund von Überlastung oder Wartungsarbeiten.
- 504 Gateway-Zeitüberschreitung: Der Server hat nicht rechtzeitig eine Antwort von einem anderen Server erhalten, zu dem er eine Verbindung herstellen wollte.
Nachdem wir nun alle Statuskategorien und die am häufigsten verwendeten Kategorien kennen, möchte ich, dass die Bibliothek alle möglichen Status unterstützt. Dazu arbeiten wir an einer Klasse, die in der Lage ist, jeden vom Server empfangenen Status-Code zu verarbeiten, solange er gültig ist.
Erstellen der Klasse CHttpStatus-Code
Da wir nun alle möglichen Status-Codes kennen, können wir die entsprechende Implementierung in die Bibliothek aufnehmen. Das Ziel ist einfach: Erstellen einer Klasse, die für die Speicherung des empfangenen Status-Codes verantwortlich ist. Die Klasse sollte auch Unterstützung für die Beschreibung jedes Status enthalten und es sollte auch möglich sein, schnell zu erkennen, zu welcher Kategorie dieser Status gehört.
Gehen wir zum Code. In demselben Ordner, der zuvor für die Klasse CHttpMethod erstellt wurde, erstellen wir eine neue Datei namens HttpStatus-Code.mqh . Am Ende wird der vollständige Pfad Includes/Connexus/Constants/HttpStatus-Code.mqh lauten.
//+------------------------------------------------------------------+ //| HttpStatusCode.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| class : CHttpStatusCodes | //| | //| [PROPERTY] | //| Name : CHttpStatusCodes | //| Heritage : No heritage | //| Description : Saved http status code. | //| | //+------------------------------------------------------------------+ class CHttpStatusCodes { public: CHttpStatusCodes(void); ~CHttpStatusCodes(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpStatusCodes::CHttpStatusCodes(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpStatusCodes::~CHttpStatusCodes(void) { } //+------------------------------------------------------------------+
Um alle möglichen Status-Codes zu erfassen, wird ein Enum mit allen möglichen Werten erstellt. Der Name der Enumeration lautet ENUM_HTTP_STATUS, der Wert der Enumeration ist der jeweilige Status-Code.
enum ENUM_HTTP_STATUS { //--- Mql error HTTP_STATUS_URL_NOT_ALLOWED = -1, HTTP_STATUS_URL_NOT_DEFINED = 1, HTTP_STATUS_METHOD_NOT_DEFINED = 2, //--- Informational HTTP_STATUS_CONTINUE = 100, HTTP_STATUS_SWITCHING_PROTOCOLS = 101, HTTP_STATUS_PROCESSING = 102, HTTP_STATUS_EARLY_HINTS = 103, //--- Successul HTTP_STATUS_OK = 200, HTTP_STATUS_CREATED = 201, HTTP_STATUS_ACCEPTED = 202, HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203, HTTP_STATUS_NO_CONTENT = 204, HTTP_STATUS_RESET_CONTENT = 205, HTTP_STATUS_PARTIAL_CONTENT = 206, HTTP_STATUS_MULTI_STATUS = 207, HTTP_STATUS_ALREADY_REPORTED = 208, //--- Redirection messages HTTP_STATUS_MULTIPLE_CHOICES = 300, HTTP_STATUS_MOVED_PERMANENTLY = 301, HTTP_STATUS_FOUND = 302, HTTP_STATUS_SEE_OTHER = 303, HTTP_STATUS_NOT_MODIFIED = 304, HTTP_STATUS_USE_PROXY = 305, HTTP_STATUS_SWITCH_PROXY = 306, HTTP_STATUS_TEMPORARY_REDIRECT = 307, HTTP_STATUS_PERMANENT_REDIRECT = 308, //--- Client error HTTP_STATUS_BAD_REQUEST = 400, HTTP_STATUS_UNAUTHORIZED = 401, HTTP_STATUS_PAYMENT_REQUIRED = 402, HTTP_STATUS_FORBIDDEN = 403, HTTP_STATUS_NOT_FOUND = 404, HTTP_STATUS_METHOD_NOT_ALLOWED = 405, HTTP_STATUS_NOT_ACCEPTABLE = 406, HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, HTTP_STATUS_REQUEST_TIMEOUT = 408, HTTP_STATUS_CONFLICT = 409, HTTP_STATUS_GONE = 410, HTTP_STATUS_LENGTH_REQUIRED = 411, HTTP_STATUS_PRECONDITION_FAILED = 412, HTTP_STATUS_PAYLOAD_TOO_LARGE = 413, HTTP_STATUS_URI_TOO_LONG = 414, HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415, HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416, HTTP_STATUS_EXPECTATION_FAILED = 417, HTTP_STATUS_MISDIRECTED_REQUEST = 421, HTTP_STATUS_UNPROCESSABLE_ENTITY = 422, HTTP_STATUS_LOCKED = 423, HTTP_STATUS_FAILED_DEPENDENCY = 424, HTTP_STATUS_TOO_EARLY = 425, HTTP_STATUS_UPGRADE_REQUIRED = 426, HTTP_STATUS_PRECONDITION_REQUIRED = 428, HTTP_STATUS_TOO_MANY_REQUESTS = 429, HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451, //--- Server error HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, HTTP_STATUS_NOT_IMPLEMENTED = 501, HTTP_STATUS_BAD_GATEWAY = 502, HTTP_STATUS_SERVICE_UNAVAILABLE = 503, HTTP_STATUS_GATEWAY_TIMEOUT = 504, HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505, HTTP_STATUS_VARIANT_ALSO_NEGOTIATES = 506, HTTP_STATUS_INSUFFICIENT_STORAGE = 507, HTTP_STATUS_LOOP_DETECTED = 508, HTTP_STATUS_NOT_EXTENDED = 510, HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511 };
Bitte beachten Sie, dass ich einige Kommentare hinzugefügt habe, die die Kategorien der einzelnen Status trennen. Beachten Sie die ersten Werte der Enumeration, ich habe diese Werte als „nutzerdefinierten Status-Code“ hinzugefügt, der automatisch von der Bibliothek generiert wird, sie sind:
- HTTP_STATUS_URL_NOT_ALLOWED: Die URL wurde nicht in die Liste der zulässigen URLs im Terminal aufgenommen
- HTTP_STATUS_URL_NOT_DEFINED: Die URL wurde in der Anfrage nicht definiert
- HTTP_STATUS_METHOD_NOT_DEFINED: Für die Anfrage wurde keine gültige Methode definiert
Wenn die Funktion WebRequest aufgerufen wird und -1 zurückgibt, bedeutet dies, dass die URL nicht zum Terminal hinzugefügt wird, wie in der MQL5-Dokumentation angegeben, sodass die Bibliothek automatisch HTTP_STATUS_URL_NOT_ALLOWED zurückgeben sollte. Eine ähnliche Logik wird auch auf die anderen nutzerdefinierten Codes angewandt, aber darauf werden wir uns im Moment nicht konzentrieren.
Lassen Sie uns mit der Entwicklung der Klasse fortfahren, diese Klasse wird ähnlich wie CHttpMethod sein, wir werden eine neue private Variable namens m_status vom Typ ENUM_HTTP_STATUS hinzufügen, und wir werden auch einige Hilfsmethoden hinzufügen, um den Wert dieser Variablen zu setzen und zu erhalten:
- die Operatoren =(int) und =(ENUM_HTTP_STATUS): Zum Setzen des Werts von m_status mithilfe des Operators „=“, wobei ein Integer- oder Enum-Wert zugewiesen wird.
- Set(ENUM_HTTP_STATUS): Legt den Status-Code mit einem Enum-Wert fest.
- Get() und GetMessage(): Gibt den aktuellen Status-Code oder nur die dem gespeicherten Code entsprechende Meldung zurück.
Nachfolgend finden Sie den Code mit der Implementierung dieser Methoden:
//+------------------------------------------------------------------+ //| class : CHttpStatusCodes | //| | //| [PROPERTY] | //| Name : CHttpStatusCodes | //| Heritage : No heritage | //| Description : Saved http status code. | //| | //+------------------------------------------------------------------+ class CHttpStatusCodes { private: ENUM_HTTP_STATUS m_status; // Stores the status used public: CHttpStatusCodes(void); ~CHttpStatusCodes(void); //--- Set void operator=(int status); void operator=(ENUM_HTTP_STATUS status); void Set(ENUM_HTTP_STATUS status); //--- Get ENUM_HTTP_STATUS Get(void); string GetMessage(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpStatusCodes::CHttpStatusCodes(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpStatusCodes::~CHttpStatusCodes(void) { } //+------------------------------------------------------------------+ //| Assignment operator to set status from integer value | //+------------------------------------------------------------------+ void CHttpStatusCodes::operator=(int status) { m_status = (ENUM_HTTP_STATUS)status; } //+------------------------------------------------------------------+ //| Assignment operator to set status from ENUM_HTTP_STATUS | //+------------------------------------------------------------------+ void CHttpStatusCodes::operator=(ENUM_HTTP_STATUS status) { m_status = status; } //+------------------------------------------------------------------+ //| Sets the HTTP status code | //+------------------------------------------------------------------+ void CHttpStatusCodes::Set(ENUM_HTTP_STATUS status) { m_status = status; } //+------------------------------------------------------------------+ //| Returns the stored HTTP status code | //+------------------------------------------------------------------+ ENUM_HTTP_STATUS CHttpStatusCodes::Get(void) { return(m_status); } //+------------------------------------------------------------------+ //| Returns a message corresponding to the stored HTTP status code | //+------------------------------------------------------------------+ string CHttpStatusCodes::GetMessage(void) { switch(m_status) { case HTTP_STATUS_URL_NOT_ALLOWED: return "The URL was not added to the list of allowed URLs in the terminal"; case HTTP_STATUS_URL_NOT_DEFINED: return "URL was not defined in the request"; case HTTP_STATUS_METHOD_NOT_DEFINED: return "Method was not defined in the request"; case HTTP_STATUS_CONTINUE: return "Continue"; case HTTP_STATUS_SWITCHING_PROTOCOLS: return "Switching Protocols"; case HTTP_STATUS_PROCESSING: return "Processing"; case HTTP_STATUS_EARLY_HINTS: return "Early Hints"; case HTTP_STATUS_OK: return "OK"; case HTTP_STATUS_CREATED: return "Created"; case HTTP_STATUS_ACCEPTED: return "Accepted"; case HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION: return "Non-Authoritative Information"; case HTTP_STATUS_NO_CONTENT: return "No Content"; case HTTP_STATUS_RESET_CONTENT: return "Reset Content"; case HTTP_STATUS_PARTIAL_CONTENT: return "Partial Content"; case HTTP_STATUS_MULTI_STATUS: return "Multi-Status"; case HTTP_STATUS_ALREADY_REPORTED: return "Already Reported"; case HTTP_STATUS_MULTIPLE_CHOICES: return "Multiple Choices"; case HTTP_STATUS_MOVED_PERMANENTLY: return "Moved Permanently"; case HTTP_STATUS_FOUND: return "Found"; case HTTP_STATUS_SEE_OTHER: return "See Other"; case HTTP_STATUS_NOT_MODIFIED: return "Not Modified"; case HTTP_STATUS_USE_PROXY: return "Use Proxy"; case HTTP_STATUS_SWITCH_PROXY: return "Switch Proxy"; case HTTP_STATUS_TEMPORARY_REDIRECT: return "Temporary Redirect"; case HTTP_STATUS_PERMANENT_REDIRECT: return "Permanent Redirect"; case HTTP_STATUS_BAD_REQUEST: return "Bad Request"; case HTTP_STATUS_UNAUTHORIZED: return "Unauthorized"; case HTTP_STATUS_PAYMENT_REQUIRED: return "Payment Required"; case HTTP_STATUS_FORBIDDEN: return "Forbidden"; case HTTP_STATUS_NOT_FOUND: return "Not Found"; case HTTP_STATUS_METHOD_NOT_ALLOWED: return "Method Not Allowed"; case HTTP_STATUS_NOT_ACCEPTABLE: return "Not Acceptable"; case HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED: return "Proxy Authentication Required"; case HTTP_STATUS_REQUEST_TIMEOUT: return "Request Timeout"; case HTTP_STATUS_CONFLICT: return "Conflict"; case HTTP_STATUS_GONE: return "Gone"; case HTTP_STATUS_LENGTH_REQUIRED: return "Length Required"; case HTTP_STATUS_PRECONDITION_FAILED: return "Precondition Failed"; case HTTP_STATUS_PAYLOAD_TOO_LARGE: return "Payload Too Large"; case HTTP_STATUS_URI_TOO_LONG: return "URI Too Long"; case HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE: return "Unsupported Media Type"; case HTTP_STATUS_RANGE_NOT_SATISFIABLE: return "Range Not Satisfiable"; case HTTP_STATUS_EXPECTATION_FAILED: return "Expectation Failed"; case HTTP_STATUS_MISDIRECTED_REQUEST: return "Misdirected Request"; case HTTP_STATUS_UNPROCESSABLE_ENTITY: return "Unprocessable Entity"; case HTTP_STATUS_LOCKED: return "Locked"; case HTTP_STATUS_FAILED_DEPENDENCY: return "Failed Dependency"; case HTTP_STATUS_TOO_EARLY: return "Too Early"; case HTTP_STATUS_UPGRADE_REQUIRED: return "Upgrade Required"; case HTTP_STATUS_PRECONDITION_REQUIRED: return "Precondition Required"; case HTTP_STATUS_TOO_MANY_REQUESTS: return "Too Many Requests"; case HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE: return "Request Header Fields Too Large"; case HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS: return "Unavailable For Legal Reasons"; case HTTP_STATUS_INTERNAL_SERVER_ERROR: return "Internal Server Error"; case HTTP_STATUS_NOT_IMPLEMENTED: return "Not Implemented"; case HTTP_STATUS_BAD_GATEWAY: return "Bad Gateway"; case HTTP_STATUS_SERVICE_UNAVAILABLE: return "Service Unavailable"; case HTTP_STATUS_GATEWAY_TIMEOUT: return "Gateway Timeout"; case HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED: return "HTTP Version Not Supported"; case HTTP_STATUS_VARIANT_ALSO_NEGOTIATES: return "Variant Also Negotiates"; case HTTP_STATUS_INSUFFICIENT_STORAGE: return "Insufficient Storage"; case HTTP_STATUS_LOOP_DETECTED: return "Loop Detected"; case HTTP_STATUS_NOT_EXTENDED: return "Not Extended"; case HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED: return "Network Authentication Required"; default: return "Unknown HTTP Status"; } } //+------------------------------------------------------------------+
Fügen wir einige weitere Hilfsmethoden hinzu, die dafür verantwortlich sind, zu prüfen, ob der in der Klasse gespeicherte Status-Code zu einer bestimmten Kategorie gehört:
- bool IsInformational(void): Information (100 - 199)
- bool IsSuccess(void): Erfolg (200 - 299)
- bool IsRedirection(void): Umleitung (300 - 399)
- bool IsClientError(void): Client-Fehler (400 - 499)
- bool IsServerError(void): Server-Fehler (500 - 599)
//+------------------------------------------------------------------+ //| class : CHttpStatusCodes | //| | //| [PROPERTY] | //| Name : CHttpStatusCodes | //| Heritage : No heritage | //| Description : Saved http status code. | //| | //+------------------------------------------------------------------+ class CHttpStatusCodes { private: ENUM_HTTP_STATUS m_status; // Stores the status used public: CHttpStatusCodes(void); ~CHttpStatusCodes(void); //--- Check which group the code is in bool IsInformational(void); // Checks if the status code is in the informational response range (100 - 199) bool IsSuccess(void); // Check if the status code is in the success range (200 - 299) bool IsRedirection(void); // Check if the status code is in the redirect range (300 - 399) bool IsClientError(void); // Checks if the status code is in the client error range (400 - 499) bool IsServerError(void); // Check if the status code is in the server error range (500 - 599) }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpStatusCodes::CHttpStatusCodes(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpStatusCodes::~CHttpStatusCodes(void) { } //+------------------------------------------------------------------+ //| Checks if the status code is in the informational response | //| range (100 - 199) | //+------------------------------------------------------------------+ bool CHttpStatusCodes::IsInformational(void) { return(m_status >= 100 && m_status <= 199); } //+------------------------------------------------------------------+ //| Check if the status code is in the success range (200 - 299) | //+------------------------------------------------------------------+ bool CHttpStatusCodes::IsSuccess(void) { return(m_status >= 200 && m_status <= 299); } //+------------------------------------------------------------------+ //| Check if the status code is in the redirect range (300 - 399) | //+------------------------------------------------------------------+ bool CHttpStatusCodes::IsRedirection(void) { return(m_status >= 300 && m_status <= 399); } //+------------------------------------------------------------------+ //| Checks if the status code is in the client error range | //| (400 - 499) | //+------------------------------------------------------------------+ bool CHttpStatusCodes::IsClientError(void) { return(m_status >= 400 && m_status <= 499); } //+------------------------------------------------------------------+ //| Check if the status code is in the server error range (500 - 599)| //+------------------------------------------------------------------+ bool CHttpStatusCodes::IsServerError(void) { return(m_status >= 500 && m_status <= 599); } //+------------------------------------------------------------------+
Schlussfolgerung
Zur besseren Veranschaulichung der Entwicklung der Bibliothek können Sie sich das folgende Diagramm ansehen:
Wir haben alle Hilfsklassen bereit, die für die Behandlung der einzelnen HTTP-Elemente unabhängig voneinander zuständig sind. Wir haben die Klassen CQueryParam , CHttpHeader und CHttpBody, die die Klasse CJson verwenden, aber es gibt keine Vererbungsbeziehung zwischen ihnen. Die in diesem Artikel erstellten Klassen sind noch nicht mit den anderen verbunden, im nächsten Artikel werden wir alles verbinden, indem wir eine HTTP-Anfrage und -Antwort erstellen.
In diesem Artikel lernen wir die HTTP-Methoden und die Status-Codes kennen, zwei sehr wichtige Elemente für die Webkommunikation zwischen Client und Server. Wenn Sie wissen, was die einzelnen Methoden bewirken, können Sie Ihre Anfragen präziser formulieren und dem Server mitteilen, welche Aktion Sie durchführen möchten, um die Effizienz zu steigern. Jede Methode hat eine Aufgabe bei der Kommunikation, und ihre korrekte Anwendung macht die Kommunikation mit der API sowohl für den Client als auch für den Server klarer, ohne Überraschungen.
Darüber hinaus sprechen wir von Status-Codes, die die direkte Antwort des Servers auf die Anfrage darstellen. Diese reichen von einem einfachen „alles gut“ (200 OK) bis hin zu clientseitigen (4xx) oder serverseitigen (5xx) Fehlermeldungen. Das Wissen, wie man mit diesen Codes umgeht, ist eine wertvolle Fähigkeit, denn oft bedeutet ein Fehler nicht das Ende der Fahnenstange, sondern eher eine Gelegenheit, sich anzupassen oder es noch einmal zu versuchen.
Während des Aufbaus der Connexus-Bibliothek haben wir gelernt, wie jedes dieser Elemente zu handhaben ist, was unsere Bibliothek robuster macht und sie in die Lage versetzt, die Feinheiten der HTTP-Kommunikation zu handhaben. Von hier aus wird unsere Klasse, die für die Methoden und Status-Codes verantwortlich ist, bereit sein, dem Entwickler ein höheres Maß an Kontrolle und Sicherheit bei der Interaktion mit APIs zu geben.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/16136
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.





- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.