using namespace std;
-const char * query_str="QUERY_STRING";
-const char * uri_str="REQUEST_URI";
-const char * method_str="REQUEST_METHOD";
-const char * iotcloudroot_str="IOTCLOUD_ROOT";
-const char * length_str="CONTENT_LENGTH";
+const char * query_str = "QUERY_STRING";
+const char * uri_str = "REQUEST_URI";
+const char * method_str = "REQUEST_METHOD";
+const char * iotcloudroot_str = "IOTCLOUD_ROOT";
+const char * length_str = "CONTENT_LENGTH";
IoTQuery::IoTQuery(FCGX_Request *request) :
request(request),
bool IoTQuery::checkDirectory() {
struct stat s;
- int err=stat(directory, &s);
+ int err = stat(directory, &s);
if (-1 == err)
return false;
return S_ISDIR(s.st_mode);
*/
void IoTQuery::decodeQuery() {
- int len=strlen(query);
- char * str=new char[len+1];
- memcpy(str, query, len+1);
- char *tok_ptr=str;
-
+ int len = strlen(query);
+ char * str = new char[len + 1];
+ memcpy(str, query, len + 1);
+ char *tok_ptr = str;
+
/* Parse commands */
- char *command=strsep(&tok_ptr, "&");
+ char *command = strsep(&tok_ptr, "&");
if (strncmp(command, "req=putslot", 11) == 0)
reqPutSlot = true;
else if (strncmp(command, "req=getslot", 11) == 0)
/* Load Sequence Number for request */
char *sequencenumber_str = strsep(&tok_ptr, "&");
if (sequencenumber_str != NULL &&
- strncmp(sequencenumber_str, "seq=", 4) == 0) {
+ strncmp(sequencenumber_str, "seq=", 4) == 0) {
sequencenumber_str = strchr(sequencenumber_str, '=');
if (sequencenumber_str != NULL) {
requestsequencenumber = strtoll(sequencenumber_str + 1, NULL, 10);
/* Update size if we get request */
char * numqueueentries_str = tok_ptr;
if (numqueueentries_str != NULL &&
- strncmp(numqueueentries_str, "max=", 4) == 0) {
+ strncmp(numqueueentries_str, "max=", 4) == 0) {
numqueueentries_str = strchr(numqueueentries_str, '=') + 1;
numqueueentries = strtoll(numqueueentries_str, NULL, 10);
}
*/
void doWrite(int fd, char *data, long long length) {
- long long offset=0;
+ long long offset = 0;
do {
- long long byteswritten=write(fd, &data[offset], length);
+ long long byteswritten = write(fd, &data[offset], length);
if (byteswritten > 0) {
length -= byteswritten;
offset += byteswritten;
}
return;
}
- } while(length != 0);
+ } while (length != 0);
}
/** Helper function to read data from file. */
bool doRead(int fd, void *buf, int numbytes) {
- int offset=0;
- char *ptr=(char *)buf;
+ int offset = 0;
+ char *ptr = (char *)buf;
do {
- int bytesread=read(fd, ptr+offset, numbytes);
+ int bytesread = read(fd, ptr + offset, numbytes);
if (bytesread > 0) {
offset += bytesread;
numbytes -= bytesread;
} else
return false;
- } while (numbytes!=0);
+ } while (numbytes != 0);
return true;
}
*/
void IoTQuery::getSlot() {
- int numrequeststosend = (int)((newestentry-requestsequencenumber)+1);
+ int numrequeststosend = (int)((newestentry - requestsequencenumber) + 1);
if (numrequeststosend < 0)
numrequeststosend = 0;
long long numbytes = 0;
int filesizes[numrequeststosend];
int fdarray[numrequeststosend];
- int index=0;
- for(long long seqn = requestsequencenumber; seqn <= newestentry; seqn++, index++) {
+ int index = 0;
+ for (long long seqn = requestsequencenumber; seqn <= newestentry; seqn++, index++) {
struct stat st;
- char *filename=getSlotFileName(seqn);
+ char *filename = getSlotFileName(seqn);
if (stat(filename, &st) == 0) {
- fdarray[index]=open(filename, O_RDONLY);
- filesizes[index]=st.st_size;
- numbytes+=filesizes[index];
+ fdarray[index] = open(filename, O_RDONLY);
+ filesizes[index] = st.st_size;
+ numbytes += filesizes[index];
} else {
- fdarray[index]=-1;
- filesizes[index]=0;
+ fdarray[index] = -1;
+ filesizes[index] = 0;
}
delete filename;
}
- const char header[]="getslot";
+ const char header[] = "getslot";
/* Size is the header + the payload + space for number of requests
plus sizes of each slot */
- long long size=sizeof(header)-1+sizeof(numrequeststosend)+4*numrequeststosend+numbytes;
+ long long size = sizeof(header) - 1 + sizeof(numrequeststosend) + 4 * numrequeststosend + numbytes;
char * response = new char[size];
- long long offset=0;
- memcpy(response, header, sizeof(header)-1);
- offset+=sizeof(header)-1;
- int numreq=htonl(numrequeststosend);
+ long long offset = 0;
+ memcpy(response, header, sizeof(header) - 1);
+ offset += sizeof(header) - 1;
+ int numreq = htonl(numrequeststosend);
memcpy(response + offset, &numreq, sizeof(numreq));
- offset+=sizeof(numrequeststosend);
- for(int i=0; i<numrequeststosend; i++) {
- int filesize=htonl(filesizes[i]);
+ offset += sizeof(numrequeststosend);
+ for (int i = 0; i < numrequeststosend; i++) {
+ int filesize = htonl(filesizes[i]);
memcpy(response + offset, &filesize, sizeof(filesize));
- offset+=sizeof(int);
+ offset += sizeof(int);
}
/* Read the file data into the buffer */
- for(int i=0; i<numrequeststosend; i++) {
- if (fdarray[i]>=0) {
- doRead(fdarray[i], response+offset, filesizes[i]);
- offset+=filesizes[i];
+ for (int i = 0; i < numrequeststosend; i++) {
+ if (fdarray[i] >= 0) {
+ doRead(fdarray[i], response + offset, filesizes[i]);
+ offset += filesizes[i];
}
}
/* Delete the response buffer and close the files. */
delete response;
- for(int i=0; i<numrequeststosend; i++) {
+ for (int i = 0; i < numrequeststosend; i++) {
if (fdarray[i] >= 0)
close(fdarray[i]);
}
void IoTQuery::setSalt() {
/* Write the slot data we received to a SLOT file */
char *filename = getSaltFileName();
- int saltfd = open(filename, O_CREAT|O_WRONLY, S_IRUSR| S_IWUSR);
- doWrite(saltfd, data, length);
- char response[0];
- sendResponse(response, 0);
- close(saltfd);
+ char * response = new char[1];
+
+ if (access(filename, F_OK) == 0)
+ {
+ /* Already Exists */
+ response[0] = 1;
+ }
+ else
+ {
+ /* Does not exist so create it */
+ int saltfd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
+ doWrite(saltfd, data, length);
+ close(saltfd);
+ response[0] = 0;
+ }
+
+
+ sendResponse(response, 1);
+
delete filename;
+ delete response;
}
/**
int filesize = 0;
struct stat st;
if (stat(filename, &st) == 0) {
- filesize=st.st_size;
+ filesize = st.st_size;
} else {
delete filename;
return;
int saltfd = open(filename, O_RDONLY);
int responsesize = filesize + sizeof(int);
char * response = new char[responsesize];
- doRead(saltfd, response+ sizeof(int), filesize);
- int n_filesize=htonl(filesize);
+ doRead(saltfd, response + sizeof(int), filesize);
+ int n_filesize = htonl(filesize);
*((int*) response) = n_filesize;
sendResponse(response, responsesize);
close(saltfd);
void IoTQuery::putSlot() {
/* Check if the request is stale and send update in that case. This
servers as an implicit failure of the request. */
- if (requestsequencenumber!=(newestentry+1)) {
+ if (requestsequencenumber != (newestentry + 1)) {
getSlot();
return;
}
/* See if we have too many slots and if so, delete the old one */
- int numberofliveslots=(int) ((newestentry-oldestentry)+1);
+ int numberofliveslots = (int) ((newestentry - oldestentry) + 1);
if (numberofliveslots >= numqueueentries) {
removeOldestSlot();
}
/* Write the slot data we received to a SLOT file */
char *filename = getSlotFileName(requestsequencenumber);
- int slotfd = open(filename, O_CREAT|O_WRONLY, S_IRUSR| S_IWUSR);
+ int slotfd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
doWrite(slotfd, data, length);
close(slotfd);
delete filename;
updateStatusFile();
/* Send response acknowledging success */
- char command[]="putslot";
- sendResponse(command, sizeof(command)-1);
+ char command[] = "putslot";
+ sendResponse(command, sizeof(command) - 1);
}
/**
void IoTQuery::sendResponse(char * bytes, int len) {
cout << "Accept-Ranges: bytes\r\n"
- << "Content-Length: " << len << "\r\n"
- << "\r\n";
+ << "Content-Length: " << len << "\r\n"
+ << "\r\n";
cout.write(bytes, len);
}
*/
char * IoTQuery::getSlotFileName(long long seqnum) {
- int directorylen=strlen(directory);
+ int directorylen = strlen(directory);
/* Size is 19 digits for ASCII representation of a long + 4
characters for SLOT string + 1 character for null termination +
directory size*/
- char * filename=new char[25+directorylen];
- snprintf(filename, 25+directorylen, "%s/SLOT%lld", directory, seqnum);
+ char * filename = new char[25 + directorylen];
+ snprintf(filename, 25 + directorylen, "%s/SLOT%lld", directory, seqnum);
return filename;
}
*/
char * IoTQuery::getSaltFileName() {
- int directorylen=strlen(directory);
+ int directorylen = strlen(directory);
/* Size is 4 characters for SALT string + 1 character for null
termination + directory size*/
- char * filename=new char[6+directorylen];
- snprintf(filename, 6+directorylen, "%s/SALT", directory);
+ char * filename = new char[6 + directorylen];
+ snprintf(filename, 6 + directorylen, "%s/SALT", directory);
return filename;
}
*/
void IoTQuery::removeOldestSlot() {
- if (oldestentry!=0) {
- char * filename=getSlotFileName(oldestentry);
+ if (oldestentry != 0) {
+ char * filename = getSlotFileName(oldestentry);
unlink(filename);
delete filename;
}
void IoTQuery::processQuery() {
getQuery();
getDirectory();
- readData();
+ if (!readData())
+ {
+ return;
+ }
+
/* Verify that we receive a post request. */
if (strncmp(method, "POST", 4) != 0) {
/* Make sure the directory is okay. */
if (directory == NULL ||
- !checkDirectory()) {
+ !checkDirectory()) {
cerr << "Directory " << directory << " does not exist" << endl;
return;
}
/* Decode query. */
decodeQuery();
-
+
/* Handle request. */
if (reqGetSlot)
getSlot();
* inserted.
*/
-void IoTQuery::readData() {
+bool IoTQuery::readData() {
if (length) {
- data = new char[length+1];
- memset(data, 0, length+1);
+ data = new char[length + 1];
+ memset(data, 0, length + 1);
cin.read(data, length);
}
do {
char dummy;
cin >> dummy;
} while (!cin.eof());
+
+ if (length)
+ {
+ if (cin.fail())
+ {
+ return false;
+ }
+ }
+
+ return true;
}
/** We require the content-length header to be sent. */
char * reqlength = FCGX_GetParam(length_str, request->envp);
if (reqlength) {
- length=strtoll(reqlength, NULL, 10);
+ length = strtoll(reqlength, NULL, 10);
} else {
- length=0;
+ length = 0;
}
}
char * split = strchr((char *)uri, '?');
if (split == NULL)
return;
- int split_len = (int) (split-uri);
+ int split_len = (int) (split - uri);
int rootdir_len = strlen(iotcloudroot);
int directory_len = split_len + rootdir_len + 1;
directory = new char[directory_len];
memcpy(directory, iotcloudroot, rootdir_len);
memcpy(directory + rootdir_len, uri, split_len);
- directory[directory_len-1]=0;
+ directory[directory_len - 1] = 0;
}
/**
int doread(int fd, void *ptr, size_t count, off_t offset) {
do {
- size_t bytesread=pread(fd, ptr, count, offset);
- if (bytesread==count) {
+ size_t bytesread = pread(fd, ptr, count, offset);
+ if (bytesread == count) {
return 1;
- } else if (bytesread==0) {
+ } else if (bytesread == 0) {
return 0;
}
- } while(1);
+ } while (1);
}
*/
bool IoTQuery::openStatusFile() {
- char statusfile[]="queuestatus";
- int len=strlen(directory);
+ char statusfile[] = "queuestatus";
+ int len = strlen(directory);
- char * filename=new char[len+sizeof(statusfile)+2];
+ char * filename = new char[len + sizeof(statusfile) + 2];
memcpy(filename, directory, len);
- filename[len]='/';
- memcpy(filename+len+1, statusfile, sizeof(statusfile));
- filename[len+sizeof(statusfile)+1]=0;
- fd=open(filename, O_CREAT| O_RDWR, S_IRUSR| S_IWUSR);
+ filename[len] = '/';
+ memcpy(filename + len + 1, statusfile, sizeof(statusfile));
+ filename[len + sizeof(statusfile) + 1] = 0;
+ fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
delete filename;
if (fd < 0) {
/* Read in queue size, oldest sequence number, and newest sequence number. */
int size;
- int needwrite=0;
+ int needwrite = 0;
if (doread(fd, &size, sizeof(size), OFFSET_MAX))
- numqueueentries=size;
+ numqueueentries = size;
else
- needwrite=1;
+ needwrite = 1;
long long entry;
if (doread(fd, &entry, sizeof(entry), OFFSET_OLD))
- oldestentry=entry;
+ oldestentry = entry;
else
- needwrite=1;
+ needwrite = 1;
if (doread(fd, &entry, sizeof(entry), OFFSET_NEW))
- newestentry=entry;
+ newestentry = entry;
else
- needwrite=1;
+ needwrite = 1;
if (needwrite)
updateStatusFile();