Skip to content

Commit 34a2d28

Browse files
committed
allow to moves all Header strings to Flash (~300 Byte) #152
1 parent e93a323 commit 34a2d28

File tree

4 files changed

+99
-72
lines changed

4 files changed

+99
-72
lines changed

src/WebSockets.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#define WEBSOCKETS_MAX_DATA_SIZE (15*1024)
4848
#define WEBSOCKETS_USE_BIG_MEM
4949
#define GET_FREE_HEAP ESP.getFreeHeap()
50+
// moves all Header strings to Flash (~300 Byte)
51+
//#define WEBSOCKETS_SAVE_RAM
5052
#else
5153
#ifdef STM32_DEVICE
5254
#define WEBSOCKETS_MAX_DATA_SIZE (15*1024)
@@ -55,6 +57,8 @@
5557
#else
5658
//atmega328p has only 2KB ram!
5759
#define WEBSOCKETS_MAX_DATA_SIZE (1024)
60+
// moves all Header strings to Flash
61+
#define WEBSOCKETS_SAVE_RAM
5862
#endif
5963
#endif
6064

@@ -134,6 +138,12 @@
134138
#error "no network type selected!"
135139
#endif
136140

141+
// moves all Header strings to Flash (~300 Byte)
142+
#ifdef WEBSOCKETS_SAVE_RAM
143+
#define WEBSOCKETS_STRING(var) F(var)
144+
#else
145+
#define WEBSOCKETS_STRING(var) var
146+
#endif
137147

