httpJson.c 16.0 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

S
slguan 已提交
16 17 18 19
#define _DEFAULT_SOURCE
#include "os.h"
#include "taosmsg.h"
#include "taoserror.h"
S
TD-1311  
Shengliang Guan 已提交
20
#include "tglobal.h"
H
hzcheng 已提交
21
#include "http.h"
S
slguan 已提交
22
#include "httpLog.h"
H
hzcheng 已提交
23 24
#include "httpJson.h"
#include "httpResp.h"
25
#include "httpUtil.h"
H
hzcheng 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

#define MAX_NUM_STR_SZ 25

char JsonItmTkn = ',';
char JsonObjStt = '{';
char JsonObjEnd = '}';
char JsonArrStt = '[';
char JsonArrEnd = ']';
char JsonStrStt = '\"';
char JsonStrEnd = '\"';
char JsonPairTkn = ':';
char JsonNulTkn[] = "null";
char JsonTrueTkn[] = "true";
char JsonFalseTkn[] = "false";

S
TD-1311  
Shengliang Guan 已提交
41 42 43 44
int32_t httpWriteBufByFd(struct HttpContext* pContext, const char* buf, int32_t sz) {
  int32_t len;
  int32_t countWait = 0;
  int32_t writeLen = 0;
H
hzcheng 已提交
45 46

  do {
S
TD-1207  
Shengliang Guan 已提交
47
    if (pContext->fd > 2) {
S
TD-1311  
Shengliang Guan 已提交
48
      len = (int32_t)taosSend(pContext->fd, buf + writeLen, (size_t)(sz - writeLen), MSG_NOSIGNAL);
S
TD-1207  
Shengliang Guan 已提交
49
    } else {
50 51 52
      return sz;
    }

H
hzcheng 已提交
53
    if (len < 0) {
S
TD-1207  
Shengliang Guan 已提交
54 55
      httpDebug("context:%p, fd:%d, socket write errno:%d:%s, times:%d", pContext, pContext->fd, errno, strerror(errno),
                countWait);
56 57 58
      if (++countWait > HTTP_WRITE_RETRY_TIMES) break;
      taosMsleep(HTTP_WRITE_WAIT_TIME_MS);
      continue;
H
hzcheng 已提交
59
    } else if (len == 0) {
S
TD-1207  
Shengliang Guan 已提交
60 61
      httpDebug("context:%p, fd:%d, socket write errno:%d:%s, connect already closed", pContext, pContext->fd, errno,
                strerror(errno));
62
      break;
H
hzcheng 已提交
63 64
    } else {
      countWait = 0;
65
      writeLen += len;
H
hzcheng 已提交
66
    }
67
  } while (writeLen < sz);
H
hzcheng 已提交
68

69
  return writeLen;
H
hzcheng 已提交
70 71
}

S
TD-1311  
Shengliang Guan 已提交
72 73
int32_t httpWriteBuf(struct HttpContext* pContext, const char* buf, int32_t sz) {
  int32_t writeSz = httpWriteBufByFd(pContext, buf, sz);
74
  if (writeSz != sz) {
S
TD-1311  
Shengliang Guan 已提交
75 76
    httpError("context:%p, fd:%d, dataSize:%d, writeSize:%d, failed to send response:\n%s", pContext, pContext->fd, sz,
              writeSz, buf);
H
hzcheng 已提交
77
  } else {
S
TD-1311  
Shengliang Guan 已提交
78
    httpTrace("context:%p, fd:%d, dataSize:%d, writeSize:%d, response:\n%s", pContext, pContext->fd, sz, writeSz, buf);
H
hzcheng 已提交
79 80 81 82 83
  }

  return writeSz;
}

S
TD-1207  
Shengliang Guan 已提交
84
int32_t httpWriteBufNoTrace(struct HttpContext* pContext, const char* buf, int32_t sz) {
S
TD-1311  
Shengliang Guan 已提交
85
  int32_t writeSz = httpWriteBufByFd(pContext, buf, sz);
S
slguan 已提交
86
  if (writeSz != sz) {
S
TD-1311  
Shengliang Guan 已提交
87 88
    httpError("context:%p, fd:%d, dataSize:%d, writeSize:%d, failed to send response", pContext, pContext->fd, sz,
              writeSz);
S
slguan 已提交
89 90 91 92 93
  }

  return writeSz;
}

