//+------------------------------------------------------------------+
//| SocketTlsReadAvailable.mq5 |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link "https://www.mql5.com
#property version "1.00"
#property script_show_inputs
//+------------------------------------------------------------------+
//| Script Eingaben |
//+------------------------------------------------------------------+
input string InpMethod ="GET"; // Method (HEAD,GET)
input string InpServer ="www.google.com"; // Server
input uint InpPort =443; // Port
input uint InpTimeout=5000; // Timeouts
//+------------------------------------------------------------------+
//| Skript Programm Start Funktion |
//+------------------------------------------------------------------+
void OnStart(void)
{
Print("Server: ",InpServer);
Print("Port: ",InpPort);
//--- Socket erstellen und sein Handle zuweisen
const int socket=SocketCreate();
if(socket==INVALID_HANDLE)
{
Print("SocketCreate() failed. Error ",GetLastError());
return;
}
//--- Festlegen der Timeouts für den Empfang und das Senden von Daten eines Socket-Systemobjekts
if(!SocketTimeouts(socket,InpTimeout,InpTimeout))
{
PrintFormat("SocketTimeouts(%u, %u) failed. Error %d",InpTimeout,InpTimeout,GetLastError());
SocketClose(socket);
return;
}
//--- connect to Server via Port
if(!SocketConnect(socket,InpServer,InpPort,InpTimeout))
{
PrintFormat("SocketConnect('%s', %u, %u) failed. Error %d",InpServer,InpPort,InpTimeout,GetLastError());
SocketClose(socket);
return;
}
//--- Daten über das zur Sicherung der Netzwerkverbindung verwendete Zertifikat abrufen
string subject,issuer,serial,thumbprint;
datetime expiration;
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
}
else
{
//--- der Server stellt kein Zertifikat bereit - eine ungesicherte Verbindung melden und verlassen
Print("The connection is not secured by a certificate");
SocketClose(socket);
return;
}
//--- Senden einer Anfrage an den Server
string request=StringFormat("%s / HTTP/1.1\r\nHost: %s\r\nUser-Agent: MetaTrader 5\r\n\r\n",InpMethod,InpServer);
if(HTTPSendTLS(socket,request))
{
//--- Request gesendet - Response erhalten
Print("\nRequest sent. Starting page loading...");
uchar response[]; // alle erhaltenen Daten (Header und Haupteil des Dokuments)
if(!HTTPRecvTLS(socket,response,InpTimeout))
{
Print("There were errors while reading the page");
SocketClose(socket);
return;
}
//--- Ausgabe der Anzahl der empfangenen Datenbytes
PrintFormat("%u bytes received",response.Size());
//--- Ausgabe nur des Headers der erhaltenen Seite
string result =CharArrayToString(response,0,WHOLE_ARRAY,CP_UTF8);
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("\nHTTP answer header received:");
Print(StringSubstr(result,0,header_end));
}
}
//--- Schließen des Sockets nach Gebrauch
SocketClose(socket);
/*
Ergebnis:
Server: www.google.com
Port: 443
TLS certificate:
Owner: /CN=www.google.com
Issuer: /C=US/O=Google Trust Services/CN=WR2
Number: 0d:43:b1:4a:bb:9c:15:96:10:e1:3d:55:23:9f:25:4e
Print: 89167618e5017f813aff981c88ce422dc1016bdf
Expiration: 2024.12.30 08:26:35
Request sent. Starting page loading...
HTTPRecvTLS: Document received within 27 attempts
25185 bytes received
HTTP answer header received:
HTTP/1.1 200 OK
Date: Fri, 25 Oct 2024 17:12:42 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-CUL2rdUOeAN7xIV6v0WUuQ' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
Accept-CH: Sec-CH-Prefers-Color-Scheme
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Set-Cookie: AEC=AVYB7coyYMCdweTDTaWeGYzmRnxzKGqsOEosH_VkbCn8xhWkFz6v0kxQFw; expires=Wed, 23-Apr-2025 17:12:42 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
Set-Cookie: NID=518=J02X02Ff4v_9sMcNoUz-1SolmuG08E26Gs438ik0J_SOJUMy7of-P-qup-LaNSWVXUL8OjhOXpGIGuJQGIoEPBnzqDKCH-46_FN4J2foHeWTlGG8bVVvQ44AHWLg1OXjrGp3CUBexYdczLWNy3LxEcb7eh6mxSvFzOelPC6-vpXkaumLQ80x9gF_RpLcAYfN4ehT; expires=Sat, 26-Apr-2025 17:12:42 GMT; path=/; domain=.google.com; HttpOnly
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Accept-Ranges: none
Vary: Accept-Encoding
Transfer-Encoding: chunked
*/
}
//+------------------------------------------------------------------+
//| Senden einer HTTP-Anfrage über eine sichere Verbindung |
//+------------------------------------------------------------------+
bool HTTPSendTLS(int socket,const string request)
{
//--- Umwandeln der Zeichenkette in ein Zeichenarray mit dem Löschen der abschließenden Null
char req[];
int len=StringToCharArray(request,req,0,WHOLE_ARRAY,CP_UTF8)-1;
if(len<0)
return false;
return(SocketTlsSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Abrufen einer Web-Seite über eine sichere Verbindung |
//+------------------------------------------------------------------+
bool HTTPRecvTLS(int socket,uchar &response[],const uint timeout_ms)
{
//--- Lesen der verfügbaren Daten einer sicheren TLS-Verbindung, bevor die Zeitüberschreitung abläuft
ulong timeout_check=GetTickCount64()+timeout_ms;
uchar block[1024]; // Puffer für den Datenblock, gelesen vom Soket
uint attempt=0; // Angeforderte Anzahl von Datenblocks
int err =0; // Fehlernummer
ResetLastError();
do
{
//--- Lesen der Blöcke, maximal 1024 Bytes
int len=SocketTlsReadAvailable(socket,block,1024);
if(len>0)
{
attempt++;
//--- Zusammenführen der erhaltenen Datenblöcke
ArrayCopy(response,block,response.Size());
//--- Auswerten der erhaltenen Daten, Bestimmen des Headers, dem Hauptteil der Seite, das Ende oder die Fehlernummer, etc.
//...
//...
//...
timeout_check=GetTickCount64()+timeout_ms;
}
else
Sleep(10);
err=GetLastError();
}
while(!IsStopped() && GetTickCount()<timeout_check && !err);
//--- Gab es irgendwelche Fehler während des Lesens?
if(err)
{
Print("Error ",err);
return(false);
}
PrintFormat("%s: Document received within %d attempts",__FUNCTION__,attempt);
return(true);
}
|