diff --git a/ESPWebDAV.cpp b/ESPWebDAV.cpp index 39de6a6..2e87b74 100644 --- a/ESPWebDAV.cpp +++ b/ESPWebDAV.cpp @@ -27,6 +27,8 @@ */ +#include "strutils.h" + #include #if defined(ARDUINO_ARCH_ESP8266) || defined(CORE_MOCK) #include @@ -76,10 +78,6 @@ const char * FileName(const char * path) #include #include -// define cal constants -const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; -const char *wdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - #define ALLOW "PROPPATCH,PROPFIND,OPTIONS,DELETE" SCUNLOCK ",COPY" SCLOCK ",MOVE,HEAD,POST,PUT,GET" #if WEBDAV_LOCK_SUPPORT @@ -129,16 +127,6 @@ static const __FlashStringHelper* streamError (Stream::Report r) #define BUF_FREE() do { (void)0; } while (0) #endif -void ESPWebDAVCore::stripSlashes(String& name) -{ - size_t i = 0; - while (i < name.length()) - if (name[i] == '/' && name.length() > 1 && ((i == name.length() - 1) || name[i + 1] == '/')) - name.remove(i, 1); - else - i++; -} - #if WEBDAV_LOCK_SUPPORT @@ -825,17 +813,6 @@ void ESPWebDAVCore::sendContentProp(const String& what, const String& response) } -String ESPWebDAVCore::date2date(time_t date) -{ - // get & convert time to required format - // Tue, 13 Oct 2015 17:07:35 GMT - tm* gTm = gmtime(&date); - char buf[40]; - snprintf(buf, sizeof(buf), "%s, %02d %s %04d %02d:%02d:%02d GMT", wdays[gTm->tm_wday], gTm->tm_mday, months[gTm->tm_mon], gTm->tm_year + 1900, gTm->tm_hour, gTm->tm_min, gTm->tm_sec); - return buf; -} - - void ESPWebDAVCore::sendPropResponse(bool isDir, const String& fullResPathFS, size_t size, time_t lastWrite, time_t creationDate) { String fullResPath = fullResPathFS; @@ -1197,33 +1174,6 @@ void ESPWebDAVCore::handleDirectoryCreate(ResourceType resource) } -String ESPWebDAVCore::urlToUri(const String& url) -{ - int index; - if (url.startsWith("http") && (index = url.indexOf("://")) <= 5) - { - int uriStart = url.indexOf('/', index + 3); - return url.substring(uriStart); - } - return url; -} - -void ESPWebDAVCore::replaceFront (String& str, const String& from, const String& to) -{ - if (from.length() && to.length() && str.indexOf(from) == 0) - { - DBG_PRINT("replaceFront(%s, %s): %s -> ", from.c_str(), to.c_str(), str.c_str()); - String repl; - repl.reserve(str.length() + to.length() - from.length() + 1); - repl = to; - size_t skip = from.length() == 1? 0: from.length(); - repl += str.c_str() + skip; - str = repl; - stripSlashes(str); - DBG_PRINT("%s", str.c_str()); - } -} - void ESPWebDAVCore::handleMove(ResourceType resource, File& src) { const char* successCode = "201 Created"; @@ -1835,71 +1785,3 @@ void ESPWebDAVCore::processRange(const String& range) } -int ESPWebDAVCore::htoi(char c) -{ - c = tolower(c); - return c >= '0' && c <= '9' ? c - '0' : - c >= 'a' && c <= 'f' ? c - 'a' + 10 : - -1; -} - - -char ESPWebDAVCore::itoH(int c) -{ - return c <= 9 ? c + '0' : c - 10 + 'A'; -} - - -int ESPWebDAVCore::hhtoi(const char* c) -{ - int h = htoi(*c); - int l = htoi(*(c + 1)); - return h < 0 || l < 0 ? -1 : (h << 4) + l; -} - - -String ESPWebDAVCore::enc2c(const String& encoded) -{ - String ret = encoded; - for (size_t i = 0; ret.length() >= 2 && i < ret.length() - 2; i++) - if (ret[i] == '%') - { - int v = hhtoi(ret.c_str() + i + 1); - if (v > 0) - { - ret[i] = v < 128 ? (char)v : '='; - ret.remove(i + 1, 2); - } - } - return ret; -} - - -static inline bool notEncodable (char c) -{ - return c > 32 && c < 127; -} - -String ESPWebDAVCore::c2enc(const String& decoded) -{ - size_t l = decoded.length(); - for (size_t i = 0; i < decoded.length(); i++) - if (!notEncodable(decoded[i])) - l += 2; - - String ret; - ret.reserve(l); - for (size_t i = 0; i < decoded.length(); i++) - { - char c = decoded[i]; - if (notEncodable(c)) - ret += c; - else - { - ret += '%'; - ret += itoH(c >> 4); - ret += itoH(c & 0xf); - } - } - return ret; -} diff --git a/ESPWebDAV.h b/ESPWebDAV.h index e0923a9..37532d8 100644 --- a/ESPWebDAV.h +++ b/ESPWebDAV.h @@ -48,8 +48,7 @@ #define DBG_WEBDAV 1 #endif -#if !defined(DBG_WEBDAV) && defined(DEBUG_ESP_PORT) && !defined(NDEBUG) -#define DBG_WEBDAV 1 +#if defined(DEBUG_ESP_PORT) #define DBG_WEBDAV_PORT DEBUG_ESP_PORT #endif @@ -137,12 +136,6 @@ class ESPWebDAVCore void setDAVRoot (const String& davRoot) { _davRoot = davRoot; } void setFsRoot (const String& fsRoot) { _fsRoot = fsRoot; } - static void stripSlashes(String& name); - static String date2date(time_t date); - static String enc2c(const String& encoded); - static String c2enc(const String& decoded); - static void replaceFront (String& str, const String& from, const String& to); - protected: static int htoi(char c); @@ -194,7 +187,6 @@ class ESPWebDAVCore bool getPayload(StreamString& payload); void stripName(String& name); void stripHost(String& name); - String urlToUri(const String& url); enum virt_e { VIRT_NONE, VIRT_PROC }; virt_e isVirtual(const String& uri); diff --git a/strutils.cpp b/strutils.cpp new file mode 100644 index 0000000..5e6ee80 --- /dev/null +++ b/strutils.cpp @@ -0,0 +1,179 @@ + +#include "strutils.h" + +#include + +// define cal constants +const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +const char *wdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + +int htoi(char c) +{ + c = tolower(c); + return c >= '0' && c <= '9' ? c - '0' : + c >= 'a' && c <= 'f' ? c - 'a' + 10 : + -1; +} + + +char itoH(int c) +{ + return c <= 9 ? c + '0' : c - 10 + 'A'; +} + + +int hhtoi(const char* c) +{ + int h = htoi(*c); + int l = htoi(*(c + 1)); + return h < 0 || l < 0 ? -1 : (h << 4) + l; +} + + +bool notEncodable (char c) +{ + return c > 32 && c < 127; +} + + +void stripSlashes(String& name) +{ + size_t i = 0; + while (i < name.length()) + if (name[i] == '/' && name.length() > 1 && ((i == name.length() - 1) || name[i + 1] == '/')) + name.remove(i, 1); + else + i++; +} + + +#if STREAMSEND_API + +String date2date(time_t date) +{ + // get & convert time to required format + // Tue, 13 Oct 2015 17:07:35 GMT + tm* gTm = gmtime(&date); + String ret; + ret.reserve(40); + S2Stream(ret).printf("%s, %02d %s %04d %02d:%02d:%02d GMT", + wdays[gTm->tm_wday], + gTm->tm_mday, + months[gTm->tm_mon], + gTm->tm_year + 1900, + gTm->tm_hour, + gTm->tm_min, + gTm->tm_sec); + return ret; +} + +#else // !STREAMSEND_API + +String date2date(time_t date) +{ + // get & convert time to required format + // Tue, 13 Oct 2015 17:07:35 GMT + tm* gTm = gmtime(&date); + char buf[40]; + snprintf(buf, sizeof(buf), "%s, %02d %s %04d %02d:%02d:%02d GMT", + wdays[gTm->tm_wday], + gTm->tm_mday, + months[gTm->tm_mon], + gTm->tm_year + 1900, + gTm->tm_hour, + gTm->tm_min, + gTm->tm_sec); + return buf; +} + +#endif // !STREAMSEND_API + + +String OLDenc2c(const String& encoded) +{ + String ret = encoded; + for (size_t i = 0; ret.length() >= 2 && i < ret.length() - 2; i++) + if (ret[i] == '%') + { + int v = hhtoi(ret.c_str() + i + 1); + if (v > 0) + { + ret[i] = v < 128 ? (char)v : '='; + ret.remove(i + 1, 2); + } + } + return ret; +} + + +String enc2c(const String& encoded) +{ + int v; + String ret; + ret.reserve(encoded.length()); + for (size_t i = 0; i < encoded.length(); i++) + { + if ( encoded[i] == '%' + && (i + 3) <= encoded.length() + && (v = hhtoi(encoded.c_str() + i + 1)) > 0) + { + ret += v; + i += 2; + } + else + ret += encoded[i]; + } + return ret; +} + + +String c2enc(const String& decoded) +{ + size_t l = decoded.length(); + for (size_t i = 0; i < decoded.length(); i++) + if (!notEncodable(decoded[i])) + l += 2; + + String ret; + ret.reserve(l); + for (size_t i = 0; i < decoded.length(); i++) + { + char c = decoded[i]; + if (notEncodable(c)) + ret += c; + else + { + ret += '%'; + ret += itoH(c >> 4); + ret += itoH(c & 0xf); + } + } + return ret; +} + + +void replaceFront (String& str, const String& from, const String& to) +{ + if (from.length() && to.length() && str.indexOf(from) == 0) + { + String repl; + repl.reserve(str.length() + to.length() - from.length() + 1); + repl = to; + size_t skip = from.length() == 1? 0: from.length(); + repl += str.c_str() + skip; + str = repl; + stripSlashes(str); + } +} + +String urlToUri(const String& url) +{ + int index; + if (url.startsWith("http") && (index = url.indexOf("://")) <= 5) + { + int uriStart = url.indexOf('/', index + 3); + return url.substring(uriStart); + } + return url; +} + diff --git a/strutils.h b/strutils.h new file mode 100644 index 0000000..8990e08 --- /dev/null +++ b/strutils.h @@ -0,0 +1,11 @@ + +#pragma once + +#include + +void stripSlashes(String& name); +String date2date(time_t date); +String enc2c(const String& encoded); +String c2enc(const String& decoded); +void replaceFront (String& str, const String& from, const String& to); +String urlToUri(const String& url);