<commit_before>/* Copyright (c) 2010-2012, <NAME>
 * All rights reserved.
 *
 * This software may be used and distributed according to the terms of
 * the New BSD License, which is incorporated herein by reference.
 */

#include <QtCore>
#include <QSqlDatabase>
#include <QSqlDriver>
#include <QHostAddress>
#include <TActionContext>
#include <TWebApplication>
#include <THttpRequest>
#include <THttpResponse>
#include <THttpUtility>
#include <TDispatcher>
#include <TActionController>
#include <TSqlDatabasePool>
#include <TSessionStore>
#include "tsystemglobal.h"
#include "thttpsocket.h"
#include "tsessionmanager.h"
#include "turlroute.h"
#include "taccesslog.h"
#ifdef Q_OS_UNIX
# include "tfcore_unix.h"
#endif

#define AUTO_ID_REGENERATION  "Session.AutoIdRegeneration"
#define DIRECT_VIEW_RENDER_MODE  "DirectViewRenderMode"
#define ENABLE_CSRF_PROTECTION_MODULE "EnableCsrfProtectionModule"
#define SESSION_COOKIE_PATH  "Session.CookiePath"
#define LISTEN_PORT  "ListenPort"

/*!
  \class TActionContext
  \brief The TActionContext class is the base class of contexts for
  action controllers.
*/


TActionContext::TActionContext(int socket)
    : sqlDatabases(Tf::app()->databaseSettingsCount() + 1), stopped(false), socketDesc(socket), httpSocket(0), currController(0)
{ }


TActionContext::~TActionContext()
{
    if (httpSocket)
        delete httpSocket;

    if (socketDesc > 0)
        TF_CLOSE(socketDesc);
    
    // Releases all database sessions
    TActionContext::releaseDatabases();
    
    for (QListIterator<TTemporaryFile *> i(tempFiles); i.hasNext(); ) {
        delete i.next();
    }

    for (QStringListIterator i(autoRemoveFiles); i.hasNext(); ) {
        QFile(i.next()).remove();
    }
}


QSqlDatabase &TActionContext::getDatabase(int id)
{
    T_TRACEFUNC("id:%d", id);

    if (id < 0 || id >= Tf::app()->databaseSettingsCount())
        return sqlDatabases[Tf::app()->databaseSettingsCount()];  // invalid db
    
    QSqlDatabase &db = sqlDatabases[id];
    if (!db.isValid()) {
        db = TSqlDatabasePool::instance()->pop(id);
        beginTransaction(db);
    }
    return db;
}


void TActionContext::releaseDatabases()
{
    rollbackTransactions();

    for (int i = 0; i < sqlDatabases.count(); ++i) {
        TSqlDatabasePool::instance()->push(sqlDatabases[i]);
    }
}


void TActionContext::execute()
{
    T_TRACEFUNC();
    TAccessLog accessLog;
    THttpResponseHeader responseHeader;

    try {
        httpSocket = new THttpSocket;
        if (!httpSocket->setSocketDescriptor(socketDesc)) {
            emitError(httpSocket->error());
            delete httpSocket;
            httpSocket = 0;
            return;
        } else {
            socketDesc = 0;
        }

        while (!httpSocket->canReadRequest()) {
            if (stopped) {
                tSystemDebug("Detected stop request");
                break;
            }

            // Check idle timeout
            if (httpSocket->idleTime() >= 10) {
                tSystemWarn("Reading a socket timed out after 10 seconds. Descriptor:%d", httpSocket->socketDescriptor());
                break;
            }
            httpSocket->waitForReadyRead(100);
        }
        
        if (!httpSocket->canReadRequest()) {
            httpSocket->abort();
            delete httpSocket;
            httpSocket = 0;
            return;
        }

        THttpRequest httpRequest = httpSocket->read();
        const THttpRequestHeader &hdr = httpRequest.header();

        // Access log
        QByteArray firstLine = hdr.method() + ' ' + hdr.path();
        firstLine += QString(" HTTP/%1.%2").arg(hdr.majorVersion()).arg(hdr.minorVersion()).toLatin1();
        accessLog.request = firstLine;
        accessLog.remoteHost = (Tf::app()->appSettings().value(LISTEN_PORT).toUInt() > 0) ? httpSocket->peerAddress().toString().toLatin1() : QByteArray("(unix)");

        tSystemDebug("method : %s", hdr.method().data());
        tSystemDebug("path : %s", hdr.path().data());

        Tf::HttpMethod method = httpRequest.method();
        QString path = THttpUtility::fromUrlEncoding(hdr.path().split('?').value(0));

        // Routing info exists?
        TRouting rt = TUrlRoute::instance().findRouting(method, path);
        tSystemDebug("Routing: controller:%s  action:%s", rt.controller.data(),
                     rt.action.data());
        
        if (rt.isEmpty()) {
            // Default URL routing
            rt.params = path.split('/');
            if (path.startsWith(QLatin1Char('/')) && !rt.params.isEmpty()) {
                rt.params.removeFirst();  // unuse first item
            }
            if (path.endsWith(QLatin1Char('/')) && !rt.params.isEmpty()) {
                rt.params.removeLast();  // unuse last item
            }

            // Direct view render mode?
            if (Tf::app()->appSettings().value(DIRECT_VIEW_RENDER_MODE).toBool()) {
                // Direct view setting
                rt.controller = "directcontroller";
                rt.action = "show";
            } else {
                if (!rt.params.value(0).isEmpty()) {
                    rt.controller = rt.params.takeFirst().toLower().toLatin1() + "controller";
                    // Default action: index
                    rt.action = rt.params.value(0, QLatin1String("index")).toLatin1();
                    if (!rt.params.isEmpty()) {
                        rt.params.takeFirst();
                    }
                }
                tSystemDebug("Active Controller : %s", rt.controller.data());
            }
        }

        // Call controller method
        TDispatcher<TActionController> ctlrDispatcher(rt.controller);
        currController = ctlrDispatcher.object();
        if (currController) {
            currController->setActionName(rt.action);
            currController->setHttpRequest(httpRequest);
            
            // Session
            if (currController->sessionEnabled()) {
                TSession session;
                QByteArray sessionId = httpRequest.cookie(TSession::sessionName());
                if (!sessionId.isEmpty()) {
                    // Finds a session
                    session = TSessionManager::instance().findSession(sessionId);
                }<commit_msg>modified not to call actions in applicationcontroller.<commit_after>/* Copyright (c) 2010-2012, <NAME>
 * All rights reserved.
 *
 * This software may be used and distributed according to the terms of
 * the New BSD License, which is incorporated herein by reference.
 */

#include <QtCore>
#include <QSqlDatabase>
#include <QSqlDriver>
#include <QHostAddress>
#include <TActionContext>
#include <TWebApplication>
#include <THttpRequest>
#include <THttpResponse>
#include <THttpUtility>
#include <TDispatcher>
#include <TActionController>
#include <TSqlDatabasePool>
#include <TSessionStore>
#include "tsystemglobal.h"
#include "thttpsocket.h"
#include "tsessionmanager.h"
#include "turlroute.h"
#include "taccesslog.h"
#ifdef Q_OS_UNIX
# include "tfcore_unix.h"
#endif

#define AUTO_ID_REGENERATION  "Session.AutoIdRegeneration"
#define DIRECT_VIEW_RENDER_MODE  "DirectViewRenderMode"
#define ENABLE_CSRF_PROTECTION_MODULE "EnableCsrfProtectionModule"
#define SESSION_COOKIE_PATH  "Session.CookiePath"
#define LISTEN_PORT  "ListenPort"

/*!
  \class TActionContext
  \brief The TActionContext class is the base class of contexts for
  action controllers.
*/


TActionContext::TActionContext(int socket)
    : sqlDatabases(Tf::app()->databaseSettingsCount() + 1), stopped(false), socketDesc(socket), httpSocket(0), currController(0)
{ }


TActionContext::~TActionContext()
{
    if (httpSocket)
        delete httpSocket;

    if (socketDesc > 0)
        TF_CLOSE(socketDesc);
    
    // Releases all database sessions
    TActionContext::releaseDatabases();
    
    for (QListIterator<TTemporaryFile *> i(tempFiles); i.hasNext(); ) {
        delete i.next();
    }

    for (QStringListIterator i(autoRemoveFiles); i.hasNext(); ) {
        QFile(i.next()).remove();
    }
}


QSqlDatabase &TActionContext::getDatabase(int id)
{
    T_TRACEFUNC("id:%d", id);

    if (id < 0 || id >= Tf::app()->databaseSettingsCount())
        return sqlDatabases[Tf::app()->databaseSettingsCount()];  // invalid db
    
    QSqlDatabase &db = sqlDatabases[id];
    if (!db.isValid()) {
        db = TSqlDatabasePool::instance()->pop(id);
        beginTransaction(db);
    }
    return db;
}


void TActionContext::releaseDatabases()
{
    rollbackTransactions();

    for (int i = 0; i < sqlDatabases.count(); ++i) {
        TSqlDatabasePool::instance()->push(sqlDatabases[i]);
    }
}


void TActionContext::execute()
{
    T_TRACEFUNC();
    TAccessLog accessLog;
    THttpResponseHeader responseHeader;

    try {
        httpSocket = new THttpSocket;
        if (!httpSocket->setSocketDescriptor(socketDesc)) {
            emitError(httpSocket->error());
            delete httpSocket;
            httpSocket = 0;
            return;
        } else {
            socketDesc = 0;
        }

        while (!httpSocket->canReadRequest()) {
            if (stopped) {
                tSystemDebug("Detected stop request");
                break;
            }

            // Check idle timeout
            if (httpSocket->idleTime() >= 10) {
                tSystemWarn("Reading a socket timed out after 10 seconds. Descriptor:%d", httpSocket->socketDescriptor());
                break;
            }
            httpSocket->waitForReadyRead(100);
        }
        
        if (!httpSocket->canReadRequest()) {
            httpSocket->abort();
            delete httpSocket;
            httpSocket = 0;
            return;
        }

        THttpRequest httpRequest = httpSocket->read();
        const THttpRequestHeader &hdr = httpRequest.header();

        // Access log
        QByteArray firstLine = hdr.method() + ' ' + hdr.path();
        firstLine += QString(" HTTP/%1.%2").arg(hdr.majorVersion()).arg(hdr.minorVersion()).toLatin1();
        accessLog.request = firstLine;
        accessLog.remoteHost = (Tf::app()->appSettings().value(LISTEN_PORT).toUInt() > 0) ? httpSocket->peerAddress().toString().toLatin1() : QByteArray("(unix)");

        tSystemDebug("method : %s", hdr.method().data());
        tSystemDebug("path : %s", hdr.path().data());

        Tf::HttpMethod method = httpRequest.method();
        QString path = THttpUtility::fromUrlEncoding(hdr.path().split('?').value(0));

        // Routing info exists?
        TRouting rt = TUrlRoute::instance().findRouting(method, path);
        tSystemDebug("Routing: controller:%s  action:%s", rt.controller.data(),
                     rt.action.data());
        
        if (rt.isEmpty()) {
            // Default URL routing
            rt.params = path.split('/');
            if (path.startsWith(QLatin1Char('/')) && !rt.params.isEmpty()) {
                rt.params.removeFirst();  // unuse first item
            }
            if (path.endsWith(QLatin1Char('/')) && !rt.params.isEmpty()) {
                rt.params.removeLast();  // unuse last item
            }

            // Direct view render mode?
            if (Tf::app()->appSettings().value(DIRECT_VIEW_RENDER_MODE).toBool()) {
                // Direct view setting
                rt.controller = "directcontroller";
                rt.action = "show";
            } else {
                if (!rt.params.value(0).isEmpty()) {
                    rt.controller = rt.params.takeFirst().toLower().toLatin1() + "controller";

                    if (rt.controller == "applicationcontroller") {
                        rt.controller.clear();  // Can not call 'ApplicationController'
                    }

                    // Default action: index
                    rt.action = rt.params.value(0, QLatin1String("index")).toLatin1();
                    if (!rt.params.isEmpty()) {
                        rt.params.takeFirst();
                    }
                }
                tSystemDebug("Active Controller : %s", rt.controller.data());
            }
        }

        // Call controller method
        TDispatcher<TActionController> ctlrDispatcher(rt.controller);
        currController = ctlrDispatcher.object();
        if (currController) {
            currController->setActionName(rt.action);
            currController->setHttpRequest(httpRequest);
            
            // Session
            if (currController->sessionEnabled()) {
                TSession session;
                QByteArray sessionId = httpRequest.cookie(TSession::sessionName());
                if (!sessionId.isEmpty()) {
                    // Finds a session
                    session = TSessionManager::instance().findSession(sessionId);
                }
{'fraction_non_alphanumeric': 0.13173793644566498, 'fraction_numerical': 0.0058061985092193015, 'mean_word_length': 2.3227320125130344, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1840759', 'n_tokens_mistral': 3674, 'n_tokens_neox': 3517, 'n_words': 716}