S
TD-1311  
Shengliang Guan 已提交
94 95
int32_t httpWriteJsonBufBody(JsonBuf* buf, bool isTheLast) {
  int32_t remain = 0;
S
TD-1207  
Shengliang Guan 已提交
96 97
  char    sLen[24];
  int32_t srcLen = (int32_t)(buf->lst - buf->buf);
S
slguan 已提交
98

H
hzcheng 已提交
99
  if (buf->pContext->fd <= 0) {
S
TD-1311  
Shengliang Guan 已提交
100
    httpTrace("context:%p, fd:%d, write json body error", buf->pContext, buf->pContext->fd);
H
hzcheng 已提交
101 102 103
    buf->pContext->fd = -1;
  }

S
slguan 已提交
104 105 106 107 108 109 110 111
  /*
   * HTTP servers often use compression to optimize transmission, for example
   * with Content-Encoding: gzip or Content-Encoding: deflate.
   * If both compression and chunked encoding are enabled, then the content stream is first compressed, then chunked;
   * so the chunk encoding itself is not compressed, and the data in each chunk is not compressed individually.
   * The remote endpoint then decodes the stream by concatenating the chunks and uncompressing the result.
   */

S
TD-1311  
Shengliang Guan 已提交
112
  if (buf->pContext->parser->acceptEncodingGzip == 0 || !tsHttpEnableCompress) {
S
slguan 已提交
113
    if (buf->lst == buf->buf) {
S
TD-1311  
Shengliang Guan 已提交
114
      httpTrace("context:%p, fd:%d, no data need dump", buf->pContext, buf->pContext->fd);
S
slguan 已提交
115 116
      return 0;  // there is no data to dump.
    } else {
S
TD-1207  
Shengliang Guan 已提交
117 118 119
      int32_t len = sprintf(sLen, "%x\r\n", srcLen);
      httpTrace("context:%p, fd:%d, write body, chunkSize:%d, response:\n%s", buf->pContext, buf->pContext->fd, srcLen,
                buf->buf);
S
slguan 已提交
120
      httpWriteBufNoTrace(buf->pContext, sLen, len);
S
TD-1207  
Shengliang Guan 已提交
121
      remain = httpWriteBufNoTrace(buf->pContext, buf->buf, srcLen);
S
slguan 已提交
122
    }
H
hzcheng 已提交
123
  } else {
S
TD-1207  
Shengliang Guan 已提交
124
    char    compressBuf[JSON_BUFFER_SIZE] = {0};
S
slguan 已提交
125
    int32_t compressBufLen = JSON_BUFFER_SIZE;
S
TD-1311  
Shengliang Guan 已提交
126
    int32_t ret = httpGzipCompress(buf->pContext, buf->buf, srcLen, compressBuf, &compressBufLen, isTheLast);
S
slguan 已提交
127 128
    if (ret == 0) {
      if (compressBufLen > 0) {
S
TD-1311  
Shengliang Guan 已提交
129
        int32_t len = sprintf(sLen, "%x\r\n", compressBufLen);
S
TD-1207  
Shengliang Guan 已提交
130 131
        httpTrace("context:%p, fd:%d, write body, chunkSize:%d, compressSize:%d, last:%d, response:\n%s", buf->pContext,
                  buf->pContext->fd, srcLen, compressBufLen, isTheLast, buf->buf);
S
slguan 已提交
132
        httpWriteBufNoTrace(buf->pContext, sLen, len);
S
TD-1311  
Shengliang Guan 已提交
133
        remain = httpWriteBufNoTrace(buf->pContext, (const char*)compressBuf, compressBufLen);
S
slguan 已提交
134
      } else {
S
TD-1451  
Shengliang Guan 已提交
135
        httpDebug("context:%p, fd:%d, last:%d, compress already dumped, response:\n%s", buf->pContext,
S
TD-1311  
Shengliang Guan 已提交
136
                  buf->pContext->fd, isTheLast, buf->buf);
S
TD-1451  
Shengliang Guan 已提交
137
        remain = 0;  // there is no data to dump.
S
slguan 已提交
138 139
      }
    } else {
S
TD-1207  
Shengliang Guan 已提交
140
      httpError("context:%p, fd:%d, failed to compress data, chunkSize:%d, last:%d, error:%d, response:\n%s",
S
TD-1311  
Shengliang Guan 已提交
141
                buf->pContext, buf->pContext->fd, srcLen, isTheLast, ret, buf->buf);
S
TD-1451  
Shengliang Guan 已提交
142
      remain = 0;
S
slguan 已提交
143
    }
H
hzcheng 已提交
144 145
  }

S
slguan 已提交
146
  httpWriteBufNoTrace(buf->pContext, "\r\n", 2);
S
TD-1311  
Shengliang Guan 已提交
147
  buf->total += (int32_t)(buf->lst - buf->buf);
H
hzcheng 已提交
148
  buf->lst = buf->buf;
S
TD-1311  
Shengliang Guan 已提交
149
  memset(buf->buf, 0, (size_t)buf->size);
S
slguan 已提交
150
  return remain;
H
hzcheng 已提交
151 152 153 154 155 156 157
}

void httpWriteJsonBufHead(JsonBuf* buf) {
  if (buf->pContext->fd <= 0) {
    buf->pContext->fd = -1;
  }

S
TD-1207  
Shengliang Guan 已提交
158 159
  char    msg[1024] = {0};
  int32_t len = -1;
H
hzcheng 已提交
160

S
TD-1311  
Shengliang Guan 已提交
161 162 163
  if (buf->pContext->parser->acceptEncodingGzip == 0 || !tsHttpEnableCompress) {
    len = sprintf(msg, httpRespTemplate[HTTP_RESPONSE_CHUNKED_UN_COMPRESS], httpVersionStr[buf->pContext->parser->httpVersion],
                  httpKeepAliveStr[buf->pContext->parser->keepAlive]);
H
hzcheng 已提交
164
  } else {
S
TD-1311  
Shengliang Guan 已提交
165 166
    len = sprintf(msg, httpRespTemplate[HTTP_RESPONSE_CHUNKED_COMPRESS], httpVersionStr[buf->pContext->parser->httpVersion],
                  httpKeepAliveStr[buf->pContext->parser->keepAlive]);
H
hzcheng 已提交
167 168 169 170 171 172 173
  }

  httpWriteBuf(buf->pContext, (const char*)msg, len);
}

void httpWriteJsonBufEnd(JsonBuf* buf) {
  if (buf->pContext->fd <= 0) {
S
TD-1311  
Shengliang Guan 已提交
174
    httpTrace("context:%p, fd:%d, json buf fd is 0", buf->pContext, buf->pContext->fd);
H
hzcheng 已提交
175 176 177
    buf->pContext->fd = -1;
  }

S
slguan 已提交
178 179
  httpWriteJsonBufBody(buf, true);
  httpWriteBufNoTrace(buf->pContext, "0\r\n\r\n", 5);  // end of chunked resp
H
hzcheng 已提交
180 181 182 183 184 185 186 187 188
}

void httpInitJsonBuf(JsonBuf* buf, struct HttpContext* pContext) {
  buf->lst = buf->buf;
  buf->total = 0;
  buf->size = JSON_BUFFER_SIZE;  // option setting
  buf->pContext = pContext;
  memset(buf->lst, 0, JSON_BUFFER_SIZE);

S
TD-1311  
Shengliang Guan 已提交
189
  if (pContext->parser->acceptEncodingGzip == 1 && tsHttpEnableCompress) {
S
slguan 已提交
190 191 192
    httpGzipCompressInit(buf->pContext);
  }

R
root 已提交
193
  httpTrace("context:%p, fd:%d, json buffer initialized", buf->pContext, buf->pContext->fd);
H
hzcheng 已提交
194 195 196 197 198 199 200 201 202 203
}

