English Русский Deutsch 日本語
preview
Connexus助手(第五部分):HTTP方法和状态码

Connexus助手(第五部分):HTTP方法和状态码

MetaTrader 5示例 | 11 六月 2025, 07:40
107 0
joaopedrodev
joaopedrodev

概述

本文是该系列文章的延续,我们将构建一个名为Connexus的库。在第一篇文章中,我们了解到WebRequest函数的基本工作原理,理解了其每个参数,并且还创建了一个示例代码,展示了该函数的使用及其困难之处。在上一篇文章中,我们了解到请求是如何工作的、请求体是什么,以及如何向服务器发送数据,最后我们还开发了对附有请求体的请求的支持。

在构建Connexus库的第五篇文章中,我们将探讨HTTP协议的一个重要方面:方法和状态码。了解每种HTTP动词的工作原理以及如何处理状态码,对于创建客户端和服务器之间可靠的交互至关重要。让我们开始吧!


HTTP方法

HTTP方法是我们要求服务器执行的操作。当您发起一个HTTP请求,比如访问一个页面或发送数据时,您实际上是在使用这些动词与服务器进行“交谈”。主要包括:

  • GET:这是经典的“给我那个(资源)”。浏览器请求查看服务器上的某样东西,无论是页面、图片还是文件。它只是获取信息,而不改变任何东西。就像询问餐厅的菜单,只是为了看看有什么供应。
  • POST:POST是那个输送包裹(资源)的人。这里,您正在向服务器发送数据。这在表单中很常见,比如当您在一个网站上注册时。可以想象成您在寄一封信:等待信到达目的地,并在那里做一些事情,例如完成注册。
  • PUT:当您使用PUT时,基本上是在说:“把这里的东西换成这个新版本”。其用于更新现有的资源。就像给您的车换机油——还是同一辆车,但现在有了新的东西。
  • DELETE:很直接,对吧?就是“把那个资源拿走。” 您要求服务器删除某样东西。再见,再也不见。
  • PATCH:PATCH更加精细。它只改变资源的一部分。就像修理玩具的一个坏掉的部分——您不需要改变一切,只需要调整坏掉的部分。
  • HEAD:这是GET,但没有主体。您只需要头部信息,而非主体。就像阅读一本书的标题而不翻开内容页面。

还有其他一些方法,例如CONNECT、OPTIONS和TRACE,但在开发人员的日常工作中很少使用。我在这里不会详细介绍每一种方法,但我希望这个库能够支持所有的HTTP方法。如果您想了解更多关于所有HTTP方法的信息,可以访问完整的协议文档,请点击此处。但相信我,在开发者的日常工作中,最常见的请求类型,如GET、POST和DELETE,足以应对大多数问题。

我想强调的是,每个请求只能使用一种方法,也就是说,一个请求不能同时是GET和POST类型。


创建CHttpMethod类

既然我们已经了解了每种HTTP方法的作用以及何时使用它们,那么让我们直接实现代码。我们将在Connexus中实现一个类,用于存储将用于发起请求的HTTP方法。这将是一个非常简单的类,无论您的编程水平如何,都能理解大部分内容。该类的目的仅仅是存储所使用的方法,但由于是在类中实现,我们会添加更多的功能,以便让Connexus库的最终用户尽可能轻松地使用。

让我们首先创建一个名为Constants的新文件夹,然后在其中创建一个名为CHttpMethod的新文件。最终路径将如下所示:Include/Constants/HttpMethod.mqh。在这个新文件中,我们将创建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)
  {
  }
//+------------------------------------------------------------------+

为了包含所有可能的HTTP方法,让我们创建一个枚举 ,该枚举将包含HTTP请求的所有可能方法。同时,让我们在类中添加一个类型为ENUM_HTTP_METHOD的新变量,命名为m_method:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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
  };
//+------------------------------------------------------------------+

既然已经有了用于存储的变量,接下来让我们创建一些辅助方法来定义和获取HTTP方法,此外还要重载=运算符以简化使用,其主要功能如下:

  • 赋值运算符(operator=):允许您直接使用=运算符来定义HTTP方法。
  • SetMethod(ENUM_HTTP_METHOD) 和SetMethod(string):通过枚举或字符串来定义HTTP方法。当参数为字符串类型时,会使用 StringToUpper()函数来正确格式化字符串。
  • GetMethod() 和GetMethodDescription():获取HTTP方法及其文本描述。 
  • void operator=(ENUM_HTTP_METHOD method):这是一个重载操作,简单来说,它用于使用“=”运算符来定义HTTP方法。以下是该运算符在实际使用中的一个示例:
    CHttpMethod method;
    method = HTTP_METHOD_POST;
  • 验证函数(如 IsPost()、IsGet() 等):它们简化了方法的验证过程,使代码更具可读性和简洁性。以下是这些函数如何帮助我们的一个示例:
    CHttpMethod method;
    method.SetMethod("POST")
    
    if(method.GetMethod() == HTTP_METHOD_POST)
      {
             //--- Action
      }
    //--- Or
    if(method.IsPost())
      {
             //--- Action
      }
    这样一来,我们就可以避免与显式方法比较。
