Пример #1
0
	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);
		}
	}
Пример #2
0
	bool HttpServer::checkSession(const QHttpRequestHeader & hdr)
	{
		// check session in cookie
		int session_id = 0;
		if (hdr.hasKey("Cookie"))
		{
			QString cookie = hdr.value("Cookie");
			int idx = cookie.find("KT_SESSID=");
			if (idx == -1)
				return false;
			
			QString number;
			idx += QString("KT_SESSID=").length();
			while (idx < cookie.length())
			{
				if (cookie[idx] >= '0' && cookie[idx] <= '9')
					number += cookie[idx];
				else
					break;
				
				idx++;
			}
					
			session_id = number.toInt();
		}
		
	
		if (session_id == session.sessionId)
		{
			// check if the session hasn't expired yet
			if(session.last_access.secsTo(QTime::currentTime())<WebInterfacePluginSettings::sessionTTL())
			{
				session.last_access=QTime::currentTime();
			}
			else
			{
				return false;
			}
		}
		else
			return false;

		return true;
	}
Пример #3
0
	bool HttpServer::checkSession(const QHttpRequestHeader & hdr)
	{
		// check session in cookie
		int session_id = 0;
		if (hdr.hasKey("Cookie"))
		{
			QString cookie = hdr.value("Cookie");
			QRegExp rx("KT_SESSID=(\\d+)",Qt::CaseInsensitive);
			int pos = 0;
			
			while ((pos = rx.indexIn(cookie, pos)) != -1) 
			{
				session_id = rx.cap(1).toInt();
				if (session_id == session.sessionId)
					break;
				pos += rx.matchedLength();
			}
		}
		
	
		if (session_id == session.sessionId)
		{
			// check if the session hasn't expired yet
			if(session.last_access.secsTo(QTime::currentTime())<WebInterfacePluginSettings::sessionTTL())
			{
				session.last_access=QTime::currentTime();
			}
			else
			{
				return false;
			}
		}
		else
			return false;

		return true;
	}
Пример #4
0
	void HttpServer::handleGet(HttpClientHandler* hdlr,const QHttpRequestHeader & hdr,bool do_not_check_session)
	{
		QString file = hdr.path();
		if (file == "/")
			file = "/login.html";
		
		//Out(SYS_WEB|LOG_DEBUG) << "GET " << hdr.path() << endl;
		
		KURL url;
		url.setEncodedPathAndQuery(file);
		
		QString path = rootDir + bt::DirSeparator() + WebInterfacePluginSettings::skin() + url.path();
		// first check if the file exists (if not send 404)
		if (!bt::Exists(path))
		{
			HttpResponseHeader rhdr(404);
			setDefaultResponseHeaders(rhdr,"text/html",false);
			hdlr->send404(rhdr,path);
			return;
		}
		
		QFileInfo fi(path);
		QString ext = fi.extension();
		
		// if it is the login page send that
		if (file == "/login.html" || file == "/")
		{
			session.logged_in = false;
			ext = "html";
			path = rootDir + bt::DirSeparator() + WebInterfacePluginSettings::skin() + "/login.html"; 
		}
		else if (!session.logged_in && (ext == "html" || ext == "php"))
		{
			// for any html or php page, a login is necessary
			redirectToLoginPage(hdlr);
			return;
		}
		else if (session.logged_in && !do_not_check_session && (ext == "html" || ext == "php"))
		{
			// if we are logged in and it's a html or php page, check the session id
			if (!checkSession(hdr))
			{
				session.logged_in = false;
				// redirect to login page
				redirectToLoginPage(hdlr);
				return;
			}
		}
		
		if (ext == "html")
		{
			HttpResponseHeader rhdr(200);
			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);
				setDefaultResponseHeaders(nhdr,"text/html",false);
				hdlr->send404(nhdr,path);
			}
		}
		else if (ext == "css" || ext == "js" || ext == "png" || ext == "ico" || ext == "gif" || ext == "jpg")
		{
			if (hdr.hasKey("If-Modified-Since"))
			{
				QDateTime dt = parseDate(hdr.value("If-Modified-Since"));
				if (dt.isValid() && dt < fi.lastModified())
				{	
					HttpResponseHeader rhdr(304);
					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(Qt::UTC).addSecs(3600),false));
					hdlr->sendResponse(rhdr);
					return;
				}
			}
			
			
			HttpResponseHeader rhdr(200);
			setDefaultResponseHeaders(rhdr,ExtensionToContentType(ext),true);
			rhdr.setValue("Last-Modified",DateTimeToString(fi.lastModified(),false));
			rhdr.setValue("Expires",DateTimeToString(QDateTime::currentDateTime(Qt::UTC).addSecs(3600),false));
			rhdr.setValue("Cache-Control","private");
			if (!hdlr->sendFile(rhdr,path))
			{
				HttpResponseHeader nhdr(404);
				setDefaultResponseHeaders(nhdr,"text/html",false);
				hdlr->send404(nhdr,path);
			}
		}
		else if (ext == "php")
		{
			bool redirect = false;
			bool shutdown = false;
			if (url.queryItems().count() > 0 && session.logged_in)
				redirect = php_i->exec(url,shutdown);
			
			if (shutdown)
			{
				// first send back login page
				redirectToLoginPage(hdlr);
				QTimer::singleShot(1000,kapp,SLOT(quit()));
			}
			else if (redirect)
			{
				HttpResponseHeader rhdr(301);
				setDefaultResponseHeaders(rhdr,"text/html",true);
				rhdr.setValue("Location",url.encodedPathAndQuery());
				
				hdlr->executePHPScript(php_i,rhdr,WebInterfacePluginSettings::phpExecutablePath(),
									   path,url.queryItems());
			}
			else
			{
				HttpResponseHeader rhdr(200);
				setDefaultResponseHeaders(rhdr,"text/html",true);
			
				hdlr->executePHPScript(php_i,rhdr,WebInterfacePluginSettings::phpExecutablePath(),
								   path,url.queryItems());
			}
		}
		else
		{
			HttpResponseHeader rhdr(404);
			setDefaultResponseHeaders(rhdr,"text/html",false);
			hdlr->send404(rhdr,path);
		}
	}
Пример #5
0
void InspectorServerRequestHandlerQt::tcpReadyRead()
{
    QHttpRequestHeader header;
    bool isWebSocket = false;
    if (!m_tcpConnection)
        return;

    if (!m_endOfHeaders) {
        while (m_tcpConnection->bytesAvailable() && !m_endOfHeaders) {
            QByteArray line = m_tcpConnection->readLine();
            m_data.append(line);
            if (line == "\r\n")
                m_endOfHeaders = true;
        }
        if (m_endOfHeaders) {
            header = QHttpRequestHeader(QString::fromLatin1(m_data));
            if (header.isValid()) {
                m_path = header.path();
                m_contentType = header.contentType().toLatin1();
                m_contentLength = header.contentLength();
                if (header.hasKey("Upgrade") && (header.value("Upgrade") == QLatin1String("WebSocket")))
                    isWebSocket = true;

                m_data.clear();
            }
        }
    }

    if (m_endOfHeaders) {
        QStringList pathAndQuery = m_path.split("?");
        m_path = pathAndQuery[0];
        QStringList words = m_path.split(QString::fromLatin1("/"));

        if (isWebSocket) {
            // switch to websocket-style WebSocketService messaging
            if (m_tcpConnection) {
                m_tcpConnection->disconnect(SIGNAL(readyRead()));
                connect(m_tcpConnection, SIGNAL(readyRead()), SLOT(webSocketReadyRead()));

                QByteArray key3 = m_tcpConnection->read(8);

                quint32 number1 = parseWebSocketChallengeNumber(header.value("Sec-WebSocket-Key1"));
                quint32 number2 = parseWebSocketChallengeNumber(header.value("Sec-WebSocket-Key2"));

                char responseData[16];
                generateWebSocketChallengeResponse(number1, number2, (unsigned char*)key3.data(), (unsigned char*)responseData);
                QByteArray response(responseData, sizeof(responseData));

                QHttpResponseHeader responseHeader(101, "WebSocket Protocol Handshake", 1, 1);
                responseHeader.setValue("Upgrade", header.value("Upgrade"));
                responseHeader.setValue("Connection", header.value("Connection"));
                responseHeader.setValue("Sec-WebSocket-Origin", header.value("Origin"));
                responseHeader.setValue("Sec-WebSocket-Location", ("ws://" + header.value("Host") + m_path));
                responseHeader.setContentLength(response.size());
                m_tcpConnection->write(responseHeader.toString().toLatin1());
                m_tcpConnection->write(response);
                m_tcpConnection->flush();

                if ((words.size() == 4)
                        && (words[1] == QString::fromLatin1("devtools"))
                        && (words[2] == QString::fromLatin1("page"))) {
                    int pageNum = words[3].toInt();

                    m_inspectorClient = m_server->inspectorClientForPage(pageNum);
                    // Attach remoteFrontendChannel to inspector, also transferring ownership.
                    if (m_inspectorClient)
                        m_inspectorClient->attachAndReplaceRemoteFrontend(new RemoteFrontendChannel(this));
                }

            }

            return;
        }
        if (m_contentLength && (m_tcpConnection->bytesAvailable() < m_contentLength))
            return;

        QByteArray content = m_tcpConnection->read(m_contentLength);
        m_endOfHeaders = false;

        QByteArray response;
        int code = 200;
        QString text = QString::fromLatin1("OK");

        // If no path is specified, generate an index page.
        if ((m_path == "") || (m_path == "/")) {
            QString indexHtml = "<html><head><title>Remote Web Inspector</title></head><body><ul>\n";
            for (QMap<int, InspectorClientQt* >::const_iterator it = m_server->m_inspectorClients.begin();
                    it != m_server->m_inspectorClients.end();
                    ++it) {
                indexHtml.append(QString("<li><a href=\"/webkit/inspector/inspector.html?page=%1\">%2</li>\n")
                                 .arg(it.key())
                                 .arg(it.value()->m_inspectedWebPage->mainFrame()->url().toString()));
            }
            indexHtml.append("</ul></body></html>");
            response = indexHtml.toLatin1();
        } else {
            QString path = QString(":%1").arg(m_path);
            QFile file(path);
            // It seems that there should be an enum or define for these status codes somewhere in Qt or WebKit,
            // but grep fails to turn one up.
            // QNetwork uses the numeric values directly.
            if (file.exists()) {
                file.open(QIODevice::ReadOnly);
                response = file.readAll();
            } else {
                code = 404;
                text = QString::fromLatin1("Not OK");
            }
        }

        QHttpResponseHeader responseHeader(code, text, 1, 0);
        responseHeader.setContentLength(response.size());
        if (!m_contentType.isEmpty())
            responseHeader.setContentType(QString::fromLatin1(m_contentType));

        QByteArray asciiHeader = responseHeader.toString().toAscii();
        m_tcpConnection->write(asciiHeader);

        m_tcpConnection->write(response);
        m_tcpConnection->flush();
        m_tcpConnection->close();

        return;
    }
}