void HttpServer::handleNormalFile(HttpClientHandler* hdlr,const QHttpRequestHeader & hdr,const QString & path) { QFileInfo fi(path); QString ext = fi.suffix(); if (hdr.hasKey("If-Modified-Since")) { QDateTime dt = parseDate(hdr.value("If-Modified-Since")); if (dt.isValid() && dt < fi.lastModified()) { HttpResponseHeader rhdr(304,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(rhdr,"text/html",true); rhdr.setValue("Cache-Control","max-age=0"); rhdr.setValue("Last-Modified",DateTimeToString(fi.lastModified(),false)); rhdr.setValue("Expires",DateTimeToString(QDateTime::currentDateTime().toUTC().addSecs(3600),false)); hdlr->sendResponse(rhdr); return; } } HttpResponseHeader rhdr(200,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(rhdr,ExtensionToContentType(ext),true); rhdr.setValue("Last-Modified",DateTimeToString(fi.lastModified(),false)); rhdr.setValue("Expires",DateTimeToString(QDateTime::currentDateTime().toUTC().addSecs(3600),false)); rhdr.setValue("Cache-Control","private"); if (!hdlr->sendFile(rhdr,path)) { HttpResponseHeader nhdr(404,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(nhdr,"text/html",false); hdlr->send404(nhdr,path); } }
void HttpServer::handleFile(HttpClientHandler* hdlr,const QHttpRequestHeader & hdr,const QString & path) { // check if the file exists (if not send 404) if (!bt::Exists(path)) { HttpResponseHeader rhdr(404,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(rhdr,"text/html",false); hdlr->send404(rhdr,path); return; } QString file = hdr.path(); if (file == "/" && WebInterfacePluginSettings::authentication()) file = "/login.html"; else if (file == "/") file = "/interface.html"; QFileInfo fi(path); QString ext = fi.suffix();; if (ext == "html") { // html pages require a login unless it is the login.html page if ((file != "/login.html" && (!session.logged_in || !checkSession(hdr))) && WebInterfacePluginSettings::authentication()) { // redirect to login page redirectToLoginPage(hdlr); return; } HttpResponseHeader rhdr(200,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(rhdr,"text/html",true); if (path.endsWith("login.html")) { // clear cookie in case of login page QDateTime dt = QDateTime::currentDateTime().addDays(-1); QString cookie = QString("KT_SESSID=666; expires=%1 +0000").arg(DateTimeToString(dt,true)); rhdr.setValue("Set-Cookie",cookie); } if (!hdlr->sendFile(rhdr,path)) { HttpResponseHeader nhdr(404,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(nhdr,"text/html",false); hdlr->send404(nhdr,path); } } else if (ext == "css" || ext == "js" || ext == "png" || ext == "ico" || ext == "gif" || ext == "jpg") { handleNormalFile(hdlr,hdr,path); } else { HttpResponseHeader rhdr(404,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(rhdr,"text/html",false); hdlr->send404(rhdr,file); } }
void HttpServer::handleGet(HttpClientHandler* hdlr,const QHttpRequestHeader & hdr) { if (rootDir.isEmpty()) { HttpResponseHeader rhdr(500,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(rhdr,"text/html",false); hdlr->send500(rhdr,i18n("Cannot find web interface skins.")); return; } QString file = hdr.path(); if (file == "/" && WebInterfacePluginSettings::authentication()) file = "/login.html"; else if (file == "/") file = "/interface.html"; KUrl url; url.setEncodedPathAndQuery(file); Out(SYS_WEB|LOG_DEBUG) << "GET " << hdr.path() << endl; WebContentGenerator* gen = content_generators.find(url.path()); if (gen) { if ((gen->getPermissions() == WebContentGenerator::LOGIN_REQUIRED && (!session.logged_in || !checkSession(hdr))) && WebInterfacePluginSettings::authentication()) { // redirect to login page redirectToLoginPage(hdlr); } else { gen->get(hdlr,hdr); } } else { QString path = commonDir() + url.path(); // first try the common dir if (!bt::Exists(path)) // doesn't exist so it must be in the skin dir path = skinDir() + url.path(); handleFile(hdlr,hdr,path); } }
void HttpServer::handleUnsupportedMethod(HttpClientHandler* hdlr,const QHttpRequestHeader & hdr) { HttpResponseHeader rhdr(500,hdr.majorVersion(),hdr.minorVersion()); setDefaultResponseHeaders(rhdr,"text/html",false); hdlr->send500(rhdr,i18n("Unsupported HTTP method")); }
/*! * Handles incoming HTTP requests and dispatches them to the appropriate service. * * The \a requestID is an opaque value generated by the connector. * * Subclasses may override this function to perform preprocessing on each * request, but they must call the base class implementation in order to * generate and dispatch the appropriate events. * * To facilitate use with multi-threaded applications, the event will remain * valid until a response is posted. */ void QxtHttpSessionManager::incomingRequest(quint32 requestID, const QHttpRequestHeader& header, QxtWebContent* content) { QMultiHash<QString, QString> cookies; foreach(const QString& cookie, header.allValues("cookie")) // QHttpHeader is case-insensitive, thankfully { foreach(const QString& kv, cookie.split("; ")) { int pos = kv.indexOf('='); if (pos == -1) continue; cookies.insert(kv.left(pos), kv.mid(pos + 1)); } } int sessionID; QString sessionCookie = cookies.value(qxt_d().sessionCookieName); qxt_d().sessionLock.lock(); if (qxt_d().sessionKeys.contains(sessionCookie)) { sessionID = qxt_d().sessionKeys[sessionCookie]; if(!sessionID && header.majorVersion() > 0 && qxt_d().autoCreateSession) sessionID = newSession(); } else if (header.majorVersion() > 0 && qxt_d().autoCreateSession) { sessionID = newSession(); } else { sessionID = 0; } QIODevice* device = connector()->getRequestConnection(requestID); QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device]; state.sessionID = sessionID; state.httpMajorVersion = header.majorVersion(); state.httpMinorVersion = header.minorVersion(); if (state.httpMajorVersion == 0 || (state.httpMajorVersion == 1 && state.httpMinorVersion == 0) || header.value("connection").toLower() == "close") state.keepAlive = false; else state.keepAlive = true; qxt_d().sessionLock.unlock(); QxtWebRequestEvent* event = new QxtWebRequestEvent(sessionID, requestID, QUrl::fromEncoded(header.path().toUtf8())); qxt_d().eventLock.lock(); qxt_d().pendingRequests.insert(QPair<int,int>(sessionID, requestID), event); qxt_d().eventLock.unlock(); QTcpSocket* socket = qobject_cast<QTcpSocket*>(device); if (socket) { event->remoteAddress = socket->peerAddress(); #if defined(QT_SECURETRANSPORT) || !defined(QT_NO_OPENSSL) QSslSocket* sslSocket = qobject_cast<QSslSocket*>(socket); if(sslSocket) { event->isSecure = true; event->clientCertificate = sslSocket->peerCertificate(); } #endif } event->method = header.method(); event->cookies = cookies; event->url.setScheme("http"); if (event->url.host().isEmpty()) event->url.setHost(header.value("host")); if (event->url.port() == -1) event->url.setPort(port()); event->contentType = header.contentType(); event->content = content; typedef QPair<QString, QString> StringPair; foreach(const StringPair& line, header.values()) { if (line.first.toLower() == "cookie") continue; event->headers.insert(line.first, line.second); } event->headers.insert("X-Request-Protocol", "HTTP/" + QString::number(state.httpMajorVersion) + '.' + QString::number(state.httpMinorVersion)); if (sessionID && session(sessionID)) { QxtAbstractWebService *service = session(sessionID); if(content) content->setParent(service); // Set content ownership to the service service->pageRequestedEvent(event); } else if (qxt_d().staticService) { qxt_d().staticService->pageRequestedEvent(event); } else { postEvent(new QxtWebErrorEvent(0, requestID, 500, "Internal Configuration Error")); } }