author | Michael Krelin <hacker@klever.net> | 2007-01-09 20:04:29 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2007-01-09 20:04:29 (UTC) |
commit | 46fa1790c6d5e990030d8b2b7ae07cb150a49730 (patch) (side-by-side diff) | |
tree | 115419ff78232cfec478222b372d8c60e15dd0fc /lib/consumer.cc | |
parent | adc2d682fa4f0aa83b4359bb212eda616cbe39dd (diff) | |
download | libopkele-46fa1790c6d5e990030d8b2b7ae07cb150a49730.zip libopkele-46fa1790c6d5e990030d8b2b7ae07cb150a49730.tar.gz libopkele-46fa1790c6d5e990030d8b2b7ae07cb150a49730.tar.bz2 |
canonicalization bug - do not add '/' after '?', add it right after hostname if needed.
-rw-r--r-- | lib/consumer.cc | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/lib/consumer.cc b/lib/consumer.cc index cbe0769..bb6358c 100644 --- a/lib/consumer.cc +++ b/lib/consumer.cc @@ -240,102 +240,109 @@ namespace opkele { || (r=curl_easy_setopt(curl,CURLOPT_URL,server.c_str())) || (r=curl_easy_setopt(curl,CURLOPT_POST,1)) || (r=curl_easy_setopt(curl,CURLOPT_POSTFIELDS,request.data())) || (r=curl_easy_setopt(curl,CURLOPT_POSTFIELDSIZE,request.length())) || (r=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,_curl_tostring)) || (r=curl_easy_setopt(curl,CURLOPT_WRITEDATA,&response)) ; if(r) throw exception_curl(OPKELE_CP_ "failed to curl_easy_setopt()",r); if(r=curl_easy_perform(curl)) throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r); params_t pp; pp.parse_keyvalues(response); if(pp.has_param("invalidate_handle")) invalidate_assoc(server,pp.get_param("invalidate_handle")); if(pp.has_param("is_valid")) { if(pp.get_param("is_valid")=="true") return; }else if(pp.has_param("lifetime")) { if(util::string_to_long(pp.get_param("lifetime"))) return; } throw failed_check_authentication(OPKELE_CP_ "failed to verify response"); } void consumer_t::retrieve_links(const string& url,string& server,string& delegate) { server.erase(); delegate.erase(); curl_t curl = curl_easy_init(); if(!curl) throw exception_curl(OPKELE_CP_ "failed to curl_easy_init()"); string html; CURLcode r; (r=curl_misc_sets(curl)) || (r=curl_easy_setopt(curl,CURLOPT_URL,url.c_str())) || (r=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,_curl_tostring)) || (r=curl_easy_setopt(curl,CURLOPT_WRITEDATA,&html)) ; if(r) throw exception_curl(OPKELE_CP_ "failed to curl_easy_setopt()",r); r = curl_easy_perform(curl); if(r && r!=CURLE_WRITE_ERROR) throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r); pcrepp::Pcre bre("<body\\b",PCRE_CASELESS); // strip out everything past body if(bre.search(html)) html.erase(bre.get_match_start()); pcrepp::Pcre hdre("<head[^>]*>",PCRE_CASELESS); if(!hdre.search(html)) throw bad_input(OPKELE_CP_ "failed to find head"); html.erase(0,hdre.get_match_end()+1); pcrepp::Pcre lre("<link\\b([^>]+)>",PCRE_CASELESS), rre("\\brel=['\"]([^'\"]+)['\"]",PCRE_CASELESS), hre("\\bhref=['\"]([^'\"]+)['\"]",PCRE_CASELESS); while(lre.search(html)) { string attrs = lre[0]; html.erase(0,lre.get_match_end()+1); if(!(rre.search(attrs)&&hre.search(attrs))) continue; if(rre[0]=="openid.server") { server = hre[0]; if(!delegate.empty()) break; }else if(rre[0]=="openid.delegate") { delegate = hre[0]; if(!server.empty()) break; } } if(server.empty()) throw failed_assertion(OPKELE_CP_ "The location has no openid.server declaration"); } assoc_t consumer_t::find_assoc(const string& server) { throw failed_lookup(OPKELE_CP_ "no find_assoc() provided"); } string consumer_t::canonicalize(const string& url) { string rv = url; // strip leading and trailing spaces string::size_type i = rv.find_first_not_of(" \t\r\n"); if(i==string::npos) throw bad_input(OPKELE_CP_ "empty URL"); if(i) rv.erase(0,i); i = rv.find_last_not_of(" \t\r\n"); assert(i!=string::npos); if(i<(rv.length()-1)) rv.erase(i+1); // add missing http:// i = rv.find("://"); if(i==string::npos) { // primitive. but do we need more? rv.insert(0,"http://"); i = sizeof("http://")-1; }else{ i += sizeof("://")-1; } - if(rv.find('/',i)==string::npos) - rv += '/'; + string::size_type qm = rv.find('?',i); + string::size_type sl = rv.find('/',i); + if(qm!=string::npos) { + if(sl==string::npos || sl>qm) + rv.insert(qm,1,'/'); + }else{ + if(sl==string::npos) + rv += '/'; + } return rv; } } |