这些方法的实现过程如下:
//+------------------------------------------------------------------+
//| 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);
  }
//+------------------------------------------------------------------+

至此,我们已经完成了负责存储所使用的HTTP方法的类的实现。我们添加了一些辅助函数,以便在之后省去部分代码。接下来,让我们继续讨论下一个辅助类。


状态码

状态码,简单来说,就是数字。该数字已标准化,服务器在处理完请求后会将其发送给客户端。每个状态码都由三位数字组成,第一位数字表示状态所属的类别(1xx、2xx、3xx、4xx 和 5xx)。该状态码简单地告诉您请求的结果是什么,是成功完成、服务器端生成了错误,还是请求发送不正确。状态码有很多种。此数字的范围在100到599之间,它们被分为5个类别。要确定状态码属于哪个类别,只需识别它所在的数值范围即可,请查看包含这些数值的表格:

状态码范围 说明
100-199
这类状态码不太常见。它们通常表示“正在处理,请稍候”之类的响应。这是服务器在告诉您,它正在处理您的请求,但尚未完成。
200-299
啊,这是我们最喜欢的响应!这就意味着一切顺利。最著名的就是200 OK — 表示“一切顺利”。您提出了请求,服务器也成功响应了。就这么简单。
300-399
服务器基本上是在告诉您:“哎呀,您走错地方了,去那儿吧。” 301 Moved Permanently表示永久重定向,而302 Found表示临时重定向——类似于“我正在修整,但您现在可以在这里找到它”。
400-499
这些是我们作为用户经常引起的典型错误。最广为人知的就是404 Not Found,当您请求的页面根本不存在时,就会出现这个错误。这就像您到达了一个地方,却发现想去的那栋建筑已经被拆除了。
500-599
现在,当问题出在另一侧时,责任就落在了服务器上。流性的500 Internal Server Error基本上就是服务器举手投降,说“这里出错了”。

状态码有多种可能,为了不让文章过于冗长,我不会一一列举。如果您想了解所有可能的值,请点击此处阅读,它详细解释了每个可能的状态码,如果你想深入了解HTTP协议,这篇文章值得一读。在开发人员的日常工作中,只会用到少数几个状态码,而且其中大部分在网络上并不常见。我将列出最常见的状态码:

1xx:信息性状态码

  • 100Continue(继续):服务器已收到请求头,客户端可以继续发送请求体。
  • 101Switching Protocols(切换协议):客户端请求更改协议,服务器已接受。

2xx:成功状态码

  • 200OK:请求已成功。
  • 201Created(已创建):请求已成功,并创建了新资源。- 204 No Content(无内容) :请求已成功,但响应体中的内容为空。

3xx:重定向状态码

  • 301Moved Permanently(永久移出):资源已被永久移动到新的URL。
  • 302Found(已找到):资源已被临时移动到新的URL。
  • 304Not Modified(未修改):资源自上次请求以来未被修改,允许客户端使用缓存版本。

4xx:客户端错误状态码

  • 400Bad Request(错误请求):请求无效或格式错误。
  • 401Unauthorized(未授权):访问未授权;需要身份验证。
  • 403Forbidden(禁止访问):服务器理解了请求,但拒绝被访问。
  • 404Not Found(未找到):未找到请求的资源。
  • 405Method Not Allowed(方法不被允许):对请求的资源不允许使用该HTTP方法。

5xx:服务器错误状态码

  • 500Internal Server Error(内部服务器错误):服务器上发生了通用错误。
  • 502Bad Gateway(错误网关):服务器在尝试履行请求时收到了无效响应。
  • 503Service Unavailable(服务不可用):服务器暂时不可用,通常是由于过载或维护。
  • 504Gateway Timeout(网关超时):服务器未及时从它尝试连接的另一台服务器上收到响应。

既然我们已经了解到所有状态类别以及最常用的状态码,那么我希望这个库能够支持所有可能的状态码。为此,我们将开发一个能够处理服务器返回的任何有效状态码的类。


创建CHttpStatusCode类

既然我们已经了解到所有可能的状态码,让我们将相应的实现添加到库中。这里的目标很简单:创建一个类,用于存储接收到的状态码。该类还应包含对每个状态码的描述支持,并且应该能够快速识别该状态码属于哪个类别。

让我们开始编写代码。在之前为CHttpMethod类创建的同一个文件夹中,我们将创建一个名为HttpStatusCode.mqh的新文件。最终,完整的路径将是Includes/Connexus/Constants/HttpStatusCode.mqh。

//+------------------------------------------------------------------+
//|                                               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)
  {
  }
//+------------------------------------------------------------------+

为了包含所有可能的状态码,我们将创建一个枚举,其中包含所有可能的值。该枚举的名称将是 ENUM_HTTP_STATUS,枚举值是对应的状态码。

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
  };

