#include "RestfulFunc.h" #include "JsonConvertHelper.hpp" #include #include #include #include "log_util.h" #include "log_api.h" #include #include "sds.h" #include "inner_log.h" //#define GBK_COMPACT static int is_utf8(const char* str) { int i; const unsigned char* bytes = (const unsigned char*)str; int num; if (str == NULL) return 1; #if 0 while (*bytes != 0x00) { if ((*bytes & 0x80) == 0x00) { // U+0000 to U+007F num = 1; } else if ((*bytes & 0xE0) == 0xC0) { // U+0080 to U+07FF num = 2; } else if ((*bytes & 0xF0) == 0xE0) { // U+0800 to U+FFFF num = 3; } else if ((*bytes & 0xF8) == 0xF0) { // U+10000 to U+10FFFF num = 4; } else { return 0; } bytes += 1; for (i = 1; i < num; ++i) { if ((*bytes & 0xC0) != 0x80) return 0; bytes += 1; } } return 1; #else while (*bytes) { if ((// ASCII // use bytes[0] <= 0x7F to allow ASCII control characters bytes[0] == 0x09 || bytes[0] == 0x0A || bytes[0] == 0x0D || (0x20 <= bytes[0] && bytes[0] <= 0x7E) ) ) { bytes += 1; continue; } if ((// non-overlong 2-byte (0xC2 <= bytes[0] && bytes[0] <= 0xDF) && (0x80 <= bytes[1] && bytes[1] <= 0xBF) ) ) { bytes += 2; continue; } if ((// excluding overlongs bytes[0] == 0xE0 && (0xA0 <= bytes[1] && bytes[1] <= 0xBF) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) ) || (// straight 3-byte ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) || bytes[0] == 0xEE || bytes[0] == 0xEF) && (0x80 <= bytes[1] && bytes[1] <= 0xBF) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) ) || (// excluding surrogates bytes[0] == 0xED && (0x80 <= bytes[1] && bytes[1] <= 0x9F) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) ) ) { bytes += 3; continue; } if ((// planes 1-3 bytes[0] == 0xF0 && (0x90 <= bytes[1] && bytes[1] <= 0xBF) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) && (0x80 <= bytes[3] && bytes[3] <= 0xBF) ) || (// planes 4-15 (0xF1 <= bytes[0] && bytes[0] <= 0xF3) && (0x80 <= bytes[1] && bytes[1] <= 0xBF) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) && (0x80 <= bytes[3] && bytes[3] <= 0xBF) ) || (// plane 16 bytes[0] == 0xF4 && (0x80 <= bytes[1] && bytes[1] <= 0x8F) && (0x80 <= bytes[2] && bytes[2] <= 0xBF) && (0x80 <= bytes[3] && bytes[3] <= 0xBF) ) ) { bytes += 4; continue; } return 0; } return 1; #endif } std::wstring s2w(const std::string str) { if (str.empty()) { return L""; } std::wstring w_str(L""); const char* origin = setlocale(LC_CTYPE, NULL); unsigned len = str.size() + 1; setlocale(LC_CTYPE, "zh_CN.gbk"); wchar_t* p = new wchar_t[len]; if (-1 != mbstowcs(p, str.c_str(), len)) { w_str = p; } else { aos_error_log((LB, "s2w::mbstowcs failed")); } delete[] p; setlocale(LC_CTYPE, origin); return w_str; } std::string w2utf8(const std::wstring wstr) { if (wstr.empty()) { return ""; } std::string str(""); char* origin = setlocale(LC_CTYPE, NULL); unsigned len = wstr.size() + 1; setlocale(LC_CTYPE, "zh_CN.utf8"); char* p = new char[len]; if (-1 != wcstombs(p, wstr.c_str(), len)) { str = p; } else { aos_error_log((LB, "w2utf8::wcstombs failed")); } setlocale(LC_CTYPE, origin); return str; } std::string gbk2utf8(const std::string str) { std::wstring wstr = s2w(str); return w2utf8(wstr); } /* if (result->statusCode / 100 == 2) { return LOG_SEND_OK; } if (result->statusCode <= 0) { return LOG_SEND_NETWORK_ERROR; } if (result->statusCode >= 500 || result->requestID == NULL) { return LOG_SEND_SERVER_ERROR; } if (result->statusCode == 403) { return LOG_SEND_QUOTA_EXCEED; } if (result->statusCode == 401 || result->statusCode == 404) { return LOG_SEND_UNAUTHORIZED; } if (result->errorMessage != NULL && strstr(result->errorMessage, LOGE_TIME_EXPIRED) != NULL) { return LOG_SEND_TIME_ERROR; } return LOG_SEND_DISCARD_ERROR; */ int LOG_OS_HttpPost(const char* url, char** header_array, int header_count, const void* data, int data_len, const char* channelId, const char* token) { int retCode = 480; HttpClientResponseResult result; HttpClientRequestConfig config(HttpRequestMethod::POST, url); config.SetTimeout(60); std::string str((const char*)data); #ifdef GBK_COMPACT if (!str.empty() && !is_utf8(str.c_str())) { std::string t = gbk2utf8(str); str = t; } #endif //GBK_COMPACT config.SetJsonBody(str.c_str()); RestfulClient client = RestfulClient::getInstance(); config.PreDo(); client.Do(&config, &result); if (result.ResponseOK()) { retCode = 481; struct CommResponse { bool success; std::string errorCode; std::string returnCode; std::string errorMsg; std::string message; JSONCONVERT2OBJECT_MEMEBER_REGISTER(success, errorCode, returnCode, errorMsg, message) JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER("success", "code", "return_code", "error_msg", "message") } responseIns; Json::Value rawRoot; if (GetJsonRootObject(rawRoot, result.content) && Json2Object(responseIns, rawRoot)) { if (responseIns.success) { retCode = 200; } else { if (responseIns.errorCode.find("RTI1002") != -1) retCode = 300; else if (!is_utf8((const char*)str.c_str())) { aos_warn_log((LB, "detect that content is not utf8-type ,skip it: %s", str.c_str())); retCode = 200; } } } else { aos_error_log((LB, "http %s extract failed: %s", url, result.content.c_str())); aos_info_log((LB, "content len: %d", data_len)); } } else { retCode = result.statusCode; } return retCode; } extern long LOG_GET_TIME(); log_status_t sls_log_init(int32_t log_global_flag) { return 0; } void sls_log_destroy() { } static const char sls_month_snames[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static const char sls_day_snames[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; void sls_rfc822_date(char *date_str, struct tm * xt) { const char *s = NULL; int real_year = 2000; /* example: "Sat, 08 Jan 2000 18:31:41 GMT" */ /* 12345678901234567890123456789 */ s = &sls_day_snames[xt->tm_wday][0]; *date_str++ = *s++; *date_str++ = *s++; *date_str++ = *s++; *date_str++ = ','; *date_str++ = ' '; *date_str++ = xt->tm_mday / 10 + '0'; *date_str++ = xt->tm_mday % 10 + '0'; *date_str++ = ' '; s = &sls_month_snames[xt->tm_mon][0]; *date_str++ = *s++; *date_str++ = *s++; *date_str++ = *s++; *date_str++ = ' '; real_year = 1900 + xt->tm_year; /* This routine isn't y10k ready. */ *date_str++ = real_year / 1000 + '0'; *date_str++ = real_year % 1000 / 100 + '0'; *date_str++ = real_year % 100 / 10 + '0'; *date_str++ = real_year % 10 + '0'; *date_str++ = ' '; *date_str++ = xt->tm_hour / 10 + '0'; *date_str++ = xt->tm_hour % 10 + '0'; *date_str++ = ':'; *date_str++ = xt->tm_min / 10 + '0'; *date_str++ = xt->tm_min % 10 + '0'; *date_str++ = ':'; *date_str++ = xt->tm_sec / 10 + '0'; *date_str++ = xt->tm_sec % 10 + '0'; *date_str++ = ' '; *date_str++ = 'G'; *date_str++ = 'M'; *date_str++ = 'T'; *date_str++ = 0; return; } void get_now_time_str(char * buffer, int bufLen, int timeOffset) { time_t rawtime = LOG_GET_TIME(); struct tm * timeinfo; if (timeOffset != 0) { rawtime += timeOffset; } timeinfo = gmtime(&rawtime); sls_rfc822_date(buffer, timeinfo); } void post_log_result_destroy(post_log_result * result) { if (result != NULL) { if (result->errorMessage != NULL) { sdsfree(result->errorMessage); } if (result->requestID != NULL) { sdsfree(result->requestID); } free(result); } } struct cur_slist { char *data; struct cur_slist *next; }; struct cur_slist * cur_slist_append(struct cur_slist *lst, const char *s) { struct cur_slist* orig; struct cur_slist *t = (struct cur_slist *)malloc(sizeof(struct cur_slist)); #ifdef WIN32 t->data = _strdup(s); #else t->data = strdup(s); #endif t->next = NULL; if(lst == NULL) return t; orig = lst; while(lst->next) { lst = lst->next; } lst->next = t; return orig; } void cur_slist_free_all(struct cur_slist *lst) { while(lst != NULL) { struct cur_slist *n = lst->next; free(lst->data); free(lst); lst = n; } } post_log_result* post_logs(const char* endpoint, const char* accesskeyId, const char* accessKey, const char* stsToken, lz4_log_buf* buffer, log_post_option* option, const char* channelId, const char* token) { post_log_result * result = (post_log_result *)malloc(sizeof(post_log_result)); memset(result, 0, sizeof(post_log_result)); { //headers struct cur_slist* headers = NULL; int res; char* header_array[50]; int header_count = 0; // url sds url = NULL; if (option->using_https) { url = sdsnew("https://"); } else { url = sdsnew("http://"); } url = sdscat(url, endpoint); if(buffer->data != NULL && buffer->length != 0) res = LOG_OS_HttpPost(url, header_array, header_count, (const void *) buffer->data, buffer->length, channelId, token); result->statusCode = res; cur_slist_free_all(headers); /* free the list again */ sdsfree(url); } return result; }