Beispiel #1
0
	void HttpServer::handlePost(HttpClientHandler* hdlr,const QHttpRequestHeader & hdr,const QByteArray & data)
	{
		Out(SYS_WEB|LOG_DEBUG) << "POST " << hdr.path() << endl;
		KUrl url;
		url.setEncodedPathAndQuery(hdr.path());
		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->post(hdlr,hdr,data);
			}
		}
		else
		{
			KUrl url;
			url.setEncodedPathAndQuery(hdr.path());
			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);
		}
	}
Beispiel #2
0
	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);
		}
	}
Beispiel #3
0
	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);
		}
	}
/*---------------------------------------------------------------------------*/
QVariant HttpRecognizer::comment( IConnection* connection )
{
	Q_ASSERT (connection);
	if (!mConnections.contains( connection->networkInfo() ))
		return "No comment yet";

	const HttpConnection con = mConnections.value( connection->networkInfo() );
	const QHttpRequestHeader request = con.lastRequestHeader();
	const QHttpResponseHeader response = con.lastResponseHeader();

	return request.method() + " " + request.value( "host" ) + request.path()
		+ (response.isValid() ? "\nHTTP " + QString::number( response.statusCode() ) + " " + response.reasonPhrase() : "" );
}
Beispiel #5
0
    void TorrentPostHandler::post(HttpClientHandler* hdlr, const QHttpRequestHeader& hdr, const QByteArray& data)
    {
        const char* ptr = data.data();
        int len = data.size();
        int pos = QString(data).indexOf("\r\n\r\n");

        if (pos == -1 || pos + 4 >= len)
        {
            HttpResponseHeader rhdr(500);
            server->setDefaultResponseHeaders(rhdr, "text/html", false);
            hdlr->send500(rhdr, i18n("Invalid data received"));
            return;
        }

        // save torrent to a temporary file
        QString save_file = kt::DataDir() + "webgui_load_torrent";
        QFile tmp_file(save_file);

        if (!tmp_file.open(QIODevice::WriteOnly))
        {
            HttpResponseHeader rhdr(500);
            server->setDefaultResponseHeaders(rhdr, "text/html", false);
            hdlr->send500(rhdr, i18n("Failed to open temporary file"));
            return;
        }

        QDataStream out(&tmp_file);
        out.writeRawData(ptr + (pos + 4), len - (pos + 4));
        tmp_file.close();

        Out(SYS_WEB | LOG_NOTICE) << "Loading file " << save_file << endl;
        core->loadSilently(KUrl(save_file), QString());

        KUrl url;
        url.setEncodedPathAndQuery(hdr.path());
        QString page = url.queryItem("page");
        // there needs to be a page to send back
        if (page.isEmpty())
        {
            server->redirectToLoginPage(hdlr);
        }
        else
        {
            // redirect to page mentioned in page parameter
            HttpResponseHeader rhdr(301);
            server->setDefaultResponseHeaders(rhdr, "text/html", true);
            rhdr.setValue("Location", "/" + page);
            hdlr->send(rhdr, QByteArray());
        }
    }
Beispiel #6
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);
		}
	}
Beispiel #7
0
void MainWidget::request( QTcpSocket *id,
                          const QHttpRequestHeader &header )
{
   mpMessageBuffer->addItem( header.toString() );
   while( mpMessageBuffer->count() > 200 )
   {
      QListWidgetItem *item = mpMessageBuffer->takeItem( 0 );
      if( item )
      {
         delete item;
      }
   }
   mpMessageBuffer->scrollToBottom();

#if 0
   if( header.path() == "/favicon.ico" )
   {
      QFile file( ":/favicon.ico" );
      file.open( QIODevice::ReadOnly | QIODevice::Text );
      emit response( id,
                     QHttpResponseHeader( 200, "OK" ),
                     file.readAll() );
      file.close();
      return;
   }
#endif
   if( header.path() == "/wait" )
   {
      mDelayList.append( id );
      return;
   }
   if( header.path() == "/get" )
   {
      QString reply( "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
                     "<response>\n"
                     " <reply>%1</reply>\n"
                     " <artist>%2</artist>\n"
                     " <title>%3</title>\n"
                     " <album>%4</album>\n"
                     " <track>%5</track>\n"
                     "</response>\n" );
      QByteArray replyMsg( reply.arg( Qt::escape( QString::fromUtf8(mMsg.constData()) ),
                                      Qt::escape( mTrackInfo.mArtist ),
                                      Qt::escape( mTrackInfo.mTitle ),
                                      Qt::escape( mTrackInfo.mAlbum ),
                                      QString::number(mTrackInfo.mTrackNr) ).toUtf8() );
      emit response( id,
                     QHttpResponseHeader( 200, "OK XML" ),
                     replyMsg );
      return;
   }
   QString html("<html>\n<head>\n<title>%1</title>\n"
         "<meta http-equiv='content-type' content='text/html; charset=UTF-8'>\n"
         "<link rel='shortcut icon' href='/favicon.ico' type='image/x-icon'>\n"
         "<script src='ajax.js' type='text/javascript'>\n"
         "</script>\n"
         "</head>\n<body>\n"
         "<h1>%2</h1>\n"
         "<p>HTTP Request: %3 %4</p>\n"
         "<table border='1'>\n"
         "<tr valign='top'><td>Artist:</td><td><textarea cols='80' rows='1' name='artist' wrap='off' readonly></textarea></td></tr>\n"
         "<tr valign='top'><td>Title:</td><td><textarea cols='80' rows='1' name='title' wrap='off' readonly></textarea></td></tr>\n"
         "<tr valign='top'><td>Album:</td><td><textarea cols='80' rows='1' name='album' wrap='off' readonly></textarea></td></tr>\n"
         "<tr valign='top'><td>Track:</td><td><textarea cols='80' rows='1' name='track' wrap='off' readonly></textarea></td></tr>\n"
         "<tr valign='top'><td>Reply:</td><td><textarea cols='80' rows='5' name='reply' wrap='off' readonly></textarea></td></tr>\n"
         "<tr valign='top'><td>Status:</td><td><input name='status' size='12' readonly>"
         "<input type='button' value='refresh' onclick='loadFields();'></td></tr>\n"
         "</table></body></html>\n"
         );
   html = html.arg( QApplication::organizationName() + ": " + QApplication::applicationName(),
                    QApplication::organizationName() + ": " + QApplication::applicationName(),
                    header.method(),
                    header.path() );

   emit response( id,
                  QHttpResponseHeader( 200, "OK" ),
                  html.toUtf8() );
}
/*!
 * 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"));
    }
}
Beispiel #9
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;
    }
}