Add HTTP GET function
The function performs a HTTP GET on a URL and returns the HTTP response.
This commit is contained in:
parent
91ab59530f
commit
f8fb9510c9
@ -16,7 +16,7 @@ then
|
||||
build-essential libssl-dev ncurses-dev bison flex \
|
||||
perl libtool libpcre3-dev tcl tcl-dev uuid \
|
||||
uuid-dev libsqlite3-dev liblzma-dev libpam0g-dev pkg-config \
|
||||
libedit-dev
|
||||
libedit-dev libcurl4-openssl-dev
|
||||
|
||||
## separatelibgnutls installation process for Ubuntu Trusty
|
||||
cat /etc/*release | grep -E "Trusty|wheezy"
|
||||
@ -49,7 +49,7 @@ else
|
||||
make libtool libopenssl-devel libaio libaio-devel flex \
|
||||
pcre-devel git wget tcl libuuid-devel \
|
||||
xz-devel sqlite3 sqlite3-devel pkg-config lua lua-devel \
|
||||
gnutls-devel libgcrypt-devel pam-devel
|
||||
gnutls-devel libgcrypt-devel pam-devel libcurl-devel
|
||||
sudo zypper -n install rpm-build
|
||||
cat /etc/*-release | grep "SUSE Linux Enterprise Server 11"
|
||||
|
||||
@ -66,7 +66,7 @@ else
|
||||
libedit-devel systemtap-sdt-devel rpm-sign wget \
|
||||
gnupg pcre-devel flex rpmdevtools git wget tcl openssl libuuid-devel xz-devel \
|
||||
sqlite sqlite-devel pkgconfig lua lua-devel rpm-build createrepo yum-utils \
|
||||
gnutls-devel libgcrypt-devel pam-devel
|
||||
gnutls-devel libgcrypt-devel pam-devel libcurl-devel
|
||||
|
||||
# Attempt to install libasan, it'll only work on CentOS 7
|
||||
sudo yum install -y --nogpgcheck libasan
|
||||
|
@ -44,6 +44,7 @@ find_package(GSSAPI)
|
||||
find_package(SQLite)
|
||||
find_package(ASAN)
|
||||
find_package(TSAN)
|
||||
find_package(CURL)
|
||||
|
||||
# Build PCRE2 so we always know the version
|
||||
# Read BuildPCRE2 for details about how to add pcre2 as a dependency to a target
|
||||
|
@ -11,6 +11,7 @@ requirements are as follows:
|
||||
* Flex 2.5.35 or later
|
||||
* libuuid
|
||||
* GNUTLS
|
||||
* libcurl
|
||||
|
||||
This is the minimum set of requirements that must be met to build the MaxScale
|
||||
core package.
|
||||
|
@ -22,12 +22,14 @@
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <maxscale/buffer.h>
|
||||
#include <maxscale/utils.h>
|
||||
#include <maxscale/jansson.hh>
|
||||
|
||||
namespace maxscale
|
||||
{
|
||||
@ -645,4 +647,26 @@ uint64_t get_byteN(const uint8_t* ptr, int bytes);
|
||||
*/
|
||||
uint8_t* set_byteN(uint8_t* ptr, uint64_t value, int bytes);
|
||||
|
||||
namespace http
|
||||
{
|
||||
|
||||
struct Result
|
||||
{
|
||||
int code; // HTTP response code
|
||||
std::string raw_body; // Raw response body
|
||||
std::unique_ptr<json_t> body; // JSON form of the body if it was valid JSON
|
||||
std::unordered_map<std::string, std::string> headers; // Headers attached to the response
|
||||
};
|
||||
|
||||
/**
|
||||
* Do a HTTP GET
|
||||
*
|
||||
* @param url URL to use
|
||||
*
|
||||
* @return A Result
|
||||
*/
|
||||
Result get(const std::string& url);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ target_link_libraries(maxscale-common
|
||||
gnutls
|
||||
gcrypt
|
||||
${MICROHTTPD_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
)
|
||||
|
||||
find_library(HAVE_LIBDL NAMES dl)
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <maxscale/alloc.h>
|
||||
#include <maxscale/config.h>
|
||||
@ -1198,4 +1199,84 @@ std::string string_printf(const char* format, ...)
|
||||
return rval;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
std::string* buf = static_cast<std::string*>(userdata);
|
||||
|
||||
if (nmemb > 0)
|
||||
{
|
||||
buf->append(ptr, nmemb);
|
||||
}
|
||||
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
size_t header_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
std::unordered_map<std::string, std::string>* map =
|
||||
static_cast<std::unordered_map<std::string, std::string>*>(userdata);
|
||||
|
||||
if (nmemb > 0)
|
||||
{
|
||||
std::string data(ptr, size * nmemb);
|
||||
auto pos = data.find_first_of(':');
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string key = data.substr(0, pos);
|
||||
std::string value = data.substr(pos + 1);
|
||||
trim(key);
|
||||
trim(value);
|
||||
map->insert(std::make_pair(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
return nmemb * size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace http
|
||||
{
|
||||
|
||||
Result get(const std::string& url)
|
||||
{
|
||||
Result res;
|
||||
char errbuf[CURL_ERROR_SIZE + 1] = "";
|
||||
CURL* curl = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res.raw_body);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &res.headers);
|
||||
|
||||
long code = 0; // needs to be a long
|
||||
|
||||
if (curl_easy_perform(curl) == CURLE_OK)
|
||||
{
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
|
||||
res.code = code;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.code = -1;
|
||||
res.raw_body = errbuf;
|
||||
}
|
||||
|
||||
// Even the errors are valid JSON so this should be OK
|
||||
json_error_t err;
|
||||
res.body.reset(json_loads(res.raw_body.c_str(), 0, &err));
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user