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

📄 httpheader.cpp

📁 一个UNIX/LINUX下的基于内容的过滤服务器源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    line += "=";    line += value;    line += "; path=/\r";    header.push_back(line);    #ifdef DGDEBUG        std::cout << "Setting cookie:" << line << std::endl;    #endif    // no expiry specified so ends with the browser session}// I'm not proud of this... --ErnestString HTTPHeader::getCookie(const char *cookie) {    String line;//    std::deque<String> cookies;    for (int i = 0; i < (signed)header.size(); i++) {        if (header[i].startsWith("Cookie:")) {            line = header[i].after("ie: ");            if (line.contains(cookie)) { // We know we have the cookie                line = line.after(cookie);                line.lop(); // Get rid of the '='                if (line.contains(";")) {                    line = line.before(";");                }            }            // break; // Technically there should be only one Cookie: header, but...        }    }    line.removeWhiteSpace();    #ifdef DGDEBUG        std::cout << "Found GBYPASS cookie:" << line << std::endl;    #endif    return line;}String HTTPHeader::decode(String s) {    if (s.length() < 3) {        return s;    }    #ifdef DGDEBUG        std::cout << "decoding url" << std::endl;    #endif    RegExp re;    #ifdef DGDEBUG        std::cout << "matches:" << re.numberOfMatches() << std::endl;    #endif    if (!re.matched()) {return s;}  // exit if not found      #ifdef DGDEBUG        std::cout << "removing %XX" << std::endl;    #endif    int match;    int offset;    int pos = 0;    int size = s.length();    String result;    String n;    for (match = 0; match < re.numberOfMatches(); match++) {        offset = re.offset(match);        if (offset > pos) {            result += s.subString(pos, offset-pos);        }        n = re.result(match).c_str();        n.lop();  // remove %        result += hexToChar(n);        pos = offset + 3;    }    if (size > pos) {        result += s.subString(pos, size-pos);    }    else {        n = "%" + n;    }    return result;}String HTTPHeader::hexToChar(String n) {    if (n.length() < 2) {        return n;    }    char* buf = new char[2];    unsigned int a, b;    unsigned char c;    a = n[0];    b = n[1];    if (a >= 'a' && a <= 'f') {        a -= 87;    }    else if (a >= 'A' && a <= 'F') {        a -= 55;    }    else if (a >= '0' && a <= '9') {        a -= 48;    }    if (b >= 'a' && b <= 'f') {        b -= 87;    }    else if (b >= 'A' && b <= 'F') {        b -= 55;    }    else if (b >= '0' && b <= '9') {        b -= 48;    }    c = a * 16 + b;    if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')         || (c >= '0' && c <= '9') || (c == '-') ) {        buf[0] = c;        buf[1] = '\0';        n = buf;    }    else {        n = "%" + n;    }    return n;}String HTTPHeader::requesttype() {  // GET,HEAD,PUT,etc - what?    return header[0].before(" ");}void HTTPHeader::out(Socket *sock) throw(exception) {    String l;  // for amalgamating to avoid conflict with the Nagel algorithm    for(int i = 0; i < (signed)header.size(); i++) {        l += header[i] + "\n";    }    l += "\r\n";    // send header to the output stream    // need exception for bad write    if (!(*sock).writeToSocket(l.toCharArray(), l.length(), 0, timeout)) {        throw exception();    }    if (postdata.buffer_length > 0) {        postdata.out(sock);    }}void HTTPHeader::in(Socket *sock) {    // the RFCs don't specify a max header line length so this should be    // dynamic really.  Pointed out (well reminded actually) by Daniel Robbins    char buff[8192];  // setup a buffer to hold the incomming HTTP line    String line;  // temp store to hold the line after processing    line="----";  // so we get past the first while    while (line.length() > 3) {  // loop until the stream is      // failed or we get to the end of the header (a line by itself)        (*sock).getline(buff, 8192, timeout);  // get a line of header from the stream        // getline will throw an exception if there is an error which will        // only be caught by HandleConnection()        line = buff;  // convert the line to a String        header.push_back(line);  // stick the line in the deque that                               // holds the header    }    header.pop_back();  // remove the final blank line of a header    checkheader();  // sort out a few bits in the header    int length;    String requestMethod = header[0].before(" ");    if (!requestMethod.contains("/") && (length = contentlength()) > 0) {        // if it's a request (not reply) with content, grab the data and store it        postdata.read(sock, length);  // get the DataBuffer to read the data    }}bool HTTPHeader::isRedirection() {    // The 1st line of the header for a redirection is thus:    // HTTP/1.(0|1) 3xx    if (header.size() < 1) {return false;}  // sometimes get called b 4 read    String answer = header[0].after(" ").before(" ");    if (answer[0] == '3' && answer.length() == 3) {        return true;    }    return false;}// squid adds this so if more support it it may be useful one dayvoid HTTPHeader::addXForwardedFor(std::string clientip) {    std::string line = "X-Forwarded-For: " + clientip + "\r";    header.push_back(String(line.c_str()));}void HTTPHeader::setTimeout(int t) {    timeout = t;}// If basic authentication is enabled DG is able to decode the username// and password from the header - however we are only interested in the// usernamestd::string HTTPHeader::getauthuser() {    String t = getauth();    t = t.before(":");    t.toLower();    return std::string(t.toCharArray());}String HTTPHeader::getauth() {    String line;    for (int i = 0; i < (signed)header.size(); i++) {        if (header[i].startsWith("Proxy-Authorization: Basic ")            || header[i].startsWith("Proxy-Authorization: basic ")) {            line = header[i].after("asic ");            line = decodeb64(line).c_str();  // its base64 MIME encoded            break;        }    }    return line;}std::string HTTPHeader::decodeb64(String line) {  // decode a block of b64 MIME    long four = 0;    int d;    std::string result = "";    int len = line.length() - 4;    for (int i = 0; i < len; i += 4) {        four = 0;        d = decode1b64(line[i + 0]);        four = four | d;        d = decode1b64(line[i + 1]);        four = (four << 6) | d;        d = decode1b64(line[i + 2]);        four = (four << 6) | d;        d = decode1b64(line[i + 3]);        four = (four << 6) | d;        d = (four & 0xFF0000) >> 16;        result += (char)d;        d = (four & 0xFF00) >> 8;        result += (char)d;        d = four & 0xFF;        result += (char)d;    }    return result;}int HTTPHeader::decode1b64(char c) {    unsigned char i = '\0';    switch (c) {        case '+':            i = 62;            break;        case '/':            i = 63;            break;        case '=':            i = 0;            break;        default: // must be A-Z, a-z or 0-9            i = '9' - c;            if (i > 0x3F) {  // under 9                i = 'Z' - c;                if (i > 0x3F) { // over Z                    i = 'z' - c;                    if (i > 0x3F) { // over z so invalid                        i = 0x80;  // so set the high bit                    }                    else {                        // a-z                        i = c - 71;                    }                }                else {                    // A-Z                    i = c - 65;                }            }            else {                // 0-9                i = c + 4;            }            break;    }    return (int)i;}bool HTTPHeader::isCompressed() {    for (int i = 0; i < (signed)header.size(); i++) {        if (header[i].startsWith("Content-Encoding:")) {            if (header[i].indexOf("identity") != -1) {  // http1.1 says this                                     // should not be here, but not must not                return false;            }            #ifdef DGDEBUG                std::cout << "is compressed" << std::endl;            #endif            return true;  // i.e. encoded with something other than clear        }    }  return false;}String HTTPHeader::contentEncoding() {    String ce;    for (int i = 0; i < (signed)header.size(); i++) {        if (header[i].startsWith("Content-Encoding:")) {            ce = header[i].after("Content-Encoding: ");            ce.toLower();            return ce;        }    }  return "";  // we need a default don't we?}String HTTPHeader::modifyEncodings(String e) {    // There are 4 types of encoding: gzip, deflate, compress and identity    // deflate is in zlib format    // compress is in unix compress format    // identity is uncompressed and supported by all browsers (obviously)    // we do not support compress    e.toLower();    String o = "Accept-Encoding: identity";    #if ZLIB_VERNUM < 0x1210        #warning 'Accept-Encoding: gzip' is disabled    #else        if (e.contains("gzip")) {            o += ",gzip";        }    #endif    if (e.contains("deflate")) {        o += ",deflate";    }    return o;}void HTTPHeader::removeEncoding(int newlen) {    for (int i = 0; i < (signed)header.size(); i++) {        if (header[i].startsWith("Content-Length:")) {            header[i] = "Content-Length: " + String(newlen);        }        if (header[i].startsWith("Content-Encoding:")) {            header[i] = "X-DansGuardian-Removed: Content-Encoding";        }    }}void HTTPHeader::setContentLength(int newlen) {    for (int i = 0; i < (signed)header.size(); i++) {        if (header[i].startsWith("Content-Length:")) {            header[i] = "Content-Length: " + String(newlen);        }    }}bool HTTPHeader::isPostUpload() {    if (header[0].before(" ") != "POST") {	return false;    }    bool answer = false;    int postlen = postdata.buffer_length;    int i;    if (postlen < 14) {  // min length for there to be a match        return false;    }    char* postdatablock = new char[postlen + 64];  // extra 64 for search    try {        postdata.copytomemory(postdatablock);        for(i = 0; i < postlen; i++) { // make lowercase char by char            if (isupper(postdatablock[i])) {                postdatablock[i] = tolower(postdatablock[i]);            }        }        RegExp mysearch;        std::string dis = "content-type: ";  // signifies file upload        char* p = new char[32];        try {            for(i = 0; i < (signed)dis.length(); i++) {                p[i] = dis[i];  // copy it to the block of memory            }            char* pend = p + dis.length();  // pointer for search            char* postdatablockend = postdatablock + postlen;            char* res = mysearch.search(postdatablock, postdatablockend, p, pend);            if (res != postdatablockend) {                answer = true;            }        } catch (exception& e) {};        delete[] p;    } catch (exception& e) {};    delete[] postdatablock;    return answer;}

⌨️ 快捷键说明

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