void httpJsonItemToken(JsonBuf* buf) {
  char c = *(buf->lst - 1);
  if (c == JsonArrStt || c == JsonObjStt || c == JsonPairTkn || c == JsonItmTkn) {
    return;
  }
  if (buf->lst > buf->buf) httpJsonToken(buf, JsonItmTkn);
}

S
TD-1311  
Shengliang Guan 已提交
204
void httpJsonString(JsonBuf* buf, char* sVal, int32_t len) {
H
hzcheng 已提交
205 206 207 208 209 210
  httpJsonItemToken(buf);
  httpJsonToken(buf, JsonStrStt);
  httpJsonPrint(buf, sVal, len);
  httpJsonToken(buf, JsonStrEnd);
}

S
TD-1311  
Shengliang Guan 已提交
211
void httpJsonOriginString(JsonBuf* buf, char* sVal, int32_t len) {
H
hzcheng 已提交
212 213 214 215
  httpJsonItemToken(buf);
  httpJsonPrint(buf, sVal, len);
}

S
TD-1311  
Shengliang Guan 已提交
216
void httpJsonStringForTransMean(JsonBuf* buf, char* sVal, int32_t maxLen) {
H
hzcheng 已提交
217 218 219 220 221 222 223 224
  httpJsonItemToken(buf);
  httpJsonToken(buf, JsonStrStt);

  if (sVal != NULL) {
    // dispose transferred meaning byte
    char* lastPos = sVal;
    char* curPos = sVal;

S
TD-1311  
Shengliang Guan 已提交
225
    for (int32_t i = 0; i < maxLen; ++i) {
H
hzcheng 已提交
226 227 228 229 230
      if (*curPos == 0) {
        break;
      }

      if (*curPos == '\"') {
S
TD-1311  
Shengliang Guan 已提交
231
        httpJsonPrint(buf, lastPos, (int32_t)(curPos - lastPos));
H
hzcheng 已提交
232 233 234 235
        curPos++;
        lastPos = curPos;
        httpJsonPrint(buf, "\\\"", 2);
      } else if (*curPos == '\\') {
S
TD-1311  
Shengliang Guan 已提交
236
        httpJsonPrint(buf, lastPos, (int32_t)(curPos - lastPos));
H
hzcheng 已提交
237 238 239 240 241 242 243 244 245
        curPos++;
        lastPos = curPos;
        httpJsonPrint(buf, "\\\\", 2);
      } else {
        curPos++;
      }
    }

    if (*lastPos) {
S
TD-1311  
Shengliang Guan 已提交
246
      httpJsonPrint(buf, lastPos, (int32_t)(curPos - lastPos));
H
hzcheng 已提交
247 248 249 250 251 252 253 254 255
    }
  }

  httpJsonToken(buf, JsonStrEnd);
}

void httpJsonInt64(JsonBuf* buf, int64_t num) {
  httpJsonItemToken(buf);
  httpJsonTestBuf(buf, MAX_NUM_STR_SZ);
L
lihui 已提交
256
  buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%" PRId64, num);
H
hzcheng 已提交
257 258
}

259 260 261 262 263 264
void httpJsonUInt64(JsonBuf* buf, uint64_t num) {
  httpJsonItemToken(buf);
  httpJsonTestBuf(buf, MAX_NUM_STR_SZ);
  buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%" PRIu64, num);
}

