-rw-r--r-- | include/opkele/discovery.h | 10 | ||||
-rw-r--r-- | lib/discovery.cc | 29 |
2 files changed, 31 insertions, 8 deletions
diff --git a/include/opkele/discovery.h b/include/opkele/discovery.h index ab4b9d9..677d7bb 100644 --- a/include/opkele/discovery.h +++ b/include/opkele/discovery.h | |||
@@ -32,13 +32,21 @@ namespace opkele { | |||
32 | } | 32 | } |
33 | }; | 33 | }; |
34 | 34 | ||
35 | typedef priority_map<string> canonical_ids_t; | 35 | typedef priority_map<string> canonical_ids_t; |
36 | typedef priority_map<string> local_ids_t; | 36 | typedef priority_map<string> local_ids_t; |
37 | typedef set<string> types_t; | 37 | typedef set<string> types_t; |
38 | typedef priority_map<string> uris_t; | 38 | struct uri_t { |
39 | string uri; | ||
40 | string append; | ||
41 | |||
42 | uri_t() { } | ||
43 | uri_t(const string& u) : uri(u) { } | ||
44 | uri_t(const string& u,const string& a) : uri(u), append(a) { } | ||
45 | }; | ||
46 | typedef priority_map<uri_t> uris_t; | ||
39 | 47 | ||
40 | class service_t { | 48 | class service_t { |
41 | public: | 49 | public: |
42 | types_t types; | 50 | types_t types; |
43 | uris_t uris; | 51 | uris_t uris; |
44 | local_ids_t local_ids; | 52 | local_ids_t local_ids; |
diff --git a/lib/discovery.cc b/lib/discovery.cc index 93409f4..6e20654 100644 --- a/lib/discovery.cc +++ b/lib/discovery.cc | |||
@@ -56,12 +56,21 @@ namespace opkele { | |||
56 | if(!strcasecmp(*(a++),"priority")) { | 56 | if(!strcasecmp(*(a++),"priority")) { |
57 | long rv; | 57 | long rv; |
58 | return (sscanf(*a,"%ld",&rv)==1)?rv:-1; | 58 | return (sscanf(*a,"%ld",&rv)==1)?rv:-1; |
59 | } | 59 | } |
60 | return -1; | 60 | return -1; |
61 | } | 61 | } |
62 | /* TODO: ideally all attributes should be | ||
63 | * retrieved in one run */ | ||
64 | static const char *element_attr(const XML_Char **a, const char *at) { | ||
65 | for(;*a;++a) | ||
66 | if(!strcasecmp(*(a++),at)) { | ||
67 | return *a; | ||
68 | } | ||
69 | return 0; | ||
70 | } | ||
62 | 71 | ||
63 | class idigger_t : public util::curl_t, public util::expat_t { | 72 | class idigger_t : public util::curl_t, public util::expat_t { |
64 | public: | 73 | public: |
65 | string xri_proxy; | 74 | string xri_proxy; |
66 | 75 | ||
67 | enum { | 76 | enum { |
@@ -115,14 +124,13 @@ namespace opkele { | |||
115 | throw bad_input(OPKELE_CP_ "not a character of importance in identity"); | 124 | throw bad_input(OPKELE_CP_ "not a character of importance in identity"); |
116 | string id(identity,fsc,lsc-fsc+1); | 125 | string id(identity,fsc,lsc-fsc+1); |
117 | idis.clear(); | 126 | idis.clear(); |
118 | if(strchr(i_leaders,id[0])) { | 127 | if(strchr(i_leaders,id[0])) { |
119 | /* TODO: further normalize xri identity? Like folding case | 128 | /* TODO: further normalize xri identity? Like folding case |
120 | * or whatever... */ | 129 | * or whatever... */ |
121 | rv = idis.normalized_id = id; | 130 | rv = id; |
122 | idis.xri_identity = true; | ||
123 | set<string> cids; | 131 | set<string> cids; |
124 | for(const struct service_type_t *st=service_types; | 132 | for(const struct service_type_t *st=service_types; |
125 | st<&service_types[sizeof(service_types)/sizeof(*service_types)];++st) { | 133 | st<&service_types[sizeof(service_types)/sizeof(*service_types)];++st) { |
126 | idis.clear(); | 134 | idis.clear(); |
127 | discover_at( idis, | 135 | discover_at( idis, |
128 | xri_proxy + util::url_encode(id)+ | 136 | xri_proxy + util::url_encode(id)+ |
@@ -152,12 +160,13 @@ namespace opkele { | |||
152 | throw failed_xri_resolution(OPKELE_CP_ | 160 | throw failed_xri_resolution(OPKELE_CP_ |
153 | "XRI resolution failed with '"+status_string+"' message" | 161 | "XRI resolution failed with '"+status_string+"' message" |
154 | ", while looking for SEP with type '"+st->uri+"'" | 162 | ", while looking for SEP with type '"+st->uri+"'" |
155 | " on canonical id", status_code); | 163 | " on canonical id", status_code); |
156 | } | 164 | } |
157 | idis.canonicalized_id = cid; | 165 | idis.canonicalized_id = cid; |
166 | idis.normalized_id = rv; idis.xri_identity = true; | ||
158 | queue_endpoints(oi,idis,st); | 167 | queue_endpoints(oi,idis,st); |
159 | } | 168 | } |
160 | }else{ | 169 | }else{ |
161 | idis.xri_identity = false; | 170 | idis.xri_identity = false; |
162 | if(id.find("://")==string::npos) | 171 | if(id.find("://")==string::npos) |
163 | id.insert(0,"http://"); | 172 | id.insert(0,"http://"); |
@@ -192,13 +201,12 @@ namespace opkele { | |||
192 | } | 201 | } |
193 | } | 202 | } |
194 | return rv; | 203 | return rv; |
195 | } | 204 | } |
196 | 205 | ||
197 | void discover_at(idiscovery_t& idis,const string& url,int xm) { | 206 | void discover_at(idiscovery_t& idis,const string& url,int xm) { |
198 | DOUT_("Doing discovery at " << url); | ||
199 | CURLcode r = easy_setopt(CURLOPT_URL,url.c_str()); | 207 | CURLcode r = easy_setopt(CURLOPT_URL,url.c_str()); |
200 | if(r) | 208 | if(r) |
201 | throw exception_curl(OPKELE_CP_ "failed to set culry urlie",r); | 209 | throw exception_curl(OPKELE_CP_ "failed to set culry urlie",r); |
202 | 210 | ||
203 | http_content_type.clear(); | 211 | http_content_type.clear(); |
204 | xmode = xm; | 212 | xmode = xm; |
@@ -387,13 +395,15 @@ namespace opkele { | |||
387 | if(is_qelement(n,NSURI_XRD "\tType")) { | 395 | if(is_qelement(n,NSURI_XRD "\tType")) { |
388 | assert(xrd); assert(xrd_service); | 396 | assert(xrd); assert(xrd_service); |
389 | cdata_buf.clear(); | 397 | cdata_buf.clear(); |
390 | cdata = &cdata_buf; | 398 | cdata = &cdata_buf; |
391 | }else if(is_qelement(n,NSURI_XRD "\tURI")) { | 399 | }else if(is_qelement(n,NSURI_XRD "\tURI")) { |
392 | assert(xrd); assert(xrd_service); | 400 | assert(xrd); assert(xrd_service); |
393 | cdata = &(xrd_service->uris.add(element_priority(a),string())); | 401 | const char *append = element_attr(a,"append"); |
402 | xrd::uri_t& uri = xrd_service->uris.add(element_priority(a),xrd::uri_t("",append?append:"")); | ||
403 | cdata = &uri.uri; | ||
394 | }else if(is_qelement(n,NSURI_XRD "\tLocalID") | 404 | }else if(is_qelement(n,NSURI_XRD "\tLocalID") |
395 | || is_qelement(n,NSURI_OPENID10 "\tDelegate") ) { | 405 | || is_qelement(n,NSURI_OPENID10 "\tDelegate") ) { |
396 | assert(xrd); assert(xrd_service); | 406 | assert(xrd); assert(xrd_service); |
397 | cdata = &(xrd_service->local_ids.add(element_priority(a),string())); | 407 | cdata = &(xrd_service->local_ids.add(element_priority(a),string())); |
398 | }else if(is_qelement(n,NSURI_XRD "\tProviderID")) { | 408 | }else if(is_qelement(n,NSURI_XRD "\tProviderID")) { |
399 | assert(xrd); assert(xrd_service); | 409 | assert(xrd); assert(xrd_service); |
@@ -481,17 +491,17 @@ namespace opkele { | |||
481 | ns = string::npos; | 491 | ns = string::npos; |
482 | }else{ | 492 | }else{ |
483 | rel.assign(rels,ns,s-ns); | 493 | rel.assign(rels,ns,s-ns); |
484 | ns = s; | 494 | ns = s; |
485 | } | 495 | } |
486 | if(rel=="openid.server") | 496 | if(rel=="openid.server") |
487 | html_openid1.uris.add(-1,href); | 497 | html_openid1.uris.add(-1,xrd::uri_t(href)); |
488 | else if(rel=="openid.delegate") | 498 | else if(rel=="openid.delegate") |
489 | html_openid1.local_ids.add(-1,href); | 499 | html_openid1.local_ids.add(-1,href); |
490 | else if(rel=="openid2.provider") | 500 | else if(rel=="openid2.provider") |
491 | html_openid2.uris.add(-1,href); | 501 | html_openid2.uris.add(-1,xrd::uri_t(href)); |
492 | else if(rel=="openid2.local_id") | 502 | else if(rel=="openid2.local_id") |
493 | html_openid2.local_ids.add(-1,href); | 503 | html_openid2.local_ids.add(-1,href); |
494 | } | 504 | } |
495 | }else if(is_element(n,"body")) { | 505 | }else if(is_element(n,"body")) { |
496 | skipping = -1; | 506 | skipping = -1; |
497 | } | 507 | } |
@@ -504,13 +514,18 @@ namespace opkele { | |||
504 | ep.claimed_id = id.canonicalized_id; | 514 | ep.claimed_id = id.canonicalized_id; |
505 | for(xrd::services_t::const_iterator isvc=id.xrd.services.begin(); | 515 | for(xrd::services_t::const_iterator isvc=id.xrd.services.begin(); |
506 | isvc!=id.xrd.services.end(); ++isvc) { | 516 | isvc!=id.xrd.services.end(); ++isvc) { |
507 | const xrd::service_t svc = isvc->second; | 517 | const xrd::service_t svc = isvc->second; |
508 | if(svc.types.find(st->uri)==svc.types.end()) continue; | 518 | if(svc.types.find(st->uri)==svc.types.end()) continue; |
509 | for(xrd::uris_t::const_iterator iu=svc.uris.begin();iu!=svc.uris.end();++iu) { | 519 | for(xrd::uris_t::const_iterator iu=svc.uris.begin();iu!=svc.uris.end();++iu) { |
510 | ep.uri = iu->second; | 520 | ep.uri = iu->second.uri; |
521 | if(id.xri_identity) { | ||
522 | if(iu->second.append=="qxri") { | ||
523 | ep.uri += id.normalized_id; | ||
524 | } /* TODO: else handle other append attribute values */ | ||
525 | } | ||
511 | if(st->forceid) { | 526 | if(st->forceid) { |
512 | ep.local_id = ep.claimed_id = st->forceid; | 527 | ep.local_id = ep.claimed_id = st->forceid; |
513 | *(oi++) = ep; | 528 | *(oi++) = ep; |
514 | }else{ | 529 | }else{ |
515 | if(svc.local_ids.empty()) { | 530 | if(svc.local_ids.empty()) { |
516 | ep.local_id = ep.claimed_id; | 531 | ep.local_id = ep.claimed_id; |