예제 #1
0
void Global_Config::load(int argc,char *argv[],char const *def)
{
    if(loaded) {
        return;
    }
    char const *def_file=def;
    int i;
    for(i=1; i<argc; i++) {
        if(strncmp(argv[i],"--config=",9)==0) {
            def_file=argv[i]+9;
            break;
        }
        else if(strcmp(argv[i],"-c")==0 && i+1<argc) {
            def_file=argv[i+1];
            break;
        }
    }
    if(def_file==NULL) {
        throw HTTP_Error("Configuration file not defined");
    }
    load(def_file);
}
예제 #2
0
bool Global_Config::get_tocken(FILE *f,tocken_t &T)
{
    int c;
    while((c=fgetc(f))!=EOF) {
        if(c=='.') {
            T.first='.';
            return true;
        }
        else if(c=='=') {
            T.first='=';
            return true;
        }
        else if(c=='\n') {
            line_counter++;
            continue;
        }
        else if(c==' ' || c=='\r' || c=='\t') {
            continue;
        }
        else if(isalpha(c)) {
            T.second="";
            T.second.reserve(32);
            T.second+=(char)c;
            while((c=fgetc(f))!=EOF && (isalnum(c) || c=='_')) {
                T.second+=(char)c;
            }
            if(c!=EOF) {
                ungetc(c,f);
            }
            T.first=WORD;
            return true;
        }
        else if(isdigit(c) || c=='-') {
            T.second="";
            T.second.reserve(32);
            T.second+=(char)c;
            T.first=INT;
            while((c=fgetc(f))!=EOF && isdigit(c)) {
                T.second+=(char)c;
            }
            if(c=='.') {
                T.second+='.';
                T.first=DOUBLE;
                while((c=fgetc(f))!=EOF && isdigit(c)) {
                    T.second+=(char)c;
                }
            }
            if(T.second=="-" || T.second=="." || T.second=="-.") {
                throw HTTP_Error("Illegal charrecters");
            }
            if(c!=EOF) {
                ungetc(c,f);
            }
            return true;
        }
        else if(c=='\"') {
            T.first=STR;
            T.second="";
            T.second.reserve(128);
            for(;;) {
                c=fgetc(f);
                if(c=='\\') {
                    if((c=fgetc(f))=='\"' ) {
                        T.second+='"';
                        continue;
                    }
                    else {
                        T.second+='\\';
                    }
                }
                if(c==EOF) {
                    throw HTTP_Error("Unexpected EOF ");
                }
                if(c=='\n') line_counter++;
                if(c=='\"') {
                    return true;
                }
                T.second+=(char)c;
            }
        }
        else if(c=='#' || c==';') {
            while((c=fgetc(f))!=EOF) {
                if(c=='\n') {
                    line_counter++;
                    break;
                }
            }
            if(c==EOF) {
                return false;
            }

        }
        else {
            throw HTTP_Error(string("Unexpected charrecter")+(char)c);
        }
    }
    return false;
}
예제 #3
0
void Global_Config::load(char const *fname)
{
    if(loaded) {
        return;
    }
    FILE *f=fopen(fname,"r");
    line_counter=1;
    if(!f) {
        throw HTTP_Error(string("Failed to open file:")+fname);
    }
    tocken_t T;
    string key;
    int state=0;
    try {
        while(get_tocken(f,T) && state != 5) {
            switch(state) {
            case 0:
                if(T.first != WORD) {
                    state=5;
                } else {
                    key=T.second;
                    state=1;
                }
                break;
            case 1:
                if(T.first != '.')
                    state=5;
                else
                    state=2;
                break;
            case 2:
                if(T.first!=WORD) {
                    state=5;
                } else {
                    state=3;
                    key+='.';
                    key+=T.second;
                }
                break;
            case 3:
                if(T.first!= '=')
                    state=5;
                else
                    state=4;
                break;
            case 4:
                if(T.first==INT) {
                    long val=atol(T.second.c_str());
                    long_map.insert(pair<string,long>(key,val));
                }
                else if(T.first==DOUBLE) {
                    double val=atof(T.second.c_str());
                    double_map.insert(pair<string,double>(key,val));
                }
                else if(T.first==STR) {
                    string_map.insert(pair<string,string>(key,T.second));
                }
                else {
                    state=5;
                    break;
                }
                state=0;
                break;
            }
        }
        if(state!=0) {
            throw HTTP_Error("Parsing error");
        }
    }
    catch (HTTP_Error &err) {
        fclose(f);
        char stmp[32];
        snprintf(stmp,32," at line %d",line_counter);
        throw HTTP_Error(string(err.get())+stmp);
    }
    fclose(f);
    loaded=true;
}
예제 #4
0
파일: http_util.cpp 프로젝트: louiz/botan
Response http_sync(http_exch_fn http_transact,
                   const std::string& verb,
                   const std::string& url,
                   const std::string& content_type,
                   const std::vector<byte>& body,
                   size_t allowable_redirects)
{
    if(url.empty())
        throw HTTP_Error("URL empty");

    const auto protocol_host_sep = url.find("://");
    if(protocol_host_sep == std::string::npos)
        throw HTTP_Error("Invalid URL '" + url + "'");

    const auto host_loc_sep = url.find('/', protocol_host_sep + 3);

    std::string hostname, loc;

    if(host_loc_sep == std::string::npos)
    {
        hostname = url.substr(protocol_host_sep + 3, std::string::npos);
        loc = "/";
    }
    else
    {
        hostname = url.substr(protocol_host_sep + 3, host_loc_sep-protocol_host_sep-3);
        loc = url.substr(host_loc_sep, std::string::npos);
    }

    std::ostringstream outbuf;

    outbuf << verb << " " << loc << " HTTP/1.0\r\n";
    outbuf << "Host: " << hostname << "\r\n";

    if(verb == "GET")
    {
        outbuf << "Accept: */*\r\n";
        outbuf << "Cache-Control: no-cache\r\n";
    }
    else if(verb == "POST")
        outbuf << "Content-Length: " << body.size() << "\r\n";

    if(!content_type.empty())
        outbuf << "Content-Type: " << content_type << "\r\n";
    outbuf << "Connection: close\r\n\r\n";
    outbuf.write(reinterpret_cast<const char*>(body.data()), body.size());

    std::istringstream io(http_transact(hostname, outbuf.str()));

    std::string line1;
    std::getline(io, line1);
    if(!io || line1.empty())
        throw HTTP_Error("No response");

    std::stringstream response_stream(line1);
    std::string http_version;
    unsigned int status_code;
    std::string status_message;

    response_stream >> http_version >> status_code;

    std::getline(response_stream, status_message);

    if(!response_stream || http_version.substr(0,5) != "HTTP/")
        throw HTTP_Error("Not an HTTP response");

    std::map<std::string, std::string> headers;
    std::string header_line;
    while (std::getline(io, header_line) && header_line != "\r")
    {
        auto sep = header_line.find(": ");
        if(sep == std::string::npos || sep > header_line.size() - 2)
            throw HTTP_Error("Invalid HTTP header " + header_line);
        const std::string key = header_line.substr(0, sep);

        if(sep + 2 < header_line.size() - 1)
        {
            const std::string val = header_line.substr(sep + 2, (header_line.size() - 1) - (sep + 2));
            headers[key] = val;
        }
    }

    if(status_code == 301 && headers.count("Location"))
    {
        if(allowable_redirects == 0)
            throw HTTP_Error("HTTP redirection count exceeded");
        return GET_sync(headers["Location"], allowable_redirects - 1);
    }

    std::vector<byte> resp_body;
    std::vector<byte> buf(4096);
    while(io.good())
    {
        io.read(reinterpret_cast<char*>(buf.data()), buf.size());
        resp_body.insert(resp_body.end(), buf.data(), &buf[io.gcount()]);
    }

    const std::string header_size = search_map(headers, std::string("Content-Length"));

    if(!header_size.empty())
    {
        if(resp_body.size() != to_u32bit(header_size))
            throw HTTP_Error("Content-Length disagreement, header says " +
                             header_size + " got " + std::to_string(resp_body.size()));
    }

    return Response(status_code, status_message, resp_body, headers);
}