265
void httpJsonTimestamp(JsonBuf* buf, int64_t t, int32_t timePrecision) {
S
TD-1207  
Shengliang Guan 已提交
266
  char       ts[35] = {0};
267
  
268 269 270
  int32_t fractionLen;
  char* format = NULL;
  time_t quot = 0;
271
  int64_t mod = 0;
272 273 274

  switch (timePrecision) {
    case TSDB_TIME_PRECISION_MILLI: {
275 276 277 278
      mod = ((t) % 1000 + 1000) % 1000;
      if (t < 0 && mod != 0) {
        t -= 1000;
      }
279 280 281 282 283 284 285
      quot = t / 1000;
      fractionLen = 5;
      format = ".%03" PRId64;
      break;
    }

    case TSDB_TIME_PRECISION_MICRO: {
286 287 288 289
      mod = ((t) % 1000000 + 1000000) % 1000000;
      if (t < 0 && mod != 0) {
        t -= 1000000;
      }
290 291 292 293 294 295 296
      quot = t / 1000000;
      fractionLen = 8;
      format = ".%06" PRId64;
      break;
    }

    case TSDB_TIME_PRECISION_NANO: {
297 298 299 300
      mod = ((t) % 1000000000 + 1000000000) % 1000000000;
      if (t < 0 && mod != 0) {
        t -= 1000000000;
      }
301 302 303 304 305 306 307
      quot = t / 1000000000;
      fractionLen = 11;
      format = ".%09" PRId64;
      break;
    }

    default:
308
      fractionLen = 0;
309
      assert(false);
S
slguan 已提交
310
  }
H
hzcheng 已提交
311

312 313 314
  struct tm ptm = {0};
  localtime_r(&quot, &ptm);
  int32_t length = (int32_t)strftime(ts, 35, "%Y-%m-%d %H:%M:%S", &ptm);
315
  length += snprintf(ts + length, fractionLen, format, mod);
H
hzcheng 已提交
316

S
slguan 已提交
317
  httpJsonString(buf, ts, length);
S
slguan 已提交
318 319
}

320
void httpJsonUtcTimestamp(JsonBuf* buf, int64_t t, int32_t timePrecision) {
S
TD-1207  
Shengliang Guan 已提交
321 322
  char       ts[40] = {0};
  struct tm* ptm;
323 324 325 326 327 328 329 330

  int32_t fractionLen;
  char* format = NULL;
  time_t quot = 0;
  long mod = 0;

  switch (timePrecision) {
    case TSDB_TIME_PRECISION_MILLI: {
331 332 333 334
      mod = ((t) % 1000 + 1000) % 1000;
      if (t < 0 && mod != 0) {
        t -= 1000;
      }
335 336 337 338 339 340 341
      quot = t / 1000;
      fractionLen = 5;
      format = ".%03" PRId64;
      break;
    }

    case TSDB_TIME_PRECISION_MICRO: {
342 343 344 345
      mod = ((t) % 1000000 + 1000000) % 1000000;
      if (t < 0 && mod != 0) {
        t -= 1000000;
      }
346 347 348 349 350 351 352
      quot = t / 1000000;
      fractionLen = 8;
      format = ".%06" PRId64;
      break;
    }

    case TSDB_TIME_PRECISION_NANO: {
353 354 355 356
      mod = ((t) % 1000000000 + 1000000000) % 1000000000;
      if (t < 0 && mod != 0) {
        t -= 1000000000;
      }
357 358 359 360 361 362 363
      quot = t / 1000000000;
      fractionLen = 11;
      format = ".%09" PRId64;
      break;
    }

    default:
364
      fractionLen = 0;
365
      assert(false);
S
slguan 已提交
366 367
  }

368
  ptm = localtime(&quot);
S
TD-1311  
Shengliang Guan 已提交
369
  int32_t length = (int32_t)strftime(ts, 40, "%Y-%m-%dT%H:%M:%S", ptm);
370
  length += snprintf(ts + length, fractionLen, format, mod);
S
TD-1311  
Shengliang Guan 已提交
371
  length += (int32_t)strftime(ts + length, 40 - length, "%z", ptm);
S
slguan 已提交
372

S
slguan 已提交
373
  httpJsonString(buf, ts, length);
H
hzcheng 已提交
374 375
}

S
TD-1311  
Shengliang Guan 已提交
376
void httpJsonInt(JsonBuf* buf, int32_t num) {
H
hzcheng 已提交
377 378 379 380 381
  httpJsonItemToken(buf);
  httpJsonTestBuf(buf, MAX_NUM_STR_SZ);
  buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%d", num);
}

382 383 384 385 386 387
void httpJsonUInt(JsonBuf* buf, uint32_t num) {
  httpJsonItemToken(buf);
  httpJsonTestBuf(buf, MAX_NUM_STR_SZ);
  buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%u", num);
}

