websockets.ino 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #ifdef ENABLE_FEATURE_WEB_CONSOLE_WEBSOCKETS
  2. /*
  3. * Returns a bool value as an indicator to describe whether a user is allowed to initiate a websocket upgrade
  4. * based on the value of a cookie. This function expects the rawCookieHeaderValue to look like this "sessionId=<someSessionIdNumberValue>|"
  5. */
  6. bool isCookieValid(String rawCookieHeaderValue) {
  7. if(wsValidSessionId != 0) {
  8. if (rawCookieHeaderValue.indexOf("sessionId") != -1) {
  9. String sessionIdStr = rawCookieHeaderValue.substring(rawCookieHeaderValue.indexOf("sessionId=") + 10, rawCookieHeaderValue.indexOf("|"));
  10. unsigned long int sessionId = strtoul(sessionIdStr.c_str(), NULL, 10);
  11. return sessionId == wsValidSessionId;
  12. }
  13. }
  14. return false;
  15. }
  16. void clearValidSessionId() {
  17. // wsValidSessionId = millis() -> clear after timeout to somehow improve "security"
  18. if( wsValidSessionId > 0 && (millis() - wsValidSessionId) > 2000 ) wsValidSessionId = 0;
  19. }
  20. /*
  21. * The WebSocketServerHttpHeaderValFunc delegate passed to webSocket.onValidateHttpHeader
  22. */
  23. bool validateHttpHeader(String headerName, String headerValue) {
  24. //assume a true response for any headers not handled by this validator
  25. bool valid = true;
  26. if(headerName.equalsIgnoreCase("Cookie")) {
  27. //if the header passed is the Cookie header, validate it according to the rules in 'isCookieValid' function
  28. valid = isCookieValid(headerValue);
  29. }
  30. return valid;
  31. }
  32. void startWebSocketServer() { // Start a WebSocket server
  33. //if(strlen(confWeb.http_user) > 0 && strlen(confWeb.http_pass) > 0) webSocket.setAuthorization(confWeb.http_user, confWeb.http_pass);
  34. const char * headerkeys[] = { "Cookie" };
  35. size_t headerKeyCount = sizeof(headerkeys) / sizeof(char*);
  36. webSocket.onValidateHttpHeader(validateHttpHeader, headerkeys, headerKeyCount);
  37. webSocket.begin(); // start the websocket server
  38. webSocket.onEvent(webSocketEvent); // if there's an incomming websocket message, go to function 'webSocketEvent'
  39. //Serial.println("WebSocket server started.");
  40. sendLog("WS: WebSocket server started on Port 81", LOGLEVEL_INFO);
  41. }
  42. void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
  43. if(length > 0) { // filter message with length=0, otherwise ESP8266 crashes
  44. char logBuf[60];
  45. switch(type) {
  46. case WStype_DISCONNECTED:
  47. Serial.printf("[%u] Disconnected!\n", num);
  48. break;
  49. case WStype_CONNECTED:
  50. {
  51. IPAddress ip = webSocket.remoteIP(num);
  52. //Serial.printf("WS: Connected Client-[%u], %d.%d.%d.%d, URL: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
  53. sprintf(logBuf, "WS: Client[%u] connected, %d.%d.%d.%d, URL: %s", num, ip[0], ip[1], ip[2], ip[3], payload);
  54. sendLog(logBuf, LOGLEVEL_INFO);
  55. // send message to client
  56. webSocket.sendTXT(num, "Connected\r\n");
  57. }
  58. break;
  59. case WStype_TEXT:
  60. //Serial.printf("WS: received from Client-[%u]: %s\n", num, payload);
  61. sprintf(logBuf, "WS: received from Client[%u]: %s", num, payload);
  62. sendLog(logBuf, LOGLEVEL_INFO);
  63. char buf[31];
  64. sprintf(buf, "%s", payload);
  65. // send received text to command handler
  66. if(strlen(buf) > 0) strlcpy(cmdPayload, buf, sizeof(cmdPayload));
  67. cmdInQueue = true; // will be checked in next loop() run
  68. // send message to client
  69. // webSocket.sendTXT(num, "message here");
  70. // send data to all connected clients
  71. // webSocket.broadcastTXT("message here");
  72. break;
  73. case WStype_ERROR:
  74. break;
  75. case WStype_BIN:
  76. Serial.printf("[%u] get binary length: %u\n", num, length);
  77. hexdump(payload, length);
  78. break;
  79. default:
  80. break;
  81. //
  82. // // send message to client
  83. // // webSocket.sendBIN(num, payload, length);
  84. // break;
  85. }
  86. }
  87. }
  88. #endif