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

📄 ncbicgi.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    }    if ( NStr::StartsWith(content_type, "multipart/form-data") ) {        string start = "boundary=";        SIZE_TYPE pos = content_type.find(start);        if ( pos == NPOS )            NCBI_THROW2(CCgiParseException, eEntry,                        "CCgiRequest::ParsePostQuery(\"" +                        content_type + "\"): no boundary field", 0);        s_ParseMultipartEntries("--" + content_type.substr(pos + start.size()),                                str, entries);        return;    }    // The caller function thinks that s_ParsePostQuery() knows how to parse    // this content type, but s_ParsePostQuery() apparently cannot do it...    _TROUBLE;}CCgiRequest::~CCgiRequest(void){    SetInputStream(0);}CCgiRequest::CCgiRequest(const CNcbiArguments*   args, const CNcbiEnvironment* env, CNcbiIstream*           istr, TFlags                  flags, int                     ifd, size_t                  errbuf_size)    : m_Env(0),      m_ErrBufSize(errbuf_size){    x_Init(args, env, istr, flags, ifd);}CCgiRequest::CCgiRequest(int                argc, const char* const* argv, const char* const* envp, CNcbiIstream*      istr, TFlags             flags, int                ifd, size_t             errbuf_size)    : m_Env(0),      m_ErrBufSize(errbuf_size){    CNcbiArguments args(argc, argv);    CNcbiEnvironment* env = new CNcbiEnvironment(envp);    flags |= fOwnEnvironment;    x_Init(&args, env, istr, flags, ifd);}void CCgiRequest::x_Init(const CNcbiArguments*   args, const CNcbiEnvironment* env, CNcbiIstream*           istr, TFlags                  flags, int                     ifd){    // Setup environment variables    _ASSERT( !m_Env );    m_Env = env;    if ( !m_Env ) {        // create a dummy environment, if is not specified        m_OwnEnv.reset(new CNcbiEnvironment);        m_Env = m_OwnEnv.get();    } else if ((flags & fOwnEnvironment) != 0) {        // take ownership over the passed environment object        m_OwnEnv.reset(const_cast<CNcbiEnvironment*>(m_Env));    }    // Cache "standard" properties    for (size_t prop = 0;  prop < (size_t) eCgi_NProperties;  prop++) {        x_GetPropertyByName(GetPropertyName((ECgiProp) prop));    }    // Compose cookies    m_Cookies.Add(GetProperty(eCgi_HttpCookie));    // Parse entries or indexes from "$QUERY_STRING" or cmd.-line args    {{        const string* query_string = 0;        if ( GetProperty(eCgi_RequestMethod).empty() ) {            // special case: "$REQUEST_METHOD" undefined, so use cmd.-line args            if (args  &&  args->Size() > 1)                query_string = &(*args)[1];        }        else if ( !(flags & fIgnoreQueryString) ) {            // regular case -- read from "$QUERY_STRING"            query_string = &GetProperty(eCgi_QueryString);        }        if ( query_string ) {            s_ParseQuery(*query_string, m_Entries, m_Indexes,                         (flags & fIndexesNotEntries) == 0);        }    }}    // POST method?    if ( AStrEquiv(GetProperty(eCgi_RequestMethod), "POST", PNocase()) ) {        if ( !istr ) {            istr = &NcbiCin;  // default input stream            ifd = STDIN_FILENO;        }        const string& content_type = GetProperty(eCgi_ContentType);        if ((flags & fDoNotParseContent) == 0  &&            (content_type.empty()  ||             content_type == "application/x-www-form-urlencoded"  ||             NStr::StartsWith(content_type, "multipart/form-data"))) {            // Automagically retrieve and parse content into entries            string str;            size_t len = GetContentLength();            if (len == kContentLengthUnknown) {                // read data until end of file                for (;;) {                    char buffer[1024];                    istr->read(buffer, sizeof(buffer));                    size_t count = istr->gcount();                    if ( count == 0 ) {                        if ( istr->eof() ) {                            break; // end of data                        }                        else {                            THROW1_TRACE(runtime_error, "\CCgiRequest::x_Init() -- error in reading POST content: read fault");                        }                    }                    str.append(buffer, count);                }            }            else {                str.resize(len);                for (size_t pos = 0;  pos < len;  ) {                    size_t rlen = len - pos;                    istr->read(&str[pos], rlen);                    size_t count = istr->gcount();                    if ( count == 0 ) {                        str.resize(pos);                        if ( istr->eof() ) {                            string err = "\CCgiRequest::x_Init() -- error in reading POST content: unexpected EOF";                            string pos_str("(pos=");                            pos_str.append(NStr::UIntToString(pos));                            pos_str.append("; content_length=");                            pos_str.append(NStr::UIntToString(len));                            pos_str.append("):\n");                            if (m_ErrBufSize  &&  pos) {                                pos_str.append(NStr::PrintableString(str),                                               0, min(m_ErrBufSize, pos));                                if (m_ErrBufSize < pos) {                                    pos_str.append("\n[truncated...]");                                }                            }                            err.append(pos_str);                            THROW1_TRACE(runtime_error, err);                        }                        else {                            THROW1_TRACE(runtime_error, "\CCgiRequest::x_Init() -- error in reading POST content: read fault");                        }                    }                    pos += count;                }            }            // parse query from the POST content            s_ParsePostQuery(content_type, str, m_Entries);            m_Input    = 0;            m_InputFD = -1;        }        else {            // Let the user to retrieve and parse the content            m_Input    = istr;            m_InputFD  = ifd;            m_OwnInput = false;        }    } else {        m_Input   = 0;        m_InputFD = -1;    }    // Check for an IMAGEMAP input entry like: "Command.x=5&Command.y=3" and    // put them with empty string key for better access    if (m_Entries.find(kEmptyStr) != m_Entries.end()) {        // there is already empty name key        ERR_POST("empty key name:  we will not check for IMAGE names");        return;    }    string image_name;    ITERATE (TCgiEntries, i, m_Entries) {        const string& entry = i->first;        // check for our case ("*.x")        if ( !NStr::EndsWith(entry, ".x") )            continue;        // get base name of IMAGE, check for the presence of ".y" part        string name = entry.substr(0, entry.size() - 2);        if (m_Entries.find(name + ".y") == m_Entries.end())            continue;        // it is a correct IMAGE name        if ( !image_name.empty() ) {            ERR_POST("duplicated IMAGE name: \"" << image_name <<                     "\" and \"" << name << "\"");            return;        }        image_name = name;    }    s_AddEntry(m_Entries,   kEmptyStr, image_name, 0);}const string& CCgiRequest::x_GetPropertyByName(const string& name) const{    return m_Env->Get(name);}const string& CCgiRequest::GetProperty(ECgiProp property) const{    return x_GetPropertyByName(GetPropertyName(property));}const string& CCgiRequest::GetRandomProperty(const string& key, bool http)    const{    if ( http ) {        return x_GetPropertyByName("HTTP_" + key);    } else {        return x_GetPropertyByName(key);    }}const CCgiEntry& CCgiRequest::GetEntry(const string& name, bool* is_found)    const{    static const CCgiEntry kEmptyEntry(kEmptyStr);    TCgiEntriesCI it = GetEntries().find(name);    bool x_found = (it != GetEntries().end());    if ( is_found ) {        *is_found = x_found;    }    return x_found ? it->second : kEmptyEntry;}const size_t CCgiRequest::kContentLengthUnknown = (size_t)(-1);size_t CCgiRequest::GetContentLength(void) const{    const string& str = GetProperty(eCgi_ContentLength);    if ( str.empty() ) {        return kContentLengthUnknown;    }    return (size_t) NStr::StringToUInt(str);}void CCgiRequest::SetInputStream(CNcbiIstream* is, bool own, int fd){    if (m_Input  &&  m_OwnInput  &&  is != m_Input) {        delete m_Input;    }    m_Input    = is;    m_InputFD  = fd;    m_OwnInput = own;}SIZE_TYPE CCgiRequest::ParseEntries(const string& str, TCgiEntries& entries){    SIZE_TYPE len = str.length();    if ( !len )        return 0;    // If no '=' present in the parsed string then try to parse it as ISINDEX    if (str.find_first_of("&=") == NPOS)        return s_ParseIsIndex(str, 0, &entries);    // No spaces are allowed 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 entries    unsigned int num = 1;    for (SIZE_TYPE beg = 0;  beg < len;  ) {        // ignore 1st ampersand (it is just a temp. slack to some biz. clients)        if (beg == 0  &&  str[0] == '&') {            beg = 1;            continue;        }        // kludge for the sake of some older browsers, which fail to decode        // "&amp;" within hrefs.        if ( !NStr::CompareNocase(str, beg, 4, "amp;") ) {            beg += 4;        }        // parse and URL-decode name        SIZE_TYPE mid = str.find_first_of("=&", beg);        if (mid == beg  ||            (mid != NPOS  &&  str[mid] == '&'  &&  mid == len-1))            return mid + 1;  // error        if (mid == NPOS)            mid = len;        string name = str.substr(beg, mid - beg);        if ((err_pos = s_URL_Decode(name)) != 0)            return beg + err_pos;  // error        // parse and URL-decode value(if any)        string value;        if (str[mid] == '=') { // has a value            mid++;            SIZE_TYPE end = str.find_first_of(" &", mid);            if (end != NPOS  &&  (str[end] != '&'  ||  end == len-1))                return end + 1;  // error            if (end == NPOS)                end = len;            value = str.substr(mid, end - mid);            if ((err_pos = s_URL_Decode(value)) != 0)                return mid + err_pos;  // error            beg = end + 1;        } else {  // has no value            beg = mid + 1;        }        // store the name-value pair        s_AddEntry(entries, name, value, num++);    }    return 0;}SIZE_TYPE CCgiRequest::ParseIndexes(const string& str, TCgiIndexes& indexes){    return s_ParseIsIndex(str, &indexes, 0);}extern string URL_DecodeString(const string& str){    string    x_str = str;    SIZE_TYPE err_pos = s_URL_Decode(x_str);    if (err_pos != 0)        NCBI_THROW2(CCgiParseException, eFormat,                    "URL_DecodeString(<badly_formatted_str>)",err_pos);    return x_str;}extern string URL_EncodeString(const string& str, EUrlEncode encode_mark_chars){    static const char s_Encode[256][4] = {        "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07",        "%08", "%09", "%0A", "%0B", "%0C", "%0D", "%0E", "%0F",        "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17",        "%18", "%19", "%1A", "%1B", "%1C", "%1D", "%1E", "%1F",        "+",   "!",   "%22", "%23", "$",   "%25", "%26", "'",        "(",   ")",   "*",   "%2B", ",",   "-",   ".",   "%2F",

⌨️ 快捷键说明

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