<commit_before>/* -*- Mode:c++; eval:(c-set-style "BSD"); c-basic-offset:4; indent-tabs-mode:nil; tab-width:8 -*- */

#include "WebAppServer.h"
#include "WebAppServerInternal.h"
#include "base64.h"

#include <stdlib.h>

using namespace std;

namespace WebAppServer {

#define VERBOSE 1

WebFastCGIConnection :: WebFastCGIConnection(
    serverPort::ConfigRecList_t &_configs, int _fd)
    : WebServerConnectionBase(_configs, _fd)
{
    state = STATE_BEGIN;
    cgiParams = NULL;
    queryStringParams = NULL;
    cgiConfig = NULL;
    time(&lastCall);
    registeredWaiter = false;

    // i wanted to startFdThread in WebServerConnectionBase, but i can't
    // because it would call pure virtual methods that aren't set up until
    // this derived contructor is complete. so.. bummer.
    startFdThread(_fd, 1000);
}

WebFastCGIConnection :: ~WebFastCGIConnection(void)
{
    if (wac && registeredWaiter)
    {
        WebAppConnectionDataFastCGI * dat = wac->connData->fcgi();
        Lock lock(dat);
        dat->waiter = NULL;
        wac = NULL;
    }
    if (cgiParams)
        delete cgiParams;
    if (queryStringParams)
        delete queryStringParams;
}

//virtual
bool
WebFastCGIConnection :: handleSomeData(void)
{
    while (1)
    {
        size_t rbSize = readbuf.size();
        if (rbSize < sizeof(FastCGIHeader))
            break; // not enough for a header.

        FastCGIRecord rec;

        readbuf.copyOut((char*)&rec.header, 0, sizeof(FastCGIHeader));
        if (rec.header.version != FastCGIHeader::VERSION_1)
        {
            cerr << "Fast CGI proto version error" << endl;
            return false;
        }

        uint16_t contLen = rec.header.get_contentLength();
        uint16_t padLen = rec.header.paddingLength;
        uint16_t fullLen = contLen + padLen + sizeof(FastCGIHeader);

        if (fullLen > rbSize)
            break; // not enough for the body.

        if (0)
            cout << "handling record of size " << contLen << endl;

        if (fullLen > sizeof(FastCGIRecord))
        {
            cerr << "FastCGI record overflow!" << endl;
            return false;
        }

        readbuf.copyOut((char*)&rec.body,
                        sizeof(FastCGIHeader), contLen);

        if (handleRecord(&rec) == false)
            return false;

        readbuf.erase0(fullLen);
    }

    return true;
}

//virtual
bool
WebFastCGIConnection :: doPoll(void)
{
    time_t now = time(NULL);

    int idleTime = now - lastCall;

    printf("FastCGI Connection idle time : %d\n", idleTime);

    if (idleTime > maxIdleTime)
        return false;

    return true;
}

//virtual
void
WebFastCGIConnection :: done(void)
{
    // wac is not deleted because it lives beyond
    // this ephemeral connection.
    wac = NULL;
    deleteMe = true;
}

static void doPercentSubstitute(CircularReaderSubstr &str)
{
    size_t pos = 0;
    while (pos != string::npos)
    {
        int pc = str.find("%",pos);
        if (pc == CircularReaderSubstr::npos)
            break;<commit_msg>deregister fastcgi waiter at the proper time (earlier)<commit_after>/* -*- Mode:c++; eval:(c-set-style "BSD"); c-basic-offset:4; indent-tabs-mode:nil; tab-width:8 -*- */

#include "WebAppServer.h"
#include "WebAppServerInternal.h"
#include "base64.h"

#include <stdlib.h>

using namespace std;

namespace WebAppServer {

#define VERBOSE 1

WebFastCGIConnection :: WebFastCGIConnection(
    serverPort::ConfigRecList_t &_configs, int _fd)
    : WebServerConnectionBase(_configs, _fd)
{
    state = STATE_BEGIN;
    cgiParams = NULL;
    queryStringParams = NULL;
    cgiConfig = NULL;
    time(&lastCall);
    registeredWaiter = false;

    // i wanted to startFdThread in WebServerConnectionBase, but i can't
    // because it would call pure virtual methods that aren't set up until
    // this derived contructor is complete. so.. bummer.
    startFdThread(_fd, 1000);
}

WebFastCGIConnection :: ~WebFastCGIConnection(void)
{
    if (wac && registeredWaiter)
    {
        WebAppConnectionDataFastCGI * dat = wac->connData->fcgi();
        Lock lock(dat);
        dat->waiter = NULL;
        wac = NULL;
    }
    if (cgiParams)
        delete cgiParams;
    if (queryStringParams)
        delete queryStringParams;
}

//virtual
bool
WebFastCGIConnection :: handleSomeData(void)
{
    while (1)
    {
        size_t rbSize = readbuf.size();
        if (rbSize < sizeof(FastCGIHeader))
            break; // not enough for a header.

        FastCGIRecord rec;

        readbuf.copyOut((char*)&rec.header, 0, sizeof(FastCGIHeader));
        if (rec.header.version != FastCGIHeader::VERSION_1)
        {
            cerr << "Fast CGI proto version error" << endl;
            return false;
        }

        uint16_t contLen = rec.header.get_contentLength();
        uint16_t padLen = rec.header.paddingLength;
        uint16_t fullLen = contLen + padLen + sizeof(FastCGIHeader);

        if (fullLen > rbSize)
            break; // not enough for the body.

        if (0)
            cout << "handling record of size " << contLen << endl;

        if (fullLen > sizeof(FastCGIRecord))
        {
            cerr << "FastCGI record overflow!" << endl;
            return false;
        }

        readbuf.copyOut((char*)&rec.body,
                        sizeof(FastCGIHeader), contLen);

        if (handleRecord(&rec) == false)
            return false;

        readbuf.erase0(fullLen);
    }

    return true;
}

//virtual
bool
WebFastCGIConnection :: doPoll(void)
{
    time_t now = time(NULL);

    int idleTime = now - lastCall;

    printf("FastCGI Connection idle time : %d\n", idleTime);

    if (idleTime > maxIdleTime)
        return false;

    return true;
}

//virtual
void
WebFastCGIConnection :: done(void)
{
    // wac is not deleted because it lives beyond
    // this ephemeral connection. we do however deregister ourselves
    // from the wac's "waiter" pointer.
    if (wac && registeredWaiter)
    {
        WebAppConnectionDataFastCGI * dat = wac->connData->fcgi();
        Lock lock(dat);
        dat->waiter = NULL;
        wac = NULL;
    }
    deleteMe = true;
}

static void doPercentSubstitute(CircularReaderSubstr &str)
{
    size_t pos = 0;
    while (pos != string::npos)
    {
        int pc = str.find("%",pos);
        if (pc == CircularReaderSubstr::npos)
            break;
{'fraction_non_alphanumeric': 0.11349306431273644, 'fraction_numerical': 0.006620428751576293, 'mean_word_length': 2.427876823338736, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 20, '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': '4655253', 'n_tokens_mistral': 2061, 'n_tokens_neox': 1978, 'n_words': 504}