| 856 | } |
| 857 | |
| 858 | void HttpResponder::SendFile(const char *_ecv_array nameOfFileToSend, bool isWebFile) noexcept |
| 859 | { |
| 860 | #if HAS_MASS_STORAGE |
| 861 | FileStore *_ecv_null fileToSend = nullptr; |
| 862 | bool zip = false; |
| 863 | Platform& platform = GetPlatform(); |
| 864 | |
| 865 | if (isWebFile) |
| 866 | { |
| 867 | if (nameOfFileToSend[0] == '/') |
| 868 | { |
| 869 | ++nameOfFileToSend; // all web files are relative to the /www folder, so remove the leading '/' |
| 870 | } |
| 871 | |
| 872 | // If we are asked to return the root, return the index file |
| 873 | if (nameOfFileToSend[0] == 0) |
| 874 | { |
| 875 | nameOfFileToSend = INDEX_PAGE_FILE; |
| 876 | } |
| 877 | |
| 878 | auto webDir = platform.GetWebDir(); |
| 879 | |
| 880 | // Check that the length of the filename requested is short enough for CombineName not to generate an error message before we try to open it. |
| 881 | // We used to report a possible virus attack in this case, but that sometimes leads to false warnings because of OCSP requests from AV programs, |
| 882 | // or file download requests after IP address changes |
| 883 | if (strlen(nameOfFileToSend) <= MaxExpectedWebDirFilenameLength) |
| 884 | { |
| 885 | for (;;) |
| 886 | { |
| 887 | // Try to open a gzipped version of the file first |
| 888 | if (!StringEndsWithIgnoreCase(nameOfFileToSend, ".gz")) |
| 889 | { |
| 890 | static_assert(MaxExpectedWebDirFilenameLength + 3 <= MaxFilenameLength); // this ensures that we can append '.gz' to the filename without overflow |
| 891 | String<MaxFilenameLength> nameBuf; |
| 892 | nameBuf.copy(nameOfFileToSend); |
| 893 | nameBuf.cat(".gz"); |
| 894 | fileToSend = platform.OpenFile(webDir.Ptr(), nameBuf.c_str(), OpenMode::read); |
| 895 | if (fileToSend != nullptr) |
| 896 | { |
| 897 | zip = true; |
| 898 | break; |
| 899 | } |
| 900 | } |
| 901 | |
| 902 | // That failed, so try to open the normal version of the file |
| 903 | fileToSend = platform.OpenFile(webDir.Ptr(), nameOfFileToSend, OpenMode::read); |
| 904 | if (fileToSend != nullptr) |
| 905 | { |
| 906 | break; |
| 907 | } |
| 908 | |
| 909 | if (StringEqualsIgnoreCase(nameOfFileToSend, INDEX_PAGE_FILE)) |
| 910 | { |
| 911 | nameOfFileToSend = OLD_INDEX_PAGE_FILE; // the index file wasn't found, so try the old one |
| 912 | } |
| 913 | else if (strchr(nameOfFileToSend, '.') == nullptr) // if we were asked to return a file without a '.' in the name, return the index page |
| 914 | { |
| 915 | nameOfFileToSend = INDEX_PAGE_FILE; |