25 #if defined(MRPT_OS_LINUX) || defined(__APPLE__)    26 #define INVALID_SOCKET (-1)    27 #include <arpa/inet.h>    30 #include <netinet/in.h>    31 #include <sys/ioctl.h>    32 #include <sys/socket.h>    33 #include <sys/types.h>    52     const string& 
url, 
string& out_content, 
string& out_errormsg, 
int port,
    53     const string& auth_user, 
const string& auth_pass,
    54     int* out_http_responsecode,
    58     std::vector<uint8_t> 
data;
    60         url, 
data, out_errormsg, port, auth_user, auth_pass,
    61         out_http_responsecode, extra_headers, out_headers, timeout_ms);
    63     out_content.resize(
data.size());
    70     const string& http_method, 
const string& http_send_content,
    71     const string& 
url, std::vector<uint8_t>& out_content, 
string& out_errormsg,
    72     int port, 
const string& auth_user, 
const string& auth_pass,
    73     int* out_http_responsecode,
    79     if (out_http_responsecode) *out_http_responsecode = 0;
    80     if (out_headers) out_headers->
clear();
    85     if (0 != ::strncmp(
url.c_str(), 
"http://", 7))
    87         out_errormsg = 
"URL must start with 'http://'";
    91     string server_addr = 
url.substr(7);
    92     string get_object = 
"/";
    95     size_t pos = server_addr.find(
"/");
    98         out_errormsg = 
"Server name not found in URL";
   101     if (pos != string::npos)
   103         get_object = server_addr.substr(pos);
   104         server_addr.resize(pos);
   112         sock.
connect(server_addr, port, timeout_ms);
   114     catch (
const std::exception& e)
   116         out_errormsg = e.what();
   124         if (extra_headers) headers_to_send = *extra_headers;
   126         headers_to_send[
"Connection"] = 
"close";  
   128         if (!headers_to_send.
has(
"User-Agent"))
   129             headers_to_send[
"User-Agent"] = 
"MRPT Library";
   133         if (!auth_user.empty())
   135             string auth_str = auth_user + string(
":") + auth_pass;
   136             std::vector<uint8_t> v(auth_str.size());
   142             headers_to_send[
"Authorization"] = string(
"Basic ") + encoded_str;
   145         if (!http_send_content.empty() &&
   146             headers_to_send.
find(
"Content-Length") == headers_to_send.
end())
   148             headers_to_send[
"Content-Length"] =
   149                 mrpt::format(
"%u", (
unsigned int)http_send_content.size());
   157             http_method.c_str(), get_object.c_str(), server_addr.c_str());
   160         for (
auto i = headers_to_send.
begin(); i != headers_to_send.
end(); ++i)
   172         req += http_send_content;
   178         std::vector<uint8_t> buf;
   179         buf.reserve(1 << 14);
   181         size_t total_read = 0;
   182         bool content_length_read = 
false;
   183         bool all_headers_read = 
false;
   184         size_t content_length = 0;
   185         size_t content_offset = 0;
   192         while (!content_length_read ||
   193                total_read < (content_offset + content_length))
   200             if (!content_length_read)
   206                 to_read_now = (content_length + content_offset) - total_read;
   210             buf.resize(total_read + to_read_now + 1);
   214                 sock.
readAsync(&buf[total_read], to_read_now, timeout_ms, 100);
   220                     if (all_headers_read)  
   224                         out_errormsg = 
"Connection to server was lost";
   229                 if (watchdog.
Tac() > 1e-3 * timeout_ms)
   231                     out_errormsg = 
"Timeout waiting answer from server";
   234                 std::this_thread::sleep_for(10ms);
   240             buf[total_read] = 
'\0';
   243             if (!all_headers_read)
   245                 const char* ptr = ::strstr(
   246                     reinterpret_cast<const char*>(&buf[0]), 
"\r\n\r\n");
   249                     all_headers_read = 
true;
   250                     const size_t pos_dblret = ((
char*)ptr) - (
char*)(&buf[0]);
   254                     if (!::strncmp(
"HTTP/", (
const char*)&buf[0], 5))
   256                         http_code = ::atoi((
const char*)&buf[9]);
   263                                 "SOURCETABLE ", (
const char*)&buf[0], 12))
   265                             http_code = ::atoi((
const char*)&buf[12]);
   270                                 "Server didn't send an HTTP/1.1 answer.";
   276                     content_offset = pos_dblret + 4;
   279                     const char* ptr_len = ::strstr(
   280                         reinterpret_cast<const char*>(&buf[0]),
   284                         content_length = ::atol(ptr_len + 15);
   285                         content_length_read = 
true;
   290                         string aux_all_headers;
   291                         deque<string> lstLines;
   292                         aux_all_headers.resize(content_offset);
   294                             &aux_all_headers[0], &buf[0], content_offset);
   297                             aux_all_headers, 
"\r\n", lstLines);
   299                         for (
auto i = lstLines.begin(); i != lstLines.end();
   302                             const size_t p = i->find(
":");
   303                             if (p == string::npos) 
continue;
   305                             const string key = i->substr(0, p);
   306                             const string val = i->substr(p + 2);
   307                             rx_headers[key] = 
val;
   314         if (out_http_responsecode) *out_http_responsecode = http_code;
   315         if (out_headers) *out_headers = rx_headers;
   318         buf.erase(buf.begin(), buf.begin() + content_offset);
   321         if (rx_headers.
has(
"Transfer-Encoding") &&
   322             rx_headers[
"Transfer-Encoding"] == 
"chunked")
   327             while (index < buf.size())
   329                 if (buf[index] == 
'\r' && buf[index + 1] == 
'\n')
   331                     buf.erase(buf.begin() + index, buf.begin() + index + 2);
   335                 const char* pCRLF = ::strstr((
const char*)&buf[index], 
"\r\n");
   338                 const size_t len_substr = ((
char*)pCRLF) - (
char*)(&buf[index]);
   340                 string sLen((
const char*)&buf[index], len_substr);
   341                 sLen = string(
"0x") + sLen;
   343                 unsigned int lenChunk;
   344                 int fields = ::sscanf(sLen.c_str(), 
"%x", &lenChunk);
   349                     buf.begin() + index, buf.begin() + index + len_substr + 2);
   362         out_content.swap(buf);
   364         if (http_code == 200)
   370             out_errormsg = 
