File indexing completed on 2024-04-28 16:01:25

0001 /** ===========================================================
0002  * @file
0003  *
0004  * This file is a part of KDE project
0005  * <a href="https://commits.kde.org/libmediawiki">libmediawiki</a>
0006  *
0007  * @date   2010-03-22
0008  * @brief  a MediaWiki C++ interface for KDE
0009  *
0010  * @author Copyright (C) 2010-2011 by Hormiere Guillaume
0011  *         <a href="mailto:hormiere dot guillaume at gmail dot com">hormiere dot guillaume at gmail dot com</a>
0012  *
0013  * This program is free software; you can redistribute it
0014  * and/or modify it under the terms of the GNU General
0015  * Public License as published by the Free Software Foundation;
0016  * either version 2, or (at your option)
0017  * any later version.
0018  *
0019  * This program is distributed in the hope that it will be useful,
0020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0022  * GNU General Public License for more details.
0023  *
0024  * ============================================================ */
0025 
0026 #include "fakeserver.h"
0027 
0028 #include <iostream>
0029 
0030 #include <QFile>
0031 
0032 FakeServer::FakeServer(QObject* const parent)
0033 :  QThread( parent )
0034 {
0035     m_clientSocket = nullptr;
0036     m_tcpServer    = nullptr;
0037 
0038     moveToThread(this);
0039 }
0040 
0041 FakeServer::~FakeServer()
0042 {
0043     quit();
0044     wait();
0045 }
0046 
0047 void FakeServer::startAndWait()
0048 {
0049     start();
0050     // this will block until the event queue starts
0051     QMetaObject::invokeMethod( this, "started", Qt::BlockingQueuedConnection );
0052 }
0053 
0054 void FakeServer::newConnection()
0055 {
0056     QMutexLocker locker(&m_mutex);
0057     m_clientSocket = m_tcpServer->nextPendingConnection();
0058 
0059     connect(m_clientSocket, SIGNAL(readyRead()),
0060             this, SLOT(dataAvailable()));
0061 }
0062 
0063 void FakeServer::dataAvailable()
0064 {
0065     QMutexLocker locker(&m_mutex);
0066 
0067     if (m_clientSocket->canReadLine())
0068     {
0069         QStringList token = QString::fromUtf8(m_clientSocket->readAll()).split(QRegExp(QStringLiteral("[ \r\n][ \r\n]*")));
0070 
0071         if (!token.empty())
0072         {
0073             FakeServer::Request request;
0074             request.type  = token[0];
0075             request.agent = token[4];
0076             request.value = token[1];
0077 
0078             // It might happen that the same request cames through more than once, so you need to check that you are
0079             // counting each different request only once.
0080             //
0081             // For more information, see: http://qt-project.org/forums/viewthread/25521
0082             //
0083             if (!m_request.contains(request))
0084             {
0085                 m_request << request;
0086 
0087                 QString retour   = m_scenarios.isEmpty() ? QStringLiteral("empty") : m_scenarios.takeFirst();
0088                 QString cookie   = m_cookie.isEmpty()    ? QStringLiteral("empty") : m_cookie.takeFirst();
0089                 QString scenario = QStringLiteral("HTTP/1.0 200 Ok\r\nContent-Type: text/html; charset=\"utf-8\"\r\nSet-Cookie:") + cookie + QStringLiteral("\r\n\r\n") + retour;
0090                 m_clientSocket->write(scenario.toLocal8Bit());
0091             }
0092         }
0093     }
0094 
0095     m_clientSocket->close();
0096 }
0097 
0098 void FakeServer::run()
0099 {
0100     m_tcpServer = new QTcpServer();
0101 
0102     if ( !m_tcpServer->listen( QHostAddress( QHostAddress::LocalHost ), 12566 ) )
0103     {
0104     }
0105 
0106     connect(m_tcpServer, SIGNAL(newConnection()),
0107             this, SLOT(newConnection()));
0108 
0109     exec();
0110 
0111     delete m_clientSocket;
0112     delete m_tcpServer;
0113 }
0114 
0115 void FakeServer::started()
0116 {
0117   // do nothing: this is a dummy slot used by startAndWait()
0118 }
0119 
0120 void FakeServer::setScenario(const QString& scenario, const QString& cookie)
0121 {
0122     QMutexLocker locker(&m_mutex);
0123 
0124     m_scenarios.clear();
0125     m_scenarios << scenario;
0126     m_cookie.clear();
0127     m_cookie << cookie;
0128     m_request.clear();
0129 }
0130 
0131 void FakeServer::addScenario(const QString& scenario, const QString& cookie )
0132 {
0133     QMutexLocker locker(&m_mutex);
0134 
0135     m_scenarios << scenario;
0136     m_cookie << cookie;
0137 }
0138 
0139 void FakeServer::addScenarioFromFile(const QString& fileName, const QString& cookie )
0140 {
0141     QFile file( fileName );
0142 
0143     if (!file.open( QFile::ReadOnly ))
0144     {
0145         return;
0146     }
0147 
0148     QTextStream in(&file);
0149     QString scenario;
0150 
0151     // When loading from files we never have the authentication phase
0152     // force jumping directly to authenticated state.
0153 
0154     while ( !in.atEnd() )
0155     {
0156             scenario.append( in.readLine() );
0157     }
0158 
0159     file.close();
0160 
0161     addScenario( scenario , cookie);
0162 }
0163 
0164 bool FakeServer::isScenarioDone( int scenarioNumber ) const
0165 {
0166     QMutexLocker locker(&m_mutex);
0167 
0168     if ( scenarioNumber < m_scenarios.size() )
0169     {
0170             return m_scenarios[scenarioNumber].isEmpty();
0171     }
0172     else
0173     {
0174             return true; // Non existent hence empty, right?
0175     }
0176 }
0177 
0178 bool FakeServer::isAllScenarioDone() const
0179 {
0180     QMutexLocker locker( &m_mutex );
0181 
0182     foreach( const QString& scenario, m_scenarios )
0183     {
0184         if ( !scenario.isEmpty() )
0185         {
0186             return false;
0187         }
0188     }
0189 
0190     return true;
0191 }