Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
web-base.c
- Committer:
- andrewboyson
- Date:
- 2019-04-28
- Revision:
- 105:43ef124233cd
- Parent:
- 103:91194cc19bbb
- Child:
- 106:7cff473be687
File content as of revision 105:43ef124233cd:
#include "web-base.h"
#include "web-derived.h"
#include "http.h"
#include "fault.h"
#include "led.h"
#include "mstimer.h"
#define DO_LOGIN DO_SERVER + 0
#define DO_FAVICON DO_SERVER + 1
#define DO_BASE_CSS DO_SERVER + 2
#define DO_NAV_CSS DO_SERVER + 3
#define DO_TRACE_HTML DO_SERVER + 4
#define DO_TRACE_AJAX DO_SERVER + 5
#define DO_TRACE_SCRIPT DO_SERVER + 6
#define DO_CLOCK_HTML DO_SERVER + 7
#define DO_CLOCK_AJAX DO_SERVER + 8
#define DO_CLOCK_SCRIPT DO_SERVER + 9
#define DO_NET_HTML DO_SERVER + 10
#define DO_NET4_HTML DO_SERVER + 11
#define DO_NET4_AJAX DO_SERVER + 12
#define DO_NET4_SCRIPT DO_SERVER + 13
#define DO_NET6_HTML DO_SERVER + 14
#define DO_NET6_AJAX DO_SERVER + 15
#define DO_NET6_SCRIPT DO_SERVER + 16
#define DO_LOG_HTML DO_SERVER + 17
#define DO_FAULT_HTML DO_SERVER + 18
#define DO_FIRMWARE_HTML DO_SERVER + 19
#define DO_FIRMWARE_AJAX DO_SERVER + 20
#define DO_FIRMWARE_SCRIPT DO_SERVER + 21
#define DO_SEND_SESSION_ID DO_DERIVED + 100
#define LOGIN_DELAY_MS 200
static int decideWhatToDoFromPath(char *pPath, char* pLastModified)
{
if (HttpSameStr(pPath, "/login" )) return DO_LOGIN;
if (HttpSameStr(pPath, "/clock" )) return DO_CLOCK_HTML;
if (HttpSameStr(pPath, "/clock-ajax" )) return DO_CLOCK_AJAX;
if (HttpSameStr(pPath, "/net" )) return DO_NET_HTML;
if (HttpSameStr(pPath, "/net4" )) return DO_NET4_HTML;
if (HttpSameStr(pPath, "/net4-ajax" )) return DO_NET4_AJAX;
if (HttpSameStr(pPath, "/net6" )) return DO_NET6_HTML;
if (HttpSameStr(pPath, "/net6-ajax" )) return DO_NET6_AJAX;
if (HttpSameStr(pPath, "/log" )) return DO_LOG_HTML;
if (HttpSameStr(pPath, "/trace" )) return DO_TRACE_HTML;
if (HttpSameStr(pPath, "/trace-ajax" )) return DO_TRACE_AJAX;
if (HttpSameStr(pPath, "/fault" )) return DO_FAULT_HTML;
if (HttpSameStr(pPath, "/firmware" )) return DO_FIRMWARE_HTML;
if (HttpSameStr(pPath, "/firmware-ajax")) return DO_FIRMWARE_AJAX;
if (HttpSameStr(pPath, "/favicon.ico" )) return HttpSameDate(WebFaviconDate, WebFaviconTime, pLastModified) ? DO_NOT_MODIFIED : DO_FAVICON;
if (HttpSameStr(pPath, "/base.css" )) return HttpSameDate(WebBaseCssDate, WebBaseCssTime, pLastModified) ? DO_NOT_MODIFIED : DO_BASE_CSS;
if (HttpSameStr(pPath, "/settings.css" )) return HttpSameDate(WebNavCssDate, WebNavCssTime, pLastModified) ? DO_NOT_MODIFIED : DO_NAV_CSS;
if (HttpSameStr(pPath, "/net4.js" )) return HttpSameDate(WebNet4ScriptDate, WebNet4ScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_NET4_SCRIPT;
if (HttpSameStr(pPath, "/net6.js" )) return HttpSameDate(WebNet6ScriptDate, WebNet6ScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_NET6_SCRIPT;
if (HttpSameStr(pPath, "/trace.js" )) return HttpSameDate(WebTraceScriptDate, WebTraceScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_TRACE_SCRIPT;
if (HttpSameStr(pPath, "/clock.js" )) return HttpSameDate(WebClockScriptDate, WebClockScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_CLOCK_SCRIPT;
if (HttpSameStr(pPath, "/firmware.js" )) return HttpSameDate(WebFirmwareScriptDate, WebFirmwareScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_FIRMWARE_SCRIPT;
return WebDerivedRequest(pPath, pLastModified);
}
static void handleQuery(int todo, char* pQuery)
{
switch (todo)
{
case DO_LOGIN: WebLoginQuery (pQuery); return;
case DO_TRACE_AJAX: WebTraceQuery (pQuery); return;
case DO_CLOCK_AJAX: WebClockQuery (pQuery); return;
case DO_CLOCK_HTML: WebClockQuery (pQuery); return;
case DO_LOG_HTML: WebLogQuery (pQuery); return;
case DO_FAULT_HTML: WebFaultQuery (pQuery); return;
case DO_FIRMWARE_HTML: WebFirmwareQuery(pQuery); return;
case DO_FIRMWARE_AJAX: WebFirmwareQuery(pQuery); return;
}
WebDerivedGet(todo, pQuery);
}
static bool handlePost(int todo, int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream)
{
switch (todo)
{
case DO_FIRMWARE_AJAX: return WebFirmwarePost(contentLength, contentStart, size, pRequestStream, positionInRequestStream);
}
return WebDerivedPost(todo, contentLength, size, pRequestStream, positionInRequestStream);
}
static void serverRequest(int size, char* pRequestStream, uint32_t positionInRequestStream, int* pToDo, bool* pPostComplete, uint32_t* pDelayUntil)
{
//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
*pToDo = decideWhatToDoFromPath(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 (*pToDo < DO_SERVER) { *pPostComplete = true; return; }
//If what to do is LOGIN then the user has just returned the login form
if (*pToDo == DO_LOGIN)
{
handleQuery(*pToDo, 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
*pPostComplete = true;
return; //Either way no query or post will be valid
}
//Have a normal request so authenticate
if (!WebLoginCookiesContainValidSessionId(pCookies))
{
WebLoginOriginalToDo = *pToDo; //Record the original destination for redirection
*pToDo = DO_LOGIN;
*pPostComplete = true;
return; //Ignore any query or post as the user is not authenticated
}
//Handle the query
handleQuery(*pToDo, pQuery);
}
//Do the upload of anything that needs it. Todos it doesn't understand are ignored.
if (!*pPostComplete) *pPostComplete = handlePost(*pToDo, contentLength, contentStart, size, pRequestStream, positionInRequestStream);
}
static void serverReply(int todo)
{
//Check if todo includes the need to send a cookie
if (todo >= DO_SEND_SESSION_ID)
{
HttpOkCookieName = WebLoginSessionNameGet();
HttpOkCookieValue = WebLoginSessionIdGet();
HttpOkCookieMaxAge = WebLoginSessionNameLife();
todo -= DO_SEND_SESSION_ID;
}
else
{
HttpOkCookieName = NULL;
HttpOkCookieValue = NULL;
HttpOkCookieMaxAge = -1;
}
//Try all the base modules
switch (todo)
{
case DO_NOT_FOUND: HttpNotFound (); return;
case DO_NOT_MODIFIED: HttpNotModified (); return;
case DO_LOGIN: WebLoginHtml (); return;
case DO_FAVICON: WebFavicon (); return;
case DO_BASE_CSS: WebBaseCss (); return;
case DO_NAV_CSS: WebNavCss (); return;
case DO_TRACE_HTML: WebTraceHtml (); return;
case DO_TRACE_AJAX: WebTraceAjax (); return;
case DO_TRACE_SCRIPT: WebTraceScript (); return;
case DO_CLOCK_HTML: WebClockHtml (); return;
case DO_CLOCK_AJAX: WebClockAjax (); return;
case DO_CLOCK_SCRIPT: WebClockScript (); return;
case DO_NET_HTML: WebNetHtml (); return;
case DO_NET4_HTML: WebNet4Html (); return;
case DO_NET4_AJAX: WebNet4Ajax (); return;
case DO_NET4_SCRIPT: WebNet4Script (); return;
case DO_NET6_HTML: WebNet6Html (); return;
case DO_NET6_AJAX: WebNet6Ajax (); return;
case DO_NET6_SCRIPT: WebNet6Script (); return;
case DO_LOG_HTML: WebLogHtml (); return;
case DO_FAULT_HTML: WebFaultHtml (); return;
case DO_FIRMWARE_HTML: WebFirmwareHtml (); return;
case DO_FIRMWARE_AJAX: WebFirmwareAjax (); return;
case DO_FIRMWARE_SCRIPT: WebFirmwareScript(); return;
}
//If not called then call the derived (child) module
WebDerivedReply(todo);
}
int WebInit()
{
HttpRequestFunction = serverRequest;
HttpReplyFunction = serverReply;
WebLoginInit();
return 0;
}