//+------------------------------------------------------------------+ //| 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 inputs | //+------------------------------------------------------------------+ input string InpMethod ="GET"; // Method (HEAD,GET) input string InpServer ="www.google.com"; // Server input uint InpPort =443; // Port input uint InpTimeout=5000; // Timeouts //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart(void) { Print("Server: ",InpServer); Print("Port: ",InpPort); //--- crée une socket et récupère son handle const int socket=SocketCreate(); if(socket==INVALID_HANDLE) { Print("SocketCreate() failed. Error ",GetLastError()); return; } //--- définit les délais d'attente pour la réception et l'envoi de données pour un objet système socket if(!SocketTimeouts(socket,InpTimeout,InpTimeout)) { PrintFormat("SocketTimeouts(%u, %u) failed. Error %d",InpTimeout,InpTimeout,GetLastError()); SocketClose(socket); return; } //--- se connecte à SERVER via le port PORT if(!SocketConnect(socket,InpServer,InpPort,InpTimeout)) { PrintFormat("SocketConnect('%s', %u, %u) failed. Error %d",InpServer,InpPort,InpTimeout,GetLastError()); SocketClose(socket); return; } //--- récupère les données sur le certificat utilisé pour sécuriser la connexion réseau 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 { //--- le serveur ne fournit pas de certificat : signale une connexion non sécurisée et fin Print("The connection is not secured by a certificate"); SocketClose(socket); return; } //--- envoie une requête au serveur 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)) { //--- demande envoyée - récupère la réponse Print("\nRequest sent. Starting page loading..."); uchar response[]; // all received data (document header and body) if(!HTTPRecvTLS(socket,response,InpTimeout)) { Print("There were errors while reading the page"); SocketClose(socket); return; } //--- indique le nombre d'octets de données reçus PrintFormat("%u bytes received",response.Size()); //--- affiche uniquement l'en-tête de la page obtenue 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)); } } //--- ferme la socket après son utilisation SocketClose(socket); /* résultat : 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 */ } //+------------------------------------------------------------------+ //| Envoie une requête HTTP via une connexion sécurisée | //+------------------------------------------------------------------+ bool HTTPSendTLS(int socket,const string request) { //--- convertit la chaîne en un tableau de caractères, ignore le zéro de fin char req[]; int len=StringToCharArray(request,req,0,WHOLE_ARRAY,CP_UTF8)-1; if(len<0) return false; return(SocketTlsSend(socket,req,len)==len); } //+------------------------------------------------------------------+ //| Récupère une page web page via une connexion sécurisée | //+------------------------------------------------------------------+ bool HTTPRecvTLS(int socket,uchar &response[],const uint timeout_ms) { //--- lit les données disponibles à partir d'une connexion TLS sécurisée avant l'expiration du délai d'attente ulong timeout_check=GetTickCount64()+timeout_ms; uchar block[1024]; // buffer for block data reading from socket uint attempt=0; // requested number of data blocks int err =0; // error code ResetLastError(); do { //--- lecture par blocs, maximum 1024 octets int len=SocketTlsReadAvailable(socket,block,1024); if(len>0) { attempt++; //--- fusionne les blocs de données obtenus ArrayCopy(response,block,response.Size()); //--- analyse les données obtenues, définit l'en-tête, le corps de la page, la fin ou l'erreur de chargement, etc. //... //... //... timeout_check=GetTickCount64()+timeout_ms; } else Sleep(10); err=GetLastError(); } while(!IsStopped() && GetTickCount()<timeout_check && !err); //--- y a-t-il eu des erreurs lors de la lecture ? if(err) { Print("Error ",err); return(false); } PrintFormat("%s: Document received within %d attempts",__FUNCTION__,attempt); return(true); } |