Skip to content

Commit

Permalink
Made API server more spec compliant.
Browse files Browse the repository at this point in the history
md5sum a.out
b23d375349c7a7966745a564f13a2ab3  a.out

The API server is _mostly_ compliant with the comments endpoint. It
doesn't follow all conventions perfectly. There are some methods (the
comments endpoint being chief among them) that refuse to pass the spider
test because of problems with the control structure and how it differs
from the other endpoints.

The comments endpoint passes error control back to the controller
function call instead of printing out the error messages itself. The
other endpoints handle their error cases within the *_<method> calls.

This could be a refactor of the comments error handling and would clear
up some of these problems.
  • Loading branch information
EdgeCaseBerg committed Nov 11, 2013
1 parent b8ae532 commit 118968e
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 15 deletions.
2 changes: 1 addition & 1 deletion green-serv.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ int main(int argc, const char* argv[]) {
char buff[1024];
bzero(buff,1024);
/*What a silly cast we have to make...*/
test_network(buff,1024,(void*(*)(void*))&doNetWork);
run_network(buff,1024,(void*(*)(void*))&doNetWork);

/*Clean Up database connection*/
mysql_library_end();
Expand Down
1 change: 1 addition & 0 deletions headers/controllers/comments.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#ifndef MISSING_ID_KEY
#define MISSING_ID_KEY "Required key id not found"
#endif
#define EMPTY_COMMENT_MESSAGE "Message may not be empty"

int comment_controller(const struct http_request * request, char * stringToReturn, int strLength);

Expand Down
6 changes: 4 additions & 2 deletions headers/network/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#define METHOD_LENGTH 7

#define FIRSTLINEBUFFSIZE 256
#define NUMTHREADS 1/*00*/
#define NUMTHREADS 100
#define DETACHED_THREADS
#undef DETACHED_THREADS
#undef DETACHED_THREADS /* Using detacthed threads runs the risk of leaving fd's open */
/* Simple struct to contain data to be sent to worker threads */
struct threadData{
char msg[16384];
Expand Down Expand Up @@ -64,6 +64,8 @@
/* This function is unlikely to live beyond testing things */
int test_network(char * buffer, int bufferLength, void*( *func )(void*) );

int run_network(char * buffer, int bufferLength, void*( *func )(void*) );



#endif
57 changes: 46 additions & 11 deletions src/controllers/comments.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ int comment_controller(const struct http_request * request, char * stringToRetur
page = atoi(tempBuf);
if(page <= 0){
/* Err */
status = 400;
status = 422;
sm_delete(sm);
goto cc_badpage;
}
Expand All @@ -55,7 +55,7 @@ int comment_controller(const struct http_request * request, char * stringToRetur
if(strncasecmp(cType, CTYPE_1,COMMENTS_CTYPE_SIZE) != 0)
if(strncasecmp(cType, CTYPE_2,COMMENTS_CTYPE_SIZE) != 0)
if(strncasecmp(cType, CTYPE_3,COMMENTS_CTYPE_SIZE) != 0){
status = 400;
status = 422;
sm_delete(sm);
goto cc_badtype;
}
Expand Down Expand Up @@ -95,12 +95,17 @@ int comment_controller(const struct http_request * request, char * stringToRetur
if( status == -1 ){
sm_delete(sm);
goto cc_nomem;
} else if(status == 400) {
} else if(status == 422) {
sm_delete(sm);
goto cc_badtype;
} else if(status == -400) {
status = 400;
sm_delete(sm);
goto cc_missing;
}else if(status == -422){
sm_delete(sm);
status = 422;
goto cc_emptymessage;
}
snprintf(stringToReturn,strLength,"%s",buffer);
break;
Expand Down Expand Up @@ -150,6 +155,10 @@ int comment_controller(const struct http_request * request, char * stringToRetur
snprintf(stringToReturn, strLength, ERROR_STR_FORMAT, status, MISSING_ID_KEY);
return status;

cc_emptymessage:
snprintf(stringToReturn, strLength, ERROR_STR_FORMAT, status, EMPTY_COMMENT_MESSAGE);
return status;

}

/*Accepts NULL for cType if no filter
Expand Down Expand Up @@ -243,15 +252,17 @@ int comment_post(char * buffer, int buffSize, const struct http_request * reques
struct gs_comment insComment;
StrMap * sm;
int i;
int empty;
int j;
int strFlag;
char keyBuffer[GS_COMMENT_MAX_LENGTH+1];
char valBuffer[GS_COMMENT_MAX_LENGTH+1];

char **convertSuccess;

bzero(keyBuffer,sizeof keyBuffer);
gs_comment_ZeroStruct(&insComment);
strFlag = 0;
convertSuccess = NULL;

sm = sm_new(HASH_TABLE_CAPACITY);
if(sm == NULL){
Expand All @@ -272,14 +283,14 @@ int comment_post(char * buffer, int buffSize, const struct http_request * reques
/*find the beginning of the value
*which is either a " or a number. So skip spaces and commas
*/
for(i++; i < request->contentLength && request->data[i] != '\0' && (request->data[i] == ',' || request->data[i] == ' ' || request->data[i] == ':'); ++i)
for(i++; i< (int)(sizeof valBuffer)-1 && i < request->contentLength && request->data[i] != '\0' && (request->data[i] == ',' || request->data[i] == ' ' || request->data[i] == ':'); ++i)
;
/*Skip any opening qoute */
if(request->data[i] != '\0' && request->data[i] == '"'){
if( i < (int)(sizeof valBuffer)-1 && request->data[i] != '\0' && request->data[i] == '"'){
i++;
strFlag = 1;
}
for(j=0; i < request->contentLength && request->data[i] != '\0'; ++j,++i){
for(j=0; i < request->contentLength && request->data[i] != '\0' && i < (int)(sizeof valBuffer)-1; ++j,++i){
if(strFlag == 0){
if(request->data[i] == ' ' || request->data[i] == '\n')
break; /*break out if num data*/
Expand All @@ -291,11 +302,12 @@ int comment_post(char * buffer, int buffSize, const struct http_request * reques
}
valBuffer[j] = '\0';
/* Skip any closing paren. */
if(request->data[i] == '"')
if(i < (int)(sizeof valBuffer) && request->data[i] == '"')
i++;
if(strlen(keyBuffer) > 0 && strlen(valBuffer) > 0)
if(strlen(keyBuffer) > 0 && strlen(valBuffer) > 0){
if(sm_put(sm, keyBuffer, valBuffer) == 0)
fprintf(stderr, "Failed to copy parameters into hash table while parsing url\n");
}
}
strFlag = 0;
}
Expand All @@ -306,14 +318,22 @@ int comment_post(char * buffer, int buffSize, const struct http_request * reques
fprintf(stderr, "required keys not found\n");
return -400;
}else{
if(sm_exists(sm,"message") == 1){
if(sm_get(sm,"type",keyBuffer, sizeof keyBuffer) == 1){
if(strlen(keyBuffer) > GS_COMMENT_MAX_LENGTH){
sm_delete(sm);
return 422;
}
}
}
if(sm_exists(sm, "type") ==1){
if(sm_get(sm,"type", valBuffer, sizeof valBuffer) == 1){
/* Verify that it is a correct type */
if(strncasecmp(valBuffer, CTYPE_1,COMMENTS_CTYPE_SIZE) != 0)
if(strncasecmp(valBuffer, CTYPE_2,COMMENTS_CTYPE_SIZE) != 0)
if(strncasecmp(valBuffer, CTYPE_3,COMMENTS_CTYPE_SIZE) != 0){
sm_delete(sm);
return 400;
return 422;
}

}
Expand All @@ -323,10 +343,25 @@ int comment_post(char * buffer, int buffSize, const struct http_request * reques
/* valid, cary on and copy over */
gs_comment_setScopeId(_shared_campaign_id, &insComment);
sm_get(sm, "message",valBuffer, sizeof valBuffer);
/* Check for message being empty */
empty = 1;
for(i=0; i < (int)strlen(valBuffer); ++i){
empty = empty && (valBuffer[i] == ' ');
}
if(empty){
sm_delete(sm);
return -422;
}
fprintf(stderr, "val::%s\n", valBuffer);
gs_comment_setContent(valBuffer, &insComment);
if(sm_exists(sm, "pin")){
sm_get(sm, "pin",keyBuffer,sizeof keyBuffer);
gs_comment_setPinId(atol(keyBuffer),&insComment);
if(strtod(keyBuffer,convertSuccess) != 0 && convertSuccess == NULL){
gs_comment_setPinId(atol(keyBuffer),&insComment);
}else{
sm_delete(sm);
return 422;
}
}
sm_get(sm, "type", insComment.cType, sizeof insComment.cType);
sm_delete(sm);
Expand Down
97 changes: 96 additions & 1 deletion src/network/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,99 @@ int test_network(char * buffer, int bufferLength, void*(*func)(void*)){
sleep(2);

return 0;
}
}


#include <unistd.h>
#include <stdio.h>
#include <signal.h>

volatile sig_atomic_t stop;
void stop_server(int signum){
/* Call me with ctrl Z if ctrl c doesnt work*/
stop = 1;
if(signum == SIGINT)
stop =1;

}

int run_network(char * buffer, int bufferLength, void*(*func)(void*)){
struct sockaddr_in sockserv,sockclient;
int socketfd,clientfd;
socklen_t clientsocklen;
char buff[BUFSIZ];
pthread_t children[NUMTHREADS];
struct threadData data[NUMTHREADS];
int i,j;
stop = 0;
#ifdef DETACHED_THREADS
pthread_attr_t attr;
#endif

clientfd = socketfd = 0;
bzero(buff,BUFSIZ);
bzero(&sockserv,sizeof(sockserv));

socketfd = createSocket();
setupSockAndBind(socketfd, &sockserv, PORT);
listen(socketfd,NUMTHREADS);

clientsocklen = sizeof socketfd;

#ifdef DETACHED_THREADS
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
#endif

signal(SIGINT, stop_server);
signal(SIGTERM, stop_server);
signal(SIGQUIT, stop_server);
signal(SIGHUP, stop_server);

i=j=0;
if(errno != 13){
while(stop == 0){
for(i=0; i < NUMTHREADS && stop == 0; i++){
clientfd = accept(socketfd,(struct sockaddr*)&sockclient,&clientsocklen);
buff[read(clientfd,buff,BUFSIZ)] = '\0';
strncpy(buffer, buff ,bufferLength);

/* A thread pool would be intelligent here */
sprintf(data[i].msg, "%s", buffer);
data[i].clientfd = clientfd;
#ifndef DETACHED_THREADS
pthread_create(&children[i],NULL,func,&data[i]);
#else
pthread_create(&children[i],&attr,func,&data[i]);
#endif
bzero(buff,BUFSIZ);
bzero(buffer,bufferLength);

}
/*Gobble Up the resources (if not detaching threads)
*If you do want to detach threads change the define.
*in net.h
*/
#ifndef DETACHED_THREADS
for(j=0; j < NUMTHREADS && j < i; ++j)
pthread_join(children[j],NULL);
#endif
}
}
#ifndef DETACHED_THREADS
for(j=0; j < i && j < NUMTHREADS; ++j)
pthread_join(children[j],NULL);
#endif
#ifdef DETACHED_THREADS
pthread_attr_destroy(&attr);
#endif
if(shutdown(socketfd,2) <0)
fprintf(stderr, "%s\n", "Problem shutting down socket descriptor");
if(close(socketfd) < 0)
fprintf(stderr, "%s\n", "Problem closing socket descriptor");
/* Sleep a moment to hope that any running threads will finish */
fprintf(stdout, "%s\n", "Exiting Server...");
sleep(2);

return 0;
}

0 comments on commit 118968e

Please sign in to comment.