mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 10:17:40 +02:00
Merge pull request #1435 from daleglass/fix-html-mime-type
Fix mime type for serving .htm and .html files with the embedded webserver.
This commit is contained in:
commit
457c622598
1 changed files with 31 additions and 30 deletions
|
@ -31,7 +31,7 @@ HTTPManager::HTTPManager(const QHostAddress& listenAddress, quint16 port, const
|
||||||
_port(port)
|
_port(port)
|
||||||
{
|
{
|
||||||
bindSocket();
|
bindSocket();
|
||||||
|
|
||||||
_isListeningTimer = new QTimer(this);
|
_isListeningTimer = new QTimer(this);
|
||||||
connect(_isListeningTimer, &QTimer::timeout, this, &HTTPManager::isTcpServerListening);
|
connect(_isListeningTimer, &QTimer::timeout, this, &HTTPManager::isTcpServerListening);
|
||||||
_isListeningTimer->start(SOCKET_CHECK_INTERVAL_IN_MS);
|
_isListeningTimer->start(SOCKET_CHECK_INTERVAL_IN_MS);
|
||||||
|
@ -39,7 +39,7 @@ HTTPManager::HTTPManager(const QHostAddress& listenAddress, quint16 port, const
|
||||||
|
|
||||||
void HTTPManager::incomingConnection(qintptr socketDescriptor) {
|
void HTTPManager::incomingConnection(qintptr socketDescriptor) {
|
||||||
QTcpSocket* socket = new QTcpSocket(this);
|
QTcpSocket* socket = new QTcpSocket(this);
|
||||||
|
|
||||||
if (socket->setSocketDescriptor(socketDescriptor)) {
|
if (socket->setSocketDescriptor(socketDescriptor)) {
|
||||||
new HTTPConnection(socket, this);
|
new HTTPConnection(socket, this);
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,7 +60,7 @@ bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QUrl& url,
|
||||||
// so we don't need to attempt to do so in the document root
|
// so we don't need to attempt to do so in the document root
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_documentRoot.isEmpty()) {
|
if (!_documentRoot.isEmpty()) {
|
||||||
// check to see if there is a file to serve from the document root for this path
|
// check to see if there is a file to serve from the document root for this path
|
||||||
QString subPath = url.path();
|
QString subPath = url.path();
|
||||||
|
@ -88,22 +88,22 @@ bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QUrl& url,
|
||||||
// this could be a directory with a trailing slash
|
// this could be a directory with a trailing slash
|
||||||
// send a redirect to the path with a slash so we can
|
// send a redirect to the path with a slash so we can
|
||||||
QString redirectLocation = '/' + subPath + '/';
|
QString redirectLocation = '/' + subPath + '/';
|
||||||
|
|
||||||
if (!url.query().isEmpty()) {
|
if (!url.query().isEmpty()) {
|
||||||
redirectLocation += "?" + url.query();
|
redirectLocation += "?" + url.query();
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QByteArray, QByteArray> redirectHeader;
|
QHash<QByteArray, QByteArray> redirectHeader;
|
||||||
redirectHeader.insert(QByteArray("Location"), redirectLocation.toUtf8());
|
redirectHeader.insert(QByteArray("Location"), redirectLocation.toUtf8());
|
||||||
|
|
||||||
connection->respond(HTTPConnection::StatusCode302, "", HTTPConnection::DefaultContentType, redirectHeader);
|
connection->respond(HTTPConnection::StatusCode302, "", HTTPConnection::DefaultContentType, redirectHeader);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the last thing is a trailing slash then we want to look for index file
|
// if the last thing is a trailing slash then we want to look for index file
|
||||||
if (subPath.endsWith('/') || subPath.size() == 0) {
|
if (subPath.endsWith('/') || subPath.size() == 0) {
|
||||||
QStringList possibleIndexFiles = QStringList() << "index.html" << "index.shtml";
|
QStringList possibleIndexFiles = QStringList() << "index.html" << "index.shtml";
|
||||||
|
|
||||||
foreach (const QString& possibleIndexFilename, possibleIndexFiles) {
|
foreach (const QString& possibleIndexFilename, possibleIndexFiles) {
|
||||||
if (QFileInfo(absoluteFilePath + possibleIndexFilename).exists()) {
|
if (QFileInfo(absoluteFilePath + possibleIndexFilename).exists()) {
|
||||||
filePath = absoluteFilePath + possibleIndexFilename;
|
filePath = absoluteFilePath + possibleIndexFilename;
|
||||||
|
@ -111,64 +111,65 @@ bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QUrl& url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filePath.isEmpty()) {
|
if (!filePath.isEmpty()) {
|
||||||
// file exists, serve it
|
// file exists, serve it
|
||||||
static QMimeDatabase mimeDatabase;
|
static QMimeDatabase mimeDatabase;
|
||||||
|
|
||||||
auto localFile = std::unique_ptr<QFile>(new QFile(filePath));
|
auto localFile = std::unique_ptr<QFile>(new QFile(filePath));
|
||||||
localFile->open(QIODevice::ReadOnly);
|
localFile->open(QIODevice::ReadOnly);
|
||||||
QByteArray localFileData;
|
QByteArray localFileData;
|
||||||
|
|
||||||
QFileInfo localFileInfo(filePath);
|
QFileInfo localFileInfo(filePath);
|
||||||
|
|
||||||
if (localFileInfo.completeSuffix() == "shtml") {
|
if (localFileInfo.completeSuffix() == "shtml") {
|
||||||
localFileData = localFile->readAll();
|
localFileData = localFile->readAll();
|
||||||
// this is a file that may have some SSI statements
|
// this is a file that may have some SSI statements
|
||||||
// the only thing we support is the include directive, but check the contents for that
|
// the only thing we support is the include directive, but check the contents for that
|
||||||
|
|
||||||
// setup our static QRegExp that will catch <!--#include virtual ... --> and <!--#include file .. --> directives
|
// setup our static QRegExp that will catch <!--#include virtual ... --> and <!--#include file .. --> directives
|
||||||
const QString includeRegExpString = "<!--\\s*#include\\s+(virtual|file)\\s?=\\s?\"(\\S+)\"\\s*-->";
|
const QString includeRegExpString = "<!--\\s*#include\\s+(virtual|file)\\s?=\\s?\"(\\S+)\"\\s*-->";
|
||||||
QRegExp includeRegExp(includeRegExpString);
|
QRegExp includeRegExp(includeRegExpString);
|
||||||
|
|
||||||
int matchPosition = 0;
|
int matchPosition = 0;
|
||||||
|
|
||||||
QString localFileString(localFileData);
|
QString localFileString(localFileData);
|
||||||
|
|
||||||
while ((matchPosition = includeRegExp.indexIn(localFileString, matchPosition)) != -1) {
|
while ((matchPosition = includeRegExp.indexIn(localFileString, matchPosition)) != -1) {
|
||||||
// check if this is a file or vitual include
|
// check if this is a file or vitual include
|
||||||
bool isFileInclude = includeRegExp.cap(1) == "file";
|
bool isFileInclude = includeRegExp.cap(1) == "file";
|
||||||
|
|
||||||
// setup the correct file path for the included file
|
// setup the correct file path for the included file
|
||||||
QString includeFilePath = isFileInclude
|
QString includeFilePath = isFileInclude
|
||||||
? localFileInfo.canonicalPath() + "/" + includeRegExp.cap(2)
|
? localFileInfo.canonicalPath() + "/" + includeRegExp.cap(2)
|
||||||
: _documentRoot + includeRegExp.cap(2);
|
: _documentRoot + includeRegExp.cap(2);
|
||||||
|
|
||||||
QString replacementString;
|
QString replacementString;
|
||||||
|
|
||||||
if (QFileInfo(includeFilePath).isFile()) {
|
if (QFileInfo(includeFilePath).isFile()) {
|
||||||
|
|
||||||
QFile includedFile(includeFilePath);
|
QFile includedFile(includeFilePath);
|
||||||
includedFile.open(QIODevice::ReadOnly);
|
includedFile.open(QIODevice::ReadOnly);
|
||||||
|
|
||||||
replacementString = QString(includedFile.readAll());
|
replacementString = QString(includedFile.readAll());
|
||||||
} else {
|
} else {
|
||||||
qCDebug(embeddedwebserver) << "SSI include directive referenced a missing file:" << includeFilePath;
|
qCDebug(embeddedwebserver) << "SSI include directive referenced a missing file:" << includeFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace the match with the contents of the file, or an empty string if the file was not found
|
// replace the match with the contents of the file, or an empty string if the file was not found
|
||||||
localFileString.replace(matchPosition, includeRegExp.matchedLength(), replacementString);
|
localFileString.replace(matchPosition, includeRegExp.matchedLength(), replacementString);
|
||||||
|
|
||||||
// push the match position forward so we can check the next match
|
// push the match position forward so we can check the next match
|
||||||
matchPosition += includeRegExp.matchedLength();
|
matchPosition += includeRegExp.matchedLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
localFileData = localFileString.toLocal8Bit();
|
localFileData = localFileString.toLocal8Bit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this is an shtml file just make the MIME type match HTML so browsers aren't confused
|
// if this is an shtml, html or htm file just make the MIME type match HTML so browsers aren't confused
|
||||||
// otherwise use the mimeDatabase to look it up
|
// otherwise use the mimeDatabase to look it up
|
||||||
auto mimeType = localFileInfo.suffix() == "shtml"
|
auto suffix = localFileInfo.suffix();
|
||||||
|
auto mimeType = (suffix == "shtml" || suffix == "html" || suffix == "htm")
|
||||||
? QString { "text/html" }
|
? QString { "text/html" }
|
||||||
: mimeDatabase.mimeTypeForFile(filePath).name();
|
: mimeDatabase.mimeTypeForFile(filePath).name();
|
||||||
|
|
||||||
|
@ -181,10 +182,10 @@ bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QUrl& url,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// respond with a 404
|
// respond with a 404
|
||||||
connection->respond(HTTPConnection::StatusCode404, "Resource not found.");
|
connection->respond(HTTPConnection::StatusCode404, "Resource not found.");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,10 +202,10 @@ void HTTPManager::isTcpServerListening() {
|
||||||
|
|
||||||
bool HTTPManager::bindSocket() {
|
bool HTTPManager::bindSocket() {
|
||||||
qCDebug(embeddedwebserver) << "Attempting to bind TCP socket on port " << QString::number(_port);
|
qCDebug(embeddedwebserver) << "Attempting to bind TCP socket on port " << QString::number(_port);
|
||||||
|
|
||||||
if (listen(_listenAddress, _port)) {
|
if (listen(_listenAddress, _port)) {
|
||||||
qCDebug(embeddedwebserver) << "TCP socket is listening on" << serverAddress() << "and port" << serverPort();
|
qCDebug(embeddedwebserver) << "TCP socket is listening on" << serverAddress() << "and port" << serverPort();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
QString errorMessage = "Failed to open HTTP server socket: " + errorString() + ", can't continue";
|
QString errorMessage = "Failed to open HTTP server socket: " + errorString() + ", can't continue";
|
||||||
|
|
Loading…
Reference in a new issue