/* microhttpd */
#include <stdbool.h>
#include <microhttpd.h>
#define PORT 8080
#define POSTBUFFERSIZE 512
#define GET 0
#define POST 1
#define REQUEST_REFUSED_PAGE \
"<html><head><title> Request refused </title></head><body> Request Refused (file exist?) </body></html>"
const char *responseOK = "\"Result\":\"OK\"";
const char *responseExist = "\"Result\":\"Queue Exist\"";
struct postStatus {
bool status;
char *buff;
};
struct NODE {
struct NODE *next;
char msg[30];
int available;
char idx[5];
};
struct MULTI_MSG_QUEUE {
int cur_size;
int max_size;
char name[20];
struct NODE *msgq;
};
int cur_multi_queue_cnt =0;
struct MULTI_MSG_QUEUE multi_queue[10] = {0};
static struct MHD_Response *request_refused_response;
static void request_completed_callback (void *cls,
struct MHD_Connection *connection,
void **con_cls,
enum MHD_RequestTerminationCode toe)
{
printf("request_completed_callback \n");
}
static enum MHD_Result access_handler_callback ( void * cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
size_t *upload_data_size, void **con_cls) {
int ret;
printf("url - %s \n", url);
printf("method - %s \n", method);
printf("version - %s \n", version);
printf("upload_data - %s size - %d \n", upload_data, (int)*upload_data_size);
struct MHD_Response * response;
char url_cpy[50] = {0};
char cmd_list[3][20] = {0};
int cmd_cnt =0;
char *str_ptr = NULL;
char queue_size[10] ={0};
char queue_message[50] = {0};
strcpy(url_cpy,url);
if(url_cpy[0] == '/') {
str_ptr = strtok(&url_cpy[1], "/");
}else {
str_ptr = strtok(url_cpy, "/");
}
while(str_ptr != NULL) {
strcpy(cmd_list[cmd_cnt], str_ptr);
str_ptr = strtok(NULL, "/");
cmd_cnt++;
}
struct postStatus *post = NULL;
post = (struct postStatus *)*con_cls;
if(post == NULL) {
post = malloc(sizeof(struct postStatus));
post->status = false;
post->buff = NULL;
*con_cls = post;
}
printf("post->status = %d \n", post->status);
if(!post->status) {
post->status = true;
return MHD_YES;
}else {
if(*upload_data_size != 0) {
post->buff = malloc(*upload_data_size +1);
memset(post->buff, 0, *upload_data_size +1);
strncpy(post->buff, upload_data, *upload_data_size);
*upload_data_size =0;
return MHD_YES;
}else {
if(strncmp(cmd_list[0], "CREATE",6) == 0) {
json_object *root, *QueueSize;
root = json_tokener_parse(post->buff);
json_object_object_get_ex(root, "QueueSize", &QueueSize);
printf("QueueSize : %s \n", json_object_get_string(QueueSize));
strcpy(queue_size, json_object_get_string(QueueSize));
}else if(strncmp(cmd_list[0], "SEND",4) == 0) {
json_object *root, *q_msg;
root = json_tokener_parse(post->buff);
json_object_object_get_ex(root, "Message", &q_msg);
printf("Message : %s \n", json_object_get_string(q_msg));
strcpy(queue_message, json_object_get_string(q_msg));
}else if(strncmp(cmd_list[0], "RECEIVE",7) == 0) {
//[no body]
}
if(post->buff != NULL) {
free(post->buff);
}
}
}
if(post != NULL) {
free(post);
}
json_object *myobj = json_object_new_object();
if(strncmp(cmd_list[0], "CREATE",6) == 0) {
int is_exist =0;
for(int i=0; i<cur_multi_queue_cnt; i++) {
if(strncmp(multi_queue[i].name, cmd_list[1], strlne(cmd_list[i]) ) == 0) {
is_exist =1;
break;
}
}
if(is_exist) {
printf("Queue Exist \n");
json_object_object_add(myobj, "Result", json_object_new_string("Queue Exist"));
}else {
multi_queue[cur_multi_queue_cnt].max_size = atoi(queue_size);
strcpy(multi_queue[cur_multi_queue_cnt].name = cmd_list[1]);
multi_queue[cur_multi_queue_cnt].cur_size =0;
multi_queue[cur_multi_queue_cnt].msgq = (struct NODE *)malloc(sizeof(struct NODE));
multi_queue[cur_multi_queue_cnt].msgq->next = NULL;
cur_multi_queue_cnt++;
json_object_object_add(myobj, "Result", json_object_new_string("Ok"));
}
}else if(strncmp(cmd_list[0], "SEND",4) == 0) {
int q_cnt =-1;
for(int i=0; i<cur_multi_queue_cnt; i++) {
if(strncmp(multi_queue[i].name, cmd_list[1], strlne(cmd_list[i]) ) == 0) {
q_cnt =i;
break;
}
}
if(q_cnt != -1) {
if(multi_queue[q_cnt].cur_size < multi_queue[q_cnt].max_size) {
struct NODE *new = (struct NODE *)malloc(sizeof(struct NODE));
char msg_cpy[30] ={0};
memset(new->msg, 0, siezeof(new->msg));
new->next = NULL;
strcpy(new->msg, queue_message);
new->available = 1;
strcpy(msg_cpy,queue_message);
int msg_loop_cnt = 0;
str_ptr = strtok(msg_cpy, "#");
while(str_ptr != NULL) {
if(msg_loop_cnt == 0) {
}else if(msg_loop_cnt == 1) {
strcpy(new->idx, str_ptr);
}
str_ptr = strtok(NULL, "#");
msg_loop_cnt++;
}
}
struct NODE *cur = multi_queuep[q_cnt].msgq;
new->next= cur->next;
cur->next = new;
multi_queue[q_cnt].cur_size++;
json_object_object_add(myobj, "Result", json_object_new_string("Ok"));
}else {
printf("Queue Full \n");
json_object_object_add(myobj, "Result", json_object_get_string("Queue Full"));
}
}else if(strncmp(cmd_list[0], "RECEIVE",7) == 0) {
//similar with SEND
}
const char *result_json = json_object_to_json_string_ext(myobj, JSON_C_TO_STRING_PLAIN);
response = MHD_create_response_from_buffer (strlen(result_json), (void *)result_json,
MHD_RESPMEM_MUST_COPY);
if(!response) {
return MHD_NO;
}
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response);
return ret;
}
int main(int argc, char *argv[]) {
struct MHD_Daemon *daemon = MHD_start_daemon (
MHD_USE_THREAD_PER_CONNECTION,
PORT,
NULL, NULL,
&access_handler_callback,
NULL,
MHD_OPTION_NOTIFY_COMPLETED,
&request_completed_callback,
NULL,
MHD_OPTION_END);
request_refused_response = MHD_create_response_from_buffer(strlen(REQUEST_REFUSED_PAGE),
(void *)REQUEST_REFUSED_PAGE,
MHD_RESPMEM_PERSISTENT);
if(daemon == NULL) {
fprintf(stderr, "MHD_start_daemon () error \n");
return EXIT_FAILURE;
}
while(true) {
getc(stdin);
}
//HTTP 데몬을 종료한다.
MHD_stop_daemon(daemon);
MHD_destroy_response(request_refused_response);
return EXIT_SUCCESS;
}