Andrew Boyson / web

Dependents:   oldheating gps motorhome heating

Revision:
130:9a5b8fe308f1
Parent:
129:6d9bffc72676
--- a/web.c	Sun Sep 01 18:12:48 2019 +0000
+++ b/web.c	Tue Sep 24 18:16:47 2019 +0000
@@ -3,15 +3,17 @@
 #include "web-server-this.h"
 #include "web.h"
 #include "web-pages-base.h"
-#include "web-connection.h"
+#include "http-connection.h"
+#include "log.h"
 #include "mstimer.h"
-#include "log.h"
 
 #define LOGIN_DELAY_MS 200
 
 #define DO_LOGIN DO_SERVER + 0
 
-static int decideWhatToDo(char *pPath, char* pLastModified)
+bool WebTrace = false;
+
+int WebDecideWhatToDo(char *pPath, char* pLastModified)
 {
     if (HttpSameStr(pPath, "/login")) return DO_LOGIN;
     
@@ -20,124 +22,49 @@
     todo = WebServerThisDecideWhatToDo(pPath, pLastModified); if (todo != DO_NOT_FOUND) return todo;
     return DO_NOT_FOUND;
 }
-static void handleQuery(int todo, char* pQuery)
+int WebHandleQuery(char* pQuery, char* pCookies, int* pTodo, uint32_t* pDelayUntil) //return -1 on stop; 0 on continue
 {
-    switch (todo)
+    //If what to do is NOTHING, NOT_FOUND or NOT_MODIFIED then no query or post will be valid so stop now
+    if (*pTodo < DO_LOGIN) return -1;
+    
+    //If what to do is LOGIN then the user has just returned the login form
+    if (*pTodo == DO_LOGIN)
     {
-        case DO_LOGIN:         WebLoginQuery   (pQuery); return;
+        WebLoginQuery(pQuery);                    //Read the password and the original location
+        if (WebLoginQueryPasswordOk)
+        {
+            if (!WebLoginSessionIdIsSet())           //If there isn't a session id already
+            {
+                WebLoginSessionIdNew();              //Create a new session id
+            }
+            *pTodo =  WebLoginOriginalToDo;          //Load the original todo and SEND_SESSION_ID
+            *pTodo += DO_SEND_SESSION_ID;
+        }
+        *pDelayUntil = MsTimerCount + LOGIN_DELAY_MS; //To prevent brute forcing the hash delay the reply to the login
+        return -1;                                    //Either way no query or post will be valid
     }
-    if (WebServerBaseHandleQuery(todo, pQuery)) return;
-    if (WebServerThisHandleQuery(todo, pQuery)) return;
+    
+    //Have a normal request so authenticate
+    if (!WebLoginCookiesContainValidSessionId(pCookies))
+    {
+        WebLoginOriginalToDo = *pTodo; //Record the original destination for redirection
+        *pTodo = DO_LOGIN;
+        return -1; //Ignore any query or post as the user is not authenticated
+    }
+
+    if (WebServerBaseHandleQuery(*pTodo, pQuery)) return 0;
+    if (WebServerThisHandleQuery(*pTodo, pQuery)) return 0;
+    return 0;
 }
-static void handlePost(int todo, int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream, bool* pComplete)
+void WebHandlePost(int todo, int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream, bool* pComplete)
 {
     if (WebServerBasePost(todo, contentLength, contentStart, size, pRequestStream, positionInRequestStream, pComplete)) return;
     if (WebServerThisPost(todo, contentLength, contentStart, size, pRequestStream, positionInRequestStream, pComplete)) return;
     *pComplete = true;
 }
 
