Hobrasoft httpd server
Embedded HTTP server for Qt and C++
shtmlcontroller.cpp
Go to the documentation of this file.
1 
8 #include "shtmlcontroller.h"
9 #include "httpconnection.h"
10 #include "httpresponse.h"
11 #include "httprequest.h"
12 #include "httpsettings.h"
13 #include <QFileInfo>
14 #include <QDir>
15 #include <QDateTime>
16 #include <QFile>
17 #include <QFileInfo>
18 #include <QDir>
19 #include <QDateTime>
20 #include <QDebug>
21 
22 using namespace HobrasoftHttpd;
23 
25  m_parent = parent;
26 }
27 
28 
30  QString path = request->path();
31 
32  QByteArray data;
33  try {
34  data = readFile(path, response, 0);
35  }
36  catch (...) {
37  return;
38  }
39  response->setHeader("Content-Type", "text/html; charset=" + settings()->encoding());
40  response->write(data);
41  response->flush();
42 
43 }
44 
45 
46 QByteArray ShtmlController::readFile(const QString& path, HttpResponse *response, int depth) {
47  QString rootpath = QDir::fromNativeSeparators(settings()->docroot());
48  depth += 1;
49  if (depth > 10) {
50  response->setStatus(500,"Server error");
51  response->write(QString("500 server error: %1<br>\nRecursive loop detected in included files.").arg(path).toUtf8());
52  response->flush();
53  throw false;;
54  }
55 
56  QByteArray data;
57  if (path.startsWith("/..") || path.startsWith("..")) {
58  response->setStatus(403,"Forbidden");
59  response->write(QString("403 Forbidden: %1<br>\nDo not use ../ in your file path").arg(path).toUtf8());
60  response->flush();
61  throw false;;
62  }
63 
64  QString filename = rootpath + "/" + path;
65  QFile file(filename);
66 
67  if (QFileInfo(filename).isDir()) {
68  response->setStatus(500, "Server error");
69  response->write(QString("500 Server error: %1<br>\nCannot include directory").arg(file.fileName()).toUtf8());
70  response->flush();
71  throw false;
72  }
73 
74  if (!file.exists()) {
75  response->setStatus(404, "Not found");
76  response->write(QString("404 File not found: %1").arg(file.fileName()).toUtf8());
77  response->flush();
78  throw false;;
79  }
80 
81  if (!file.open(QIODevice::ReadOnly)) {
82  response->setStatus(403, "Forbidden");
83  response->write(QString("403 Forbidden: %1").arg(file.fileName()).toUtf8());
84  response->flush();
85  throw false;;
86  }
87 
88  while (!file.atEnd()) {
89  QString line = QString::fromUtf8(file.readLine());
90  if (line.contains(QRegExp("^\\s*<!--\\s*#include\\s+\".+\"\\s*-->\\s*$"))) {
91  QStringList lineparts = line.split('"');
92  if (lineparts.size() != 3) {
93  continue;
94  }
95  data += readFile(lineparts[1], response, depth);
96  continue;
97  }
98  data += line.toUtf8();
99  }
100 
101  file.close();
102  return data;
103 }
104 
void service(HttpRequest *request, HttpResponse *response)
Processes one request.
HttpResponse * response()
Returns new instance of HttpResponse class.
QString path() const
Returns path of the request (/files/index.html)
Definition: httprequest.h:78
void flush()
Writes last part of the response and closes the socket when possible.
Response to HTTP request - headers, cookies and body.
Definition: httpresponse.h:30
void write(const QByteArray &data)
Writes data to response body.
Processes incoming requests.
const HttpSettings * settings() const
Returns pointer to HttpSettings used in the HttpServer.
QByteArray readFile(const QString &path, HttpResponse *response, int depth)
Reads and processes one file, other files can be included recursivelly.
Processes HTTP request, parses headers, body and files sent by HTTP protocol.
Definition: httprequest.h:23
void setStatus(int code, const QString &description=QString())
Set the status code and the description of the response.
void setHeader(const QString &name, const QString &value)
Sets or rewrite one header.
ShtmlController(HttpConnection *parent)
Construct sets the default parameter from configuration (encoding and root)
Namespace of HTTP server.
One single connection to http server.