lolautoaccept/src/websocketclient.cpp

107 lines
2.8 KiB
C++

#include "websocketclient.h"
#include <Log.h>
#include <curl/easy.h>
#include <unistd.h>
static curl_socket_t opensocketfunc_callback(void* clientp, curlsocktype purpose, struct curl_sockaddr* address) {
return *((int*) clientp) = socket(address->family, address->socktype, address->protocol);
}
static void dump(const char* text, FILE* stream, unsigned char* ptr, size_t size) {
const unsigned int width = 0x40;
fprintf(stream, "%s, %10.10lu bytes (0x%8.8lx)\n", text, (unsigned long) size, (unsigned long) size);
for (size_t i = 0; i < size; i += width) {
fprintf(stream, "%4.4lx: ", (unsigned long) i);
for (size_t c = 0; (c < width) && (i + c < size); c++) {
/* check for 0D0A; if found, skip past and start a new line of output */
fprintf(stream, "%c", (ptr[i + c] >= 0x20) && (ptr[i + c] < 0x80) ? ptr[i + c] : '.');
}
fputc('\n', stream); /* newline */
}
fflush(stream);
}
static int my_trace(CURL* handle, curl_infotype type, char* data, size_t size, void* userp) {
const char* text;
(void) handle; /* prevent compiler warning */
switch (type) {
case CURLINFO_TEXT:
fprintf(stderr, "== Info: %s", data);
/* FALLTHROUGH */
default: /* in case a new one is introduced to shock us */
return 0;
case CURLINFO_HEADER_OUT:
text = "=> Send header";
break;
case CURLINFO_DATA_OUT:
text = "=> Send data";
break;
case CURLINFO_HEADER_IN:
text = "<= Recv header";
break;
case CURLINFO_DATA_IN:
text = "<= Recv data";
break;
case CURLINFO_SSL_DATA_OUT:
case CURLINFO_SSL_DATA_IN:
return 0;
}
dump(text, stderr, (unsigned char*) data, size);
return 0;
}
static size_t stringWriteCallback(char* contents, size_t size, size_t nmemb, void* userdata) {
if (userdata) {
std::string* str = (std::string*) userdata;
str->append(contents, size * nmemb);
return size * nmemb;
}
return 0;
}
WebSocketClient::WebSocketClient() {
curl = curl_easy_init();
if(!curl) {
Log::error << __PRETTY_FUNCTION__ << " curl_easy_init() failed";
}
// curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocketfunc_callback);
// curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &fd);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, stringWriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, 0); // TODO
// disable ssl-cert checks
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
}
void WebSocketClient::send(const std::string& data) {
if(fd >= 0) {
ssize_t res = ::write(fd, data.c_str(), data.size());
if(res < data.size()) {
Log::warn << "write to socket: " << fd << " failed with: " << errno;
}
}
}
WebSocketClient::~WebSocketClient() {
if(curl) {
curl_easy_cleanup(curl);
curl = nullptr;
}
}