|
|
@ -372,65 +372,6 @@ class ApiJsonWebHandler final : public ApiBaseWebHandler { |
|
|
|
public: |
|
|
|
static constexpr size_t BufferSize { API_JSON_BUFFER_SIZE }; |
|
|
|
|
|
|
|
struct ReadOnlyStream : public Stream { |
|
|
|
ReadOnlyStream() = delete; |
|
|
|
explicit ReadOnlyStream(const uint8_t* buffer, size_t size) : |
|
|
|
_buffer(buffer), |
|
|
|
_size(size) |
|
|
|
{} |
|
|
|
|
|
|
|
int available() override { |
|
|
|
return _size - _index; |
|
|
|
} |
|
|
|
|
|
|
|
int peek() override { |
|
|
|
if (_index < _size) { |
|
|
|
return static_cast<int>(_buffer[_index]); |
|
|
|
} |
|
|
|
|
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
int read() override { |
|
|
|
auto peeked = peek(); |
|
|
|
if (peeked >= 0) { |
|
|
|
++_index; |
|
|
|
} |
|
|
|
|
|
|
|
return peeked; |
|
|
|
} |
|
|
|
|
|
|
|
// since we are fixed in size, no need for any timeouts and the only available option is to return full chunk of data
|
|
|
|
size_t readBytes(uint8_t* ptr, size_t size) override { |
|
|
|
if ((_index < _size) && ((_size - _index) >= size)) { |
|
|
|
std::copy(_buffer + _index, _buffer + _index + size, ptr); |
|
|
|
_index += size; |
|
|
|
return size; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
size_t readBytes(char* ptr, size_t size) override { |
|
|
|
return readBytes(reinterpret_cast<uint8_t*>(ptr), size); |
|
|
|
} |
|
|
|
|
|
|
|
void flush() override { |
|
|
|
} |
|
|
|
|
|
|
|
size_t write(const uint8_t*, size_t) override { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
size_t write(uint8_t) override { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
const uint8_t* _buffer; |
|
|
|
const size_t _size; |
|
|
|
size_t _index { 0 }; |
|
|
|
}; |
|
|
|
|
|
|
|
ApiJsonWebHandler() = delete; |
|
|
|
ApiJsonWebHandler(const ApiJsonWebHandler&) = delete; |
|
|
|
ApiJsonWebHandler(ApiJsonWebHandler&&) = delete; |
|
|
@ -500,10 +441,12 @@ public: |
|
|
|
void _handlePut(AsyncWebServerRequest* request, uint8_t* data, size_t size) { |
|
|
|
// XXX: arduinojson v5 de-serializer will happily read garbage from raw ptr, since there's no length limit
|
|
|
|
// this is fixed in v6 though. for now, use a wrapper, but be aware that this actually uses more mem for the jsonbuffer
|
|
|
|
DynamicJsonBuffer jsonBuffer(BufferSize); |
|
|
|
ReadOnlyStream stream(data, size); |
|
|
|
auto reader = espurna::StringView( |
|
|
|
reinterpret_cast<const char*>(data), |
|
|
|
reinterpret_cast<const char*>(data + size)); |
|
|
|
|
|
|
|
JsonObject& root = jsonBuffer.parseObject(stream); |
|
|
|
DynamicJsonBuffer jsonBuffer(BufferSize); |
|
|
|
JsonObject& root = jsonBuffer.parseObject(reader); |
|
|
|
if (!root.success()) { |
|
|
|
request->send(500); |
|
|
|
return; |
|
|
|