MQL5Book/Scripts/p7/SocketReadWriteHTTP.mq5

120 lines
4.1 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:09:41 +02:00
//+------------------------------------------------------------------+
//| SocketReadWriteHTTP.mq5 |
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property description "Requests a header (meta-data) of a web-page (insecure HTTP)."
#property description "NB: Default 'Server' requires to allow 'www.mql5.com' in terminal settings - to use other servers, change the settings accordingly."
#property script_show_inputs
#include "..\..\Include\PRTF.mqh"
input string Server = "www.mql5.com";
input uint Port = 80;
//+------------------------------------------------------------------+
//| Send HTTP-request via socket (insecure connection) |
//+------------------------------------------------------------------+
bool HTTPSend(int socket, const string request)
{
char req[];
int len = StringToCharArray(request, req, 0, WHOLE_ARRAY, CP_UTF8) - 1;
if(len < 0) return false;
return SocketSend(socket, req, len) == len;
}
//+------------------------------------------------------------------+
//| Receive HTTP-response via socket (insecure connection) |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket, string &result, const uint timeout)
{
uchar response[];
int len; // must be signed int to keep -1 in case of error
uint start = GetTickCount();
result = "";
do
{
ResetLastError();
if(!(len = (int)SocketIsReadable(socket)))
{
Sleep(10); // wait for data or timeout
}
else
if((len = SocketRead(socket, response, len, 10)) > 0)
{
result += CharArrayToString(response, 0, len); // NB: no CP_UTF8 because of 'HEAD'er
const int p = StringFind(result, "\r\n\r\n");
if(p > 0)
{
// HTTP header ends with double "new line", so using this parsing
// we make sure entire header received
Print("HTTP-header found");
StringSetLength(result, p); // cut off document body
return true;
}
start = GetTickCount();
}
}
while(GetTickCount() - start < timeout && !IsStopped() && !_LastError);
if(_LastError) PRTF(_LastError);
return StringLen(result) > 0;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
PRTF(Server);
PRTF(Port);
const int socket = PRTF(SocketCreate());
if(socket == INVALID_HANDLE) return;
if(PRTF(SocketConnect(socket, Server, Port, 5000)))
{
if(PRTF(HTTPSend(socket, StringFormat(
"HEAD / HTTP/1.1\r\nHost: %s\r\nUser-Agent: MetaTrader 5\r\n\r\n",
Server))))
{
string response;
if(PRTF(HTTPRecv(socket, response, 5000)))
{
// may be usefull to track 'Content-Length:',
// 'Content-Language:', 'Last-Modified:'
// and other attributes in the header
Print(response);
}
}
}
SocketClose(socket);
}
//+------------------------------------------------------------------+
/*
Example:
Server=www.mql5.com / ok
Port=80 / ok
SocketCreate()=1 / ok
SocketConnect(socket,Server,Port,5000)=true / ok
HTTPSend(socket,StringFormat(HEAD / HTTP/1.1
Host: %s
,Server))=true / ok
HTTP-header found
HTTPRecv(socket,response,5000)=true / ok
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sun, 31 Jul 2022 10:24:00 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://www.mql5.com/
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Frame-Options: SAMEORIGIN
*/
//+------------------------------------------------------------------+