Aktualizace na verzi 3.2.4
This commit is contained in:
@ -128,8 +128,7 @@ AsyncEventSourceMessage::~AsyncEventSourceMessage() {
|
||||
free(_data);
|
||||
}
|
||||
|
||||
size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) {
|
||||
(void)time;
|
||||
size_t AsyncEventSourceMessage::ack(size_t len, __attribute__((unused)) uint32_t time) {
|
||||
// If the whole message is now acked...
|
||||
if (_acked + len > _len) {
|
||||
// Return the number of extra bytes acked (they will be carried on to the next message)
|
||||
@ -142,17 +141,19 @@ size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This could also return void as the return value is not used.
|
||||
// Leaving as-is for compatibility...
|
||||
size_t AsyncEventSourceMessage::send(AsyncClient* client) {
|
||||
if (_sent >= _len) {
|
||||
size_t AsyncEventSourceMessage::write(AsyncClient* client) {
|
||||
if (_sent >= _len || !client->canSend()) {
|
||||
return 0;
|
||||
}
|
||||
const size_t len_to_send = _len - _sent;
|
||||
auto position = reinterpret_cast<const char*>(_data + _sent);
|
||||
const size_t sent_now = client->write(position, len_to_send);
|
||||
_sent += sent_now;
|
||||
return sent_now;
|
||||
size_t len = min(_len - _sent, client->space());
|
||||
size_t sent = client->add((const char*)_data + _sent, len);
|
||||
_sent += sent;
|
||||
return sent;
|
||||
}
|
||||
|
||||
size_t AsyncEventSourceMessage::send(AsyncClient* client) {
|
||||
size_t sent = write(client);
|
||||
return sent && client->send() ? sent : 0;
|
||||
}
|
||||
|
||||
// Client
|
||||
@ -174,6 +175,8 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest* request, A
|
||||
|
||||
_server->_addClient(this);
|
||||
delete request;
|
||||
|
||||
_client->setNoDelay(true);
|
||||
}
|
||||
|
||||
AsyncEventSourceClient::~AsyncEventSourceClient() {
|
||||
@ -211,11 +214,6 @@ void AsyncEventSourceClient::_onAck(size_t len, uint32_t time) {
|
||||
// Same here, acquiring the lock early
|
||||
std::lock_guard<std::mutex> lock(_lockmq);
|
||||
#endif
|
||||
while (len && _messageQueue.size()) {
|
||||
len = _messageQueue.front().ack(len, time);
|
||||
if (_messageQueue.front().finished())
|
||||
_messageQueue.pop_front();
|
||||
}
|
||||
_runQueue();
|
||||
}
|
||||
|
||||
@ -264,11 +262,24 @@ size_t AsyncEventSourceClient::packetsWaiting() const {
|
||||
}
|
||||
|
||||
void AsyncEventSourceClient::_runQueue() {
|
||||
// Calls to this private method now already protected by _lockmq acquisition
|
||||
// so no extra call of _lockmq.lock() here..
|
||||
for (auto& i : _messageQueue) {
|
||||
if (!i.sent())
|
||||
i.send(_client);
|
||||
size_t total_bytes_written = 0;
|
||||
for (auto i = _messageQueue.begin(); i != _messageQueue.end(); ++i) {
|
||||
if (!i->sent()) {
|
||||
const size_t bytes_written = i->write(_client);
|
||||
total_bytes_written += bytes_written;
|
||||
if (bytes_written == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (total_bytes_written > 0)
|
||||
_client->send();
|
||||
|
||||
size_t len = total_bytes_written;
|
||||
while (len && _messageQueue.size()) {
|
||||
len = _messageQueue.front().ack(len);
|
||||
if (_messageQueue.front().finished()) {
|
||||
_messageQueue.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,7 +403,8 @@ AsyncEventSourceResponse::AsyncEventSourceResponse(AsyncEventSource* server) {
|
||||
}
|
||||
|
||||
void AsyncEventSourceResponse::_respond(AsyncWebServerRequest* request) {
|
||||
String out = _assembleHead(request->version());
|
||||
String out;
|
||||
_assembleHead(out, request->version());
|
||||
request->client()->write(out.c_str(), _headLength);
|
||||
_state = RESPONSE_WAIT_ACK;
|
||||
}
|
||||
|
@ -49,14 +49,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_MAX_SSE_CLIENTS
|
||||
#ifdef ESP32
|
||||
#define DEFAULT_MAX_SSE_CLIENTS 8
|
||||
#else
|
||||
#define DEFAULT_MAX_SSE_CLIENTS 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class AsyncEventSource;
|
||||
class AsyncEventSourceResponse;
|
||||
class AsyncEventSourceClient;
|
||||
@ -74,7 +66,8 @@ class AsyncEventSourceMessage {
|
||||
public:
|
||||
AsyncEventSourceMessage(const char* data, size_t len);
|
||||
~AsyncEventSourceMessage();
|
||||
size_t ack(size_t len, uint32_t time __attribute__((unused)));
|
||||
size_t ack(size_t len, uint32_t time = 0);
|
||||
size_t write(AsyncClient* client);
|
||||
size_t send(AsyncClient* client);
|
||||
bool finished() { return _acked == _len; }
|
||||
bool sent() { return _sent == _len; }
|
||||
@ -99,6 +92,8 @@ class AsyncEventSourceClient {
|
||||
AsyncClient* client() { return _client; }
|
||||
void close();
|
||||
void write(const char* message, size_t len);
|
||||
void send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event.c_str(), id, reconnect); }
|
||||
void send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event, id, reconnect); }
|
||||
void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0);
|
||||
bool connected() const { return (_client != NULL) && _client->connected(); }
|
||||
uint32_t lastId() const { return _lastId; }
|
||||
@ -124,13 +119,15 @@ class AsyncEventSource : public AsyncWebHandler {
|
||||
ArAuthorizeConnectHandler _authorizeConnectHandler;
|
||||
|
||||
public:
|
||||
AsyncEventSource(const String& url) : _url(url){};
|
||||
AsyncEventSource(const String& url) : _url(url) {};
|
||||
~AsyncEventSource() { close(); };
|
||||
|
||||
const char* url() const { return _url.c_str(); }
|
||||
void close();
|
||||
void onConnect(ArEventHandlerFunction cb);
|
||||
void authorizeConnect(ArAuthorizeConnectHandler cb);
|
||||
void send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event.c_str(), id, reconnect); }
|
||||
void send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event, id, reconnect); }
|
||||
void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0);
|
||||
// number of clients connected
|
||||
size_t count() const;
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(ESP32)
|
||||
#if ESP_IDF_VERSION_MAJOR < 5
|
||||
#include "./port/SHA1Builder.h"
|
||||
#include "BackPort_SHA1Builder.h"
|
||||
#else
|
||||
#include <SHA1Builder.h>
|
||||
#endif
|
||||
@ -36,11 +36,8 @@
|
||||
#include <Hash.h>
|
||||
#endif
|
||||
|
||||
#define MAX_PRINTF_LEN 64
|
||||
|
||||
using namespace asyncsrv;
|
||||
|
||||
|
||||
size_t webSocketSendFrameWindow(AsyncClient* client) {
|
||||
if (!client->canSend())
|
||||
return 0;
|
||||
@ -589,30 +586,23 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) {
|
||||
size_t AsyncWebSocketClient::printf(const char* format, ...) {
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
char* temp = new char[MAX_PRINTF_LEN];
|
||||
if (!temp) {
|
||||
va_end(arg);
|
||||
return 0;
|
||||
}
|
||||
char* buffer = temp;
|
||||
size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg);
|
||||
size_t len = vsnprintf(nullptr, 0, format, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
char* buffer = new char[len + 1];
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
va_start(arg, format);
|
||||
len = vsnprintf(buffer, len + 1, format, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (len > (MAX_PRINTF_LEN - 1)) {
|
||||
buffer = new char[len + 1];
|
||||
if (!buffer) {
|
||||
delete[] temp;
|
||||
return 0;
|
||||
}
|
||||
va_start(arg, format);
|
||||
vsnprintf(buffer, len + 1, format, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
text(buffer, len);
|
||||
if (buffer != temp) {
|
||||
delete[] buffer;
|
||||
}
|
||||
delete[] temp;
|
||||
delete[] buffer;
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -620,30 +610,23 @@ size_t AsyncWebSocketClient::printf(const char* format, ...) {
|
||||
size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) {
|
||||
va_list arg;
|
||||
va_start(arg, formatP);
|
||||
char* temp = new char[MAX_PRINTF_LEN];
|
||||
if (!temp) {
|
||||
va_end(arg);
|
||||
return 0;
|
||||
}
|
||||
char* buffer = temp;
|
||||
size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg);
|
||||
size_t len = vsnprintf_P(nullptr, 0, formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
char* buffer = new char[len + 1];
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
va_start(arg, formatP);
|
||||
len = vsnprintf_P(buffer, len + 1, formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (len > (MAX_PRINTF_LEN - 1)) {
|
||||
buffer = new char[len + 1];
|
||||
if (!buffer) {
|
||||
delete[] temp;
|
||||
return 0;
|
||||
}
|
||||
va_start(arg, formatP);
|
||||
vsnprintf_P(buffer, len + 1, formatP, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
text(buffer, len);
|
||||
if (buffer != temp) {
|
||||
delete[] buffer;
|
||||
}
|
||||
delete[] temp;
|
||||
delete[] buffer;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
@ -1008,22 +991,24 @@ size_t AsyncWebSocket::printf(uint32_t id, const char* format, ...) {
|
||||
|
||||
size_t AsyncWebSocket::printfAll(const char* format, ...) {
|
||||
va_list arg;
|
||||
char* temp = new char[MAX_PRINTF_LEN];
|
||||
if (!temp)
|
||||
va_start(arg, format);
|
||||
size_t len = vsnprintf(nullptr, 0, format, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
char* buffer = new char[len + 1];
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
va_start(arg, format);
|
||||
size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg);
|
||||
va_end(arg);
|
||||
delete[] temp;
|
||||
|
||||
AsyncWebSocketSharedBuffer buffer = std::make_shared<std::vector<uint8_t>>(len);
|
||||
|
||||
va_start(arg, format);
|
||||
vsnprintf((char*)buffer->data(), len + 1, format, arg);
|
||||
len = vsnprintf(buffer, len + 1, format, arg);
|
||||
va_end(arg);
|
||||
|
||||
textAll(buffer);
|
||||
textAll(buffer, len);
|
||||
delete[] buffer;
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1042,22 +1027,24 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...) {
|
||||
|
||||
size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) {
|
||||
va_list arg;
|
||||
char* temp = new char[MAX_PRINTF_LEN];
|
||||
if (!temp)
|
||||
va_start(arg, formatP);
|
||||
size_t len = vsnprintf_P(nullptr, 0, formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
char* buffer = new char[len + 1];
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
va_start(arg, formatP);
|
||||
size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg);
|
||||
va_end(arg);
|
||||
delete[] temp;
|
||||
|
||||
AsyncWebSocketSharedBuffer buffer = std::make_shared<std::vector<uint8_t>>(len + 1);
|
||||
|
||||
va_start(arg, formatP);
|
||||
vsnprintf_P((char*)buffer->data(), len + 1, formatP, arg);
|
||||
len = vsnprintf_P(buffer, len + 1, formatP, arg);
|
||||
va_end(arg);
|
||||
|
||||
textAll(buffer);
|
||||
textAll(buffer, len);
|
||||
delete[] buffer;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
@ -1192,7 +1179,8 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest* request) {
|
||||
request->client()->close(true);
|
||||
return;
|
||||
}
|
||||
String out(_assembleHead(request->version()));
|
||||
String out;
|
||||
_assembleHead(out, request->version());
|
||||
request->client()->write(out.c_str(), _headLength);
|
||||
_state = RESPONSE_WAIT_ACK;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <Arduino.h>
|
||||
#if ESP_IDF_VERSION_MAJOR < 5
|
||||
|
||||
#include "SHA1Builder.h"
|
||||
#include "BackPort_SHA1Builder.h"
|
||||
|
||||
// 32-bit integer manipulation macros (big endian)
|
||||
|
||||
@ -202,7 +202,7 @@ void SHA1Builder::process(const uint8_t *data) {
|
||||
|
||||
// Public methods
|
||||
|
||||
void SHA1Builder::begin(void) {
|
||||
void SHA1Builder::begin() {
|
||||
total[0] = 0;
|
||||
total[1] = 0;
|
||||
|
@ -12,6 +12,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <Arduino.h>
|
||||
#if ESP_IDF_VERSION_MAJOR < 5
|
||||
|
||||
#ifndef SHA1Builder_h
|
||||
#define SHA1Builder_h
|
||||
|
||||
@ -37,3 +40,5 @@ class SHA1Builder {
|
||||
};
|
||||
|
||||
#endif // SHA1Builder_h
|
||||
|
||||
#endif // ESP_IDF_VERSION_MAJOR < 5
|
@ -45,10 +45,10 @@
|
||||
|
||||
#include "literals.h"
|
||||
|
||||
#define ASYNCWEBSERVER_VERSION "3.2.0"
|
||||
#define ASYNCWEBSERVER_VERSION "3.2.4"
|
||||
#define ASYNCWEBSERVER_VERSION_MAJOR 3
|
||||
#define ASYNCWEBSERVER_VERSION_MINOR 2
|
||||
#define ASYNCWEBSERVER_VERSION_REVISION 0
|
||||
#define ASYNCWEBSERVER_VERSION_REVISION 4
|
||||
#define ASYNCWEBSERVER_FORK_mathieucarbou
|
||||
|
||||
#ifdef ASYNCWEBSERVER_REGEX
|
||||
@ -155,7 +155,9 @@ class AsyncWebHeader {
|
||||
const String& name() const { return _name; }
|
||||
const String& value() const { return _value; }
|
||||
String toString() const {
|
||||
String str = _name;
|
||||
String str;
|
||||
str.reserve(_name.length() + _value.length() + 2);
|
||||
str.concat(_name);
|
||||
str.concat((char)0x3a);
|
||||
str.concat((char)0x20);
|
||||
str.concat(_value);
|
||||
@ -333,11 +335,15 @@ class AsyncWebServerRequest {
|
||||
void sendChunked(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); }
|
||||
void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); }
|
||||
|
||||
#ifndef ESP8266
|
||||
[[deprecated("Replaced by send(...)")]]
|
||||
#endif
|
||||
void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) {
|
||||
send(code, contentType, content, len, callback);
|
||||
}
|
||||
#ifndef ESP8266
|
||||
[[deprecated("Replaced by send(...)")]]
|
||||
#endif
|
||||
void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) {
|
||||
send(code, contentType, content, callback);
|
||||
}
|
||||
@ -370,13 +376,17 @@ class AsyncWebServerRequest {
|
||||
AsyncResponseStream* beginResponseStream(const char* contentType, size_t bufferSize = 1460);
|
||||
AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460) { return beginResponseStream(contentType.c_str(), bufferSize); }
|
||||
|
||||
#ifndef ESP8266
|
||||
[[deprecated("Replaced by beginResponse(...)")]]
|
||||
#endif
|
||||
AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) {
|
||||
return beginResponse(code, contentType, content, len, callback);
|
||||
return beginResponse(code, contentType.c_str(), content, len, callback);
|
||||
}
|
||||
#ifndef ESP8266
|
||||
[[deprecated("Replaced by beginResponse(...)")]]
|
||||
#endif
|
||||
AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) {
|
||||
return beginResponse(code, contentType, content, callback);
|
||||
return beginResponse(code, contentType.c_str(), content, callback);
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
@ -583,8 +593,21 @@ class AsyncWebServerResponse {
|
||||
virtual void setContentType(const char* type);
|
||||
virtual bool addHeader(const char* name, const char* value, bool replaceExisting = true);
|
||||
bool addHeader(const String& name, const String& value, bool replaceExisting = true) { return addHeader(name.c_str(), value.c_str(), replaceExisting); }
|
||||
bool addHeader(const char* name, long value, bool replaceExisting = true) { return addHeader(name, String(value), replaceExisting); }
|
||||
bool addHeader(const String& name, long value, bool replaceExisting = true) { return addHeader(name.c_str(), value, replaceExisting); }
|
||||
virtual bool removeHeader(const char* name);
|
||||
virtual String _assembleHead(uint8_t version);
|
||||
virtual const AsyncWebHeader* getHeader(const char* name) const;
|
||||
|
||||
#ifndef ESP8266
|
||||
[[deprecated("Use instead: _assembleHead(String& buffer, uint8_t version)")]]
|
||||
#endif
|
||||
String _assembleHead(uint8_t version) {
|
||||
String buffer;
|
||||
_assembleHead(buffer, version);
|
||||
return buffer;
|
||||
}
|
||||
virtual void _assembleHead(String& buffer, uint8_t version);
|
||||
|
||||
virtual bool _started() const;
|
||||
virtual bool _finished() const;
|
||||
virtual bool _failed() const;
|
||||
|
@ -624,7 +624,6 @@ bool AsyncWebServerRequest::hasHeader(const __FlashStringHelper* data) const {
|
||||
|
||||
const AsyncWebHeader* AsyncWebServerRequest::getHeader(const char* name) const {
|
||||
auto iter = std::find_if(std::begin(_headers), std::end(_headers), [&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); });
|
||||
|
||||
return (iter == std::end(_headers)) ? nullptr : &(*iter);
|
||||
}
|
||||
|
||||
|
@ -125,9 +125,8 @@ const char* AsyncWebServerResponse::responseCodeToString(int code) {
|
||||
return T_HTTP_CODE_ANY;
|
||||
}
|
||||
}
|
||||
#else // ESP8266
|
||||
const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code)
|
||||
{
|
||||
#else // ESP8266
|
||||
const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) {
|
||||
switch (code) {
|
||||
case 100:
|
||||
return FPSTR(T_HTTP_CODE_100);
|
||||
@ -230,12 +229,12 @@ void AsyncWebServerResponse::setCode(int code) {
|
||||
}
|
||||
|
||||
void AsyncWebServerResponse::setContentLength(size_t len) {
|
||||
if (_state == RESPONSE_SETUP)
|
||||
if (_state == RESPONSE_SETUP && addHeader(T_Content_Length, len, true))
|
||||
_contentLength = len;
|
||||
}
|
||||
|
||||
void AsyncWebServerResponse::setContentType(const char* type) {
|
||||
if (_state == RESPONSE_SETUP)
|
||||
if (_state == RESPONSE_SETUP && addHeader(T_Content_Type, type, true))
|
||||
_contentType = type;
|
||||
}
|
||||
|
||||
@ -249,6 +248,11 @@ bool AsyncWebServerResponse::removeHeader(const char* name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const AsyncWebHeader* AsyncWebServerResponse::getHeader(const char* name) const {
|
||||
auto iter = std::find_if(std::begin(_headers), std::end(_headers), [&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); });
|
||||
return (iter == std::end(_headers)) ? nullptr : &(*iter);
|
||||
}
|
||||
|
||||
bool AsyncWebServerResponse::addHeader(const char* name, const char* value, bool replaceExisting) {
|
||||
for (auto i = _headers.begin(); i != _headers.end(); ++i) {
|
||||
if (i->name().equalsIgnoreCase(name)) {
|
||||
@ -268,41 +272,56 @@ bool AsyncWebServerResponse::addHeader(const char* name, const char* value, bool
|
||||
return true;
|
||||
}
|
||||
|
||||
String AsyncWebServerResponse::_assembleHead(uint8_t version) {
|
||||
void AsyncWebServerResponse::_assembleHead(String& buffer, uint8_t version) {
|
||||
if (version) {
|
||||
addHeader(T_Accept_Ranges, T_none, false);
|
||||
if (_chunked)
|
||||
addHeader(T_Transfer_Encoding, T_chunked, false);
|
||||
}
|
||||
String out;
|
||||
constexpr size_t bufSize = 300;
|
||||
char buf[bufSize];
|
||||
|
||||
#ifndef ESP8266
|
||||
snprintf(buf, bufSize, "HTTP/1.%d %d %s\r\n", version, _code, responseCodeToString(_code));
|
||||
if (_sendContentLength)
|
||||
addHeader(T_Content_Length, String(_contentLength), false);
|
||||
|
||||
if (_contentType.length())
|
||||
addHeader(T_Content_Type, _contentType.c_str(), false);
|
||||
|
||||
// precompute buffer size to avoid reallocations by String class
|
||||
size_t len = 0;
|
||||
len += 50; // HTTP/1.1 200 <reason>\r\n
|
||||
for (const auto& header : _headers)
|
||||
len += header.name().length() + header.value().length() + 4;
|
||||
|
||||
// prepare buffer
|
||||
buffer.reserve(len);
|
||||
|
||||
// HTTP header
|
||||
#ifdef ESP8266
|
||||
buffer.concat(PSTR("HTTP/1."));
|
||||
#else
|
||||
snprintf_P(buf, bufSize, PSTR("HTTP/1.%d %d %s\r\n"), version, _code, String(responseCodeToString(_code)).c_str());
|
||||
buffer.concat("HTTP/1.");
|
||||
#endif
|
||||
out.concat(buf);
|
||||
|
||||
if (_sendContentLength) {
|
||||
snprintf_P(buf, bufSize, PSTR("Content-Length: %d\r\n"), _contentLength);
|
||||
out.concat(buf);
|
||||
}
|
||||
if (_contentType.length()) {
|
||||
snprintf_P(buf, bufSize, PSTR("Content-Type: %s\r\n"), _contentType.c_str());
|
||||
out.concat(buf);
|
||||
}
|
||||
buffer.concat(version);
|
||||
buffer.concat(' ');
|
||||
buffer.concat(_code);
|
||||
buffer.concat(' ');
|
||||
buffer.concat(responseCodeToString(_code));
|
||||
buffer.concat(T_rn);
|
||||
|
||||
// Add headers
|
||||
for (const auto& header : _headers) {
|
||||
snprintf_P(buf, bufSize, PSTR("%s: %s\r\n"), header.name().c_str(), header.value().c_str());
|
||||
out.concat(buf);
|
||||
buffer.concat(header.name());
|
||||
#ifdef ESP8266
|
||||
buffer.concat(PSTR(": "));
|
||||
#else
|
||||
buffer.concat(": ");
|
||||
#endif
|
||||
buffer.concat(header.value());
|
||||
buffer.concat(T_rn);
|
||||
}
|
||||
_headers.clear();
|
||||
|
||||
out.concat(T_rn);
|
||||
_headLength = out.length();
|
||||
return out;
|
||||
buffer.concat(T_rn);
|
||||
_headLength = buffer.length();
|
||||
}
|
||||
|
||||
bool AsyncWebServerResponse::_started() const { return _state > RESPONSE_SETUP; }
|
||||
@ -337,7 +356,8 @@ AsyncBasicResponse::AsyncBasicResponse(int code, const char* contentType, const
|
||||
|
||||
void AsyncBasicResponse::_respond(AsyncWebServerRequest* request) {
|
||||
_state = RESPONSE_HEADERS;
|
||||
String out = _assembleHead(request->version());
|
||||
String out;
|
||||
_assembleHead(out, request->version());
|
||||
size_t outLen = out.length();
|
||||
size_t space = request->client()->space();
|
||||
if (!_contentLength && space >= outLen) {
|
||||
@ -411,7 +431,7 @@ AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback) : _c
|
||||
|
||||
void AsyncAbstractResponse::_respond(AsyncWebServerRequest* request) {
|
||||
addHeader(T_Connection, T_close, false);
|
||||
_head = _assembleHead(request->version());
|
||||
_assembleHead(_head, request->version());
|
||||
_state = RESPONSE_HEADERS;
|
||||
_ack(request, 0, 0);
|
||||
}
|
||||
@ -472,9 +492,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
outLen = sprintf_P((char*)buf + headLen, PSTR("%x"), readLen) + headLen;
|
||||
while (outLen < headLen + 4)
|
||||
buf[outLen++] = ' ';
|
||||
outLen = sprintf((char*)buf+headLen, "%04x", readLen) + headLen;
|
||||
buf[outLen++] = '\r';
|
||||
buf[outLen++] = '\n';
|
||||
outLen += readLen;
|
||||
@ -635,9 +653,9 @@ AsyncFileResponse::~AsyncFileResponse() {
|
||||
void AsyncFileResponse::_setContentTypeFromPath(const String& path) {
|
||||
#if HAVE_EXTERN_GET_Content_Type_FUNCTION
|
||||
#ifndef ESP8266
|
||||
extern const char* getContentType(const String& path);
|
||||
extern const char* getContentType(const String& path);
|
||||
#else
|
||||
extern const __FlashStringHelper* getContentType(const String& path);
|
||||
extern const __FlashStringHelper* getContentType(const String& path);
|
||||
#endif
|
||||
_contentType = getContentType(path);
|
||||
#else
|
||||
|
Reference in New Issue
Block a user