range transfers for GET and PUT work...they seem more reliable on iffy power now, too

This commit is contained in:
2021-03-30 22:52:47 -07:00
parent 2f8e620af7
commit 321ad64a27
2 changed files with 60 additions and 19 deletions

View File

@@ -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", "<http://apache.org/dav/propset/fs/1>");
// 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)<remaining)?sizeof(buf):remaining);
client.write(buf, numRead);
remaining-=numRead;
}
}
}
rFile.close();
@@ -458,6 +495,10 @@ void ESPWebDAV::handlePut(ResourceType resource) {
}
else
{
// reopen file so we can seek within it
nFile.close();
nFile.open(uri.c_str(), O_RDWR);
// set up buffer
const size_t WRITE_BLOCK_CONST = 512;
uint8_t buf[WRITE_BLOCK_CONST];
@@ -465,7 +506,7 @@ void ESPWebDAV::handlePut(ResourceType resource) {
size_t numRemaining = contentLen;
// seek to beginning of range
nFile.seekSet(_contentRangeStart);
nFile.seekSet(_contentRangeStart);
// update file
while (numRemaining>0)

View File

@@ -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");