mirror of
https://github.com/me-no-dev/ESPAsyncWebServer.git
synced 2025-09-29 15:50:56 +02:00
Close #77: Allow modification of hardcoded headers
This commit is contained in:
committed by
Mathieu Carbou
parent
504231c96f
commit
f0402e5a6e
@@ -61,6 +61,27 @@ void setup() {
|
||||
request->send(LittleFS, "/index.html");
|
||||
});
|
||||
|
||||
/*
|
||||
❯ curl -I -X HEAD http://192.168.4.1/download
|
||||
HTTP/1.1 200 OK
|
||||
Content-Length: 1024
|
||||
Content-Type: application/octet-stream
|
||||
Connection: close
|
||||
Accept-Ranges: bytes
|
||||
*/
|
||||
// Ref: https://github.com/mathieucarbou/ESPAsyncWebServer/pull/80
|
||||
server.on("/download", HTTP_HEAD | HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||
if (request->method() == HTTP_HEAD) {
|
||||
AsyncWebServerResponse* response = request->beginResponse(200, "application/octet-stream");
|
||||
response->setContentLength(1024); // myFile.getSize()
|
||||
response->addHeader("Accept-Ranges", "bytes");
|
||||
// ...
|
||||
request->send(response);
|
||||
} else {
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
// Send a GET request to <IP>/get?message=<message>
|
||||
server.on("/get", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||
String message;
|
||||
|
@@ -581,8 +581,9 @@ class AsyncWebServerResponse {
|
||||
virtual void setContentLength(size_t len);
|
||||
void setContentType(const String& type) { setContentType(type.c_str()); }
|
||||
virtual void setContentType(const char* type);
|
||||
virtual void addHeader(const char* name, const char* value);
|
||||
void addHeader(const String& name, const String& value) { addHeader(name.c_str(), value.c_str()); }
|
||||
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); }
|
||||
virtual bool removeHeader(const char* name);
|
||||
virtual String _assembleHead(uint8_t version);
|
||||
virtual bool _started() const;
|
||||
virtual bool _finished() const;
|
||||
|
@@ -239,18 +239,43 @@ void AsyncWebServerResponse::setContentType(const char* type) {
|
||||
_contentType = type;
|
||||
}
|
||||
|
||||
void AsyncWebServerResponse::addHeader(const char* name, const char* value) {
|
||||
bool AsyncWebServerResponse::removeHeader(const char* name) {
|
||||
for (auto i = _headers.begin(); i != _headers.end(); ++i) {
|
||||
if (i->name().equalsIgnoreCase(name)) {
|
||||
_headers.erase(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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)) {
|
||||
// header already set
|
||||
if (replaceExisting) {
|
||||
// remove, break and add the new one
|
||||
_headers.erase(i);
|
||||
break;
|
||||
} else {
|
||||
// do not update
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// header was not found found, or existing one was removed
|
||||
_headers.emplace_back(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
String AsyncWebServerResponse::_assembleHead(uint8_t version) {
|
||||
if (version) {
|
||||
addHeader(T_Accept_Ranges, T_none);
|
||||
addHeader(T_Accept_Ranges, T_none, false);
|
||||
if (_chunked)
|
||||
addHeader(Transfer_Encoding, T_chunked);
|
||||
addHeader(T_Transfer_Encoding, T_chunked, false);
|
||||
}
|
||||
String out;
|
||||
int bufSize = 300;
|
||||
constexpr size_t bufSize = 300;
|
||||
char buf[bufSize];
|
||||
|
||||
#ifndef ESP8266
|
||||
@@ -307,7 +332,7 @@ AsyncBasicResponse::AsyncBasicResponse(int code, const char* contentType, const
|
||||
if (!_contentType.length())
|
||||
_contentType = T_text_plain;
|
||||
}
|
||||
addHeader(T_Connection, T_close);
|
||||
addHeader(T_Connection, T_close, false);
|
||||
}
|
||||
|
||||
void AsyncBasicResponse::_respond(AsyncWebServerRequest* request) {
|
||||
@@ -385,7 +410,7 @@ AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback) : _c
|
||||
}
|
||||
|
||||
void AsyncAbstractResponse::_respond(AsyncWebServerRequest* request) {
|
||||
addHeader(T_Connection, T_close);
|
||||
addHeader(T_Connection, T_close, false);
|
||||
_head = _assembleHead(request->version());
|
||||
_state = RESPONSE_HEADERS;
|
||||
_ack(request, 0, 0);
|
||||
@@ -663,7 +688,7 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const char* con
|
||||
|
||||
if (!download && !fs.exists(_path) && fs.exists(_path + T__gz)) {
|
||||
_path = _path + T__gz;
|
||||
addHeader(T_Content_Encoding, T_gzip);
|
||||
addHeader(T_Content_Encoding, T_gzip, false);
|
||||
_callback = nullptr; // Unable to process zipped templates
|
||||
_sendContentLength = true;
|
||||
_chunked = false;
|
||||
@@ -688,7 +713,7 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const char* con
|
||||
// set filename and force rendering
|
||||
snprintf_P(buf, sizeof(buf), PSTR("inline"));
|
||||
}
|
||||
addHeader(T_Content_Disposition, buf);
|
||||
addHeader(T_Content_Disposition, buf, false);
|
||||
}
|
||||
|
||||
AsyncFileResponse::AsyncFileResponse(File content, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) {
|
||||
@@ -696,7 +721,7 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const cha
|
||||
_path = path;
|
||||
|
||||
if (!download && String(content.name()).endsWith(T__gz) && !path.endsWith(T__gz)) {
|
||||
addHeader(T_Content_Encoding, T_gzip);
|
||||
addHeader(T_Content_Encoding, T_gzip, false);
|
||||
_callback = nullptr; // Unable to process gzipped templates
|
||||
_sendContentLength = true;
|
||||
_chunked = false;
|
||||
@@ -719,7 +744,7 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const cha
|
||||
} else {
|
||||
snprintf_P(buf, sizeof(buf), PSTR("inline"));
|
||||
}
|
||||
addHeader(T_Content_Disposition, buf);
|
||||
addHeader(T_Content_Disposition, buf, false);
|
||||
}
|
||||
|
||||
size_t AsyncFileResponse::_fillBuffer(uint8_t* data, size_t len) {
|
||||
|
@@ -41,7 +41,7 @@ static constexpr const char* T_none = "none";
|
||||
static constexpr const char* T_UPGRADE = "Upgrade";
|
||||
static constexpr const char* T_WS = "websocket";
|
||||
static constexpr const char* T_WWW_AUTH = "WWW-Authenticate";
|
||||
static constexpr const char* Transfer_Encoding = "Transfer-Encoding";
|
||||
static constexpr const char* T_Transfer_Encoding = "Transfer-Encoding";
|
||||
|
||||
// HTTP Methods
|
||||
static constexpr const char* T_ANY = "ANY";
|
||||
@@ -210,7 +210,7 @@ static const char T_none[] PROGMEM = "none";
|
||||
static const char T_UPGRADE[] PROGMEM = "Upgrade";
|
||||
static const char T_WS[] PROGMEM = "websocket";
|
||||
static const char T_WWW_AUTH[] PROGMEM = "WWW-Authenticate";
|
||||
static const char Transfer_Encoding[] PROGMEM = "Transfer-Encoding";
|
||||
static const char T_Transfer_Encoding[] PROGMEM = "Transfer-Encoding";
|
||||
|
||||
// HTTP Methods
|
||||
static const char T_ANY[] PROGMEM = "ANY";
|
||||
|
Reference in New Issue
Block a user