⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 databuffer.cpp

📁 一个UNIX/LINUX下的基于内容的过滤服务器源代码
💻 CPP
字号:
//Please refer to http://dansguardian.org/?page=copyright//for the license for this code.//Written by Daniel Barron (daniel@//jadeb/.com).//For support go to http://groups.yahoo.com/group/dansguardian//  This program is free software; you can redistribute it and/or modify//  it under the terms of the GNU General Public License as published by//  the Free Software Foundation; either version 2 of the License, or//  (at your option) any later version.////  This program is distributed in the hope that it will be useful,//  but WITHOUT ANY WARRANTY; without even the implied warranty of//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the//  GNU General Public License for more details.////  You should have received a copy of the GNU General Public License//  along with this program; if not, write to the Free Software//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#include <syslog.h>#include "String.hpp"#include <algorithm>#include "DataBuffer.hpp"#include <cstdlib>#include <unistd.h>#include <zlib.h>#include <cerrno>#include <fstream>#ifdef __GCCVER3    #include <istream>#else    #include <istream.h>#endifextern OptionContainer o;DataBuffer::DataBuffer():data(new char[0]),buffer_length(0),compresseddata(NULL),compressed_buffer_length(0),timeout(20),decompress("") {}// set buffer length to zero and initialise the char* memory block to hold// the data - initialisation/creation functionDataBuffer::~DataBuffer() {    delete[] data;    if (compresseddata != NULL) {        delete[] compresseddata;        compresseddata = NULL;    }}// delete the memory block when the class is destryedbool DataBuffer::in(Socket *sock) {//    if (decompress.contains("gzip")) {//        ingzip(sock);  // incomming stream is gzip compressed//        return;//    }    bool toobig = false;    int rc, newsize;    char* block;  // buffer for storing a grabbed block from the                      // imput stream    char* temp;    while(true) {        if (buffer_length >= 32768) {            newsize = buffer_length;        }        else {            newsize = 32768;        }        block = new char[newsize];        try {            (*sock).checkForInput(timeout);        }  catch (exception& e) {            delete[] block;            break;        }        rc = (*sock).readFromSocket(block, newsize, 0, timeout);        // grab a block of input, doubled each time        if (rc < 1) {            delete[] block;            break;  // an error occured so end the while()                    // or none received so pipe is closed        }        if (rc > 0) {            temp = new char[buffer_length + rc];  // replacement store            memcpy(temp, data, buffer_length);  // copy the current data            memcpy(temp + buffer_length, block, rc);  // copy the new data            delete[] data;  // delete the current data block            data = temp;            buffer_length += rc;  // update data size counter        }        delete[] block;        if (buffer_length > o.max_content_filter_size) {            toobig = true;            break;        }    }    if (!toobig) {        if (decompress.contains("deflate")) {            #ifdef DGDEBUG                std::cout << "zlib format" << std::endl;            #endif            zlibinflate(false);  // incoming stream was zlib compressed        }        else if (decompress.contains("gzip")) {            #ifdef DGDEBUG                std::cout << "gzip format" << std::endl;            #endif            zlibinflate(true);  // incoming stream was gzip compressed        }    }    return toobig;}void DataBuffer::read(Socket *sock, int l) throw (exception)  {    delete[] data;  // delete the current data store (should be emtpy anyway)    data = new char[l + 2];  // create a new store large enough    int rc;    rc = (*sock).readFromSocketn(data, l, 0, timeout); // read in the [POST] data    if (rc < 0) {        throw exception();  // danger, danger Will Robinson    }  // The above should be all that's needed - but wait there's more!  // Normal data appended to the header by POST is actually 2 bytes longer  // than the Content-Length header says.  It contains a carrage return and  // a new line character.  Simple - just add a fudgefactor of 2.  // No.  Because when uploading a file via a form the POST data is  // *exactly* as stated and trying to read even 1 more byte will cause the  // read to hang.  Also Netscape 4.7x it does it differently.  // So we need to check the status of the connection to see if there really  // are more bytes to read.  if ((*sock).checkForInput()) {      rc = (*sock).readFromSocket(data + l, 2, 0, timeout);      // if an error occured (rc < 1) we ignore it and try and continue      if (rc > 0) {          l += 2;  // adjust the length      }  }  buffer_length = l;  // update data size counter}void DataBuffer::out(Socket *sock) throw(exception) {    (*sock).readyForOutput(timeout);  // exceptions on timeout or error    // need exception or something for a bad write    if (!(*sock).writeToSocket(data, buffer_length, 0, timeout)) {        throw exception();    }  // write the data block out to the stream}void DataBuffer::copytomemory(char* location) {  memcpy(location, data, buffer_length);  // doh?  what does this do?}void DataBuffer::setTimeout(int t) {    timeout = t;}void DataBuffer::setDecompress(String d) {    decompress = d;}void DataBuffer::zlibinflate(bool header) {    if (buffer_length < 12) {        return; // it can't possibly be zlib'd    }    #ifdef DGDEBUG        std::cout << "compressed size:" << buffer_length << std::endl;    #endif    #if ZLIB_VERNUM < 0x1210        #warning ************************************        #warning For gzip support you need zlib 1.2.1        #warning or later to be installed.        #warning You can ignore this warning but        #warning internet bandwidth may be wasted.        #warning ************************************        if (header) {            return;        }    #endif//    ofstream logfile("/tmp/zlib", ios::out);//    logfile.write(data, buffer_length);//    logfile.close();    int newsize = buffer_length * 5;  // good estimate of deflated HTML    char* block;    char* temp;    block = new char[newsize];    int err;    int bout;    int bytesgot = 0;    z_stream d_stream;    d_stream.zalloc = (alloc_func)0;    d_stream.zfree = (free_func)0;    d_stream.opaque = (voidpf)0;    d_stream.next_in = (Bytef*)data;    d_stream.avail_in = buffer_length;    d_stream.next_out = (Bytef*)block;    d_stream.avail_out = newsize;    if (header) {        err = inflateInit2(&d_stream, 15 + 32);    }    else {        err = inflateInit2(&d_stream, -15);    }    if (err != Z_OK) {  // was a problem so just return        delete[] block; // don't forget to free claimed memory        #ifdef DGDEBUG            std::cerr << "bad init inflate:" << err << std::endl;        #endif        return;    }    while (true) {        #ifdef DGDEBUG            std::cerr << "inflate loop" << std::endl;        #endif        err = inflate(&d_stream, Z_NO_FLUSH);        bout = newsize - bytesgot - d_stream.avail_out;        bytesgot += bout;        if (err == Z_STREAM_END) {            break;        }        if (err != Z_OK) {  // was a problem so just return            delete[] block; // don't forget to free claimed memory            #ifdef DGDEBUG                std::cerr << "bad inflate:" << String(err) << std::endl;            #endif            return;        }        newsize = bytesgot * 2;        temp = new char[newsize];        memcpy(temp, block, bytesgot);        delete[] block;        block = temp;        d_stream.next_out = (Bytef*)(block + bytesgot);        d_stream.avail_out = newsize - bytesgot;    }    compresseddata = data;    compressed_buffer_length = buffer_length;    data = block;    buffer_length = bytesgot;    // I could create a new block the exact size and memcpy    // it over to save RAM but RAM is cheap and this saves CPU//    data = new char[bytesgot];//    memcpy(data, block, bytesgot);//    delete[] block;}// Does a regexp search and replace.bool DataBuffer::contentRegExp(int filtergroup) {    #ifdef DGDEBUG        std::cout << "Starting content reg exp replace" << std::endl;    #endif    bool contentmodified = false;    unsigned int i;    int j;    unsigned int s =  (*o.fg[filtergroup]).content_regexp_list_comp.size();    int matches;    String exp;    String replacement;    int replen;    int sizediff;    char* newblock;    char* dstpos;    int srcoff;    int nextoffset;    for (i = 0; i < s; i++) {        if ((*o.fg[filtergroup]).content_regexp_list_comp[i].match(data)) {            replacement = (*o.fg[filtergroup]).content_regexp_list_rep[i];            replen = replacement.length();            matches = (*o.fg[filtergroup]).content_regexp_list_comp[i].numberOfMatches();            sizediff = matches * replen;            for (j = 0; j < matches; j++) {                sizediff -= (*o.fg[filtergroup]).content_regexp_list_comp[i].length(j);            }            newblock = new char[buffer_length + sizediff];            srcoff = 0;            dstpos = newblock;            #ifdef DGDEBUG                std::cout << "content matches:" << matches << std::endl;            #endif            for (j = 0; j < matches; j++) {                nextoffset = (*o.fg[filtergroup]).content_regexp_list_comp[i].offset(j);                if (nextoffset > srcoff) {                    memcpy(dstpos, data + srcoff, nextoffset - srcoff);                    dstpos += nextoffset - srcoff;                    srcoff = nextoffset;                }                memcpy(dstpos, replacement.toCharArray(), replen);                dstpos += replen;                srcoff += (*o.fg[filtergroup]).content_regexp_list_comp[i].length(j);            }            if (srcoff < buffer_length) {                memcpy(dstpos, data + srcoff,  buffer_length - srcoff);            }            delete[] data;            data = newblock;            buffer_length = buffer_length + sizediff;            contentmodified = true;        }    }    return contentmodified;}void DataBuffer::swapbacktocompressed() {    if (compresseddata != NULL && compressed_buffer_length > 0) {        delete[] data;        buffer_length = compressed_buffer_length;        data = compresseddata;        compresseddata = NULL;        compressed_buffer_length = 0;    } // drop the decompressed version if there}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -