• Main Page
  • Classes
  • Files
  • File List
  • File Members

lib/bfHttpServer/src/staticfilecontroller.cpp

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     // Convert relative path to absolute, based on the directory of the config file.
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     // Forbid access to files outside the docroot directory
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     // Check if we have the file in cache
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         // The file is not in cache.
00055         // If the filename is a directory, append index.html.
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                     // Return the file content and store it also in the cache
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                     // Return the file content, do not store in cache
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     // Todo: add all of your content types
00114 }

Generated on Mon Dec 26 2011 12:09:22 for QtWebApp by  doxygen 1.7.1