format(
"HTTP error %i", http_code);
   374     catch (
const std::exception& e)
   376         out_errormsg = e.what();
   387     const string& 
url, std::vector<uint8_t>& out_content, 
string& out_errormsg,
   388     int port, 
const string& auth_user, 
const string& auth_pass,
   389     int* out_http_responsecode,
   394         "GET", 
"", 
url, out_content, out_errormsg, port, auth_user, auth_pass,
   395         out_http_responsecode, extra_headers, out_headers, timeout_ms);
   405     const std::string& server_name, std::string& out_ip,
   406     const unsigned int timeout_ms)
   409     if (server_name.find_first_not_of(
"0123456789. ") == std::string::npos)
   412         out_ip = server_name;
   420     std::future<std::string> dns_result_fut =
   421         std::async(std::launch::async, [&]() {
   426                 WORD wVersionRequested = MAKEWORD(2, 0);
   428                 if (WSAStartup(wVersionRequested, &wsaData))
   431                         << 
"thread_DNS_solver_async: Error calling WSAStartup";
   432                     return std::string();
   438             std::string dns_result;
   440             hostent* he = gethostbyname(server_name.c_str());
   452                 dns_result = string(inet_ntoa(ADDR));
   462         dns_result_fut.wait_for(std::chrono::milliseconds(timeout_ms));
   464     if (status == std::future_status::ready)
   467         out_ip = dns_result_fut.get();
   468         return !out_ip.empty();
   483     const int errnum = WSAGetLastError();
   486         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
   487             FORMAT_MESSAGE_IGNORE_INSERTS,
   488         nullptr, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&s,
   490     const std::string str = 
mrpt::format(
"%s [errno=%d]", s, errnum);
   494     return std::string(strerror(errno));
   499     const std::string& address, 
const int max_attempts,
   500     std::string* output_str )
   505     string cmd_str = 
"ping";
   508 #if defined(MRPT_OS_LINUX) || defined(__APPLE__)   520 #if defined(MRPT_OS_LINUX) || defined(__APPLE__) double Tac() noexcept
Stops the stopwatch. 
 
iterator begin() noexcept
 
std::string to_string(T v)
Just like std::to_string(), but with an overloaded version for std::string arguments. 
 
void connect(const std::string &remotePartAddress, unsigned short remotePartTCPPort, unsigned int timeout_ms=0)
Establishes a connection with a remote part. 
 
std::string std::string format(std::string_view fmt, ARGS &&... args)
 
bool isConnected()
Returns true if this objects represents a successfully connected socket. 
 
A high-performance stopwatch, with typical resolution of nanoseconds. 
 
std::string getLastSocketErrorStr()
Returns a description of the last Sockets error. 
 
ERRORCODE_HTTP http_get(const string &url, std::vector< uint8_t > &out_content, string &out_errormsg, int port=80, const string &auth_user=string(), const string &auth_pass=string(), int *out_http_responsecode=nullptr, mrpt::system::TParameters< string > *extra_headers=nullptr, mrpt::system::TParameters< string > *out_headers=nullptr, int timeout_ms=1000)
Perform an HTTP GET operation (version for retrieving the data as a std::vector<uint8_t>) ...
 
void tokenize(const std::string &inString, const std::string &inDelimiters, OUT_CONTAINER &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters. 
 
bool Ping(const std::string &address, const int max_attempts, std::string *output_str=nullptr)
Ping an IP address. 
 
ERRORCODE_HTTP
Possible returns from a HTTP request. 
 
bool has(const std::string &s) const
 
bool DNS_resolve_async(const std::string &server_name, std::string &out_ip, const unsigned int timeout_ms=3000)
Resolve a server address by its name, returning its IP address as a string - This method has a timeou...
 
iterator find(const std::string &key)
 
int executeCommand(const std::string &command, std::string *output=nullptr, const std::string &mode="r")
Execute Generic Shell Command. 
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
void encodeBase64(const std::vector< uint8_t > &inputData, std::string &outString)
Encode a sequence of bytes as a string in base-64. 
 
A TCP socket that can be connected to a TCP server, implementing MRPT's CStream interface for passing...
 
ERRORCODE_HTTP http_request(const string &http_method, const string &http_send_content, const string &url, std::vector< uint8_t > &out_content, string &out_errormsg, int port=80, const string &auth_user=string(), const string &auth_pass=string(), int *out_http_responsecode=nullptr, mrpt::system::TParameters< string > *extra_headers=nullptr, mrpt::system::TParameters< string > *out_headers=nullptr, int timeout_ms=1000)
Generic function for HTTP GET & POST methods. 
 
A set of useful routines for networking. 
 
Serial and networking devices and utilities. 
 
void Tic() noexcept
Starts the stopwatch. 
 
size_t readAsync(void *Buffer, const size_t Count, const int timeoutStart_ms=-1, const int timeoutBetween_ms=-1)
A method for reading from the socket with an optional timeout. 
 
For usage when passing a dynamic number of (numeric) arguments to a function, by name. 
 
void sendString(const std::string &str)
Writes a string to the socket. 
 
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy". 
 
static struct FontData data