138148
typedef enum {
139149
WSC_NOT_CONNECTED,

src/WebSocketsClient.cpp

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,15 @@ void WebSocketsClient::handleClientData(void) {
404404
}
405405
#endif
406406

407+
407408
/**
408409
* send the WebSocket header to Server
409410
* @param client WSclient_t * ptr to the client struct
410411
*/
411412
void WebSocketsClient::sendHeader(WSclient_t * client) {
412413

414+
static const char * NEW_LINE = "\r\n";
415+
413416
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header...\n");
414417

415418
uint8_t randomKey[16] = { 0 };
@@ -424,45 +427,59 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
424427
unsigned long start = micros();
425428
#endif
426429

427-
String transport;
428430
String handshake;
429-
if(!client->isSocketIO || (client->isSocketIO && client->cSessionId.length() > 0)) {
430-
if(client->isSocketIO) {
431-
transport = "&transport=websocket&sid=" + client->cSessionId;
432-
}
433-
handshake = "GET " + client->cUrl + transport + " HTTP/1.1\r\n"
434-
"Host: " + _host + ":" + _port + "\r\n"
435-
"Connection: Upgrade\r\n"
436-
"Upgrade: websocket\r\n"
437-
"Sec-WebSocket-Version: 13\r\n"
438-
"Sec-WebSocket-Key: " + client->cKey + "\r\n";
439-
440-
if(client->cProtocol.length() > 0) {
441-
handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n";
442-
}
443-
444-
if(client->cExtensions.length() > 0) {
445-
handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n";
446-
}
447-
448-
} else {
449-
handshake = "GET " + client->cUrl + "&transport=polling HTTP/1.1\r\n"
450-
"Host: " + _host + ":" + _port + "\r\n"
451-
"Connection: keep-alive\r\n";
452-
}
453-
454-
handshake += "Origin: file://\r\n"
455-
"User-Agent: arduino-WebSocket-Client\r\n";
456-
457-
if(client->base64Authorization.length() > 0) {
458-
handshake += "Authorization: Basic " + client->base64Authorization + "\r\n";
459-
}
460-
461-
if(client->plainAuthorization.length() > 0) {
462-
handshake += "Authorization: " + client->plainAuthorization + "\r\n";
431+
bool ws_header = true;
432+
String url = client->cUrl;
433+
434+
if(client->isSocketIO) {
435+
if(client->cSessionId.length() == 0) {
436+
url += WEBSOCKETS_STRING("&transport=polling");
437+
ws_header = false;
438+
} else {
439+
url += WEBSOCKETS_STRING("&transport=websocket&sid=");
440+
url += client->cSessionId;
441+
}
463442
}
464443

465-
handshake += "\r\n";
444+
handshake = WEBSOCKETS_STRING("GET ");
445+
handshake += url + WEBSOCKETS_STRING(" HTTP/1.1\r\n"
446+
"Host: ");
447+
handshake += _host + ":" + _port + NEW_LINE;
448+
449+
if(ws_header) {
450+
handshake += WEBSOCKETS_STRING("Connection: Upgrade\r\n"
451+
"Upgrade: websocket\r\n"
452+
"Sec-WebSocket-Version: 13\r\n"
453+
"Sec-WebSocket-Key: ");
454+
handshake += client->cKey + NEW_LINE;
455+
456+
if(client->cProtocol.length() > 0) {
457+
handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: ");
458+
handshake +=client->cProtocol + NEW_LINE;
459+
}
460+
461+
if(client->cExtensions.length() > 0) {
462+
handshake += WEBSOCKETS_STRING("Sec-WebSocket-Extensions: ");
463+
handshake +=client->cExtensions + NEW_LINE;
464+
}
465+
} else {
466+
handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n");
467+
}
468+
469+
handshake += WEBSOCKETS_STRING("Origin: file://\r\n"
470+
"User-Agent: arduino-WebSocket-Client\r\n");
471+
472+
if(client->base64Authorization.length() > 0) {
473+
handshake += WEBSOCKETS_STRING("Authorization: Basic ");
474+
handshake += client->base64Authorization + NEW_LINE;
475+
}
476+
477+
if(client->plainAuthorization.length() > 0) {
478+
handshake += WEBSOCKETS_STRING("Authorization: ");
479+
handshake += client->plainAuthorization + NEW_LINE;
480+
}
481+
482+
handshake += NEW_LINE;
466483

467484
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t*)handshake.c_str());
468485
client->tcp->write((uint8_t*)handshake.c_str(), handshake.length());
@@ -486,32 +503,32 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
486503
if(headerLine->length() > 0) {
487504
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str());
488505

489-
if(headerLine->startsWith("HTTP/1.")) {
506+
if(headerLine->startsWith(WEBSOCKETS_STRING("HTTP/1."))) {
490507
// "HTTP/1.1 101 Switching Protocols"
491508
client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt();
492509
} else if(headerLine->indexOf(':')) {
493510
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
494511
String headerValue = headerLine->substring(headerLine->indexOf(':') + 2);
495512

496-
if(headerName.equalsIgnoreCase("Connection")) {
497-
if(headerValue.equalsIgnoreCase("upgrade")) {
513+
if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) {
514+
if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("upgrade"))) {
498515
client->cIsUpgrade = true;
499516
}
500-
} else if(headerName.equalsIgnoreCase("Upgrade")) {
501-
if(headerValue.equalsIgnoreCase("websocket")) {
517+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) {
518+
if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) {
502519
client->cIsWebsocket = true;
503520
}
504-
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Accept")) {
521+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Accept"))) {
505522
client->cAccept = headerValue;
506523
client->cAccept.trim(); // see rfc6455
507-
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Protocol")) {
524+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) {
508525
client->cProtocol = headerValue;
509-
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) {
526+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) {
510527
client->cExtensions = headerValue;
511-
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) {
528+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) {
512529
client->cVersion = headerValue.toInt();
513-
} else if(headerName.equalsIgnoreCase("Set-Cookie")) {
514-
if (headerValue.indexOf("HttpOnly") > -1) {
530+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) {
531+
if (headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) {
515532
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";"));
516533
} else {
517534
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1);

src/WebSocketsServer.cpp

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -667,13 +667,16 @@ bool WebSocketsServer::hasMandatoryHeader(String headerName) {
667667
return false;
668668
}
669669

670+
670671
/**
671672
* handles http header reading for WebSocket upgrade
672673
* @param client WSclient_t * ///< pointer to the client struct
673674
* @param headerLine String ///< the header being read / processed
674675
*/
675676
void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
676677

678+
static const char * NEW_LINE = "\r\n";
679+
677680
headerLine->trim(); // remove \r
678681

679682
if(headerLine->length() > 0) {
@@ -693,25 +696,25 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
693696
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
694697
String headerValue = headerLine->substring(headerLine->indexOf(':') + 2);
695698

696-
if(headerName.equalsIgnoreCase("Connection")) {
699+
if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) {
697700
headerValue.toLowerCase();
698-
if(headerValue.indexOf("upgrade") >= 0) {
701+
if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) {
699702
client->cIsUpgrade = true;
700703
}
701-
} else if(headerName.equalsIgnoreCase("Upgrade")) {
702-
if(headerValue.equalsIgnoreCase("websocket")) {
704+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) {
705+
if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) {
703706
client->cIsWebsocket = true;
704707
}
705-
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) {
708+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) {
706709
client->cVersion = headerValue.toInt();
707-
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Key")) {
710+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) {
708711
client->cKey = headerValue;
709712
client->cKey.trim(); // see rfc6455
710-
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Protocol")) {
713+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) {
711714
client->cProtocol = headerValue;
712-
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) {
715+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) {
713716
client->cExtensions = headerValue;
714-
} else if(headerName.equalsIgnoreCase("Authorization")) {
717+
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) {
715718
client->base64Authorization = headerValue;
716719
} else {
717720
client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue);
@@ -764,7 +767,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
764767

765768
if(_base64Authorization.length() > 0) {
766769
if(client->base64Authorization.length() > 0) {
767-
String auth = "Basic ";
770+
String auth = WEBSOCKETS_STRING("Basic ");
768771
auth += _base64Authorization;
769772
if(auth != client->base64Authorization) {
770773
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num);
@@ -787,32 +790,30 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
787790

788791
client->status = WSC_CONNECTED;
789792

790-
client->tcp->write("HTTP/1.1 101 Switching Protocols\r\n"
793+
String handshake = WEBSOCKETS_STRING("HTTP/1.1 101 Switching Protocols\r\n"
791794
"Server: arduino-WebSocketsServer\r\n"
792795
"Upgrade: websocket\r\n"
793796
"Connection: Upgrade\r\n"
794797
"Sec-WebSocket-Version: 13\r\n"
795798
"Sec-WebSocket-Accept: ");
796-
client->tcp->write((uint8_t*)sKey.c_str(), sKey.length());
799+
handshake += sKey + NEW_LINE;
797800

798801
if(_origin.length() > 0) {
799-
String origin = "\r\nAccess-Control-Allow-Origin: ";
800-
origin += _origin;
801-
origin += "\r\n";
802-
client->tcp->write((uint8_t*)origin.c_str(), origin.length());
802+
handshake += WEBSOCKETS_STRING("Access-Control-Allow-Origin: ");
803+
handshake +=_origin + NEW_LINE;
803804
}
804805

805806
if(client->cProtocol.length() > 0) {
806-
String protocol = "\r\nSec-WebSocket-Protocol: ";
807-
protocol += _protocol;
808-
protocol += "\r\n";
809-
client->tcp->write((uint8_t*)protocol.c_str(), protocol.length());
810-
} else {
811-
client->tcp->write("\r\n");
807+
handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: ");
808+
handshake +=_protocol + NEW_LINE;
812809
}
813810

814811
// header end
815-
client->tcp->write("\r\n");
812+
handshake += NEW_LINE;
813+
814+
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t*)handshake.c_str());
815+
816+
client->tcp->write((uint8_t*)handshake.c_str(), handshake.length());
816817

817818
headerDone(client);
818819

src/WebSocketsServer.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ class WebSocketsServer: protected WebSockets {
149149
* @param client WSclient_t * ptr to the client struct
150150
*/
151151
virtual void handleAuthorizationFailed(WSclient_t *client) {
152-
153-
client->tcp->write("HTTP/1.1 401 Unauthorized\r\n"
152+
client->tcp->write("HTTP/1.1 401 Unauthorized\r\n"
154153
"Server: arduino-WebSocket-Server\r\n"
155154
"Content-Type: text/plain\r\n"
156155
"Content-Length: 45\r\n"

0 commit comments

Comments
 (0)