mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
Merge branch 'WifiSendP' of https://github.com/Makuna/Arduino into Makuna-WifiSendP
Conflicts: README.md
This commit is contained in:
commit
c0e0836a0b
@ -35,8 +35,8 @@ class StringSumHelper;
|
||||
// an abstract class used as a means to proide a unique pointer type
|
||||
// but really has no body
|
||||
class __FlashStringHelper;
|
||||
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
|
||||
|
||||
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
|
||||
#define F(string_literal) (FPSTR(PSTR(string_literal)))
|
||||
|
||||
// The string class
|
||||
class String {
|
||||
|
@ -78,6 +78,32 @@ Both `Serial` and `Serial1` objects support 5, 6, 7, 8 data bits, odd (O), even
|
||||
The Program memory features work much the same way as on a regular Arduino; placing read only data and strings in read only memory and freeing heap for your application.
|
||||
The important difference is that on the ESP8266 the literal strings are not pooled. This means that the same literal string defined inside a `F("")` and/or `PSTR("")` will take up space for each instance in the code. So you will need to manage the duplicate strings yourself.
|
||||
|
||||
There is one additional helper macro to make it easier to pass ```const PROGMEM``` strings to methods that take a ```__FlashStringHelper``` called ```FPSTR()```. The use of this will help make it easier to pool strings.
|
||||
Not pooling strings...
|
||||
|
||||
```С++
|
||||
String response1;
|
||||
response1 += F("http:");
|
||||
...
|
||||
String response2;
|
||||
response2 += F("http:");
|
||||
```
|
||||
|
||||
using FPSTR would become...
|
||||
|
||||
```С++
|
||||
const char HTTP[] PROGMEM = "http:";
|
||||
...
|
||||
{
|
||||
String response1;
|
||||
response1 += FPSTR(HTTP);
|
||||
...
|
||||
String response2;
|
||||
response2 += FPSTR(HTTP);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## WiFi(ESP8266WiFi library)
|
||||
|
||||
This is mostly similar to WiFi shield library. Differences include:
|
||||
|
@ -129,30 +129,51 @@ void ESP8266WebServer::sendHeader(const String& name, const String& value, bool
|
||||
}
|
||||
}
|
||||
|
||||
void ESP8266WebServer::send(int code, const char* content_type, const String& content) {
|
||||
String response = "HTTP/1.1 ";
|
||||
response += String(code);
|
||||
response += " ";
|
||||
response += _responseCodeToString(code);
|
||||
response += "\r\n";
|
||||
|
||||
if (!content_type)
|
||||
content_type = "text/html";
|
||||
|
||||
sendHeader("Content-Type", content_type, true);
|
||||
if (_contentLength != CONTENT_LENGTH_UNKNOWN && _contentLength != CONTENT_LENGTH_NOT_SET) {
|
||||
sendHeader("Content-Length", String(_contentLength).c_str());
|
||||
} else if(content.length() > 0){
|
||||
sendHeader("Content-Length", String(content.length()).c_str());
|
||||
}
|
||||
sendHeader("Connection", "close");
|
||||
sendHeader("Access-Control-Allow-Origin", "*");
|
||||
|
||||
response += _responseHeaders;
|
||||
response += "\r\n";
|
||||
response += content;
|
||||
_responseHeaders = String();
|
||||
sendContent(response);
|
||||
void ESP8266WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
|
||||
response = "HTTP/1.1 ";
|
||||
response += String(code);
|
||||
response += " ";
|
||||
response += _responseCodeToString(code);
|
||||
response += "\r\n";
|
||||
|
||||
if (!content_type)
|
||||
content_type = "text/html";
|
||||
|
||||
sendHeader("Content-Type", content_type, true);
|
||||
if (_contentLength != CONTENT_LENGTH_UNKNOWN && _contentLength != CONTENT_LENGTH_NOT_SET) {
|
||||
sendHeader("Content-Length", String(_contentLength).c_str());
|
||||
}
|
||||
else if (contentLength > 0){
|
||||
sendHeader("Content-Length", String(contentLength).c_str());
|
||||
}
|
||||
sendHeader("Connection", "close");
|
||||
sendHeader("Access-Control-Allow-Origin", "*");
|
||||
|
||||
response += _responseHeaders;
|
||||
response += "\r\n";
|
||||
_responseHeaders = String();
|
||||
}
|
||||
|
||||
void ESP8266WebServer::send(int code, const char* content_type, const String& content) {
|
||||
String header;
|
||||
_prepareHeader(header, code, content_type, content.length());
|
||||
sendContent(header);
|
||||
|
||||
sendContent(content);
|
||||
}
|
||||
|
||||
void ESP8266WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
|
||||
size_t contentLength = 0;
|
||||
|
||||
if (content != NULL) {
|
||||
contentLength = strlen_P(content);
|
||||
}
|
||||
|
||||
String header;
|
||||
_prepareHeader(header, code, String(FPSTR(content_type)).c_str(), contentLength);
|
||||
sendContent(header);
|
||||
sendContent_P(content);
|
||||
}
|
||||
|
||||
void ESP8266WebServer::send(int code, char* content_type, const String& content) {
|
||||
@ -178,6 +199,34 @@ void ESP8266WebServer::sendContent(const String& content) {
|
||||
}
|
||||
}
|
||||
|
||||
void ESP8266WebServer::sendContent_P(PGM_P content) {
|
||||
char contentUnit[HTTP_DOWNLOAD_UNIT_SIZE + 1];
|
||||
|
||||
contentUnit[HTTP_DOWNLOAD_UNIT_SIZE] = '\0';
|
||||
|
||||
while (content != NULL) {
|
||||
size_t contentUnitLen;
|
||||
PGM_P contentNext;
|
||||
|
||||
// due to the memccpy signature, lots of casts are needed
|
||||
contentNext = (PGM_P)memccpy_P((void*)contentUnit, (PGM_VOID_P)content, 0, HTTP_DOWNLOAD_UNIT_SIZE);
|
||||
|
||||
if (contentNext == NULL) {
|
||||
// no terminator, more data available
|
||||
content += HTTP_DOWNLOAD_UNIT_SIZE;
|
||||
contentUnitLen = HTTP_DOWNLOAD_UNIT_SIZE;
|
||||
}
|
||||
else {
|
||||
// reached terminator
|
||||
contentUnitLen = contentNext - content;
|
||||
content = NULL;
|
||||
}
|
||||
|
||||
// write is so overloaded, had to use the cast to get it pick the right one
|
||||
_currentClient.write((const char*)contentUnit, contentUnitLen);
|
||||
}
|
||||
}
|
||||
|
||||
String ESP8266WebServer::arg(const char* name) {
|
||||
for (int i = 0; i < _currentArgCount; ++i) {
|
||||
if (_currentArgs[i].key == name)
|
||||
|
@ -80,10 +80,12 @@ public:
|
||||
void send(int code, const char* content_type = NULL, const String& content = String(""));
|
||||
void send(int code, char* content_type, const String& content);
|
||||
void send(int code, const String& content_type, const String& content);
|
||||
void send_P(int code, PGM_P content_type, PGM_P content);
|
||||
|
||||
void setContentLength(size_t contentLength) { _contentLength = contentLength; }
|
||||
void sendHeader(const String& name, const String& value, bool first = false);
|
||||
void sendContent(const String& content);
|
||||
void sendContent_P(PGM_P content);
|
||||
|
||||
template<typename T> size_t streamFile(T &file, const String& contentType){
|
||||
setContentLength(file.size());
|
||||
@ -104,7 +106,8 @@ protected:
|
||||
void _parseForm(WiFiClient& client, String boundary, uint32_t len);
|
||||
void _uploadWriteByte(uint8_t b);
|
||||
uint8_t _uploadReadByte(WiFiClient& client);
|
||||
|
||||
void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
|
||||
|
||||
struct RequestHandler;
|
||||
struct RequestArgument {
|
||||
String key;
|
||||
|
Loading…
x
Reference in New Issue
Block a user