H
hzcheng 已提交
388 389 390
void httpJsonFloat(JsonBuf* buf, float num) {
  httpJsonItemToken(buf);
  httpJsonTestBuf(buf, MAX_NUM_STR_SZ);
S
slguan 已提交
391 392 393
  if (isinf(num) || isnan(num)) {
    buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "null");
  } else if (num > 1E10 || num < -1E10) {
H
hzcheng 已提交
394 395 396 397 398 399 400 401 402
    buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%.5e", num);
  } else {
    buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%.5f", num);
  }
}

void httpJsonDouble(JsonBuf* buf, double num) {
  httpJsonItemToken(buf);
  httpJsonTestBuf(buf, MAX_NUM_STR_SZ);
S
slguan 已提交
403 404 405
  if (isinf(num) || isnan(num)) {
    buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "null");
  } else if (num > 1E10 || num < -1E10) {
H
hzcheng 已提交
406 407 408 409 410 411 412 413
    buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%.9e", num);
  } else {
    buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%.9f", num);
  }
}

void httpJsonNull(JsonBuf* buf) { httpJsonString(buf, "null", 4); }

S
TD-1311  
Shengliang Guan 已提交
414
void httpJsonBool(JsonBuf* buf, int32_t val) {
H
hzcheng 已提交
415 416 417 418 419 420
  if (val == 0)
    httpJsonPrint(buf, JsonFalseTkn, sizeof(JsonFalseTkn));
  else
    httpJsonPrint(buf, JsonTrueTkn, sizeof(JsonTrueTkn));
}

S
TD-1311  
Shengliang Guan 已提交
421
void httpJsonPairHead(JsonBuf* buf, char* name, int32_t len) {
H
hzcheng 已提交
422 423 424 425 426
  httpJsonItemToken(buf);
  httpJsonString(buf, name, len);
  httpJsonToken(buf, JsonPairTkn);
}

S
TD-1311  
Shengliang Guan 已提交
427
void httpJsonPair(JsonBuf* buf, char* name, int32_t nameLen, char* sVal, int32_t valLen) {
H
hzcheng 已提交
428 429 430 431
  httpJsonPairHead(buf, name, nameLen);
  httpJsonString(buf, sVal, valLen);
}

S
TD-1311  
Shengliang Guan 已提交
432
void httpJsonPairOriginString(JsonBuf* buf, char* name, int32_t nameLen, char* sVal, int32_t valLen) {
H
hzcheng 已提交
433 434 435 436
  httpJsonPairHead(buf, name, nameLen);
  httpJsonOriginString(buf, sVal, valLen);
}

S
TD-1311  
Shengliang Guan 已提交
437
void httpJsonPairIntVal(JsonBuf* buf, char* name, int32_t nNameLen, int32_t num) {
H
hzcheng 已提交
438 439 440 441
  httpJsonPairHead(buf, name, nNameLen);
  httpJsonInt(buf, num);
}

S
TD-1311  
Shengliang Guan 已提交
442
void httpJsonPairInt64Val(JsonBuf* buf, char* name, int32_t nNameLen, int64_t num) {
H
hzcheng 已提交
443 444 445 446
  httpJsonPairHead(buf, name, nNameLen);
  httpJsonInt64(buf, num);
}

S
TD-1311  
Shengliang Guan 已提交
447
void httpJsonPairBoolVal(JsonBuf* buf, char* name, int32_t nNameLen, int32_t num) {
H
hzcheng 已提交
448 449 450 451
  httpJsonPairHead(buf, name, nNameLen);
  httpJsonBool(buf, num);
}

S
TD-1311  
Shengliang Guan 已提交
452
void httpJsonPairFloatVal(JsonBuf* buf, char* name, int32_t nNameLen, float num) {
H
hzcheng 已提交
453 454 455 456
  httpJsonPairHead(buf, name, nNameLen);
  httpJsonFloat(buf, num);
}

S
TD-1311  
Shengliang Guan 已提交
457
void httpJsonPairDoubleVal(JsonBuf* buf, char* name, int32_t nNameLen, double num) {
H
hzcheng 已提交
458 459 460 461
  httpJsonPairHead(buf, name, nNameLen);
  httpJsonDouble(buf, num);
}