请注意,我添加了一些注释来分隔不同类别的状态码。观察枚举的第一个值,我添加了这些值作为“自定义状态码”,它们将由库自动生成,这些自定义状态码包括:

  • HTTP_STATUS_URL_NOT_ALLOWED:终端中未将该URL添加到允许的URL列表中
  • HTTP_STATUS_URL_NOT_DEFINED:请求中未定义该URL
  • HTTP_STATUS_METHOD_NOT_DEFINED:未给请求定义有效的方法

当调用WebRequest函数并返回-1时,根据MQL5文档的说明,意味着该URL未添加到终端中,因此库应自动返回HTTP_STATUS_URL_NOT_ALLOWED。类似的逻辑将应用于其他自定义状态码,但目前我们不会深入讨论这一点。

让我们继续开发这个类,其类似于CHttpMethod 类。我们将添加一个新的私有变量m_status,其类型为ENUM_HTTP_STATUS,并且还将添加一些辅助方法来设置和获取该变量的值:

  • operator=(int) 和 operator=(ENUM_HTTP_STATUS):使用 = 运算符设置 m_status 的值,可以接收一个整数值或一个枚举值。
  • Set(ENUM_HTTP_STATUS):使用枚举值设置状态码。
  • Get() 和 GetMessage() :返回当前的状态码或仅返回与存储的状态码对应的消息。

以下是实现这些方法的代码:

//+------------------------------------------------------------------+
//| 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";
     }
  }
//+------------------------------------------------------------------+

让我们再添加一些辅助方法,这些方法将负责检查类中存储的状态码是否属于特定的类别,方法包括:

  • bool IsInformational(void):检查状态码是否属于信息性类别(范围 100 - 199)
  • bool IsSuccess(void):检查状态码是否属于成功类别(范围 200 - 299)
  • bool IsRedirection(void):检查状态码是否属于重定向类别(范围 300 - 399)
  • bool IsClientError(void):检查状态码是否属于客户端错误类别(范围 400 - 499)
  • bool IsServerError(void):检查状态码是否属于服务器错误类别(范围 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);
  }
//+------------------------------------------------------------------+


结论

为了让库的开发进度更加直观,请参考以下图表:

图表

我们已经准备好了所有辅助类,这些类负责独立处理每个HTTP元素。我们拥有CQueryParam、CHttpHeader和CHttpBody类,它们都使用了CJson 类,但它们之间不存在继承关系。本文中创建的类尚未与其他类建立连接,在下一篇文章中,我们将通过创建一个HTTP请求和响应来将所有内容连接起来。

在本文中,我们了解到HTTP方法和状态码,这两者在客户端和服务器之间的网络通信中至关重要。了解每种方法的作用,可以让您更精确地发出请求,告知服务器您想要执行的操作,从而提高效率。每种方法在通信中都有其作用,正确使用这些方法可以使客户端和服务器之间的 API 通信更加清晰,避免出现意外情况。

此外,我们还讨论了状态码,这些状态码是服务器对请求处理结果的直接响应。从简单的“一切正常”(200 OK)到客户端错误(4xx)或服务器错误(5xx)消息不等。了解如何处理这些状态码是一项宝贵的技能,因为错误往往并不意味着结束,而是提供了调整或重试的机会。

在构建Connexus库的过程中,我们学习了如何处理这些元素,这使我们的库更加健壮,能够处理HTTP通信中的细微差别。从这里开始,我们负责处理方法和状态码的类将为开发人员在与 API 交互时提供更高水平的控制和安全性。

本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/16136

在 MQL5 中创建交易管理员面板(第五部分):双因素认证(2FA) 在 MQL5 中创建交易管理员面板(第五部分):双因素认证(2FA)
今天,我们将讨论如何增强当前正在开发的交易管理员面板的安全性。我们将探讨如何在新的安全策略中实施 MQL5,并将 Telegram API 集成到双因素认证(2FA)中。本次讨论将提供有关 MQL5 在加强安全措施方面的应用的宝贵见解。此外,我们还将研究 MathRand 函数,重点关注其功能以及如何在我们构建的安全框架中有效利用它。继续阅读以了解更多信息!
交易中的神经网络:探索局部数据结构 交易中的神经网络:探索局部数据结构
在嘈杂的条件下有效识别和预存市场数据的局部结构是交易中的一项关键任务。运用自注意力机制在处理这类数据方面展现出可喜的结果;不过,经典方式并未考虑底层结构的局部特征。在本文中,我将引入一种能够协同这些结构依赖关系的算法。
创建 MQL5-Telegram 集成 EA 交易(第 6 部分):添加响应式内联按钮 创建 MQL5-Telegram 集成 EA 交易(第 6 部分):添加响应式内联按钮
在本文中,我们将交互式内联按钮集成到 MQL5 EA 交易中,允许通过 Telegram 进行实时控制。每次按下按钮都会触发特定的操作,并将响应发送回用户。我们还模块化了函数,以便有效地处理 Telegram 消息和回调查询。
交易中的神经网络:场景感知物体检测(HyperDet3D) 交易中的神经网络:场景感知物体检测(HyperDet3D)
我们邀请您来领略一种利用超网络检测物体的新方式。超网络针对主模型生成权重,允许参考具体的当前市场形势。这种方式令我们能够通过令模型适配不同的交易条件来提升预测准确性。