SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
qtwebapp::StaticFileController Class Reference

#include <staticfilecontroller.h>

+ Inheritance diagram for qtwebapp::StaticFileController:
+ Collaboration diagram for qtwebapp::StaticFileController:

Classes

struct  CacheEntry
 

Public Member Functions

 StaticFileController (QSettings *settings, QObject *parent=NULL)
 
 StaticFileController (const HttpDocrootSettings &settings, QObject *parent=NULL)
 
void service (HttpRequest &request, HttpResponse &response)
 
void service (QByteArray &path, HttpResponse &response)
 
- Public Member Functions inherited from qtwebapp::HttpRequestHandler
 HttpRequestHandler (QObject *parent=NULL)
 
virtual ~HttpRequestHandler ()
 

Private Member Functions

void setContentType (QString file, HttpResponse &response) const
 

Private Attributes

QString encoding
 
QString docroot
 
int maxAge
 
int cacheTimeout
 
int maxCachedFileSize
 
QCache< QString, CacheEntrycache
 
QMutex mutex
 
bool useQtSettings
 

Detailed Description

Definition at line 49 of file staticfilecontroller.h.

Constructor & Destructor Documentation

◆ StaticFileController() [1/2]

StaticFileController::StaticFileController ( QSettings *  settings,
QObject *  parent = NULL 
)

Constructor with Qt settings

Definition at line 15 of file staticfilecontroller.cpp.

References cache, cacheTimeout, docroot, encoding, maxAge, and maxCachedFileSize.

16  :HttpRequestHandler(parent), useQtSettings(true)
17 {
18  maxAge=settings->value("maxAge","60000").toInt();
19  encoding=settings->value("encoding","UTF-8").toString();
20  docroot=settings->value("path",".").toString();
21  if(!(docroot.startsWith(":/") || docroot.startsWith("qrc://")))
22  {
23  // Convert relative path to absolute, based on the directory of the config file.
24  #ifdef Q_OS_WIN32
25  if (QDir::isRelativePath(docroot) && settings->format()!=QSettings::NativeFormat)
26  #else
27  if (QDir::isRelativePath(docroot))
28  #endif
29  {
30  QFileInfo configFile(settings->fileName());
31  docroot=QFileInfo(configFile.absolutePath(),docroot).absoluteFilePath();
32  }
33  }
34  qDebug("StaticFileController: docroot=%s, encoding=%s, maxAge=%i",qPrintable(docroot),qPrintable(encoding),maxAge);
35  maxCachedFileSize=settings->value("maxCachedFileSize","65536").toInt();
36  cache.setMaxCost(settings->value("cacheSize","1000000").toInt());
37  cacheTimeout=settings->value("cacheTime","60000").toInt();
38  qDebug("StaticFileController: cache timeout=%i, size=%i",cacheTimeout,cache.maxCost());
39 }
QCache< QString, CacheEntry > cache
HttpRequestHandler(QObject *parent=NULL)

◆ StaticFileController() [2/2]

StaticFileController::StaticFileController ( const HttpDocrootSettings settings,
QObject *  parent = NULL 
)

Constructor with settings structure

Definition at line 41 of file staticfilecontroller.cpp.

References cache, qtwebapp::HttpDocrootSettings::cacheSize, qtwebapp::HttpDocrootSettings::cacheTime, cacheTimeout, docroot, qtwebapp::HttpDocrootSettings::encoding, encoding, qtwebapp::HttpDocrootSettings::maxAge, maxAge, qtwebapp::HttpDocrootSettings::maxCachedFileSize, maxCachedFileSize, and qtwebapp::HttpDocrootSettings::path.

42  :HttpRequestHandler(parent), useQtSettings(false)
43 {
44  maxAge=settings.maxAge;
45  encoding=settings.encoding;
46  docroot=settings.path;
47  if(!(docroot.startsWith(":/") || docroot.startsWith("qrc://")))
48  {
49  // Convert relative path to absolute, based on the directory of the config file.
50  if (QDir::isRelativePath(docroot))
51  {
52  docroot = QFileInfo(QDir::currentPath(), docroot).absoluteFilePath();
53  }
54  }
55  qDebug("StaticFileController: docroot=%s, encoding=%s, maxAge=%i",qPrintable(docroot),qPrintable(encoding),maxAge);
57  cache.setMaxCost(settings.cacheSize);
58  cacheTimeout=settings.cacheTime;
59  qDebug("StaticFileController: cache timeout=%i, size=%i",cacheTimeout,cache.maxCost());
60 }
QCache< QString, CacheEntry > cache
HttpRequestHandler(QObject *parent=NULL)

Member Function Documentation

◆ service() [1/2]

void StaticFileController::service ( HttpRequest request,
HttpResponse response 
)
virtual

Generates the response from HTTP request

Reimplemented from qtwebapp::HttpRequestHandler.

Definition at line 62 of file staticfilecontroller.cpp.

References qtwebapp::HttpRequest::getPath().

Referenced by WebAPIRequestMapper::service().

63 {
64  QByteArray path = request.getPath();
65  service(path, response);
66 }
QByteArray getPath() const
void service(HttpRequest &request, HttpResponse &response)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ service() [2/2]

void StaticFileController::service ( QByteArray &  path,
HttpResponse response 
)

Generates the response directly from the path

Definition at line 68 of file staticfilecontroller.cpp.

References cache, cacheTimeout, qtwebapp::StaticFileController::CacheEntry::created, docroot, qtwebapp::StaticFileController::CacheEntry::document, qtwebapp::StaticFileController::CacheEntry::filename, maxAge, maxCachedFileSize, mutex, setContentType(), qtwebapp::HttpResponse::setHeader(), qtwebapp::HttpResponse::setStatus(), and qtwebapp::HttpResponse::write().

69 {
70  //QByteArray path=request.getPath();
71  // Check if we have the file in cache
72  qint64 now=QDateTime::currentMSecsSinceEpoch();
73  mutex.lock();
74  CacheEntry* entry=cache.object(path);
75  if (entry && (cacheTimeout==0 || entry->created>now-cacheTimeout))
76  {
77  QByteArray document=entry->document; //copy the cached document, because other threads may destroy the cached entry immediately after mutex unlock.
78  QByteArray filename=entry->filename;
79  mutex.unlock();
80  qDebug("StaticFileController: Cache hit for %s",path.data());
81  setContentType(filename,response);
82  response.setHeader("Cache-Control","max-age="+QByteArray::number(maxAge/1000));
83  response.write(document);
84  }
85  else
86  {
87  mutex.unlock();
88  // The file is not in cache.
89  qDebug("StaticFileController: Cache miss for %s",path.data());
90  // Forbid access to files outside the docroot directory
91  if (path.contains("/.."))
92  {
93  qWarning("StaticFileController::service: detected forbidden characters in path %s",path.data());
94  response.setStatus(403,"forbidden");
95  response.write("403 forbidden",true);
96  return;
97  }
98  // If the filename is a directory, append index.html.
99  if (QFileInfo(docroot+path).isDir())
100  {
101  path+="/index.html";
102  }
103  // Try to open the file
104  QFile file(docroot+path);
105  qDebug("StaticFileController: Open file %s",qPrintable(file.fileName()));
106  if (file.open(QIODevice::ReadOnly))
107  {
108  setContentType(path,response);
109  response.setHeader("Cache-Control","max-age="+QByteArray::number(maxAge/1000));
110  if (file.size()<=maxCachedFileSize)
111  {
112  // Return the file content and store it also in the cache
113  entry=new CacheEntry();
114  while (!file.atEnd() && !file.error())
115  {
116  QByteArray buffer=file.read(65536);
117  response.write(buffer);
118  entry->document.append(buffer);
119  }
120  entry->created=now;
121  entry->filename=path;
122  mutex.lock();
123  //cache.insert(request.getPath(),entry,entry->document.size());
124  cache.insert(path,entry,entry->document.size());
125  mutex.unlock();
126  }
127  else
128  {
129  // Return the file content, do not store in cache
130  while (!file.atEnd() && !file.error())
131  {
132  response.write(file.read(65536));
133  }
134  }
135  file.close();
136  }
137  else {
138  if (file.exists())
139  {
140  qWarning("StaticFileController::service: Cannot open existing file %s for reading",qPrintable(file.fileName()));
141  response.setStatus(403,"forbidden");
142  response.write("403 forbidden",true);
143  }
144  else
145  {
146  qWarning("StaticFileController::service: File %s not found",qPrintable(file.fileName()));
147  response.setStatus(404,"not found");
148  response.write("404 not found",true);
149  }
150  }
151  }
152 }
QCache< QString, CacheEntry > cache
void setHeader(QByteArray name, QByteArray value)
void setContentType(QString file, HttpResponse &response) const
void write(QByteArray data, bool lastPart=false)
void setStatus(int statusCode, QByteArray description=QByteArray())
+ Here is the call graph for this function:

◆ setContentType()

void StaticFileController::setContentType ( QString  file,
HttpResponse response 
) const
private

Set a content-type header in the response depending on the ending of the filename

Definition at line 154 of file staticfilecontroller.cpp.

References encoding, and qtwebapp::HttpResponse::setHeader().

Referenced by service().

155 {
156  if (fileName.endsWith(".png"))
157  {
158  response.setHeader("Content-Type", "image/png");
159  }
160  else if (fileName.endsWith(".jpg"))
161  {
162  response.setHeader("Content-Type", "image/jpeg");
163  }
164  else if (fileName.endsWith(".gif"))
165  {
166  response.setHeader("Content-Type", "image/gif");
167  }
168  else if (fileName.endsWith(".pdf"))
169  {
170  response.setHeader("Content-Type", "application/pdf");
171  }
172  else if (fileName.endsWith(".txt"))
173  {
174  response.setHeader("Content-Type", qPrintable("text/plain; charset="+encoding));
175  }
176  else if (fileName.endsWith(".html") || fileName.endsWith(".htm"))
177  {
178  response.setHeader("Content-Type", qPrintable("text/html; charset="+encoding));
179  }
180  else if (fileName.endsWith(".css"))
181  {
182  response.setHeader("Content-Type", "text/css");
183  }
184  else if (fileName.endsWith(".js"))
185  {
186  response.setHeader("Content-Type", "text/javascript");
187  }
188  else if (fileName.endsWith(".svg"))
189  {
190  response.setHeader("Content-Type", "image/svg+xml");
191  }
192  else if (fileName.endsWith(".woff"))
193  {
194  response.setHeader("Content-Type", "font/woff");
195  }
196  else if (fileName.endsWith(".woff2"))
197  {
198  response.setHeader("Content-Type", "font/woff2");
199  }
200  else if (fileName.endsWith(".ttf"))
201  {
202  response.setHeader("Content-Type", "application/x-font-ttf");
203  }
204  else if (fileName.endsWith(".eot"))
205  {
206  response.setHeader("Content-Type", "application/vnd.ms-fontobject");
207  }
208  else if (fileName.endsWith(".otf"))
209  {
210  response.setHeader("Content-Type", "application/font-otf");
211  }
212  else if (fileName.endsWith(".yaml"))
213  {
214  response.setHeader("Content-Type", "text/plain");
215  }
216  // Todo: add all of your content types
217  else
218  {
219  qDebug("StaticFileController: unknown MIME type for filename '%s'", qPrintable(fileName));
220  }
221 }
void setHeader(QByteArray name, QByteArray value)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ cache

QCache<QString,CacheEntry> qtwebapp::StaticFileController::cache
private

Cache storage

Definition at line 90 of file staticfilecontroller.h.

Referenced by service(), and StaticFileController().

◆ cacheTimeout

int qtwebapp::StaticFileController::cacheTimeout
private

Timeout for each cached file

Definition at line 84 of file staticfilecontroller.h.

Referenced by service(), and StaticFileController().

◆ docroot

QString qtwebapp::StaticFileController::docroot
private

Root directory of documents

Definition at line 72 of file staticfilecontroller.h.

Referenced by service(), and StaticFileController().

◆ encoding

QString qtwebapp::StaticFileController::encoding
private

Encoding of text files

Definition at line 69 of file staticfilecontroller.h.

Referenced by setContentType(), and StaticFileController().

◆ maxAge

int qtwebapp::StaticFileController::maxAge
private

Maximum age of files in the browser cache

Definition at line 75 of file staticfilecontroller.h.

Referenced by service(), and StaticFileController().

◆ maxCachedFileSize

int qtwebapp::StaticFileController::maxCachedFileSize
private

Maximum size of files in cache, larger files are not cached

Definition at line 87 of file staticfilecontroller.h.

Referenced by service(), and StaticFileController().

◆ mutex

QMutex qtwebapp::StaticFileController::mutex
private

Used to synchronize cache access for threads

Definition at line 93 of file staticfilecontroller.h.

Referenced by service().

◆ useQtSettings

bool qtwebapp::StaticFileController::useQtSettings
private

Settings flag

Definition at line 96 of file staticfilecontroller.h.


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