websockets.ino 4.2 KB

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