S
TD-1311  
Shengliang Guan 已提交
462
void httpJsonPairNullVal(JsonBuf* buf, char* name, int32_t nNameLen) {
H
hzcheng 已提交
463 464 465 466
  httpJsonPairHead(buf, name, nNameLen);
  httpJsonNull(buf);
}

S
TD-1311  
Shengliang Guan 已提交
467
void httpJsonPairArray(JsonBuf* buf, char* name, int32_t len, httpJsonBuilder fnBuilder, void* dsHandle) {
H
hzcheng 已提交
468 469 470 471
  httpJsonPairHead(buf, name, len);
  httpJsonArray(buf, fnBuilder, dsHandle);
}

S
TD-1311  
Shengliang Guan 已提交
472
void httpJsonPairObject(JsonBuf* buf, char* name, int32_t len, httpJsonBuilder fnBuilder, void* dsHandle) {
H
hzcheng 已提交
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
  httpJsonPairHead(buf, name, len);
  httpJsonObject(buf, fnBuilder, dsHandle);
}

void httpJsonObject(JsonBuf* buf, httpJsonBuilder fnBuilder, void* dsHandle) {
  httpJsonItemToken(buf);
  httpJsonToken(buf, JsonObjStt);
  (*fnBuilder)(buf, dsHandle);
  httpJsonToken(buf, JsonObjEnd);
}

void httpJsonArray(JsonBuf* buf, httpJsonBuilder fnBuilder, void* jsonHandle) {
  httpJsonItemToken(buf);
  httpJsonToken(buf, JsonArrStt);
  (*fnBuilder)(buf, jsonHandle);
  httpJsonToken(buf, JsonArrEnd);
}

S
TD-1311  
Shengliang Guan 已提交
491
void httpJsonTestBuf(JsonBuf* buf, int32_t safety) {
H
hzcheng 已提交
492 493
  if ((buf->lst - buf->buf + safety) < buf->size) return;
  // buf->slot = *buf->lst;
S
slguan 已提交
494
  httpWriteJsonBufBody(buf, false);
H
hzcheng 已提交
495 496 497 498 499 500 501
}

void httpJsonToken(JsonBuf* buf, char c) {
  httpJsonTestBuf(buf, MAX_NUM_STR_SZ);  // maybe object stack
  *buf->lst++ = c;
}

S
TD-1311  
Shengliang Guan 已提交
502
void httpJsonPrint(JsonBuf* buf, const char* json, int32_t len) {
H
hzcheng 已提交
503 504 505 506 507
  if (len == 0 || len >= JSON_BUFFER_SIZE) {
    return;
  }

  if (len > buf->size) {
S
slguan 已提交
508
    httpWriteJsonBufBody(buf, false);
H
hzcheng 已提交
509 510 511 512 513 514 515 516 517
    httpJsonPrint(buf, json, len);
    // buf->slot = json[len - 1];
    return;
  }
  httpJsonTestBuf(buf, len + 2);
  memcpy(buf->lst, json, (size_t)len);
  buf->lst += len;
}

S
TD-1311  
Shengliang Guan 已提交
518
void httpJsonPairStatus(JsonBuf* buf, int32_t code) {
H
hzcheng 已提交
519 520 521 522 523
  if (code == 0) {
    httpJsonPair(buf, "status", 6, "succ", 4);
  } else {
    httpJsonPair(buf, "status", 6, "error", 5);
    httpJsonItemToken(buf);
S
Shengliang Guan 已提交
524
    httpJsonPairIntVal(buf, "code", 4, code & 0XFFFF);
S
Shengliang Guan 已提交
525 526 527 528 529 530
    httpJsonItemToken(buf);
    if (code == TSDB_CODE_MND_DB_NOT_SELECTED) {
      httpJsonPair(buf, "desc", 4, "failed to create database", 23);
    } else if (code == TSDB_CODE_MND_INVALID_TABLE_NAME) {
      httpJsonPair(buf, "desc", 4, "failed to create table", 22);
    } else {
S
TD-1311  
Shengliang Guan 已提交
531
      httpJsonPair(buf, "desc", 4, (char*)tstrerror(code), (int32_t)strlen(tstrerror(code)));
H
hzcheng 已提交
532 533
    }
  }
534
}