112 lines
4.4 KiB
MQL5
112 lines
4.4 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| WebRequestAuth.mq5 |
|
||
|
//| Copyright 2022, MetaQuotes Ltd. |
|
||
|
//| https://www.mql5.com |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#property description "Request Digest authorization on a protected web-page."
|
||
|
#property description "NB: Default 'Address' requires to allow 'httpbin.org' in terminal settings - to use other addresses, change settings accordingly."
|
||
|
#property script_show_inputs
|
||
|
|
||
|
#include "..\..\Include\PRTF.mqh"
|
||
|
#include "..\..\Include\StringUtils.mqh"
|
||
|
#include "..\..\Include\URL.mqh"
|
||
|
#include "..\..\Include\HTTPHeader.mqh"
|
||
|
|
||
|
const string Method = "GET";
|
||
|
input string Address = "https://httpbin.org/digest-auth/auth/test/pass";
|
||
|
input string Headers = "User-Agent: noname";
|
||
|
input int Timeout = 5000;
|
||
|
input string User = "test";
|
||
|
input string Password = "pass";
|
||
|
input bool DumpDataToFiles = true;
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Script program start function |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void OnStart()
|
||
|
{
|
||
|
string parts[];
|
||
|
URL::parse(Address, parts);
|
||
|
|
||
|
uchar data[], result[];
|
||
|
string response;
|
||
|
int code = PRTF(WebRequest(Method, Address, Headers, Timeout, data, result, response));
|
||
|
Print(response);
|
||
|
if(code == 401)
|
||
|
{
|
||
|
if(StringLen(User) == 0 || StringLen(Password) == 0)
|
||
|
{
|
||
|
Print("Credentials required");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
code = -1;
|
||
|
HttpHeader header(response, '\n', ':');
|
||
|
const string auth = header["WWW-Authenticate"];
|
||
|
if(StringFind(auth, "Basic ") == 0)
|
||
|
{
|
||
|
string Header = Headers;
|
||
|
if(StringLen(Header) > 0) Header += "\r\n";
|
||
|
Header += "Authorization: Basic ";
|
||
|
Header += HttpHeader::hash(User + ":" + Password, CRYPT_BASE64);
|
||
|
PRTF(Header);
|
||
|
code = PRTF(WebRequest(Method, Address, Header, Timeout, data, result, response));
|
||
|
Print(response);
|
||
|
}
|
||
|
else if(StringFind(auth, "Digest ") == 0)
|
||
|
{
|
||
|
HttpHeader params(StringSubstr(auth, 7), ',', '=');
|
||
|
string realm = HttpHeader::unquote(params["realm"]);
|
||
|
if(realm != NULL)
|
||
|
{
|
||
|
string qop = HttpHeader::unquote(params["qop"]);
|
||
|
if(qop == "auth")
|
||
|
{
|
||
|
string h1 = HttpHeader::hash(User + ":" + realm + ":" + Password);
|
||
|
string h2 = HttpHeader::hash(Method + ":" + parts[URL_PATH]);
|
||
|
string nonce = HttpHeader::unquote(params["nonce"]);
|
||
|
string counter = StringFormat("%08x", 1);
|
||
|
string cnonce = StringFormat("%08x", MathRand());
|
||
|
string h3 = HttpHeader::hash(h1 + ":" + nonce + ":" + counter + ":" + cnonce + ":" + qop + ":" + h2);
|
||
|
|
||
|
string Header = Headers;
|
||
|
if(StringLen(Header) > 0) Header += "\r\n";
|
||
|
Header += "Authorization: Digest ";
|
||
|
Header += "username=\"" + User + "\",";
|
||
|
Header += "realm=\"" + realm + "\",";
|
||
|
Header += "nonce=\"" + nonce + "\",";
|
||
|
Header += "uri=\"" + parts[URL_PATH] + "\",";
|
||
|
Header += "qop=" + qop + ",";
|
||
|
Header += "nc=" + counter + ",";
|
||
|
Header += "cnonce=\"" + cnonce + "\",";
|
||
|
Header += "response=\"" + h3 + "\",";
|
||
|
Header += "opaque=" + params["opaque"] + "";
|
||
|
PRTF(Header);
|
||
|
code = PRTF(WebRequest(Method, Address, Header, Timeout, data, result, response));
|
||
|
Print(response);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(code > -1)
|
||
|
{
|
||
|
if(ArraySize(result) > 0)
|
||
|
{
|
||
|
PrintFormat("Got data: %d bytes", ArraySize(result));
|
||
|
if(DumpDataToFiles)
|
||
|
{
|
||
|
const string filename = parts[URL_HOST] +
|
||
|
(StringLen(parts[URL_PATH]) > 1 ? parts[URL_PATH] : "/_index_.htm");
|
||
|
Print("Saving ", filename);
|
||
|
PRTF(FileSave(filename, result));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Print(CharArrayToString(result, 0, 80, CP_UTF8));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|