Skip to content

Commit 04049f9

Browse files
committed
Replace use of LinkedList<T> with std::list for request headers
Based on commit 2183add of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Step two of removal of homebrewed LinkedList in favor of standard C++ containers. For consistency, the list of interesting headers in the request has been converted to a std::vector<String>. Also, const versions of header query functions have been implemented. The original patch also happens to fix bug me-no-dev#837, and this manual cherry-pick replaces the previous fix with the dumbfixes one.
1 parent a20b754 commit 04049f9

File tree

2 files changed

+86
-41
lines changed

2 files changed

+86
-41
lines changed

src/ESPAsyncWebServer.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "Arduino.h"
2525

2626
#include <functional>
27+
#include <list>
2728
#include "FS.h"
2829

2930
#include "StringArray.h"
@@ -154,7 +155,7 @@ class AsyncWebServerRequest {
154155
AsyncWebServer* _server;
155156
AsyncWebHandler* _handler;
156157
AsyncWebServerResponse* _response;
157-
StringArray _interestingHeaders;
158+
std::vector<String> _interestingHeaders;
158159
ArDisconnectHandler _onDisconnectfn;
159160

160161
String _temp;
@@ -176,7 +177,7 @@ class AsyncWebServerRequest {
176177
size_t _contentLength;
177178
size_t _parsedLength;
178179

179-
LinkedList<AsyncWebHeader *> _headers;
180+
std::list<AsyncWebHeader> _headers;
180181
LinkedList<AsyncWebParameter *> _params;
181182
LinkedList<String *> _pathParams;
182183

@@ -270,9 +271,12 @@ class AsyncWebServerRequest {
270271
bool hasHeader(const String& name) const; // check if header exists
271272
bool hasHeader(const __FlashStringHelper * data) const; // check if header exists
272273

273-
AsyncWebHeader* getHeader(const String& name) const;
274-
AsyncWebHeader* getHeader(const __FlashStringHelper * data) const;
275-
AsyncWebHeader* getHeader(size_t num) const;
274+
AsyncWebHeader* getHeader(const String& name);
275+
const AsyncWebHeader* getHeader(const String& name) const;
276+
AsyncWebHeader* getHeader(const __FlashStringHelper * data);
277+
const AsyncWebHeader* getHeader(const __FlashStringHelper * data) const;
278+
AsyncWebHeader* getHeader(size_t num);
279+
const AsyncWebHeader* getHeader(size_t num) const;
276280

277281
size_t params() const; // get arguments count
278282
bool hasParam(const String& name, bool post=false, bool file=false) const;

src/WebRequest.cpp

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c)
5151
, _expectingContinue(false)
5252
, _contentLength(0)
5353
, _parsedLength(0)
54-
, _headers(LinkedList<AsyncWebHeader *>([](AsyncWebHeader *h){ delete h; }))
5554
, _params(LinkedList<AsyncWebParameter *>([](AsyncWebParameter *p){ delete p; }))
5655
, _pathParams(LinkedList<String *>([](String *p){ delete p; }))
5756
, _multiParseState(0)
@@ -76,12 +75,12 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c)
7675
}
7776

7877
AsyncWebServerRequest::~AsyncWebServerRequest(){
79-
_headers.free();
78+
_headers.clear();
8079

8180
_params.free();
8281
_pathParams.free();
8382

84-
_interestingHeaders.free();
83+
_interestingHeaders.clear();
8584

8685
if(_response != NULL){
8786
delete _response;
@@ -182,20 +181,19 @@ void AsyncWebServerRequest::_onData(void *buf, size_t len){
182181
}
183182

184183
void AsyncWebServerRequest::_removeNotInterestingHeaders(){
185-
if (_interestingHeaders.containsIgnoreCase(F("ANY"))) {
186-
return; // nothing to do
187-
}
188-
// When removing items from the list, we must increase the iterator first
189-
// before removing the current item, otherwise the iterator is invalidated
190-
// So, no for(;;) loop can be used, see: https://stackoverflow.com/q/596162
191-
auto i_header = _headers.begin();
192-
const auto i_end = _headers.end();
193-
while (i_header != i_end){
194-
const auto header = *i_header;
195-
++i_header;
196-
if(!_interestingHeaders.containsIgnoreCase(header->name().c_str())){
197-
_headers.remove(header);
198-
}
184+
if (std::any_of(std::begin(_interestingHeaders), std::end(_interestingHeaders),
185+
[](const String &str){ return str.equalsIgnoreCase(F("ANY")); }))
186+
return; // nothing to do
187+
188+
for(auto iter = std::begin(_headers); iter != std::end(_headers); )
189+
{
190+
const auto name = iter->name();
191+
192+
if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders),
193+
[&name](const String &str){ return str.equalsIgnoreCase(name); }))
194+
iter = _headers.erase(iter);
195+
else
196+
iter++;
199197
}
200198
}
201199

