Merge pull request #52 from jtanx/master
[matches/MCTX3420.git] / server / fastcgi.c
index 08c413b..57c5b1b 100644 (file)
@@ -45,6 +45,8 @@ static void IdentifyHandler(FCGIContext *context, char *params) {
        FCGI_JSONPair("description", "MCTX3420 Server API (2013)");
        FCGI_JSONPair("build_date", __DATE__ " " __TIME__);
        FCGI_JSONLong("api_version", API_VERSION);
+       FCGI_JSONBool("logged_in", FCGI_HasControl(context, getenv("COOKIE_STRING")));
+       FCGI_JSONPair("friendly_name", "");
 
        //Sensor and actuator information
        if (ident_sensors) {
@@ -77,14 +79,14 @@ static void IdentifyHandler(FCGIContext *context, char *params) {
  * the system at any one time. The key can be forcibly generated, revoking
  * any previous control keys. To be used in conjunction with HTTP 
  * basic authentication.
- * This function will generate a JSON response that indicates success/failure.
  * @param context The context to work in
  * @param force Whether to force key generation or not.
- */ 
-void FCGI_LockControl(FCGIContext *context, bool force) {
+ * @return true on success, false otherwise (eg someone else already in control)
+ */
+bool FCGI_LockControl(FCGIContext *context, bool force) {
        time_t now = time(NULL);
        bool expired = now - context->control_timestamp > CONTROL_TIMEOUT;
-       
+
        if (force || !*(context->control_key) || expired) 
        {
                SHA_CTX sha1ctx;
@@ -100,7 +102,9 @@ void FCGI_LockControl(FCGIContext *context, bool force) {
                for (i = 0; i < 20; i++)
                        sprintf(context->control_key + i * 2, "%02x", sha1[i]);
                snprintf(context->control_ip, 16, "%s", getenv("REMOTE_ADDR"));
+               return true;
        }
+       return false;
 }
 
 /**
@@ -114,7 +118,8 @@ void FCGI_LockControl(FCGIContext *context, bool force) {
 bool FCGI_HasControl(FCGIContext *context, const char *key) {
        time_t now = time(NULL);
        int result = (now - context->control_timestamp) <= CONTROL_TIMEOUT &&
-                                key != NULL && !strcmp(context->control_key, key);
+                       key != NULL && context->control_key[0] != '\0' &&
+                       !strcmp(context->control_key, key);
        if (result) {
                context->control_timestamp = now; //Update the control_timestamp
        }
@@ -128,8 +133,6 @@ bool FCGI_HasControl(FCGIContext *context, const char *key) {
  */
 void FCGI_ReleaseControl(FCGIContext *context) {
        *(context->control_key) = 0;
-       FCGI_BeginJSON(context, STATUS_OK);
-       FCGI_EndJSON();
        return;
 }
 
@@ -287,6 +290,25 @@ void FCGI_BeginJSON(FCGIContext *context, StatusCodes status_code)
        FCGI_JSONPair("control_state", Control_GetModeName());
 }
 
+/**
+ * Generic accept response in JSON format.
+ * @param context The context to work in
+ * @param description A short description.
+ * @param cookie Optional. If given, the cookie field is set to that value.
+ */
+void FCGI_AcceptJSON(FCGIContext *context, const char *description, const char *cookie)
+{
+       printf("Content-type: application/json; charset=utf-8\r\n");
+       if (cookie) {
+               printf("Set-Cookie: %s\r\n", cookie);
+       }
+       printf("\r\n{\r\n");
+       printf("\t\"module\" : \"%s\"", context->current_module);
+       FCGI_JSONLong("status", STATUS_OK);
+       FCGI_JSONPair("description", description);
+       FCGI_EndJSON();
+}
+
 /**
  * Adds a key/value pair to a JSON response. The response must have already
  * been initiated by FCGI_BeginJSON. Special characters are not escaped.
@@ -441,17 +463,17 @@ void * FCGI_RequestLoop (void *data)
        while (FCGI_Accept() >= 0) {
                
                ModuleHandler module_handler = NULL;
-               char module[BUFSIZ], params[BUFSIZ], cookie[BUFSIZ];
+               char module[BUFSIZ], params[BUFSIZ];
+               //Don't need to copy if we're not modifying string contents
+               const char *cookie = getenv("COOKIE_STRING");
                
                //strncpy doesn't zero-truncate properly
                snprintf(module, BUFSIZ, "%s", getenv("DOCUMENT_URI_LOCAL"));
                snprintf(params, BUFSIZ, "%s", getenv("QUERY_STRING"));
-               snprintf(cookie, BUFSIZ, "%s", getenv("COOKIE_STRING"));
 
                Log(LOGDEBUG, "Got request #%d - Module %s, params %s", context.response_number, module, params);
                Log(LOGDEBUG, "Cookie: %s", cookie);
 
-
                
                //Remove trailing slashes (if present) from module query
                size_t lastchar = strlen(module) - 1;
@@ -486,11 +508,9 @@ void * FCGI_RequestLoop (void *data)
                context.current_module = module;
                context.response_number++;
                
-
-
                if (module_handler) 
                {
-                       if (module_handler != Login_Handler)
+                       if (module_handler != Login_Handler && module_handler != IdentifyHandler)
                        {
                                if (cookie[0] == '\0')
                                {

UCC git Repository :: git.ucc.asn.au