Logo Pico-Framework A web-first embedded framework for C++
Loading...
Searching...
No Matches
FileHandler Class Reference

Helper class for accessing the file system and serving file content. More...

#include <HttpFileserver.h>

+ Collaboration diagram for FileHandler:

Public Member Functions

 FileHandler ()
 Construct a new FileHandler object.
 
bool init ()
 Initialize and mount the storage (e.g., SD card).
 
bool listDirectory (const std::string &path, std::vector< FileInfo > &out)
 Return a list of a given directory.
 
bool serveFile (HttpResponse &res, const char *uri)
 Serve a file to the client via the HttpResponse object.
 

Public Attributes

bool mounted = false
 Flag indicating whether storage is mounted.
 

Private Attributes

StorageManagerstorageManager
 

Detailed Description

Definition at line 27 of file HttpFileserver.h.

Constructor & Destructor Documentation

◆ FileHandler()

FileHandler::FileHandler ( )

Construct a new FileHandler object.

Definition at line 48 of file HttpFileserver.cpp.

49{
50}

Member Function Documentation

◆ init()

bool FileHandler::init ( )

Initialize and mount the storage (e.g., SD card).

Returns
true if mounted successfully.
Returns
true if mounted successfully.

Definition at line 53 of file HttpFileserver.cpp.

54{
56 if (storage->mount())
57 {
58 TRACE("Storage mounted successfully\n");
59 return true;
60 }
61 else
62 {
63 printf("Storage mount failed\n");
64 return false;
65 }
66}
#define TRACE(...)
Default trace (INFO level).
Definition DebugTrace.h:187
static constexpr std::uintptr_t getTypeKey()
Definition AppContext.h:91
Abstract base class for storage access and file operations.
virtual bool mount()=0
Mount the underlying storage.

References AppContext::getTypeKey(), StorageManager::mount(), and TRACE.

+ Here is the call graph for this function:

◆ listDirectory()

bool FileHandler::listDirectory ( const std::string &  path,
std::vector< FileInfo > &  out 
)

Return a list of a given directory.

Parameters
pathDirectory path to list.
Parameters
pathDirectory path to list.

Definition at line 69 of file HttpFileserver.cpp.

70{
71 auto *storage = AppContext::get<StorageManager>();
72 return storage->listDirectory(path, out);
73}

References AppContext::getTypeKey().

Referenced by HttpFileserver::handle_list_directory().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ serveFile()

bool FileHandler::serveFile ( HttpResponse res,
const char *  uri 
)

Serve a file to the client via the HttpResponse object.

Parameters
resHTTP response object.
uriURI or path to the file.
Returns
true if file was served successfully.
Parameters
resHTTP response object.
uriURI or path to the file.
Returns
true if file was served successfully.

Definition at line 76 of file HttpFileserver.cpp.

77{
78 std::string path = uri;
79
81 if (!storageManager->mount())
82 {
83 printf("Storage mount failed\n");
84 JsonResponse::sendError(res, 500, "MOUNT_FAILED", "Storage mount failed");
85 return false;
86 }
87
88 if (!storageManager->exists(path))
89 {
91 {
92 TRACE("Storage is not mounted — static file access failed\n");
93 JsonResponse::sendError(res, 500, "NOT_MOUNTED", "Storage not mounted");
94 return false;
95 }
96 else
97 {
98 printf("File not found: %s\n", path.c_str());
99 JsonResponse::sendError(res, 404, "NOT_FOUND", "File Not Found: " + std::string(uri));
100 return false;
101 }
102 }
103
104 size_t fileSize = storageManager->getFileSize(path);
105 if (fileSize == 0)
106 {
107 JsonResponse::sendError(res, 500, "FILESIZE_ERROR", "Error getting file size for: " + std::string(uri));
108 return false;
109 }
110
111 std::string mimeType = getMimeType(path);
112 TRACE("Serving file: %s, size: %zu bytes, MIME type: %s\n", path.c_str(), fileSize, mimeType.c_str());
113
114 if (mimeType == "text/html" || mimeType == "application/javascript" || mimeType == "text/css")
115 {
116 // Gzip magic number: 0x1F 0x8B (in little-endian)
117 const uint8_t gzip_magic_number[] = {0x1F, 0x8B};
118 std::string magic_number;
119 if (storageManager->readFileString(path, 0, 2, magic_number))
120 {
121 TRACE("Read magic number in hex: ");
122 for (size_t i = 0; i < magic_number.size(); ++i)
123 {
124 TRACE("%02X ", static_cast<unsigned char>(magic_number[i]));
125 }
126 TRACE("\n");
127 if (magic_number[0] == gzip_magic_number[0] && magic_number[1] == gzip_magic_number[1]) // GZIP magic number
128 {
129 TRACE("File is already gzipped: %s\n", path.c_str());
130 TRACE("Setting Content-Encoding to gzip\n");
131 res.set("Content-Encoding", "gzip");
132 }
133 }
134 }
135
136 res.start(200, fileSize, mimeType.c_str());
137
138 storageManager->streamFile(path, [&](const uint8_t *data, size_t len)
139 {
140 res.writeChunk(reinterpret_cast<const char*>(data), len);
141 vTaskDelay(pdMS_TO_TICKS(STREAM_SEND_DELAY_MS)); }); // allow tcpip thread to get in
142
143 res.finish();
144 return true;
145}
StorageManager * storageManager
void writeChunk(const char *data, size_t length)
Send a chunk of the response body.
HttpResponse & set(const std::string &field, const std::string &value)
Set a generic header field.
void finish()
Finish the response (placeholder for potential finalization).
void start(int code, size_t contentLength, const std::string &contentType="application/octet-stream", const std::string &contentEncoding="")
Begin a streaming response by sending headers.
virtual bool isMounted() const =0
Check mounted.
virtual bool readFileString(const std::string &path, uint32_t startPosition, uint32_t length, std::string &buffer)=0
Read a file string into a memory buffer.
virtual size_t getFileSize(const std::string &path)=0
Get the size of a file.
virtual bool streamFile(const std::string &path, std::function< void(const uint8_t *, size_t)> chunkCallback)=0
Stream a file in chunks via callback.
virtual bool exists(const std::string &path)=0
Check whether a file or directory exists at the given path.
#define STREAM_SEND_DELAY_MS
void sendError(HttpResponse &res, int statusCode, const std::string &code, const std::string &message)
std::string getMimeType(const std::string &filePath)

References StorageManager::exists(), HttpResponse::finish(), StorageManager::getFileSize(), getMimeType(), AppContext::getTypeKey(), StorageManager::isMounted(), StorageManager::mount(), StorageManager::readFileString(), JsonResponse::sendError(), HttpResponse::set(), HttpResponse::start(), storageManager, STREAM_SEND_DELAY_MS, StorageManager::streamFile(), TRACE, and HttpResponse::writeChunk().

Referenced by HttpFileserver::handle_static_request(), and HttpResponse::sendFile().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ mounted

bool FileHandler::mounted = false

Definition at line 58 of file HttpFileserver.h.

◆ storageManager

StorageManager* FileHandler::storageManager
private

Definition at line 61 of file HttpFileserver.h.

Referenced by serveFile().


The documentation for this class was generated from the following files: