/*!
  Loads a query from the given file \a filename.
*/
bool TSqlQuery::load(const QString &filename)
{
    QMutexLocker locker(&cacheMutex);

    QString query = queryCache.value(filename);
    if (!query.isEmpty()) {
        return QSqlQuery::prepare(query);
    }

    QDir dir(queryDirPath());
    QFile file(dir.filePath(filename));
    tSystemDebug("SQL_QUERY_ROOT: %s", qPrintable(dir.dirName()));
    tSystemDebug("filename: %s", qPrintable(file.fileName()));
    if (!file.open(QIODevice::ReadOnly)) {
        tSystemError("Unable to open file: %s", qPrintable(file.fileName()));
        return false;
    }

    query = QObject::tr(file.readAll().constData());
    bool res = QSqlQuery::prepare(query);
    if (res) {
        // Caches the query-string
        queryCache.insert(filename, query);
    }
    return res;
}
void ServerManager::startServer(int id) const
{
    QStringList args = QCoreApplication::arguments();
    args.removeFirst();

    if (id < 0) {
        id = startCounter;
    }

    TWebApplication::MultiProcessingModule mpm = Tf::app()->multiProcessingModule();
    if (mpm == TWebApplication::Hybrid || mpm == TWebApplication::Thread) {
        if (id < maxServers) {
            args.prepend(QString::number(id));
            args.prepend("-i");  // give ID for app server
        }
    }

    if (listeningSocket > 0) {
        args.prepend(QString::number(listeningSocket));
        args.prepend("-s");
    }

    QProcess *tfserver = new QProcess;
    serversStatus.insert(tfserver, id);

    connect(tfserver, SIGNAL(started()), this, SLOT(updateServerStatus()));
    connect(tfserver, SIGNAL(error(QProcess::ProcessError)), this, SLOT(errorDetect(QProcess::ProcessError)));
    connect(tfserver, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(serverFinish(int, QProcess::ExitStatus)));
    connect(tfserver, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError()));    // For error notification

#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
    // Sets LD_LIBRARY_PATH environment variable
    QString ldpath = ".";  // means the lib dir
    QString sysldpath = QProcess::systemEnvironment().filter("LD_LIBRARY_PATH=", Qt::CaseSensitive).value(0).mid(16);
    if (!sysldpath.isEmpty()) {
        ldpath += ":";
        ldpath += sysldpath;
    }

    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    env.insert("LD_LIBRARY_PATH", ldpath);
    tSystemDebug("export %s=%s", "LD_LIBRARY_PATH", qPrintable(ldpath));

    QString preload = Tf::appSettings()->value(Tf::LDPreload).toString();
    if (!preload.isEmpty()) {
        env.insert("LD_PRELOAD", preload);
        tSystemDebug("export %s=%s", "LD_PRELOAD", qPrintable(preload));
    }
    tfserver->setProcessEnvironment(env);
