/
githubmirror
/
rsyslog
Обзор
Документация
Войти
/
githubmirror
/
rsyslog
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
plugins/fmhttp/fmhttp.c
191 строка
6 KB
Rainer Gerhards
tests: stabilize ARMv7 Valgrind runs
21 май 2026, 17:51
21 май 2026, 17:51
11a5f89
Код
Авторство
О чём код?
/* 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 <limits.h> #include <stdlib.h> #include <stdint.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 chunkLen; size_t newlen; struct curl_funcData *const curlData = (struct curl_funcData *)userdata; assert(curlData != NULL); if (ptr == NULL) { LogError(0, RS_RET_ERR, "internal error: libcurl provided ptr=NULL"); return 0; } if (nmemb != 0 && size > SIZE_MAX / nmemb) { LogError(0, RS_RET_ERR, "rainerscript: http_request reply too large"); return 0; } chunkLen = size * nmemb; if (curlData->replyLen > SIZE_MAX - 1 || chunkLen > SIZE_MAX - curlData->replyLen - 1 || curlData->replyLen > UINT_MAX || chunkLen > UINT_MAX - curlData->replyLen) { LogError(0, RS_RET_ERR, "rainerscript: http_request reply too large"); return 0; } newlen = curlData->replyLen + chunkLen; 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, chunkLen); curlData->replyLen = newlen; curlData->reply = buf; return chunkLen; } 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; struct curl_funcData curlData = {.reply = NULL, .replyLen = 0}; assert(func != NULL); rsRetVal iRet __attribute__((unused)) = RS_RET_OK; CHKmalloc(handle = curl_easy_init()); curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curlResult); curl_easy_setopt(handle, CURLOPT_WRITEDATA, &curlData); 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); 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 = 0; func->funcdata = NULL; 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) { (void)func; } 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; curl_global_cleanup(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_FMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; CURLcode curlRet; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ curlRet = curl_global_init(CURL_GLOBAL_DEFAULT); if (curlRet != CURLE_OK) { LogError(0, RS_RET_OBJ_CREATION_FAILED, "fmhttp: curl_global_init failed: %s", curl_easy_strerror(curlRet)); ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); } CODEmodInit_QueryRegCFSLineHdlr dbgprintf("rsyslog fmhttp init called, compiled with version %s\n", VERSION); ENDmodInit