WebRequest, message body array content

 

Hi, need second opinion about message body as getting error 400 for response (Your client has issued a malformed or illegal request).


Code sample makes first request to Binance API about exchange info with success and second request about history bars fails with error 400, there must be something wrong with message body that is sent and I cannot figure out what is wrong.


Any ideas, please comment.


//+------------------------------------------------------------------+
//|                                               test_websocket.mq5 |
//|                                                  Copyright 2024. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include "config.mqh"
#include "../include/jAson.mqh" // https://www.mql5.com/en/code/13663

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- prepare array
   char res_data[], data[];

//--- exchange info
   Print("[INFO]: get Binance Spot, exchange info.");

   if(!SendWebRequest(__FUNCTION__, 0, "/api/v3/exchangeInfo", data, res_data))
      Print("[ERROR]: fail exchane info request!");
   else
      Print("[INFO]: success exchange info, result data size: " + string(ArraySize(res_data)));

//--- history bars
   Print("[INFO]: get Binance Spot, history bars.");
   ArrayFree(res_data);
   ArrayFree(data);

   // https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data
   string endpoint = "/api/v3/klines";
   string symbol_str ="BTCUSDT";
   string interval_str = "1m";
   int limit_int = 1000;

   string data_str =  StringFormat("{\"symbol\":\"%s\",\"interval\":\"%s\",\"limit\":\"%d\"}", symbol_str, interval_str, limit_int);

   StringToCharArray(data_str, data, 0, WHOLE_ARRAY, CP_UTF8);

   //Print("[INFO]: Request URL: '", REST_URL + endpoint, "'"); >> [INFO]: Request URL: 'https://api-gcp.binance.com/api/v3/klines'
   //Print("[INFO]: Request Data: '", data_str, "'"); >> [INFO]: Request Data: '{"symbol":"BTCUSDT","interval":"1m","limit":"1000"}'
   //Print("[INFO]: Request Data char array: '", CharArrayToString(data), "'"); .> [INFO]: Request Data char array: '{"symbol":"BTCUSDT","interval":"1m","limit":"1000"}'



//   CJAVal jv;
//   jv["symbol"]="BTCUSDT";
//   jv["interval"]="1m";
//   jv["limit"] = 1000;
//
//   ArrayResize(data, StringToCharArray(jv.Serialize(), data, 0, WHOLE_ARRAY)-1);
//   Print("[INFO]: json: ", CharArrayToString(data)); >> [INFO]: json: {"symbol":"BTCUSDT","interval":"1m","limit":1000}



// WORKS IN BROWSER >> https://api-gcp.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1m&limit=1000
   if(!SendWebRequest(__FUNCTION__, 0, endpoint, data, res_data))
      Print("[ERROR]: fail history bars request!");
   else
      Print("[INFO]: result history bar data size: ", string(ArraySize(res_data)));

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Connect to API                                                   |
//+------------------------------------------------------------------+
bool SendWebRequest(string caller_str, int method, string endpoint, char & data[], char & res_data[])
  {
//--- variable used
   int request = -1;

   string server_headers;

//--- request method
   switch(method)
     {
      //--- 'GET' method
      case  0:
         //request = WebRequest("GET", REST_URL + endpoint, BINANCE_HEADERS, NULL, 5000, data, ArraySize(data), res_data, server_headers);
         //request = WebRequest("GET", REST_URL + endpoint, NULL, "Content-Type: text/plain\r\n", 5000, data, ArraySize(data), res_data, server_headers);
         //request = WebRequest("GET", REST_URL + endpoint, BINANCE_HEADERS, "Content-Type: application/json\r\n", 5000, data, ArraySize(data), res_data, server_headers);
         request = WebRequest("GET", REST_URL + endpoint, NULL, NULL, 5000, data, ArraySize(data), res_data, server_headers);
         break;

      //--- 'POST' method
      case  1:
         Print("Webrequest POST method");
         break;

      //--- 'DELETE' method   
      case  2:
         Print("Webrequest DELETE method");
         break;

      //--- failed
      default:
         Print("[ERROR]: Failed to make web request, unknown method:", method, " to endpoint:", endpoint);
         break;
     }

//--- request handling
   if(request != 200)
     {
      Print("[ERROR]: Request failed with error code:");
      Print(server_headers);
      Print(CharArrayToString(res_data));
      return(false);

     }

//--- success execution
   return(true);

  }
//+------------------------------------------------------------------+
 
IsHusky:

Hi, need second opinion about message body as getting error 400 for response (Your client has issued a malformed or illegal request).


Code sample makes first request to Binance API about exchange info with success and second request about history bars fails with error 400, there must be something wrong with message body that is sent and I cannot figure out what is wrong.


Any ideas, please comment.


Seems that GET I can use workaround by sending full request as part of url. Strange but it works

string endpoint = "/api/v3/klines?symbol=BTCUSDT&interval=1m&limit=1000";

request = WebRequest("GET", BINANCE_API + endpoint, NULL, NULL, 5000, data, ArraySize(data), res_data, server_headers);