From 653043f7b1b8027eb65c1525cec95bdcc8ac0b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 13 Aug 2015 23:52:34 +0200 Subject: [PATCH] add OPTIONS method + CORS --- server/httpreply.cpp | 4 ++++ server/httprequest.cpp | 4 ++++ server/httprequest.h | 1 + server/webserver.cpp | 15 +++++++++------ tests/auto/webserver/testwebserver.cpp | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/server/httpreply.cpp b/server/httpreply.cpp index f431dca7..57376dc9 100644 --- a/server/httpreply.cpp +++ b/server/httpreply.cpp @@ -135,7 +135,9 @@ HttpReply::HttpReply(QObject *parent) : // set known headers setHeader(HttpHeaderType::ServerHeader, "guh/" + QByteArray(GUH_VERSION_STRING)); setHeader(HttpHeaderType::DateHeader, QDateTime::currentDateTime().toString("ddd, dd MMM yyyy hh:mm:ss").toUtf8() + " GMT"); + setRawHeader("Access-Control-Allow-Origin","*"); setHeader(HttpHeaderType::CacheControlHeader, "no-cache"); + setHeader(HttpHeaderType::ConnectionHeader, "Keep-Alive"); packReply(); } @@ -155,7 +157,9 @@ HttpReply::HttpReply(const HttpReply::HttpStatusCode &statusCode, const HttpRepl // set known headers setHeader(HttpHeaderType::ServerHeader, "guh/" + QByteArray(GUH_VERSION_STRING)); setHeader(HttpHeaderType::DateHeader, QDateTime::currentDateTime().toString("ddd, dd MMM yyyy hh:mm:ss").toUtf8() + " GMT"); + setRawHeader("Access-Control-Allow-Origin","*"); setHeader(HttpHeaderType::CacheControlHeader, "no-cache"); + setHeader(HttpHeaderType::ConnectionHeader, "Keep-Alive"); packReply(); } diff --git a/server/httprequest.cpp b/server/httprequest.cpp index af678987..5d67a813 100644 --- a/server/httprequest.cpp +++ b/server/httprequest.cpp @@ -43,6 +43,8 @@ Represents the HTTP/1.1 PUT method. \value Delete Represents the HTTP/1.1 DELETE method. + \value Options + Represents the HTTP/1.1 OPTIONS method. \value Unhandled Represents every other method which is not handled. */ @@ -256,6 +258,8 @@ HttpRequest::RequestMethod HttpRequest::getRequestMethodType(const QString &meth return RequestMethod::Put; } else if (methodString == "DELETE") { return RequestMethod::Delete; + } else if (methodString == "OPTIONS") { + return RequestMethod::Options; } qCWarning(dcWebServer) << "Method" << methodString << "will not be handled."; return RequestMethod::Unhandled; diff --git a/server/httprequest.h b/server/httprequest.h index 07cd7b69..18a22147 100644 --- a/server/httprequest.h +++ b/server/httprequest.h @@ -36,6 +36,7 @@ public: Post, Put, Delete, + Options, Unhandled }; diff --git a/server/webserver.cpp b/server/webserver.cpp index d0b951ca..30b9682d 100644 --- a/server/webserver.cpp +++ b/server/webserver.cpp @@ -113,7 +113,6 @@ WebServer::WebServer(const QSslConfiguration &sslConfiguration, QObject *parent) if (!m_webinterfaceDir.exists()) qCWarning(dcWebServer) << "Web interface public folder" << m_webinterfaceDir.path() << "does not exist."; - // check SSL if (m_useSsl && m_sslConfiguration.isNull()) m_useSsl = false; @@ -161,7 +160,6 @@ bool WebServer::verifyFile(QSslSocket *socket, const QString &fileName) reply.setPayload("403 Forbidden."); reply.packReply(); writeData(socket, reply.data()); - socket->close(); return false; } @@ -172,7 +170,6 @@ bool WebServer::verifyFile(QSslSocket *socket, const QString &fileName) reply.setPayload("403 Forbidden. Page not readable."); reply.packReply(); writeData(socket, reply.data()); - socket->close(); return false; } return true; @@ -190,11 +187,10 @@ QString WebServer::fileName(const QString &query) return m_webinterfaceDir.path() + fileName; } - void WebServer::writeData(QSslSocket *socket, const QByteArray &data) { socket->write(data); - socket->close(); + //socket->close(); } void WebServer::incomingConnection(qintptr socketDescriptor) @@ -289,12 +285,19 @@ void WebServer::readClient() // verify method if (request.method() == HttpRequest::Unhandled) { HttpReply reply(HttpReply::MethodNotAllowed); - reply.setHeader(HttpReply::AllowHeader, "GET, PUT, POST, DELETE"); + reply.setHeader(HttpReply::AllowHeader, "GET, PUT, POST, DELETE, OPTIONS"); reply.setPayload("405 Method not allowed."); writeData(socket, reply.data()); return; } + // check CORS call + if (request.method() == HttpRequest::Options) { + HttpReply reply(HttpReply::Ok); + reply.setRawHeader("Access-Control-Allow-Methods","PUT, POST, GET, DELETE, OPTIONS"); + writeData(socket, reply.data()); + } + // verify API query if (request.url().path().startsWith("/api/v1")) { emit httpRequestReady(clientId, request); diff --git a/tests/auto/webserver/testwebserver.cpp b/tests/auto/webserver/testwebserver.cpp index 5370c089..45bcb61e 100644 --- a/tests/auto/webserver/testwebserver.cpp +++ b/tests/auto/webserver/testwebserver.cpp @@ -158,9 +158,9 @@ void TestWebserver::checkAllowedMethodCall_data() QTest::newRow("PUT") << "PUT" << 200; QTest::newRow("POST") << "POST" << 200; QTest::newRow("DELETE") << "DELETE" << 200; + QTest::newRow("OPTIONS") << "OPTIONS" << 200; QTest::newRow("HEAD") << "HEAD" << 405; QTest::newRow("CONNECT") << "CONNECT" << 405; - QTest::newRow("OPTIONS") << "OPTIONS" << 405; QTest::newRow("TRACE") << "TRACE" << 405; }