#endif

    // Executes treefrog server
    tfserver->start(TFSERVER_CMD, args, QIODevice::ReadOnly);
    tfserver->closeReadChannel(QProcess::StandardOutput);
    tfserver->closeWriteChannel();
    tSystemDebug("tfserver started");
    ++startCounter;
}
Exemple #3
0
void THttpRequest::parseBody(const QByteArray &body, const THttpRequestHeader &header)
{
    switch (method()) {
    case Tf::Post: {
        QString ctype = QString::fromLatin1(header.contentType().trimmed());
        if (ctype.startsWith("multipart/form-data", Qt::CaseInsensitive)) {
            // multipart/form-data
            d->multipartFormData = TMultipartFormData(body, boundary());
            d->formItems = d->multipartFormData.formItems();

        } else if (ctype.startsWith("application/json", Qt::CaseInsensitive)) {
#if QT_VERSION >= 0x050000
            d->jsonData = QJsonDocument::fromJson(body);
#else
            tSystemWarn("unsupported content-type: %s", qPrintable(ctype));
#endif
        } else {
            // 'application/x-www-form-urlencoded'
            if (!body.isEmpty()) {
                QList<QByteArray> formdata = body.split('&');
                for (QListIterator<QByteArray> i(formdata); i.hasNext(); ) {
                    QList<QByteArray> nameval = i.next().split('=');
                    if (!nameval.value(0).isEmpty()) {
                        // URL decode
                        QString key = THttpUtility::fromUrlEncoding(nameval.value(0));
                        QString val = THttpUtility::fromUrlEncoding(nameval.value(1));
                        d->formItems.insertMulti(key, val);
                        tSystemDebug("POST Hash << %s : %s", qPrintable(key), qPrintable(val));
                    }
                }
            }
        }
        /* FALL THROUGH */ }

    case Tf::Get: {
        // query parameter
        QList<QByteArray> data = d->header.path().split('?');
        QString getdata = data.value(1);
        if (!getdata.isEmpty()) {
            QStringList pairs = getdata.split('&', QString::SkipEmptyParts);
            for (QStringListIterator i(pairs); i.hasNext(); ) {
                QStringList s = i.next().split('=');
                if (!s.value(0).isEmpty()) {
                    QString key = THttpUtility::fromUrlEncoding(s.value(0).toLatin1());
                    QString val = THttpUtility::fromUrlEncoding(s.value(1).toLatin1());
                    d->queryItems.insertMulti(key, val);
                    tSystemDebug("GET Hash << %s : %s", qPrintable(key), qPrintable(val));
                }
            }
        }
        break; }

    default:
        // do nothing
        break;
    }
}
bool TApplicationServer::open()
{
    T_TRACEFUNC();

    if (!isListening()) {
        quint16 port = Tf::app()->treefrogSettings().value("ListenPort").toUInt();
        if (!nativeListen(QHostAddress::Any, port)) {
            tSystemError("listen failed.  port:%d", port);
            return false;
        } else {
            tSystemDebug("listen successfully.  port:%d", port);
        }
    }

    // Loads libraries
    if (!libLoaded) {

        // Sets work directory
        QString libPath = Tf::app()->libPath();
        if (QDir(libPath).exists()) {
            // To resolve the symbols in the app libraries
            QDir::setCurrent(libPath);
        } else {
            tSystemError("lib directory not found");
            return false;
        }
        
        QStringList filter;
#if defined(Q_OS_WIN)
        filter << "controller.dll" << "view.dll";
#elif defined(Q_OS_DARWIN)
        filter << "libcontroller.dylib" << "libview.dylib";
#elif defined(Q_OS_UNIX)
        filter << "libcontroller.so" << "libview.so";
#else
        filter << "libcontroller.*" << "libview.*";
#endif

        QDir controllerDir(".");
        QStringList list = controllerDir.entryList(filter, QDir::Files);
        for (QStringListIterator i(list); i.hasNext(); ) {
            QString path = controllerDir.absoluteFilePath(i.next());
            QLibrary lib(path);
            if (lib.load()) {
                tSystemDebug("Library loaded: %s", qPrintable(path));
                libLoaded = true;
            } else {
                tSystemDebug("%s", qPrintable(lib.errorString()));
            }
        }
    }

    TUrlRoute::initialize();
    TSqlDatabasePool::initialize();
    return true;
}
void TEpoll::dispatchSendData()
{
    TSendData *sd;
    while (sendRequests.dequeue(sd)) {
        TEpollSocket *sock = sd->socket;

        if (Q_UNLIKELY(sock->socketDescriptor() <= 0)) {
            tSystemDebug("already disconnected:  sid:%d", sock->socketId());
            continue;
        }

        switch (sd->method) {
        case TSendData::Disconnect:
            deletePoll(sock);
            sock->close();
            sock->deleteLater();
            break;

        case TSendData::SwitchToWebSocket: {
            tSystemDebug("Switch to WebSocket");
            Q_ASSERT(sd->buffer == nullptr);

            QByteArray secKey = sd->header.rawHeader("Sec-WebSocket-Key");
            tSystemDebug("secKey: %s", secKey.data());
            int newsocket = TApplicationServerBase::duplicateSocket(sock->socketDescriptor());

            // Switch to WebSocket
            TEpollWebSocket *ws = new TEpollWebSocket(newsocket, sock->peerAddress(), sd->header);
            ws->moveToThread(Tf::app()->thread());
            addPoll(ws, (EPOLLIN | EPOLLOUT | EPOLLET));  // reset

            // Stop polling and delete
            deletePoll(sock);
            sock->deleteLater();

            // WebSocket opening
            TSession session;
            QByteArray sessionId = sd->header.cookie(TSession::sessionName());
            if (!sessionId.isEmpty()) {
                // Finds a session
                session = TSessionManager::instance().findSession(sessionId);
            }
            ws->startWorkerForOpening(session);
            break; }

        default:
            tSystemError("Logic error [%s:%d]", __FILE__, __LINE__);
            if (sd->buffer) {
                delete sd->buffer;
            }
            break;
        }

        delete sd;
    }
}
bool TApplicationServerBase::loadLibraries()
{
    T_TRACEFUNC("");

    // Loads libraries
    if (libsLoaded.isEmpty()) {
        // Sets work directory
        QString libPath = Tf::app()->libPath();
        if (QDir(libPath).exists()) {
            // To resolve the symbols in the app libraries
            QDir::setCurrent(libPath);
        } else {
            tSystemError("lib directory not found");
            return false;
        }

        loadedTimestamp = latestLibraryTimestamp();

#if defined(Q_OS_WIN)
        QStringList libs = { "controller", "view" };
#elif defined(Q_OS_LINUX)
        QStringList libs = { "libcontroller.so", "libview.so" };
#elif defined(Q_OS_DARWIN)
        QStringList libs = { "libcontroller.dylib", "libview.dylib" };
#else
        QStringList libs = { "libcontroller.so", "libview.so" };
#endif

        for (const auto &libname : libs) {
            auto lib = new QLibrary(libname);
            if (lib->load()) {
                tSystemDebug("Library loaded: %s", qPrintable(lib->fileName()));
                libsLoaded << lib;
            } else {
                tSystemWarn("%s", qPrintable(lib->errorString()));
            }
        }

        QStringList controllers = TActionController::availableControllers();
        tSystemDebug("Available controllers: %s", qPrintable(controllers.join(" ")));
    }
    QDir::setCurrent(Tf::app()->webRootPath());

    TSystemBus::instantiate();
    TPublisher::instantiate();
    TUrlRoute::instantiate();
    TSqlDatabasePool::instantiate();
    TKvsDatabasePool::instantiate();
    return true;
}
void TBasicTimer::start()
{
    tSystemDebug("TBasicTimer::start");
    if (receiver_ && interval_ > 0) {
        QBasicTimer::start(interval_, receiver_);
    }
}
Exemple #8
0
bool TSqlObject::remove()
{
    syncToSqlRecord();
    QString del = TActionContext::currentDatabase().driver()->sqlStatement(QSqlDriver::DeleteStatement, tableName(), *static_cast<QSqlRecord *>(this), false);
    
    if (del.isEmpty()) {
        sqlError = QSqlError(QLatin1String("Unable to delete row"),
                             QString(), QSqlError::StatementError);
        return false;
    }

    del.append(" WHERE ");
    int revIndex = metaObject()->indexOfProperty(REVISION_PROPERTY_NAME);
    if (revIndex >= 0) {
        bool ok;
        int revsion = property(REVISION_PROPERTY_NAME).toInt(&ok);
        if (!ok || revsion <= 0) {
            sqlError = QSqlError(QLatin1String("Unable to convert the 'revision' property to an int"),
                                 QString(), QSqlError::UnknownError);
            tError("Unable to convert the 'revsion' property to an int, %s", qPrintable(objectName()));
            return false;
        }

        del.append(TSqlQuery::escapeIdentifier(REVISION_PROPERTY_NAME));
        del.append("=").append(TSqlQuery::formatValue(revsion));
        del.append(" AND ");
    }

    const char *pkName = metaObject()->property(metaObject()->propertyOffset() + primaryKeyIndex()).name();
    if (primaryKeyIndex() < 0 || !pkName) {
        QString msg = QString("Not found the primary key for table ") + tableName();
        sqlError = QSqlError(msg, QString(), QSqlError::StatementError);
        tError("%s", qPrintable(msg));
        return false;
    }
    del.append(TSqlQuery::escapeIdentifier(pkName));
    del.append("=").append(TSqlQuery::formatValue(property(pkName)));

    tSystemDebug("SQL statement: %s", qPrintable(del));
    QSqlQuery query(TActionContext::currentDatabase());
    bool res = query.exec(del);
    sqlError = query.lastError();
    if (!res) {
        tSystemError("SQL delete error: %s", qPrintable(sqlError.text()));
        return false;
    }
    
    // Optimistic lock check
    if (query.numRowsAffected() != 1) {
        if (revIndex >= 0) {
            QString msg = QString("Row was updated or deleted from table ") + tableName() + QLatin1String(" by another transaction");
            sqlError = QSqlError(msg, QString(), QSqlError::UnknownError);
            throw SqlException(msg, __FILE__, __LINE__);
        }
        tWarn("Row was deleted by another transaction, %s", qPrintable(tableName()));
    }

    clear();
    return true;
}
Exemple #9
0
bool TSqlObject::create()
{
    // Sets the default value of 'revision' property
    int index = metaObject()->indexOfProperty(REVISION_PROPERTY_NAME);
    if (index >= 0) {
        setProperty(REVISION_PROPERTY_NAME, 1);  // 1 : default value
    }

    // Sets the values of 'created_at' and 'updated_at' properties
    for (int i = metaObject()->propertyOffset(); i < metaObject()->propertyCount(); ++i) {
        const char *propName = metaObject()->property(i).name();
        if (QLatin1String("created_at") == propName
            || QLatin1String("updated_at") == propName) {
            setProperty(propName, QDateTime::currentDateTime());
        }
    }

    syncToSqlRecord();
    QString ins = TActionContext::currentDatabase().driver()->sqlStatement(QSqlDriver::InsertStatement, tableName(), *static_cast<QSqlRecord *>(this), false);
    if (ins.isEmpty()) {
        sqlError = QSqlError(QLatin1String("No fields to insert"),
                             QString(), QSqlError::StatementError);
        tWarn("SQL statement error, no fields to insert");
        return false;
    }

    tSystemDebug("SQL statement: %s", qPrintable(ins));
    QSqlQuery query(TActionContext::currentDatabase());
    bool res = query.exec(ins);
    sqlError = query.lastError();
    if (!res) {
        tSystemError("SQL insert error: %s", qPrintable(sqlError.text()));
    }
    return res;
}
bool TSessionRedisStore::store(TSession &session)
{
    QByteArray data;
    QDataStream ds(&data, QIODevice::WriteOnly);
    ds << *static_cast<const QVariantMap *>(&session);
    data = qCompress(data, 1).toBase64();

#ifndef TF_NO_DEBUG
    {
        QByteArray badummy;
        QDataStream dsdmy(&badummy, QIODevice::ReadWrite);
        dsdmy << *static_cast<const QVariantMap *>(&session);

        TSession dummy;
        dsdmy.device()->seek(0);
        dsdmy >> *static_cast<QVariantMap *>(&dummy);
        if (dsdmy.status() != QDataStream::Ok) {
            tSystemError("Failed to store a session into the cookie store. Must set objects that can be serialized.");
        }
    }
#endif

    TRedis redis;
    tSystemDebug("TSessionRedisStore::store  id:%s", session.id().data());
    return redis.setEx('_' + session.id(), data, lifeTimeSecs());
}
int TSmtpMailer::read(QList<QByteArray> *reply)
{
    if (reply)
        reply->clear();

    int code = 0;
    for (;;) {
        QByteArray rcv = socket->readLine().trimmed();
        if (rcv.isEmpty()) {
            if (socket->waitForReadyRead(5000)) {
                continue;
            } else {
                break;
            }
        }
        tSystemDebug("S: %s", rcv.data());

        if (code == 0)
            code = rcv.left(3).toInt();

        if (rcv.length() < 4)
            break;

        if (reply) {
            QByteArray ba = rcv.mid(4);
            if (!ba.isEmpty())
                *reply << ba;
        }

        if (code > 0 && rcv.at(3) == ' ')
            break;
    }
    return code;
}
bool TSendmailMailer::send()
{
    QMutexLocker locker(&sendMutex); // Global lock for load reduction of mail server
    if (sendmailCmd.isEmpty()) {
        return false;
    }

    QStringList args;
    QByteArray rawmail = mailMessage.toByteArray();
    const QList<QByteArray> recipients = mailMessage.recipients();

    for (auto &recipt : recipients) {
        args.clear();
        args << recipt;

        QProcess sendmail;
        sendmail.start(sendmailCmd, args);
        if (!sendmail.waitForStarted(5000)) {
            tSystemError("Sendmail error. CMD: %s", qPrintable(sendmailCmd));
            return false;
        }

        sendmail.write(rawmail);
        sendmail.write("\n.\n");
        sendmail.waitForFinished();
        tSystemDebug("Mail sent. Recipients: %s", recipt.data());
    }

    return true;
}
bool TSmtpMailer::cmdEhlo()
{
    QByteArray ehlo;
    ehlo.append("EHLO [");
    ehlo.append(qPrintable(socket->localAddress().toString()));
    ehlo.append("]");

    QList<QByteArray> reply;
    if (cmd(ehlo, &reply) != 250) {
        return false;
    }

    // Gets AUTH methods
    for (auto &s : (const QList<QByteArray>&)reply) {
        QString str(s);
        if (str.startsWith("AUTH ", Qt::CaseInsensitive)) {
            svrAuthMethods = str.mid(5).split(' ', QString::SkipEmptyParts);
            tSystemDebug("AUTH: %s", qPrintable(svrAuthMethods.join(",")));
        }
        if (str.startsWith("STARTTLS", Qt::CaseInsensitive)) {
            tlsAvailable = true;
        }
    }
    return true;
}
Exemple #14
0
void TApplicationServerBase::unloadLibraries()
{
    for (auto lib : libsLoaded) {
        lib->unload();
        tSystemDebug("Library unloaded: %s", qPrintable(lib->fileName()));
    }
    libsLoaded.clear();
}
void TApplicationScheduler::start(int msec)
{
    if (Tf::app()->applicationServerId() == 0) {
        // Starts where applicaraion server ID is 0
        TScheduler::start(msec);
        tSystemDebug("TApplicationScheduler::start msec:%d", msec);
    }
}
bool TUrlRoute::addRouteFromString(QString line)
{
    QStringList items = line.split(' ', QString::SkipEmptyParts);

    if (items.count() == 3) {
        // Trimm quotes
        QString method = items[0];
        QString route = THttpUtility::trimmedQuotes(items[1]);
        QString destination = THttpUtility::trimmedQuotes(items[2]);

        TRoute rt;

        rt.method = TRoute::methodFromString(method);

        if (rt.method == TRoute::Invalid)
        {
            tError("Invalid method, '%s'", qPrintable(items[0]));
            return false;
        }

        // parse controller and action
        QStringList list = destination.split('#');
        if (list.count() == 2) {
            rt.controller = list[0].toLower().toLatin1() + "controller";
            rt.action = list[1].toLatin1();
        } else {
            tError("Invalid destination, '%s'", qPrintable(destination));
            return false;
        }

        rt.components = route.split('/');
        if (route.startsWith('/')) rt.components.takeFirst();
        if (route.endsWith('/')) rt.components.takeLast();

        if (rt.components.indexOf(":params") >= 0)
        {
            if (rt.components.indexOf(":params") != rt.components.length() - 1)
            {
                tError("Invalid route: :params must be at the end! [%s]",qPrintable(route));
                return false;
            }
            else
            {
                rt.components.takeLast();
                rt.has_variable_params = 1;
            }
        }

        routes << rt;
        tSystemDebug("added route: method:%d components:%s ctrl:%s action:%s, params:%d",
                     rt.method, qPrintable(rt.components.join('/')), rt.controller.data(),
                     rt.action.data(), rt.has_variable_params);
        return true;
    } else {
        tError("Invalid directive, '%s'", qPrintable(line));
        return false;
    }
}
bool TUrlRoute::addRouteFromString(const QString &line)
{
     QStringList items = line.simplified().split(' ');
     if (items.count() != 3) {
         tError("Invalid directive, '%s'", qPrintable(line));
         return false;
     }

     // Trimm quotes
     items[1] = THttpUtility::trimmedQuotes(items[1]);
     items[2] = THttpUtility::trimmedQuotes(items[2]);
     QString &path = items[1];

     if (path.contains(":params") && !path.endsWith(":params")) {
         tError(":params must be specified as last directive.");
         return false;
     }

     TRoute rt;

     // Check method
     rt.method = directiveHash()->value(items[0].toLower(), TRoute::Invalid);
     if (rt.method == TRoute::Invalid) {
         tError("Invalid directive, '%s'", qPrintable(items[0]));
         return false;
     }

     // parse path
     rt.componentList = splitPath(path);
     rt.hasVariableParams = rt.componentList.contains(":params");

     for (int i = 0; i < rt.componentList.count(); ++i) {
         const QString &c = rt.componentList[i];
         if (c.startsWith(":")) {
             if (c != ":param" && c != ":params") {
                 return false;
             }
         } else {
             rt.keywordIndexes << i;
         }
     }

     // parse controller and action
     QStringList list = items[2].split('#');
     if (list.count() == 2) {
         rt.controller = list[0].toLower().toLatin1() + "controller";
         rt.action = list[1].toLatin1();
     } else {
         tError("Invalid action, '%s'", qPrintable(items[2]));
         return false;
     }

     routes << rt;
     tSystemDebug("route: method:%d path:%s  ctrl:%s action:%s params:%d",
                  rt.method, qPrintable(QLatin1String("/") + rt.componentList.join("/")), rt.controller.data(),
                  rt.action.data(), rt.hasVariableParams);
     return true;
}
void TApplicationServerBase::invokeStaticRelease()
{
    // Calls staticRelease()
    TDispatcher<TActionController> dispatcher("applicationcontroller");
    bool dispatched = dispatcher.invoke("staticRelease", QStringList(), Qt::DirectConnection);
    if (!dispatched) {
        tSystemDebug("No such method: staticRelease() of ApplicationController");
    }
}
Exemple #19
0
void TSharedMemoryLogStream::setNonBufferingMode()
{
    tSystemDebug("TSharedMemoryLogStream::setNonBufferingMode()");
    if (!isNonBufferingMode()) {
        flush();
        shareMem->detach();
    }
    TAbstractLogStream::setNonBufferingMode();
}
Exemple #20
0
void TAbstractWebSocket::renewKeepAlive()
{
    tSystemDebug("renewKeepAlive");
    QMutexLocker locker(&mutexData);

    if (keepAliveTimer) {
        QTimer::singleShot(0, keepAliveTimer, SLOT(start()));
    }
}
void TAbstractWebSocket::renewKeepAlive()
{
    tSystemDebug("renewKeepAlive");
    QMutexLocker locker(&mutexData);

    if (keepAliveTimer) {
        QMetaObject::invokeMethod(keepAliveTimer, "start", Qt::QueuedConnection);
    }
}
/*!
  Returns true if the user \a user is allowed to access to the requested
  action; otherwise returns false.
*/
bool TAccessValidator::validate(const TAbstractUser *user) const
{
    bool ret = allowDefault;
    const TActionController *controller = Tf::currentContext()->currentController();
    Q_ASSERT(controller);

    if (accessRules.isEmpty()) {
        tWarn("No rule for access validation: %s", qPrintable(controller->className()));
        return ret;
    }

    if (!user || user->identityKey().isEmpty()) {
        // Searches a access rule for an unauthenticated user
        for (const auto &rule : accessRules) {
            if (rule.type == AccessRule::UnauthenticatedUser
                && rule.action == controller->activeAction()) {
                ret = rule.allow;
                break;
            }
        }
        if (ret) {
            tSystemDebug("Access '%s' action by an unauthenticated user : Allow", qPrintable(controller->activeAction()));
        } else {
            tSystemWarn("Access '%s' action by an unauthenticated user : Deny", qPrintable(controller->activeAction()));
        }

    } else {
        for (const auto &rule : accessRules) {
            if (rule.action == controller->activeAction()
                && ((rule.type == AccessRule::User && rule.key == user->identityKey())
                    || (!user->groupKey().isEmpty() && rule.key == user->groupKey()))) {
                ret = rule.allow;
                break;
            }
        }
        if (ret) {
            tSystemDebug("Access '%s' action by '%s' user : Allow", qPrintable(controller->activeAction()), qPrintable(user->identityKey()));
        } else {
            tSystemWarn("Access '%s' action by '%s' user : Deny", qPrintable(controller->activeAction()), qPrintable(user->identityKey()));
        }
    }

    return ret;
}
bool TMongoDriver::open(const QString &db, const QString &user, const QString &password, const QString &host, quint16 port, const QString &)
{
    if (host.isEmpty()) {
        return false;
    }

    if (!port)
        port = MONGO_DEFAULT_PORT;

    mongo_clear_errors(mongoConnection);
    mongo_set_op_timeout(mongoConnection, 1000);
    int status = mongo_client(mongoConnection, qPrintable(host), port);

    if (status != MONGO_OK) {
        switch (mongoConnection->err) {
        case MONGO_CONN_NO_SOCKET:
            tSystemError("MongoDB socket error: %s", mongoConnection->lasterrstr);
            break;

        case MONGO_CONN_FAIL:
            tSystemError("MongoDB connection failed: %s", mongoConnection->lasterrstr);
            break;

        case MONGO_CONN_NOT_MASTER:
            tSystemDebug("MongoDB not master: %s", mongoConnection->lasterrstr);
            break;

        default:
            tSystemError("MongoDB error: %s", mongoConnection->lasterrstr);
            break;
        }
        return false;
    }

    if (!user.isEmpty()) {
        status = mongo_cmd_authenticate(mongoConnection, qPrintable(db), qPrintable(user), qPrintable(password));
        if (status != MONGO_OK) {
            tSystemDebug("MongoDB authentication error: %s", mongoConnection->lasterrstr);
            return false;
        }
    }

    return (status == MONGO_OK);
}
void TEpollHttpSocket::startWorker()
{
    tSystemDebug("TEpollHttpSocket::startWorker");

    TActionWorker *worker = new TActionWorker(this);
    worker->moveToThread(Tf::app()->thread());
    connect(worker, SIGNAL(finished()), this, SLOT(releaseWorker()));
    ++myWorkerCounter; // count-up
    worker->start();
}
/*!
  \~english
  Renders the \a view view.

  \~japanese
  ビューを描画する
*/
QByteArray TActionController::renderView(TActionView *view)
{
    T_TRACEFUNC("view: %p  layout: %s", view, qPrintable(layout()));

    if (!view) {
        tSystemError("view null pointer.  action:%s", qPrintable(activeAction()));
        return QByteArray();
    }
    view->setController(this);
    view->setVariantHash(allVariants());

    if (!layoutEnabled()) {
        // Renders without layout
        tSystemDebug("Renders without layout");
        return Tf::app()->codecForHttpOutput()->fromUnicode(view->toString());
    }
  
    // Displays with layout
    QString lay = (layout().isNull()) ? name().toLower() : layout().toLower();
    TDispatcher<TActionView> layoutDispatcher(layoutClassName(lay));
    TActionView *layoutView = layoutDispatcher.object();

    TDispatcher<TActionView> defLayoutDispatcher(layoutClassName("application"));
    if (!layoutView) {
        if (!layout().isNull()) {
            tSystemDebug("Not found layout: %s", qPrintable(layout()));
            return QByteArray();
        } else {
            // Use default layout
            layoutView = defLayoutDispatcher.object();
            if (!layoutView) {
                tSystemDebug("Not found default layout. Renders without layout.");
                return Tf::app()->codecForHttpOutput()->fromUnicode(view->toString());
            }
        }
    }

    // Renders layout
    layoutView->setVariantHash(allVariants());
    layoutView->setController(this);
    layoutView->setSubActionView(view);
    return Tf::app()->codecForHttpOutput()->fromUnicode(layoutView->toString());
}
int TMultiplexingServer::epollDel(int fd)
{
    int ret = tf_epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, NULL);
    int err = errno;
    if (ret < 0 && err != ENOENT) {
        tSystemError("Failed epoll_ctl (EPOLL_CTL_DEL)  fd:%d errno:%d", fd, errno);
        epollClose(fd);
    } else {
        tSystemDebug("OK epoll_ctl (EPOLL_CTL_DEL)  fd:%d", fd);
    }
    return ret;
}
Exemple #27
0
TThreadApplicationServer::TThreadApplicationServer(int listeningSocket, QObject *parent)
    : QTcpServer(parent), TApplicationServerBase(), listenSocket(listeningSocket), maxThreads(0), reloadTimer()
{
    QString mpm = Tf::appSettings()->value(Tf::MultiProcessingModule).toString().toLower();
    maxThreads = Tf::appSettings()->readValue(QLatin1String("MPM.") + mpm + ".MaxThreadsPerAppServer").toInt();
    if (maxThreads == 0) {
        maxThreads = Tf::appSettings()->readValue(QLatin1String("MPM.") + mpm + ".MaxServers", "128").toInt();
    }
    tSystemDebug("MaxThreads: %d", maxThreads);

    Q_ASSERT(Tf::app()->multiProcessingModule() == TWebApplication::Thread);
}
bool TSmtpMailer::write(const QByteArray &command)
{
    QByteArray cmd = command;
    if (!cmd.endsWith(CRLF)) {
        cmd += CRLF;
    }

    int len = socket->write(cmd);
    socket->flush();
    tSystemDebug("C: %s", cmd.trimmed().data());
    return (len == cmd.length());
}
void TEpollHttpSocket::parse()
{
    if (Q_UNLIKELY(limitBodyBytes < 0)) {
        limitBodyBytes = Tf::appSettings()->value(Tf::LimitRequestBody, "0").toInt();
    }

    if (Q_LIKELY(lengthToRead < 0)) {
        int idx = httpBuffer.indexOf("\r\n\r\n");
        if (idx > 0) {
            THttpRequestHeader header(httpBuffer);
            tSystemDebug("content-length: %d", header.contentLength());

            if (limitBodyBytes > 0 && header.contentLength() > (uint)limitBodyBytes) {
                throw ClientErrorException(413);  // Request Entity Too Large
            }

            lengthToRead = qMax(idx + 4 + (qint64)header.contentLength() - httpBuffer.length(), 0LL);
            tSystemDebug("lengthToRead: %d", (int)lengthToRead);
        }
    } else {
        tSystemWarn("Unreachable code in normal communication");
    }
}
void TActionForkProcess::start()
{
    if (currentActionContext)
        return;

    currentActionContext = this;
    std::cerr << "_accepted" << std::flush;  // send to tfmanager

    QList<THttpRequest> reqs;
    QEventLoop eventLoop;
    httpSocket = new THttpSocket;

    if (!httpSocket->setSocketDescriptor(TActionContext::socketDesc)) {
        emitError(httpSocket->error());
        goto socket_error;
    }
    TActionContext::socketDesc = 0;

    for (;;) {
        reqs = TActionThread::readRequest(httpSocket);
        tSystemDebug("HTTP request count: %d", reqs.count());

        if (reqs.isEmpty()) {
            break;
        }

        for (QMutableListIterator<THttpRequest> it(reqs); it.hasNext(); ) {
            THttpRequest &req = it.next();
            TActionContext::execute(req);

            httpSocket->flush();  // Flush socket
            TActionContext::release();
        }

        if (!httpSocket->waitForReadyRead(5000))
            break;
    }

    closeHttpSocket();  // disconnect

    // For cleanup
    while (eventLoop.processEvents()) {}

    emit finished();
    QCoreApplication::exit(1);

socket_error:
    delete httpSocket;
    httpSocket = 0;
}