-static void reply(int todo)
-{
-    //Try all the base modules
-    switch (todo)
-    {
-        case DO_LOGIN:           WebLoginHtml     (); return;
-        case DO_NOT_FOUND:       HttpNotFound     (); return;
-        case DO_NOT_MODIFIED:    HttpNotModified  (); return;
-    }
-    
-    //If not called then call the derived (child) module
-    if (WebServerBaseReply(todo)) return;
-    if (WebServerThisReply(todo)) return;
-}
-static void handleRequest(int connectionId, int size, char* pRequestStream, uint32_t positionInRequestStream)
+void WebAddResponse(int todo)
 {
-    struct WebConnection* pConnection;
-    if (!positionInRequestStream)
-    {
-        pConnection = WebConnectionNew(connectionId);
-    }
-    else
-    {
-        pConnection = WebConnectionOrNull(connectionId);
-        if (!pConnection)
-        {
-            LogTimeF("WebRequest - no connection corresponds to id %d\r\n", connectionId);
-            return;
-        }
-    }
-    
-    pConnection->delayUntil = MsTimerCount; //Default to no delay unless modified;
-    
-    //Handle request for the first packet of data received but leave todo the same after that.
-    int contentLength = 0;
-    int contentStart  = 0;
-    if (size && positionInRequestStream == 0)
-    {
-        //Read the headers
-        char* pMethod;
-        char* pPath;
-        char* pQuery;
-        char* pLastModified;
-        char* pCookies;
-        contentStart = HttpRequestRead(pRequestStream, size, &pMethod, &pPath, &pQuery, &pLastModified, &pCookies, &contentLength);
-        
-        //Ask the web server what to do
-        pConnection->toDo = decideWhatToDo(pPath, pLastModified);
-        
-        //If what to do is NOTHING, NOT_FOUND or NOT_MODIFIED then no query or post will be valid so stop now
-        if (pConnection->toDo < DO_LOGIN) { pConnection->postComplete = true; return; }
-        
-        //If what to do is LOGIN then the user has just returned the login form
-        if (pConnection->toDo == DO_LOGIN)
-        {
-            handleQuery(pConnection->toDo, pQuery);                  //Read the password and the original location
-            if (WebLoginQueryPasswordOk)
-            {
-                if (!WebLoginSessionIdIsSet())           //If there isn't a session id already
-                {
-                    WebLoginSessionIdNew();              //Create a new session id
-                }
-                pConnection->toDo =  WebLoginOriginalToDo;          //Load the original todo and SEND_SESSION_ID
-                pConnection->toDo += DO_SEND_SESSION_ID;
-            }
-            pConnection->delayUntil = MsTimerCount + LOGIN_DELAY_MS; //To prevent brute forcing the hash delay the reply to the login
-            pConnection->postComplete = true;
-            return;                                       //Either way no query or post will be valid
-        }
-        
-        //Have a normal request so authenticate
-        if (!WebLoginCookiesContainValidSessionId(pCookies))
-        {
-            WebLoginOriginalToDo = pConnection->toDo; //Record the original destination for redirection
-            pConnection->toDo = DO_LOGIN;
-            pConnection->postComplete = true;
-            return; //Ignore any query or post as the user is not authenticated
-        }
-        
-        //Handle the query
-        handleQuery(pConnection->toDo, pQuery);
-    }
-    
-    //Do the upload of anything that needs it. Todos it doesn't understand are ignored.
-    if (!pConnection->postComplete) handlePost(pConnection->toDo, contentLength, contentStart, size, pRequestStream, positionInRequestStream, &pConnection->postComplete);
-}
-
-static bool pollSomethingToSend(int connectionId, bool clientFinished) //returns true if finished; false if not; 
-{
-    struct WebConnection* pConnection = WebConnectionOrNull(connectionId);
-    if (!pConnection) return false; //Protects the gap between the connection being established and the request being started
-    
-    if (!pConnection->toDo)
-    {
-        if (clientFinished) return true;  //The client hasn't requested anything and never will so finish
-        else                return false; //The client hasn't requested anything yet but still could
-    }
-    if (!pConnection->postComplete               ) return false; //Wait for the request (usually a POST) to finish
-    if (!MsTimerAbsolute(pConnection->delayUntil)) return false; //Wait a while (usually after a LOGIN attempt)
-    
-    int todo = pConnection->toDo; //Make a copy so that we don't modify todo in the state
-
     //Check if todo includes the need to send a cookie
     if (todo >= DO_SEND_SESSION_ID)
     {
@@ -153,18 +80,20 @@
         HttpOkCookieMaxAge = -1;
     }
     
-    reply(todo);
+    //Try all the base modules
+    switch (todo)
+    {
+        case DO_LOGIN:           WebLoginHtml     (); return;
+        case DO_NOT_FOUND:       HttpNotFound     (); return;
+        case DO_NOT_MODIFIED:    HttpNotModified  (); return;
+    }
     
-    return !HttpBufFilled(); //If we haven't used a full buffer then we have finished
+    //If not called then call the derived (child) module
+    if (WebServerBaseReply(todo)) return;
+    if (WebServerThisReply(todo)) return;
 }
 
-int WebInit()
-{
-    HttpFunctionReset   = WebConnectionReset;
-    HttpFunctionRequest = handleRequest;
-    HttpFunctionPoll    = pollSomethingToSend;
-    
-    WebLoginInit();
-    
-    return 0;
+void WebInit()
+{   
+    WebLoginInit();  
 }
\ No newline at end of file