forked from me-no-dev/ESPAsyncWebServer
Fixed templating engine bug. (#267)
Signed-off-by: Alexandr Zarubkin <me21@yandex.ru>
This commit is contained in:
committed by
Me No Dev
parent
054824a174
commit
8139925eb9
@@ -42,6 +42,10 @@ class AsyncBasicResponse: public AsyncWebServerResponse {
|
|||||||
class AsyncAbstractResponse: public AsyncWebServerResponse {
|
class AsyncAbstractResponse: public AsyncWebServerResponse {
|
||||||
private:
|
private:
|
||||||
String _head;
|
String _head;
|
||||||
|
// Data is inserted into cache at begin().
|
||||||
|
// This is inefficient with vector, but if we use some other container,
|
||||||
|
// we won't be able to access it as contiguous array of bytes when reading from it,
|
||||||
|
// so by gaining performance in one place, we'll lose it in another.
|
||||||
std::vector<uint8_t> _cache;
|
std::vector<uint8_t> _cache;
|
||||||
size_t _readDataFromCacheOrContent(uint8_t* data, const size_t len);
|
size_t _readDataFromCacheOrContent(uint8_t* data, const size_t len);
|
||||||
size_t _fillBufferAndProcessTemplates(uint8_t* buf, size_t maxLen);
|
size_t _fillBufferAndProcessTemplates(uint8_t* buf, size_t maxLen);
|
||||||
|
@@ -378,8 +378,6 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size
|
|||||||
// temporary buffer to hold parameter name
|
// temporary buffer to hold parameter name
|
||||||
uint8_t buf[TEMPLATE_PARAM_NAME_LENGTH + 1];
|
uint8_t buf[TEMPLATE_PARAM_NAME_LENGTH + 1];
|
||||||
String paramName;
|
String paramName;
|
||||||
// cache position to insert remainder of template parameter value
|
|
||||||
std::vector<uint8_t>::iterator i = _cache.end();
|
|
||||||
// If closing placeholder is found:
|
// If closing placeholder is found:
|
||||||
if(pTemplateEnd) {
|
if(pTemplateEnd) {
|
||||||
// prepare argument to callback
|
// prepare argument to callback
|
||||||
@@ -403,16 +401,14 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size
|
|||||||
// prepare argument to callback
|
// prepare argument to callback
|
||||||
*pTemplateEnd = 0;
|
*pTemplateEnd = 0;
|
||||||
paramName = String(reinterpret_cast<char*>(buf));
|
paramName = String(reinterpret_cast<char*>(buf));
|
||||||
// Copy remaining read-ahead data into cache (when std::vector::insert returning iterator will be available, these 3 lines can be simplified into 1)
|
// Copy remaining read-ahead data into cache
|
||||||
const size_t pos = _cache.size();
|
_cache.insert(_cache.begin(), pTemplateEnd + 1, buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent);
|
||||||
_cache.insert(_cache.end(), pTemplateEnd + 1, buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent);
|
|
||||||
i = _cache.begin() + pos;
|
|
||||||
pTemplateEnd = &data[len - 1];
|
pTemplateEnd = &data[len - 1];
|
||||||
}
|
}
|
||||||
else // closing placeholder not found in file data, store found percent symbol as is and advance to the next position
|
else // closing placeholder not found in file data, store found percent symbol as is and advance to the next position
|
||||||
{
|
{
|
||||||
// but first, store read file data in cache
|
// but first, store read file data in cache
|
||||||
_cache.insert(_cache.end(), buf + (&data[len - 1] - pTemplateStart), buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent);
|
_cache.insert(_cache.begin(), buf + (&data[len - 1] - pTemplateStart), buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent);
|
||||||
++pTemplateStart;
|
++pTemplateStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -434,9 +430,7 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size
|
|||||||
// make room for param value
|
// make room for param value
|
||||||
// 1. move extra data to cache if parameter value is longer than placeholder AND if there is no room to store
|
// 1. move extra data to cache if parameter value is longer than placeholder AND if there is no room to store
|
||||||
if((pTemplateEnd + 1 < pTemplateStart + numBytesCopied) && (originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1) < len)) {
|
if((pTemplateEnd + 1 < pTemplateStart + numBytesCopied) && (originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1) < len)) {
|
||||||
size_t pos = i - _cache.begin();
|
_cache.insert(_cache.begin(), &data[originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1)], &data[len]);
|
||||||
_cache.insert(i, &data[originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1)], &data[len]);
|
|
||||||
i = _cache.begin() + pos;
|
|
||||||
//2. parameter value is longer than placeholder text, push the data after placeholder which not saved into cache further to the end
|
//2. parameter value is longer than placeholder text, push the data after placeholder which not saved into cache further to the end
|
||||||
memmove(pTemplateStart + numBytesCopied, pTemplateEnd + 1, &data[originalLen] - pTemplateStart - numBytesCopied);
|
memmove(pTemplateStart + numBytesCopied, pTemplateEnd + 1, &data[originalLen] - pTemplateStart - numBytesCopied);
|
||||||
} else if(pTemplateEnd + 1 != pTemplateStart + numBytesCopied)
|
} else if(pTemplateEnd + 1 != pTemplateStart + numBytesCopied)
|
||||||
@@ -447,7 +441,7 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size
|
|||||||
memcpy(pTemplateStart, pvstr, numBytesCopied);
|
memcpy(pTemplateStart, pvstr, numBytesCopied);
|
||||||
// If result is longer than buffer, copy the remainder into cache (this could happen only if placeholder text itself did not fit entirely in buffer)
|
// If result is longer than buffer, copy the remainder into cache (this could happen only if placeholder text itself did not fit entirely in buffer)
|
||||||
if(numBytesCopied < pvlen) {
|
if(numBytesCopied < pvlen) {
|
||||||
_cache.insert(i, pvstr + numBytesCopied, pvstr + pvlen);
|
_cache.insert(_cache.begin(), pvstr + numBytesCopied, pvstr + pvlen);
|
||||||
} else if(pTemplateStart + numBytesCopied < pTemplateEnd + 1) { // result is copied fully; if result is shorter than placeholder text...
|
} else if(pTemplateStart + numBytesCopied < pTemplateEnd + 1) { // result is copied fully; if result is shorter than placeholder text...
|
||||||
// there is some free room, fill it from cache
|
// there is some free room, fill it from cache
|
||||||
const size_t roomFreed = pTemplateEnd + 1 - pTemplateStart - numBytesCopied;
|
const size_t roomFreed = pTemplateEnd + 1 - pTemplateStart - numBytesCopied;
|
||||||
|
Reference in New Issue
Block a user