| 74 | } |
| 75 | |
| 76 | void onFile(HttpRequest& request, HttpResponse& response) |
| 77 | { |
| 78 | ++requestCount; |
| 79 | |
| 80 | String file = request.uri.getRelativePath(); |
| 81 | String fmt = request.uri.getQueryParameter("format"); |
| 82 | |
| 83 | if(dirExist(file)) { |
| 84 | if(fmt.equalsIgnoreCase("archive")) { |
| 85 | debug_i("Sending streaming archive"); |
| 86 | IFS::FileSystem::NameInfo fsinfo; |
| 87 | fileGetSystemInfo(fsinfo); |
| 88 | ArchiveStream::VolumeInfo volumeInfo; |
| 89 | volumeInfo.name = F("Backup of '") + fsinfo.name + "'"; |
| 90 | if(file.length() != 0) { |
| 91 | volumeInfo.name += F("; root = '") + file + "'"; |
| 92 | } |
| 93 | auto archive = new ArchiveStream(volumeInfo, file, ArchiveStream::Flag::IncludeMountPoints); |
| 94 | response.sendDataStream(archive, archive->getMimeType()); |
| 95 | return; |
| 96 | } |
| 97 | |
| 98 | auto dir = new Directory; |
| 99 | IFS::DirectoryTemplate* tmpl; |
| 100 | if(fmt.equalsIgnoreCase("json")) { |
| 101 | auto source = new FlashMemoryStream(listing_json); |
| 102 | tmpl = new IFS::JsonDirectoryTemplate(source, dir); |
| 103 | } else if(fmt.equalsIgnoreCase("text")) { |
| 104 | auto source = new FlashMemoryStream(listing_txt); |
| 105 | tmpl = new IFS::DirectoryTemplate(source, dir); |
| 106 | } else { |
| 107 | auto source = new FlashMemoryStream(listing_html); |
| 108 | tmpl = new IFS::HtmlDirectoryTemplate(source, dir); |
| 109 | } |
| 110 | tmpl->onGetValue(getValue); |
| 111 | dir->open(file); |
| 112 | tmpl->gotoSection(0); |
| 113 | response.sendDataStream(tmpl, tmpl->getMimeType()); |
| 114 | return; |
| 115 | } |
| 116 | |
| 117 | if(fmt) { |
| 118 | debug_e("'format' option only supported for directories"); |
| 119 | response.code = HTTP_STATUS_BAD_REQUEST; |
| 120 | return; |
| 121 | } |
| 122 | |
| 123 | // response.setCache(86400, true); // It's important to use cache for better performance. |
| 124 | auto stream = new FileStream; |
| 125 | if(!stream->open(file)) { |
| 126 | int err = stream->getLastError(); |
| 127 | response.code = (err == IFS::Error::NotFound) ? HTTP_STATUS_NOT_FOUND : HTTP_STATUS_INTERNAL_SERVER_ERROR; |
| 128 | delete stream; |
| 129 | return; |
| 130 | } |
| 131 | FileStat stat; |
| 132 | stream->stat(stat); |
| 133 | if(stat.compression.type == IFS::Compression::Type::GZip) { |
nothing calls this directly
no test coverage detected