@@ -370,7 +368,7 @@ bool AsyncWebServerRequest::_parseReqHeader(){
370368
}
371369
}
372370
}
373-
_headers.add(new AsyncWebHeader(name, value));
371+
_headers.emplace_back(name, value);
374372
}
375373
_temp = String();
376374
return true;
@@ -611,12 +609,12 @@ void AsyncWebServerRequest::_parseLine(){
611609
}
612610

613611
size_t AsyncWebServerRequest::headers() const{
614-
return _headers.length();
612+
return _headers.size();
615613
}
616614

617615
bool AsyncWebServerRequest::hasHeader(const String& name) const {
618616
for(const auto& h: _headers){
619-
if(h->name().equalsIgnoreCase(name)){
617+
if(h.name().equalsIgnoreCase(name)){
620618
return true;
621619
}
622620
}
@@ -627,22 +625,64 @@ bool AsyncWebServerRequest::hasHeader(const __FlashStringHelper * data) const {
627625
return hasHeader(String(data));
628626
}
629627

630-
AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) const {
631-
for(const auto& h: _headers){
632-
if(h->name().equalsIgnoreCase(name)){
633-
return h;
634-
}
628+
AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) {
629+
auto iter = std::find_if(std::begin(_headers), std::end(_headers),
630+
[&name](const AsyncWebHeader &header){ return header.name().equalsIgnoreCase(name); });
631+
632+
if (iter == std::end(_headers))
633+
return nullptr;
634+
635+
return &(*iter);
636+
}
637+
638+
const AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) const {
639+
auto iter = std::find_if(std::begin(_headers), std::end(_headers),
640+
[&name](const AsyncWebHeader &header){ return header.name().equalsIgnoreCase(name); });
641+
642+
if (iter == std::end(_headers))
643+
return nullptr;
644+
645+
return &(*iter);
646+
}
647+
648+
AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) {
649+
PGM_P p = reinterpret_cast<PGM_P>(data);
650+
size_t n = strlen_P(p);
651+
char * name = (char*) malloc(n+1);
652+
if (name) {
653+
strcpy_P(name, p);
654+
AsyncWebHeader* result = getHeader( String(name));
655+
free(name);
656+
return result;
657+
} else {
658+
return nullptr;
659+
}
660+
}
661+
662+
const AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) const {
663+
PGM_P p = reinterpret_cast<PGM_P>(data);
664+
size_t n = strlen_P(p);
665+
char * name = (char*) malloc(n+1);
666+
if (name) {
667+
strcpy_P(name, p);
668+
const AsyncWebHeader* result = getHeader( String(name));
669+
free(name);
670+
return result;
671+
} else {
672+
return nullptr;
635673
}
636-
return nullptr;
637674
}
638675

639-
AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) const {
640-
return getHeader(String(data));
676+
AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) {
677+
if (num >= _headers.size())
678+
return nullptr;
679+
return &(*std::next(std::begin(_headers), num));
641680
}
642681

643-
AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const {
644-
auto header = _headers.nth(num);
645-
return header ? *header : nullptr;
682+
const AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const {
683+
if (num >= _headers.size())
684+
return nullptr;
685+
return &(*std::next(std::begin(_headers), num));
646686
}
647687

648688
size_t AsyncWebServerRequest::params() const {
@@ -681,8 +721,9 @@ AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const {
681721
}
682722

683723
void AsyncWebServerRequest::addInterestingHeader(const String& name){
684-
if(!_interestingHeaders.containsIgnoreCase(name))
685-
_interestingHeaders.add(name);
724+
if(std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders),
725+
[&name](const String &str){ return str.equalsIgnoreCase(name); }))
726+
_interestingHeaders.push_back(name);
686727
}
687728

688729
void AsyncWebServerRequest::send(AsyncWebServerResponse *response){
@@ -879,7 +920,7 @@ const String& AsyncWebServerRequest::pathArg(size_t i) const {
879920
}
880921

881922
const String& AsyncWebServerRequest::header(const char* name) const {
882-
AsyncWebHeader* h = getHeader(String(name));
923+
const AsyncWebHeader* h = getHeader(String(name));
883924
return h ? h->value() : emptyString;
884925
}
885926

@@ -889,12 +930,12 @@ const String& AsyncWebServerRequest::header(const __FlashStringHelper * data) co
889930

890931

891932
const String& AsyncWebServerRequest::header(size_t i) const {
892-
AsyncWebHeader* h = getHeader(i);
933+
const AsyncWebHeader* h = getHeader(i);
893934
return h ? h->value() : emptyString;
894935
}
895936

896937
const String& AsyncWebServerRequest::headerName(size_t i) const {
897-
AsyncWebHeader* h = getHeader(i);
938+
const AsyncWebHeader* h = getHeader(i);
898939
return h ? h->name() : emptyString;
899940
}
900941

0 commit comments

Comments
 (0)