icinga2/jsonrpc/netstring.cpp

81 lines
1.9 KiB
C++
Raw Normal View History

2012-03-28 13:24:49 +02:00
#include <cstdio>
#include "i2-jsonrpc.h"
using namespace icinga;
/* based on https://github.com/PeterScott/netstring-c/blob/master/netstring.c */
2012-04-16 16:27:41 +02:00
Message::Ptr Netstring::ReadMessageFromFIFO(FIFO::Ptr fifo)
2012-03-28 13:24:49 +02:00
{
size_t buffer_length = fifo->GetSize();
2012-03-28 21:20:13 +02:00
char *buffer = (char *)fifo->GetReadBuffer();
2012-03-28 13:24:49 +02:00
/* minimum netstring length is 3 */
if (buffer_length < 3)
2012-03-28 21:20:13 +02:00
return NULL;
2012-03-28 13:24:49 +02:00
/* no leading zeros allowed */
if (buffer[0] == '0' && isdigit(buffer[1]))
throw exception(/*"Invalid netstring (leading zero)"*/);
size_t len, i;
len = 0;
for (i = 0; i < buffer_length && isdigit(buffer[i]); i++) {
/* length specifier must have at most 9 characters */
if (i >= 9)
2012-03-28 21:20:13 +02:00
return NULL;
2012-03-28 13:24:49 +02:00
len = len * 10 + (buffer[i] - '0');
}
/* make sure the buffer is large enough */
if (i + len + 1 >= buffer_length)
2012-03-28 21:20:13 +02:00
return NULL;
2012-03-28 13:24:49 +02:00
/* check for the colon delimiter */
if (buffer[i++] != ':')
throw exception(/*"Invalid Netstring (missing :)"*/);
/* check for the comma delimiter after the string */
if (buffer[i + len] != ',')
throw exception(/*"Invalid Netstring (missing ,)"*/);
2012-03-28 21:20:13 +02:00
/* nuke the comma delimiter */
buffer[i + len] = '\0';
cJSON *object = cJSON_Parse(&buffer[i]);
if (object == NULL) {
/* restore the comma */
buffer[i + len] = ',';
throw exception(/*"Invalid JSON string"*/);
}
2012-03-28 13:24:49 +02:00
/* remove the data from the fifo */
fifo->Read(NULL, i + len + 1);
2012-04-16 16:27:41 +02:00
return make_shared<Message>(object);
2012-03-28 13:24:49 +02:00
}
2012-04-16 16:27:41 +02:00
void Netstring::WriteMessageToFIFO(FIFO::Ptr fifo, Message::Ptr message)
2012-03-28 13:24:49 +02:00
{
char *json;
2012-04-16 16:27:41 +02:00
shared_ptr<cJSON> object = message->GetJson();
size_t len;
#ifdef _DEBUG
2012-04-16 16:27:41 +02:00
json = cJSON_Print(object.get());
#else /* _DEBUG */
2012-04-16 16:27:41 +02:00
json = cJSON_PrintUnformatted(object.get());
#endif /* _DEBUG */
len = strlen(json);
2012-03-28 13:24:49 +02:00
char strLength[50];
2012-03-28 21:20:13 +02:00
sprintf(strLength, "%lu", (unsigned long)len);
2012-03-28 13:24:49 +02:00
fifo->Write(strLength, strlen(strLength));
2012-03-28 21:20:13 +02:00
fifo->Write(json, len);
free(json);
2012-03-28 13:24:49 +02:00
fifo->Write(",", 1);
}