Downloads: set the last modifier date/time of the files to the current UTC time, no need to expose the actual date/time

This commit is contained in:
emeric
2020-09-01 13:47:03 +02:00
parent b3f14153d2
commit 52d5c3fee3
3 changed files with 38 additions and 16 deletions
+32 -13
View File
@@ -22,6 +22,9 @@
#include <cstddef>
#include <fstream>
#include <Wt/WDate.h>
#include <Wt/WTime.h>
#include "utils/Path.hpp"
// Done using specs from https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
@@ -56,6 +59,7 @@ namespace Zip
void write8(std::size_t offset, std::uint8_t value);
void write16(std::size_t offset, std::uint16_t value);
void write32(std::size_t offset, std::uint32_t value);
void writeDateTime(std::size_t offset, const Wt::WDateTime& time);
private:
std::byte* _buffer {};
@@ -84,6 +88,24 @@ namespace Zip
_buffer[offset + 3] = static_cast<std::byte>(value >> 24);
}
void
ZipHeader::writeDateTime(std::size_t offset, const Wt::WDateTime& dateTime)
{
std::uint32_t encodedDateTime{};
// Date
encodedDateTime |= ((dateTime.date().year() - 1980) << 25);
encodedDateTime |= (dateTime.date().month() << 21);
encodedDateTime |= (dateTime.date().day() << 16);
// Time
encodedDateTime |= (dateTime.time().hour() << 11);
encodedDateTime |= (dateTime.time().minute() << 5);
encodedDateTime |= (dateTime.time().second() << 1);
write32(offset, encodedDateTime);
}
class LocalFileHeader : public ZipHeader
{
public:
@@ -94,11 +116,7 @@ namespace Zip
void setVersionNeededToExtract(unsigned major, unsigned minor) { assert(minor < 10); write16(4, major*10 + minor); }
void setGeneralPurposeFlags(std::uint16_t flags) { write16(6, flags); }
void setCompressionMethod(CompressionMethod compressionMethod) { write16(8, compressionMethod); }
void setLastModifiedDateTime()
{ // TODO
write16(10, 0); // time
write16(12, 0); // date
}
void setLastModifiedDateTime(const Wt::WDateTime& dateTime) { writeDateTime(10, dateTime); }
void setCrc32UncompressedData(std::uint32_t crc) { write32(14, crc); }
void setCompressedSize(std::size_t size) { write32(18, size); }
void setUncompressedSize(std::size_t size) { write32(22, size); }
@@ -129,11 +147,7 @@ namespace Zip
void setVersionNeededToExtract(unsigned major, unsigned minor) { assert(minor < 10); write16(6, major*10 + minor); }
void setGeneralPurposeFlags(std::uint16_t flags) { write16(8, flags); }
void setCompressionMethod(CompressionMethod method) { write16(10, method); }
void setLastModifiedDateTime()
{
write16(12, 0); // time
write16(14, 0); // date
}
void setLastModifiedDateTime(const Wt::WDateTime& dateTime) { writeDateTime(12, dateTime); }
void setCrc32UncompressedData(std::uint32_t crc32) { write32(16, crc32); }
void setCompressedSize(std::size_t size) { write32(20, size); }
void setUncompressedSize(std::size_t size) { write32(24, size); }
@@ -163,7 +177,7 @@ namespace Zip
static constexpr std::size_t getHeaderSize() { return 22; }
};
Zipper::Zipper(const std::map<std::string, std::filesystem::path>& files)
Zipper::Zipper(const std::map<std::string, std::filesystem::path>& files, const Wt::WDateTime& lastModifiedTime)
{
for (const auto& [filename, filePath] : files)
{
@@ -175,6 +189,11 @@ namespace Zip
if (ec)
throw ZipperException {"Cannot get file size for '" + filePath.string() + "': " + ec.message()};
if (lastModifiedTime.isValid())
fileContext.lastModifiedTime = lastModifiedTime;
else
fileContext.lastModifiedTime = getLastWriteTime(filePath);
_files[filename] = std::move(fileContext);
_totalZipSize += LocalFileHeader::getHeaderSize();
@@ -279,7 +298,7 @@ namespace Zip
header.setCrc32UncompressedData(ZipHeader::UnknownCrc32);
header.setCompressedSize(ZipHeader::UnknownFileSize);
header.setUncompressedSize(ZipHeader::UnknownFileSize);
header.setLastModifiedDateTime(); // getLastWriteTime(*_currentFile));
header.setLastModifiedDateTime(_currentFile->second.lastModifiedTime);
header.setFileNameLength(_currentFile->first.size());
header.setExtraFieldLength(0);
@@ -393,7 +412,7 @@ namespace Zip
header.setCompressionMethod(ZipHeader::CompressionMethod::NoCompression);
header.setCompressedSize(_currentFile->second.fileSize);
header.setUncompressedSize(_currentFile->second.fileSize);
header.setLastModifiedDateTime(); // getLastWriteTime(*_currentFile));
header.setLastModifiedDateTime(_currentFile->second.lastModifiedTime);
header.setCrc32UncompressedData(_currentFile->second.fileCrc32.getResult());
header.setFileNameLength(_currentFile->first.size());
header.setExtraFieldLength(0);
+4 -1
View File
@@ -23,6 +23,8 @@
#include <set>
#include <filesystem>
#include <Wt/WDateTime.h>
#include "Exception.hpp"
#include "utils/Crc32Calculator.hpp"
@@ -41,7 +43,7 @@ namespace Zip
using SizeZype = std::uint64_t;
Zipper(const std::map<std::string, std::filesystem::path>& files);
Zipper(const std::map<std::string, std::filesystem::path>& files, const Wt::WDateTime& lastModifiedTime = {});
static constexpr std::size_t minOutputBufferSize = 64;
std::size_t writeSome(std::byte* buffer, std::size_t bufferSize);
@@ -64,6 +66,7 @@ namespace Zip
{
std::filesystem::path filePath;
std::size_t fileSize;
Wt::WDateTime lastModifiedTime;
Utils::Crc32Calculator fileCrc32;
std::size_t localFileHeaderOffset {};
};
+2 -2
View File
@@ -22,8 +22,8 @@
#include <iostream>
#include <iomanip>
#include <Wt/WApplication.h>
#include <Wt/Http/Response.h>
#include <Wt/WLocalDateTime.h>
#include "database/Artist.hpp"
#include "database/Release.hpp"
@@ -165,7 +165,7 @@ createZipper(const std::vector<Database::Track::pointer>& tracks)
files.emplace(fileName, track->getPath());
}
return std::make_unique<Zip::Zipper>(files);
return std::make_unique<Zip::Zipper>(files, Wt::WLocalDateTime::currentDateTime().toUTC());
}
DownloadReleaseResource::DownloadReleaseResource(Database::IdType releaseId)