summaryrefslogtreecommitdiffstats
path: root/plugins/fmhttp/fmhttp.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/fmhttp/fmhttp.c')
-rw-r--r--plugins/fmhttp/fmhttp.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/plugins/fmhttp/fmhttp.c b/plugins/fmhttp/fmhttp.c
new file mode 100644
index 0000000..c465b23
--- /dev/null
+++ b/plugins/fmhttp/fmhttp.c
@@ -0,0 +1,188 @@
+/* fmhttp.c
+ * This is a function module for http functions.
+ *
+ * File begun on 2018-03-16 by JGerhards
+ *
+ * Copyright 2010-2018 Rainer Gerhards, Jan Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "config.h"
+#include "rsyslog.h"
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <ctype.h>
+#include <curl/curl.h>
+#include "errmsg.h"
+#include "conf.h"
+#include "syslogd-types.h"
+#include "template.h"
+#include "msg.h"
+#include "parserif.h"
+#include "module-template.h"
+#include "rainerscript.h"
+#include "unicode-helper.h"
+
+MODULE_TYPE_FUNCTION
+MODULE_TYPE_NOKEEP
+DEF_FMOD_STATIC_DATA
+
+struct curl_funcData {
+ const char *reply;
+ size_t replyLen;
+};
+
+/* curl callback for doFunc_http_request */
+static size_t
+curlResult(void *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ char *buf;
+ size_t newlen;
+ struct cnffunc *const func = (struct cnffunc *) userdata;
+ assert(func != NULL);
+ struct curl_funcData *const curlData = (struct curl_funcData*) func->funcdata;
+ assert(curlData != NULL);
+
+ if(ptr == NULL) {
+ LogError(0, RS_RET_ERR, "internal error: libcurl provided ptr=NULL");
+ return 0;
+ }
+
+ newlen = curlData->replyLen + size*nmemb;
+ if((buf = realloc((void*)curlData->reply, newlen + 1)) == NULL) {
+ LogError(errno, RS_RET_ERR, "rainerscript: realloc failed in curlResult");
+ return 0; /* abort due to failure */
+ }
+ memcpy(buf+curlData->replyLen, (char*)ptr, size*nmemb);
+ curlData->replyLen = newlen;
+ curlData->reply = buf;
+ return size*nmemb;
+}
+
+static void ATTR_NONNULL()
+doFunc_http_request(struct cnffunc *__restrict__ const func,
+ struct svar *__restrict__ const ret,
+ void *__restrict__ const usrptr,
+ wti_t *__restrict__ const pWti)
+{
+ struct svar srcVal;
+ int bMustFree;
+ cnfexprEval(func->expr[0], &srcVal, usrptr, pWti);
+ char *url = (char*) var2CString(&srcVal, &bMustFree);
+
+ int resultSet = 0;
+ CURL *handle = NULL;
+ CURLcode res;
+ assert(func != NULL);
+ struct curl_funcData *const curlData = (struct curl_funcData*) func->funcdata;
+ assert(curlData != NULL);
+ rsRetVal iRet __attribute__((unused)) = RS_RET_OK;
+
+ CHKmalloc(handle = curl_easy_init());
+ curl_easy_setopt(handle, CURLOPT_NOSIGNAL, TRUE);
+ curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curlResult);
+ curl_easy_setopt(handle, CURLOPT_WRITEDATA, func);
+
+ curl_easy_setopt(handle, CURLOPT_URL, url);
+ res = curl_easy_perform(handle);
+ if(res != CURLE_OK) {
+ LogError(0, RS_RET_IO_ERROR,
+ "rainerscript: http_request to failed, URL: '%s', error %s",
+ url, curl_easy_strerror(res));
+ ABORT_FINALIZE(RS_RET_OK);
+ }
+
+
+ CHKmalloc(ret->d.estr = es_newStrFromCStr(curlData->reply, curlData->replyLen));
+ ret->datatype = 'S';
+ resultSet = 1;
+
+finalize_it:
+ free((void*)curlData->reply);
+ curlData->reply = NULL;
+ curlData->replyLen = 0;
+
+ if(handle != NULL) {
+ curl_easy_cleanup(handle);
+ }
+ if(!resultSet) {
+ /* provide dummy value */
+ ret->d.n = 0;
+ ret->datatype = 'N';
+ }
+ if(bMustFree) {
+ free(url);
+ }
+ varFreeMembers(&srcVal);
+}
+
+static rsRetVal ATTR_NONNULL(1)
+initFunc_http_request(struct cnffunc *const func)
+{
+ DEFiRet;
+
+ func->destructable_funcdata = 1;
+ CHKmalloc(func->funcdata = calloc(1, sizeof(struct curl_funcData)));
+ if(func->nParams != 1) {
+ parser_errmsg("rsyslog logic error in line %d of file %s\n",
+ __LINE__, __FILE__);
+ FINALIZE;
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+static void ATTR_NONNULL(1)
+destructFunc_http_request(struct cnffunc *const func)
+{
+ if(func->funcdata != NULL) {
+ free((void*) ((struct curl_funcData*)func->funcdata)->reply);
+ }
+}
+
+static struct scriptFunct functions[] = {
+ {"http_request", 1, 1, doFunc_http_request, initFunc_http_request, destructFunc_http_request},
+ {NULL, 0, 0, NULL, NULL, NULL} //last element to check end of array
+};
+
+BEGINgetFunctArray
+CODESTARTgetFunctArray
+ *version = 1;
+ *functArray = functions;
+ENDgetFunctArray
+
+
+BEGINmodExit
+CODESTARTmodExit
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_FMOD_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ dbgprintf("rsyslog fmhttp init called, compiled with version %s\n", VERSION);
+ENDmodInit