diff --git a/sonoff/xdrv_02_webserver.ino b/sonoff/xdrv_02_webserver.ino index 46699d757..bcc8b9173 100644 --- a/sonoff/xdrv_02_webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -29,6 +29,8 @@ uint8_t *efm8bb1_update = NULL; #endif // USE_RF_FLASH +#define D_TASMOTA_TOKEN "Tasmota-Token" + enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1 }; const char HTTP_HEAD[] PROGMEM = @@ -57,7 +59,7 @@ const char HTTP_HEAD[] PROGMEM = "eb('p1').focus();" "}" "function lx(){" - "if(to==0){" + "if(to==1){" "if(tp<30){" "tp++;" "lt=setTimeout(lx,33);" // Wait for token from server @@ -74,21 +76,22 @@ const char HTTP_HEAD[] PROGMEM = "eb('l1').innerHTML=s;" "}" "};" - "x.open('GET','ay?t='+to+pc,true);" // Async request + "x.open('GET','ay'+pc,true);" // Async request + "x.setRequestHeader('" D_TASMOTA_TOKEN "',to);" "x.send();" // Perform command if available and get updated information "pc='';" "lt=setTimeout(la,2345-(tp*33));" "}" "function la(p){" "if(la.arguments.length==1){" - "pc='&'+p;" + "pc='?'+p;" "clearTimeout(lt);" "}else{pc='';}" - "to=0;tp=0;" + "to=1;tp=0;" "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) "x=new XMLHttpRequest();" "x.onreadystatechange=function(){" - "if(x.readyState==4&&x.status==200){to=x.responseText;}else{to=0;}" + "if(x.readyState==4&&x.status==200){to=x.getResponseHeader('" D_TASMOTA_TOKEN "');}else{to=1;}" "};" "x.open('GET','az',true);" // Async request "x.send();" // Get token from server @@ -344,6 +347,8 @@ const char HDR_CTYPE_XML[] PROGMEM = "text/xml"; const char HDR_CTYPE_JSON[] PROGMEM = "application/json"; const char HDR_CTYPE_STREAM[] PROGMEM = "application/octet-stream"; +const char HDR_TASMOTA_TOKEN[] PROGMEM = D_TASMOTA_TOKEN; + #define DNS_PORT 53 enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER}; @@ -359,7 +364,7 @@ uint8_t upload_progress_dot_count; uint8_t config_block_count = 0; uint8_t config_xor_on = 0; uint8_t config_xor_on_set = CONFIG_FILE_XOR; -long ajax_token = 0; +long ajax_token = 1; // Helper function to avoid code duplication (saves 4k Flash) static void WebGetArg(const char* arg, char* out, size_t max) @@ -631,9 +636,15 @@ void HandleToken() { char token[11]; - ajax_token = random(0x7FFFFFFF); + ajax_token = random(2, 0x7FFFFFFF); snprintf_P(token, sizeof(token), PSTR("%u"), ajax_token); + SetHeader(); + WebServer->sendHeader(FPSTR(HDR_TASMOTA_TOKEN), token); + snprintf_P(token, sizeof(token), PSTR("%u"), random(0x7FFFFFFF)); WebServer->send(200, FPSTR(HDR_CTYPE_HTML), token); + + const char* header_key[] = { D_TASMOTA_TOKEN }; + WebServer->collectHeaders(header_key, 1); } void HandleAjaxStatusRefresh() @@ -641,16 +652,13 @@ void HandleAjaxStatusRefresh() char svalue[80]; char tmp[100]; - WebGetArg("t", tmp, sizeof(tmp)); - char *p = tmp; - long ajax_token_received = strtol(p, &p, 10); - if (ajax_token_received != ajax_token) { + if (WebServer->header(FPSTR(HDR_TASMOTA_TOKEN)).toInt() != ajax_token) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_FILE_NOT_FOUND)); SetHeader(); WebServer->send(404, FPSTR(HDR_CTYPE_PLAIN), mqtt_data); return; } - ajax_token = 0; + ajax_token = 1; WebGetArg("o", tmp, sizeof(tmp)); if (strlen(tmp)) { @@ -1986,7 +1994,7 @@ int WebSend(char *buffer) /*********************************************************************************************/ enum WebCommands { CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_WEBSEND, CMND_EMULATION }; -const char kWebCommands[] PROGMEM = D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_WEBSEND "|" D_CMND_EMULATION ; +const char kWebCommands[] PROGMEM = D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_WEBSEND "|" D_CMND_EMULATION ; const char kWebSendStatus[] PROGMEM = D_JSON_DONE "|" D_JSON_WRONG_PARAMETERS "|" D_JSON_CONNECT_FAILED "|" D_JSON_HOST_NOT_FOUND ; bool WebCommand()