ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/libs/libcgi/patches/001-add_check_session.patch b/package/libs/libcgi/patches/001-add_check_session.patch
new file mode 100644
index 0000000..d4c8b7e
--- /dev/null
+++ b/package/libs/libcgi/patches/001-add_check_session.patch
@@ -0,0 +1,230 @@
+diff -r -u libcgi-back-1.0/libcgi-1.0/src/cgi.c libcgi-1.0/src/cgi.c
+--- libcgi-back-1.0/libcgi-1.0/src/cgi.c 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/cgi.c 2015-05-11 16:19:55.980570364 +0800
+@@ -143,16 +143,18 @@
+ char *method;
+
+ method = getenv("REQUEST_METHOD");
+-
++ system("echo \"cgi_process_form!\" > /tmp/my_debug");
+ // When METHOD has no contents, the default action is to process it as GET method
+- if (method == NULL || !strcasecmp("GET", method)) {
++ if (method == NULL || !strcasecmp("GET", method) || !strcasecmp("POST", method)) {
+ char *dados;
+ dados = getenv("QUERY_STRING");
+-
++
+ // Sometimes, GET comes with not any data
+- if (dados == NULL || strlen(dados) < 1)
+- return NULL;
+-
++ if (dados == NULL || strlen(dados) < 1) {
++ system("echo \"query string is null!\" > /tmp/my_debug");
++ return NULL;
++ }
++ system("echo \"query string is not null!\" > /tmp/my_debug");
+ return process_data(dados, &formvars_start, &formvars_last, '=', '&');
+ }
+ else if (!strcasecmp("POST", method)) {
+diff -r -u libcgi-back-1.0/libcgi-1.0/src/cgi.h libcgi-1.0/src/cgi.h
+--- libcgi-back-1.0/libcgi-1.0/src/cgi.h 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/cgi.h 2015-05-08 16:56:51.865844100 +0800
+@@ -25,6 +25,14 @@
+ extern "C" {
+ #endif
+
++#define LAST_ACCESS_TIME "last_time"
++#define LOG_STATUS "log_status"
++#define USER_ID "user_name"
++#define USER_PSWD "user_pswd"
++//second
++#define MAX_SESSION_TIMEOUT 600
++//tmp buffer size
++#define TMP_BUF_MAX 256
+
+ // general purpose linked list. Actualy isn't very portable
+ // because uses only 'name' and 'value' variables to store data.
+@@ -36,6 +44,15 @@
+ struct formvarsA *next;
+ } formvars;
+
++enum {
++ SESS_VALID,
++ SESS_NO_COOKIE,
++ SESS_NO_ACCESS_TIME,
++ SESS_NOT_FOUND,
++ SESS_INVALID,
++ SESS_TIMEOUT
++};
++
+ extern formvars *formvars_start;
+ extern formvars *formvars_last;
+ extern formvars *cookies_start;
+diff -r -u libcgi-back-1.0/libcgi-1.0/src/cookie.c libcgi-1.0/src/cookie.c
+--- libcgi-back-1.0/libcgi-1.0/src/cookie.c 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/cookie.c 2015-05-12 10:27:11.335231627 +0800
+@@ -92,14 +92,30 @@
+ aux = cookies;
+
+ while (cookies) {
+- position = 0;
++start: position = 0;
++
+ data = (formvars *)malloc(sizeof(formvars));
+ if (!data)
+ libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
+
+- while (*aux++ != '=')
+- position++;
+
++ if ((strchr(cookies, '=')) == NULL) {
++ aux = NULL;
++ free(data);
++ cookies = aux;
++ goto end;
++ }
++
++ while (*aux++ != '=') {
++ if (*(aux-1) != ';') {
++ position++;
++ } else {
++ position = 0;
++ free(data);
++ cookies = aux;
++ goto start;
++ }
++ }
+ data->name = (char *)malloc(position+1);
+ if (!data->name) {
+ libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
+@@ -120,7 +136,8 @@
+ while (*aux++ != ';')
+ position++;
+ // Eliminate the blank space after ';'
+- aux++;
++ while(*aux == ' ')
++ aux++;
+ }
+
+ data->value = (char *)malloc(position + 1);
+@@ -134,7 +151,7 @@
+ slist_add(data, &cookies_start, &cookies_last);
+ cookies = aux;
+ }
+-
++end:
+ return cookies_start;
+ }
+
+diff -r -u libcgi-back-1.0/libcgi-1.0/src/session.c libcgi-1.0/src/session.c
+--- libcgi-back-1.0/libcgi-1.0/src/session.c 2014-10-28 15:16:27.000000000 +0800
++++ libcgi-1.0/src/session.c 2015-05-12 14:23:44.854940353 +0800
+@@ -124,6 +124,7 @@
+ SESS_OPEN_FILE
+ } sess_error;
+
++
+ // This variables are used to control the linked list of all
+ // session objects. Most of time you don't need to use them
+ // directly
+@@ -214,8 +215,6 @@
+ {
+ formvars *data;
+
+- cgi_init_headers();
+-
+ // Rewrites all data to session file
+ sess_file = fopen(sess_fname, "w");
+
+@@ -547,10 +546,90 @@
+ fclose(fp);
+ sess_initialized = 1;
+ free(buf);
+-
+ return 1;
+ }
+
++/**
++* check the request validation.
++* This function is responsible for reading a exist session file and
++* validate the request. It no session file found will return session_invalid
++* if file found but session timeout will return session_timeout, meanwhile
++* destroy the session file anyway
++* if seesion is valid will return session_valid and refresh the session access time
++* @see session_destroy()
++*/
++int cgi_session_check()
++{
++ char *buf = NULL, *sid = NULL, *value = NULL;;
++ struct stat st;
++ FILE *fp;
++ struct timeval cur_tv;
++ time_t last_time;
++ char tmp[TMP_BUF_MAX] = { 0 };
++
++ // Get the session ID
++ sid = cgi_cookie_value(SESSION_COOKIE_NAME);
++
++ // If there isn't a session ID
++ if (sid == NULL) {
++ return SESS_NO_COOKIE;
++ }
++
++ save_path_len = strlen(SESSION_SAVE_PATH) + strlen(SESSION_FILE_PREFIX);
++
++ sess_fname = (char *)malloc(save_path_len + SESS_ID_LEN + 1);
++ if (!sess_fname)
++ libcgi_error(E_MEMORY, "File %s, line %s", __FILE__, __LINE__);
++
++ snprintf(sess_fname, (SESS_ID_LEN + save_path_len + 1), "%s%s%s", SESSION_SAVE_PATH, SESSION_FILE_PREFIX, sid);
++ sess_fname[SESS_ID_LEN + save_path_len] = '\0';
++
++ errno = 0;
++ fp = fopen(sess_fname, "r");
++ if (errno == ENOENT) {
++ // The file doesn't exists
++ return SESS_NOT_FOUND;
++ }
++
++ strncpy(sess_id, sid, SESS_ID_LEN);
++ sess_id[SESS_ID_LEN] = '\0';
++
++ stat(sess_fname, &st);
++ buf = (char *)malloc(st.st_size + 2);
++ if (!buf)
++ libcgi_error(E_MEMORY, "File %s, line %s", __FILE__, __LINE__);
++
++ fgets(buf, st.st_size+1, fp);
++ if (buf != NULL && strlen(buf) > 1)
++ process_data(buf, &sess_list_start, &sess_list_last, '=', ';');
++
++ fclose(fp);
++ sess_initialized = 1;
++ free(buf);
++
++ gettimeofday(&cur_tv, NULL);
++ value = cgi_session_var(LAST_ACCESS_TIME);
++ if (!value) {
++ return SESS_NO_ACCESS_TIME;
++ }
++
++ last_time = (time_t)atol(value);
++
++ if (cur_tv.tv_sec - last_time > MAX_SESSION_TIMEOUT) {
++ cgi_session_destroy();
++ return SESS_TIMEOUT;
++ }
++
++ //refresh last access time
++ memset(tmp, 0, TMP_BUF_MAX);
++ snprintf(tmp, TMP_BUF_MAX - 1, "%u", cur_tv.tv_sec );
++ if ( cgi_session_alter_var(LAST_ACCESS_TIME, tmp)) {
++ return SESS_VALID;
++ }
++ else {
++ return SESS_INVALID;
++ }
++}
+ /**
+ * @}
+ */