Make response stream to not require content length
Update the example in ReadMe as well
This commit is contained in:
parent
d295256694
commit
f8deeee5bc
53
README.md
53
README.md
|
@ -262,8 +262,50 @@ request->send(response);
|
|||
|
||||
### Print to response
|
||||
```cpp
|
||||
AsyncResponseStream *response = request->beginResponseStream("text/plain", 12);
|
||||
response->print("Hello World!");
|
||||
AsyncResponseStream *response = request->beginResponseStream("text/html");
|
||||
response->printf("<!DOCTYPE html><html><head><title>Webpage at %s</title></head><body>", request->url().c_str());
|
||||
|
||||
response->print("<h2>Hello ");
|
||||
response->print(request->client()->remoteIP());
|
||||
response->print("</h2>");
|
||||
|
||||
response->print("<h3>General</h3>");
|
||||
response->print("<ul>");
|
||||
response->printf("<li>Version: %s</li>", request->version()?"HTTP/1.0":"HTTP/1.1");
|
||||
response->printf("<li>Method: %s</li>", request->methodToString());
|
||||
response->printf("<li>URL: %s</li>", request->url().c_str());
|
||||
response->printf("<li>Host: %s</li>", request->host().c_str());
|
||||
response->printf("<li>ContentType: %s</li>", request->contentType().c_str());
|
||||
response->printf("<li>ContentLength: %u</li>", request->contentLength());
|
||||
response->printf("<li>Multipart: %s</li>", request->multipart()?"true":"false");
|
||||
response->print("</ul>");
|
||||
|
||||
response->print("<h3>Headers</h3>");
|
||||
response->print("<ul>");
|
||||
int headers = request->headers();
|
||||
for(int i=0;i<headers;i++){
|
||||
AsyncWebHeader* h = request->getHeader(i);
|
||||
response->printf("<li>%s: %s</li>", h->name().c_str(), h->value().c_str());
|
||||
}
|
||||
response->print("</ul>");
|
||||
|
||||
response->print("<h3>Parameters</h3>");
|
||||
response->print("<ul>");
|
||||
int params = request->params();
|
||||
for(int i=0;i<params;i++){
|
||||
AsyncWebParameter* p = request->getParam(i);
|
||||
if(p->isFile()){
|
||||
response->printf("<li>FILE[%s]: %s, size: %u</li>", p->name().c_str(), p->value().c_str(), p->size());
|
||||
} else if(p->isPost()){
|
||||
response->printf("<li>POST[%s]: %s</li>", p->name().c_str(), p->value().c_str());
|
||||
} else {
|
||||
response->printf("<li>GET[%s]: %s</li>", p->name().c_str(), p->value().c_str());
|
||||
}
|
||||
}
|
||||
response->print("</ul>");
|
||||
|
||||
response->print("</body></html>");
|
||||
//send the response last
|
||||
request->send(response);
|
||||
```
|
||||
|
||||
|
@ -298,13 +340,6 @@ request->send("text/plain", 0, [](uint8_t *buffer, size_t maxLen) -> size_t {
|
|||
});
|
||||
```
|
||||
|
||||
### Print to response without content length
|
||||
```cpp
|
||||
AsyncResponseStream *response = request->beginResponseStream("text/plain", 0);
|
||||
response->print("Hello World!");
|
||||
request->send(response);
|
||||
```
|
||||
|
||||
|
||||
## Setting up the server
|
||||
```cpp
|
||||
|
|
|
@ -72,7 +72,7 @@ class AsyncResponseStream: public AsyncAbstractResponse, public Print {
|
|||
private:
|
||||
cbuf *_content;
|
||||
public:
|
||||
AsyncResponseStream(String contentType, size_t len, size_t bufferSize);
|
||||
AsyncResponseStream(String contentType, size_t bufferSize);
|
||||
~AsyncResponseStream();
|
||||
bool _sourceValid(){ return (_state < RESPONSE_END); }
|
||||
size_t _fillBuffer(uint8_t *buf, size_t maxLen);
|
||||
|
|
|
@ -153,6 +153,7 @@ class AsyncWebServerRequest {
|
|||
String contentType(){ return _contentType; }
|
||||
size_t contentLength(){ return _contentLength; }
|
||||
bool multipart(){ return _isMultipart; }
|
||||
const char * methodToString();
|
||||
|
||||
bool authenticate(const char * username, const char * password);
|
||||
bool authenticate(const char * hash);
|
||||
|
@ -173,7 +174,7 @@ class AsyncWebServerRequest {
|
|||
AsyncWebServerResponse *beginResponse(Stream &stream, String contentType, size_t len);
|
||||
AsyncWebServerResponse *beginResponse(String contentType, size_t len, AwsResponseFiller callback);
|
||||
AsyncWebServerResponse *beginChunkedResponse(String contentType, AwsResponseFiller callback);
|
||||
AsyncResponseStream *beginResponseStream(String contentType, size_t len, size_t bufferSize=1460);
|
||||
AsyncResponseStream *beginResponseStream(String contentType, size_t bufferSize=1460);
|
||||
|
||||
int headers(); // get header count
|
||||
bool hasHeader(String name);
|
||||
|
@ -243,6 +244,7 @@ class AsyncWebServerResponse {
|
|||
virtual void setContentType(String type);
|
||||
virtual void addHeader(String name, String value);
|
||||
virtual String _assembleHead(uint8_t version);
|
||||
virtual bool _started();
|
||||
virtual bool _finished();
|
||||
virtual bool _failed();
|
||||
virtual void _respond(AsyncWebServerRequest *request);
|
||||
|
|
|
@ -121,6 +121,7 @@ String AsyncWebServerResponse::_assembleHead(uint8_t version){
|
|||
return out;
|
||||
}
|
||||
|
||||
bool AsyncWebServerResponse::_started(){ return _state > RESPONSE_SETUP; }
|
||||
bool AsyncWebServerResponse::_finished(){ return _state > RESPONSE_WAIT_ACK; }
|
||||
bool AsyncWebServerResponse::_failed(){ return _state == RESPONSE_FAILED; }
|
||||
void AsyncWebServerResponse::_respond(AsyncWebServerRequest *request){ _state = RESPONSE_END; request->client()->close(); }
|
||||
|
@ -405,11 +406,9 @@ size_t AsyncChunkedResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||
* Response Stream (You can print/write/printf to it, up to the contentLen bytes)
|
||||
* */
|
||||
|
||||
AsyncResponseStream::AsyncResponseStream(String contentType, size_t len, size_t bufferSize){
|
||||
AsyncResponseStream::AsyncResponseStream(String contentType, size_t bufferSize){
|
||||
_code = 200;
|
||||
_contentLength = len;
|
||||
if(!len)
|
||||
_sendContentLength = false;
|
||||
_contentLength = 0;
|
||||
_contentType = contentType;
|
||||
_content = new cbuf(bufferSize);
|
||||
}
|
||||
|
@ -423,14 +422,16 @@ size_t AsyncResponseStream::_fillBuffer(uint8_t *buf, size_t maxLen){
|
|||
}
|
||||
|
||||
size_t AsyncResponseStream::write(const uint8_t *data, size_t len){
|
||||
if(_finished())
|
||||
if(_started())
|
||||
return 0;
|
||||
|
||||
if(len > _content->room()){
|
||||
size_t needed = len - _content->room();
|
||||
_content->resizeAdd(needed);
|
||||
}
|
||||
return _content->write((const char*)data, len);
|
||||
size_t written = _content->write((const char*)data, len);
|
||||
_contentLength += written;
|
||||
return written;
|
||||
}
|
||||
|
||||
size_t AsyncResponseStream::write(uint8_t data){
|
||||
|
|
|
@ -630,8 +630,8 @@ AsyncWebServerResponse * AsyncWebServerRequest::beginChunkedResponse(String cont
|
|||
return new AsyncCallbackResponse(contentType, 0, callback);
|
||||
}
|
||||
|
||||
AsyncResponseStream * AsyncWebServerRequest::beginResponseStream(String contentType, size_t len, size_t bufferSize){
|
||||
return new AsyncResponseStream(contentType, len, bufferSize);
|
||||
AsyncResponseStream * AsyncWebServerRequest::beginResponseStream(String contentType, size_t bufferSize){
|
||||
return new AsyncResponseStream(contentType, bufferSize);
|
||||
}
|
||||
|
||||
void AsyncWebServerRequest::send(int code, String contentType, String content){
|
||||
|
@ -770,3 +770,15 @@ String AsyncWebServerRequest::urlDecode(const String& text){
|
|||
return decoded;
|
||||
}
|
||||
|
||||
|
||||
const char * AsyncWebServerRequest::methodToString(){
|
||||
if(_method == HTTP_ANY) return "ANY";
|
||||
else if(_method == HTTP_GET) return "GET";
|
||||
else if(_method == HTTP_POST) return "POST";
|
||||
else if(_method == HTTP_DELETE) return "DELETE";
|
||||
else if(_method == HTTP_PUT) return "PUT";
|
||||
else if(_method == HTTP_PATCH) return "PATCH";
|
||||
else if(_method == HTTP_HEAD) return "HEAD";
|
||||
else if(_method == HTTP_OPTIONS) return "OPTIONS";
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue