diff --git a/src/plugins/http/inc/httpInt.h b/src/plugins/http/inc/httpInt.h index de595907659ffc84c42afb7802b1a7902b126ea1..2aa01244c6877a8ec614fbe5a2f63f296f3df4f5 100644 --- a/src/plugins/http/inc/httpInt.h +++ b/src/plugins/http/inc/httpInt.h @@ -37,7 +37,7 @@ #define HTTP_BUFFER_SIZE 8388608 #define HTTP_STEP_SIZE 4096 //http message get process step by step #define HTTP_METHOD_SCANNER_SIZE 7 //http method fp size -#define HTTP_GC_TARGET_SIZE 512 +#define HTTP_GC_TARGET_SIZE 16384 #define HTTP_WRITE_RETRY_TIMES 500 #define HTTP_WRITE_WAIT_TIME_MS 5 #define HTTP_PASSWORD_LEN TSDB_UNI_LEN diff --git a/src/plugins/http/src/httpGcJson.c b/src/plugins/http/src/httpGcJson.c index 2d361d37940a93c3627ef53883a342d12183e6a1..7e4658b36465e88e30ceb4315730d784becb99d4 100644 --- a/src/plugins/http/src/httpGcJson.c +++ b/src/plugins/http/src/httpGcJson.c @@ -130,14 +130,34 @@ bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, // for group by if (groupFields != -1) { char target[HTTP_GC_TARGET_SIZE] = {0}; - int32_t len; - len = snprintf(target, HTTP_GC_TARGET_SIZE, "%s{", aliasBuffer); + int32_t len = 0, cur = 0; + cur = snprintf(target, HTTP_GC_TARGET_SIZE, "%s{", aliasBuffer); + if (cur < 0 || cur >= HTTP_GC_TARGET_SIZE) { + httpError("context:%p, fd:%d, too long alias: %s", pContext, pContext->fd, aliasBuffer); + return false; + } + + len += cur; for (int32_t i = dataFields + 1; i < num_fields; i++) { + // -2 means the last '}' and '\0' +#define HTTP_GC_CHECK_SIZE(name) if (cur < 0 || cur >= HTTP_GC_TARGET_SIZE - len - 2) { \ + if (cur < 0) { \ + httpError("context:%p, fd:%d, failed to snprintf for: %s", pContext, pContext->fd, name); \ + } else { \ + httpError("context:%p, fd:%d, snprintf overflow for: %s", pContext, pContext->fd, name); \ + target[len] = '\0'; \ + } \ + break; \ + } else { \ + len += cur; \ + } if (row[i] == NULL) { - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:nil", fields[i].name); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:nil", fields[i].name); + HTTP_GC_CHECK_SIZE(fields[i].name) if (i < num_fields - 1) { - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, ", "); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, ", "); + HTTP_GC_CHECK_SIZE(fields[i].name) } continue; @@ -146,40 +166,49 @@ bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, switch (fields[i].type) { case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT: - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:%d", fields[i].name, *((int8_t *)row[i])); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:%d", fields[i].name, *((int8_t *)row[i])); + HTTP_GC_CHECK_SIZE(fields[i].name) break; case TSDB_DATA_TYPE_SMALLINT: - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:%d", fields[i].name, *((int16_t *)row[i])); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:%d", fields[i].name, *((int16_t *)row[i])); + HTTP_GC_CHECK_SIZE(fields[i].name) break; case TSDB_DATA_TYPE_INT: - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:%d,", fields[i].name, *((int32_t *)row[i])); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:%d,", fields[i].name, *((int32_t *)row[i])); + HTTP_GC_CHECK_SIZE(fields[i].name) break; case TSDB_DATA_TYPE_BIGINT: - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:%" PRId64, fields[i].name, *((int64_t *)row[i])); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:%" PRId64, fields[i].name, *((int64_t *)row[i])); + HTTP_GC_CHECK_SIZE(fields[i].name) break; case TSDB_DATA_TYPE_FLOAT: - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:%.5f", fields[i].name, GET_FLOAT_VAL(row[i])); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:%.5f", fields[i].name, GET_FLOAT_VAL(row[i])); + HTTP_GC_CHECK_SIZE(fields[i].name) break; case TSDB_DATA_TYPE_DOUBLE: - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:%.9f", fields[i].name, GET_DOUBLE_VAL(row[i])); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:%.9f", fields[i].name, GET_DOUBLE_VAL(row[i])); + HTTP_GC_CHECK_SIZE(fields[i].name) break; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: if (row[i] != NULL) { - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:", fields[i].name); - memcpy(target + len, (char *)row[i], length[i]); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:", fields[i].name); + HTTP_GC_CHECK_SIZE(fields[i].name) + memcpy(target + len, (char *)row[i], MIN(length[i], HTTP_GC_TARGET_SIZE - len - 3)); len = (int32_t)strlen(target); } break; default: - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "%s:%s", fields[i].name, "-"); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, "%s:%s", fields[i].name, "-"); + HTTP_GC_CHECK_SIZE(fields[i].name) break; } if (i < num_fields - 1) { - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, ", "); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 2, ", "); + HTTP_GC_CHECK_SIZE(fields[i].name) } } - len += snprintf(target + len, HTTP_GC_TARGET_SIZE - len, "}"); + cur = snprintf(target + len, HTTP_GC_TARGET_SIZE - len - 1, "}"); if (strcmp(target, targetBuffer) != 0) { // first target not write this section diff --git a/tests/script/general/http/grafana.sim b/tests/script/general/http/grafana.sim index 414b859bd3dcaa78ab7d814afd660c9894857cc3..b47edce28cb170a67fe119f76965eae704c4ff43 100644 --- a/tests/script/general/http/grafana.sim +++ b/tests/script/general/http/grafana.sim @@ -50,6 +50,9 @@ sql insert into t3 values('2017-12-25 21:25:41', 3) sql insert into t3 values('2017-12-25 21:26:41', 3) sql insert into t3 values('2017-12-25 21:27:41', 3) +sql create table m3 (ts timestamp, col1 int, col2 float, txt binary(500)) +sql insert into m3 values(now, 1, 2.0, 'HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS') + print =============== step2 - login system_content curl 127.0.0.1:7111/grafana/ @@ -179,4 +182,10 @@ if $system_content != @[{"refId":"A","target":"{count(v1):3}","datapoints":[[15. return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d '[{"refId":"A","alias":"taosd","sql":"select last(col1), last(col2), last(txt) from d1.m3 group by txt"}]' 127.0.0.1:7111/grafana/query +print 20-> $system_content +if $system_content != @[{"refId":"A","target":"taosd{last(col2):2.00000, last(txt):HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS HELLO TAOS}","datapoints":[[1,"-"]]}]@ then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT