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

📄 ncbicgi.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        end++;    range->first  = beg;    range->second = end;    return (beg == end) ? 0 : *beg;}const CCgiCookie* CCgiCookies::Find(const string& name, TCRange* range)    const{    CCgiCookies& nonconst_This = const_cast<CCgiCookies&>(*this);    if ( range ) {        TRange x_range;        const CCgiCookie* ck = nonconst_This.Find(name, &x_range);        range->first  = x_range.first;        range->second = x_range.second;        return ck;    } else {        return nonconst_This.Find(name, 0);    }}bool CCgiCookies::Remove(CCgiCookie* cookie, bool destroy){    if (!cookie  ||  m_Cookies.erase(cookie) == 0)        return false;    if ( destroy )        delete cookie;    return true;}size_t CCgiCookies::Remove(TRange& range, bool destroy){    size_t count = 0;    for (TIter iter = range.first;  iter != range.second;  iter++, count++) {        if ( destroy )            delete *iter;    }    m_Cookies.erase(range.first, range.second);    return count;}void CCgiCookies::Clear(void){    ITERATE (TSet, cookie, m_Cookies) {        delete *cookie;    }    m_Cookies.clear();}/////////////////////////////////////////////////////////  CCgiRequest//// Standard property namesstatic const string s_PropName[eCgi_NProperties + 1] = {    "SERVER_SOFTWARE",    "SERVER_NAME",    "GATEWAY_INTERFACE",    "SERVER_PROTOCOL",    "SERVER_PORT",    "REMOTE_HOST",    "REMOTE_ADDR",    "CONTENT_TYPE",    "CONTENT_LENGTH",    "REQUEST_METHOD",    "PATH_INFO",    "PATH_TRANSLATED",    "SCRIPT_NAME",    "QUERY_STRING",    "AUTH_TYPE",    "REMOTE_USER",    "REMOTE_IDENT",    "HTTP_ACCEPT",    "HTTP_COOKIE",    "HTTP_IF_MODIFIED_SINCE",    "HTTP_REFERER",    "HTTP_USER_AGENT",    ""  // eCgi_NProperties};const string& CCgiRequest::GetPropertyName(ECgiProp prop){    if ((long) prop < 0  ||  (long) eCgi_NProperties <= (long) prop) {        _TROUBLE;        throw logic_error("CCgiRequest::GetPropertyName(BadPropIdx)");    }    return s_PropName[prop];}// Return integer (0..15) corresponding to the "ch" as a hex digit// Return -1 on errorstatic int s_HexChar(char ch) THROWS_NONE{    if ('0' <= ch  &&  ch <= '9')        return ch - '0';    if ('a' <= ch  &&  ch <= 'f')        return 10 + (ch - 'a');    if ('A' <= ch  &&  ch <= 'F')        return 10 + (ch - 'A');    return -1;}// URL-decode string "str" into itself// Return 0 on success;  otherwise, return 1-based error positionstatic SIZE_TYPE s_URL_Decode(string& str){    SIZE_TYPE len = str.length();    if ( !len )        return 0;    SIZE_TYPE p = 0;    for (SIZE_TYPE pos = 0;  pos < len;  p++) {        switch ( str[pos] ) {        case '%': {            if (pos + 2 > len)                return (pos + 1);            int i1 = s_HexChar(str[pos+1]);            if (i1 < 0  ||  15 < i1)                return (pos + 2);            int i2 = s_HexChar(str[pos+2]);            if (i2 < 0  ||  15 < i2)                return (pos + 3);            str[p] = s_HexChar(str[pos+1]) * 16 + s_HexChar(str[pos+2]);            pos += 3;            break;        }        case '+': {            str[p] = ' ';            pos++;            break;        }        default:            str[p] = str[pos++];        }    }    if (p < len) {        str[p] = '\0';        str.resize(p);    }    return 0;}// Add another entry to the container of entriesvoid s_AddEntry(TCgiEntries& entries, const string& name,                const string& value, unsigned int position,                const string& filename = kEmptyStr){    entries.insert(TCgiEntries::value_type                   (name, CCgiEntry(value, filename, position)));}// Parse ISINDEX-like query string into "indexes" XOR "entries" --// whichever is not null// Return 0 on success;  return 1-based error position otherwisestatic SIZE_TYPE s_ParseIsIndex(const string& str,                                TCgiIndexes* indexes, TCgiEntries* entries){    _ASSERT( !indexes != !entries );    SIZE_TYPE len = str.length();    if ( !len )        return 0;    // No '=' and spaces must present in the parsed string    SIZE_TYPE err_pos = str.find_first_of("=& \t\r\n");    if (err_pos != NPOS)        return err_pos + 1;    // Parse into indexes    unsigned int num = 1;    for (SIZE_TYPE beg = 0;  beg < len;  ) {        // parse and URL-decode ISINDEX name        SIZE_TYPE end = str.find_first_of('+', beg);        if (end == beg  ||  end == len-1)            return end + 1;  // error        if (end == NPOS)            end = len;        string name = str.substr(beg, end - beg);        if ((err_pos = s_URL_Decode(name)) != 0)            return beg + err_pos;  // error        // store        if ( indexes ) {            indexes->push_back(name);        } else {            s_AddEntry(*entries, name, kEmptyStr, num++);        }        // continue        beg = end + 1;    }    return 0;}// Guess if "str" is ISINDEX- or FORM-like, then fill out// "entries" XOR "indexes";  if "indexes_as_entries" is "true" then// interprete indexes as FORM-like entries(with empty value) and so// put them to "entries"static void s_ParseQuery(const string& str,                         TCgiEntries&  entries,                         TCgiIndexes&  indexes,                         bool          indexes_as_entries){    if (str.find_first_of("=&") == NPOS) { // ISINDEX        SIZE_TYPE err_pos = indexes_as_entries ?            s_ParseIsIndex(str, 0, &entries) :            s_ParseIsIndex(str, &indexes, 0);        if (err_pos != 0)            NCBI_THROW2(CCgiParseException, eIndex,                        "Init CCgiRequest::ParseISINDEX(\"" +                        str + "\"", err_pos);    } else {  // regular(FORM) entries        SIZE_TYPE err_pos = CCgiRequest::ParseEntries(str, entries);        if (err_pos != 0)            NCBI_THROW2(CCgiParseException, eEntry,                        "Init CCgiRequest::ParseFORM(\"" +                        str + "\")", err_pos);    }}static string s_FindAttribute(const string& str, const string& name,                              SIZE_TYPE start, SIZE_TYPE end,                              bool required){    SIZE_TYPE att_pos = str.find("; " + name + "=\"", start);    if (att_pos == NPOS  ||  att_pos >= end) {        if (required) {            NCBI_THROW2(CCgiParseException, eAttribute,                        "s_FindAttribute: missing " + name + " in "                        + str.substr(start, end - start),                        start);        } else {            return kEmptyStr;        }    }    SIZE_TYPE att_start = att_pos + name.size() + 4;    SIZE_TYPE att_end   = str.find('\"', att_start);    if (att_end == NPOS  ||  att_end >= end) {        NCBI_THROW2(CCgiParseException, eFormat,                    "s_FindAttribute: malformatted " + name + " in "                    + str.substr(att_pos, end - att_pos),                    att_start);    }    return str.substr(att_start, att_end - att_start);}static void s_ParseMultipartEntries(const string& boundary,                                    const string& str,                                    TCgiEntries&  entries){    const string    s_Me("s_ParseMultipartEntries");    const string    s_Eol(HTTP_EOL);    const SIZE_TYPE eol_size = s_Eol.size();    SIZE_TYPE    pos           = 0;    SIZE_TYPE    boundary_size = boundary.size();    SIZE_TYPE    end_pos;    unsigned int num           = 1;    if (NStr::Compare(str, 0, boundary_size + eol_size, boundary + s_Eol)        != 0) {        if (NStr::StartsWith(str, boundary + "--")) {            // potential corner case: no actual data            return;        }        NCBI_THROW2(CCgiParseException, eEntry,                    s_Me + ": input does not start with boundary line "                    + boundary,                    0);    }    {{        SIZE_TYPE tail_size = boundary_size + eol_size + 2;        SIZE_TYPE tail_start = str.find(s_Eol + boundary + "--");        if (tail_start == NPOS) {            NCBI_THROW2(CCgiParseException, eEntry,                        s_Me + ": input does not contain trailing boundary "                        + boundary + "--",                        0);        }        end_pos = tail_start + tail_size;    }}    pos += boundary_size + eol_size;    while (pos < end_pos) {        SIZE_TYPE next_boundary = str.find(s_Eol + boundary, pos);        _ASSERT(next_boundary != NPOS);        string name, filename;        bool found = false;        for (;;) {            SIZE_TYPE bol_pos = pos, eol_pos = str.find(s_Eol, pos);            _ASSERT(eol_pos != NPOS);            if (pos == eol_pos) {                // blank -- end of headers                pos += eol_size;                break;            }            pos = str.find(':', bol_pos);            if (pos == NPOS  ||  pos >= eol_pos) {                NCBI_THROW2(CCgiParseException, eEntry,                            s_Me + ": no colon in header "                            + str.substr(bol_pos, eol_pos - bol_pos),                            bol_pos);            }            if (NStr::CompareNocase(str, bol_pos, pos - bol_pos,                                    "Content-Disposition") != 0) {                ERR_POST(Warning << s_Me << ": ignoring unrecognized header "                         + str.substr(bol_pos, eol_pos - bol_pos));                pos = eol_pos + eol_size;                continue;            }            if (NStr::CompareNocase(str, pos, 13, ": form-data; ") != 0) {                NCBI_THROW2(CCgiParseException, eEntry,                            s_Me + ": bad Content-Disposition header "                            + str.substr(bol_pos, eol_pos - bol_pos),                            pos);            }            pos += 11;            name     = s_FindAttribute(str, "name",     pos, eol_pos, true);            filename = s_FindAttribute(str, "filename", pos, eol_pos, false);            found = true;            pos = eol_pos + eol_size;        }        if (!found) {            NCBI_THROW2(CCgiParseException, eEntry,                        s_Me + ": missing Content-Disposition header", pos);        }        s_AddEntry(entries, name, str.substr(pos, next_boundary - pos),                   num++, filename);        pos = next_boundary + 2*eol_size + boundary_size;    }}static void s_ParsePostQuery(const string& content_type, const string& str,                             TCgiEntries& entries){    if (content_type.empty()  ||        content_type == "application/x-www-form-urlencoded") {        // remove trailing end of line '\r' and/or '\n'        // (this can happen if Content-Length: was not specified)        SIZE_TYPE err_pos;        SIZE_TYPE eol = str.find_first_of("\r\n");        if (eol != NPOS) {            err_pos = CCgiRequest::ParseEntries(str.substr(0, eol), entries);        } else {            err_pos = CCgiRequest::ParseEntries(str, entries);        }        if ( err_pos != 0 ) {            NCBI_THROW2(CCgiParseException, eEntry,                        "Init CCgiRequest::ParseFORM(\"" +                        str + "\")", err_pos);        }        return;

⌨️ 快捷键说明

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