From 321ad64a27517083859433f3b1f06116f1cded2a Mon Sep 17 00:00:00 2001 From: Scott Alfter Date: Tue, 30 Mar 2021 22:52:47 -0700 Subject: [PATCH] range transfers for GET and PUT work...they seem more reliable on iffy power now, too --- ESPWebDAV.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++--------- WebSrv.cpp | 16 ++++++------- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/ESPWebDAV.cpp b/ESPWebDAV.cpp index 1eb2916..ba81e85 100644 --- a/ESPWebDAV.cpp +++ b/ESPWebDAV.cpp @@ -110,6 +110,11 @@ void ESPWebDAV::handleRequest(String blank) { // add header that gets sent everytime sendHeader("DAV", "1, 2"); + // these headers are for webdavfs (https://github.com/miquels/webdavfs) + // pretend to be enough like Apache that we get read/write support + sendHeader("Server", "ESPWebDAV (use Apache put range)"); + sendHeader("DAV", ""); + // handle properties if(method.equals("PROPFIND")) return handleProp(resource); @@ -349,24 +354,56 @@ void ESPWebDAV::handleGet(ResourceType resource, bool isGet) { rFile.open(uri.c_str(), O_READ); sendHeader("Allow", "PROPFIND,OPTIONS,DELETE,COPY,MOVE,HEAD,POST,PUT,GET"); - size_t fileSize = rFile.fileSize(); - setContentLength(fileSize); + size_t fileSize; + if (_contentRangeStart==CONTENT_RANGE_NOT_SET && _contentRangeEnd==CONTENT_RANGE_NOT_SET) + { + fileSize=rFile.fileSize(); + } + else + { + fileSize=_contentRangeEnd-_contentRangeStart+1; + sendHeader("Accept-Ranges", "bytes"); + sendHeader("Content-Range", "bytes "+String(_contentRangeStart)+"-"+String(_contentRangeEnd)+"/"+String(rFile.fileSize())); + } + setContentLength(fileSize); + String contentType = getMimeType(uri); if(uri.endsWith(".gz") && contentType != "application/x-gzip" && contentType != "application/octet-stream") sendHeader("Content-Encoding", "gzip"); - send("200 OK", contentType.c_str(), ""); + if (!isGet) + send("200 OK", contentType.c_str(), ""); + + if(isGet) + { - if(isGet) { // disable Nagle if buffer size > TCP MTU of 1460 // client.setNoDelay(1); - // send the file - while(rFile.available()) { - // SD read speed ~ 17sec for 4.5MB file - int numRead = rFile.read(buf, sizeof(buf)); - client.write(buf, numRead); - } + if (_contentRangeStart==CONTENT_RANGE_NOT_SET && _contentRangeEnd==CONTENT_RANGE_NOT_SET) + { + send("200 OK", contentType.c_str(), ""); + // send the whole file + while(rFile.available()) + { + // SD read speed ~ 17sec for 4.5MB file + int numRead = rFile.read(buf, sizeof(buf)); + client.write(buf, numRead); + } + } + else + { + send("206 Partial Content", contentType.c_str(), ""); + // send the selected range + rFile.seekSet(_contentRangeStart); + size_t remaining=fileSize; + while (remaining>0) + { + int numRead=rFile.read(buf, (sizeof(buf)0) diff --git a/WebSrv.cpp b/WebSrv.cpp index 42c72e1..578048c 100644 --- a/WebSrv.cpp +++ b/WebSrv.cpp @@ -192,7 +192,7 @@ bool ESPWebDAV::parseRequest() { contentLengthHeader = headerValue; else if(headerName.equalsIgnoreCase("Destination")) destinationHeader = headerValue; - else if (headerName.equalsIgnoreCase("Content-Range")) + else if (headerName.equalsIgnoreCase("Content-Range") || headerName.equalsIgnoreCase("Range")) { contentRangeHeader = headerValue; _contentRangeStart = _contentRangeEnd = 0; @@ -201,15 +201,15 @@ bool ESPWebDAV::parseRequest() { { if (headerValue.c_str()[i]=='-') { - bDashReached=true; - break; + bDashReached=true; + continue; } if (headerValue.c_str()[i]>='0' && headerValue.c_str()[i]<='9') { - if (!bDashReached) - _contentRangeStart=_contentRangeStart*10+(headerValue[i]-'0'); - else - _contentRangeEnd=_contentRangeEnd*10+(headerValue[i]-'0'); + if (!bDashReached) + _contentRangeStart=_contentRangeStart*10+(headerValue[i]-'0'); + else + _contentRangeEnd=_contentRangeEnd*10+(headerValue[i]-'0'); } } } @@ -261,7 +261,7 @@ void ESPWebDAV::_prepareHeader(String& response, String code, const char* conten sendHeader("Content-Length", String(_contentLength)); else if(_contentLength == CONTENT_LENGTH_UNKNOWN) { _chunked = true; - sendHeader("Accept-Ranges","none"); + sendHeader("Accept-Ranges","bytes"); sendHeader("Transfer-Encoding","chunked"); } sendHeader("Connection", "close");