Go to the documentation of this file.00001
00006 #include "staticfilecontroller.h"
00007 #include <QFileInfo>
00008 #include <QDir>
00009 #include <QDateTime>
00010
00011 StaticFileController::StaticFileController(QSettings* settings, QObject* parent)
00012 :HttpRequestHandler(parent)
00013 {
00014 maxAge=settings->value("maxAge","60000").toInt();
00015 encoding=settings->value("encoding","UTF-8").toString();
00016 docroot=settings->value("path",".").toString();
00017
00018 #ifdef Q_OS_WIN32
00019 if (QDir::isRelativePath(docroot) && settings->format()!=QSettings::NativeFormat)
00020 #else
00021 if (QDir::isRelativePath(docroot))
00022 #endif
00023 {
00024 QFileInfo configFile(settings->fileName());
00025 docroot=QFileInfo(configFile.absolutePath(),docroot).absoluteFilePath();
00026 }
00027 qDebug("StaticFileController: docroot=%s, encoding=%s, maxAge=%i",qPrintable(docroot),qPrintable(encoding),maxAge);
00028 maxCachedFileSize=settings->value("maxCachedFileSize","65536").toInt();
00029 cache.setMaxCost(settings->value("cacheSize","1000000").toInt());
00030 cacheTimeout=settings->value("cacheTime","60000").toInt();
00031 qDebug("StaticFileController: cache timeout=%i, size=%i",cacheTimeout,cache.maxCost());
00032 }
00033
00034
00035 void StaticFileController::service(HttpRequest& request, HttpResponse& response) {
00036 QByteArray path=request.getPath();
00037
00038 if (path.startsWith("/..")) {
00039 qWarning("StaticFileController: somebody attempted to access a file outside the docroot directory");
00040 response.setStatus(403,"forbidden");
00041 response.write("403 forbidden",true);
00042 }
00043
00044 qint64 now=QDateTime::currentMSecsSinceEpoch();
00045 CacheEntry* entry=cache.object(path);
00046 if (entry && (cacheTimeout==0 || entry->created>now-cacheTimeout)) {
00047 qDebug("StaticFileController: Cache hit for %s",path.data());
00048 setContentType(path,response);
00049 response.setHeader("Cache-Control","max-age="+QByteArray::number(maxAge/1000));
00050 response.write(entry->document);
00051 }
00052 else {
00053 qDebug("StaticFileController: Cache miss for %s",path.data());
00054
00055
00056 if (QFileInfo(docroot+path).isDir()) {
00057 path+="/index.html";
00058 }
00059 QFile file(docroot+path);
00060 if (file.exists()) {
00061 qDebug("StaticFileController: Open file %s",qPrintable(file.fileName()));
00062 if (file.open(QIODevice::ReadOnly)) {
00063 setContentType(path,response);
00064 response.setHeader("Cache-Control","max-age="+QByteArray::number(maxAge/1000));
00065 if (file.size()<=maxCachedFileSize) {
00066
00067 entry=new CacheEntry();
00068 while (!file.atEnd() && !file.error()) {
00069 QByteArray buffer=file.read(65536);
00070 response.write(buffer);
00071 entry->document.append(buffer);
00072 }
00073 entry->created=now;
00074 cache.insert(request.getPath(),entry,entry->document.size());
00075 }
00076 else {
00077
00078 while (!file.atEnd() && !file.error()) {
00079 response.write(file.read(65536));
00080 }
00081 }
00082 file.close();
00083 }
00084 else {
00085 qWarning("StaticFileController: Cannot open existing file %s for reading",qPrintable(file.fileName()));
00086 response.setStatus(403,"forbidden");
00087 response.write("403 forbidden",true);
00088 }
00089 }
00090 else {
00091 response.setStatus(404,"not found");
00092 response.write("404 not found",true);
00093 }
00094 }
00095 }
00096
00097 void StaticFileController::setContentType(QString fileName, HttpResponse& response) const {
00098 if (fileName.endsWith(".png")) {
00099 response.setHeader("Content-Type", "image/png");
00100 }
00101 else if (fileName.endsWith(".jpg")) {
00102 response.setHeader("Content-Type", "image/jpeg");
00103 }
00104 else if (fileName.endsWith(".gif")) {
00105 response.setHeader("Content-Type", "image/gif");
00106 }
00107 else if (fileName.endsWith(".txt")) {
00108 response.setHeader("Content-Type", qPrintable("text/plain; charset="+encoding));
00109 }
00110 else if (fileName.endsWith(".html") || fileName.endsWith(".htm")) {
00111 response.setHeader("Content-Type", qPrintable("text/html; charset=charset="+encoding));
00112 }
00113
00114 }