ResolverFlags flags, ResolverState state)
throws PartialResolutionException
{
log.trace("resolveAuthSegment - segment='" + segment + "'");
XRDS xrdsOut = new XRDS();
XRDS tmpXRDS = null;
CanonicalID parentCID = null;
boolean authResComplete = false;
ResolverFlags currentFlags = null; // this is only for overriding by HttpsBypassAuthority settings
String parentXRI = ((XRIAuthority)qxri.getAuthorityPath()).getRootAuthority();
XRISegment remainingSegment = segment;
// if caching in use, we know that the root is always considered "cached"
boolean parentIsCached = cache != null;
while (remainingSegment != null && remainingSegment.getNumSubSegments() > 0) {
// clone flags
currentFlags = new ResolverFlags(flags);
// more subsegments to resolve
String query = remainingSegment.getSubSegmentAt(0).toURINormalForm(true);
log.debug("resolveAuthSegment - resolving subsegment '" + query + "'");
checkMaxRequests(xrdsOut, query, state);
// if HTTPS is requested and what we are resolving is allowed to bypass HTTPS, we turn off the HTTPS flag
// for auth-res service selection
if (currentFlags.isHttps() && isHttpsBypassAuthority(parentXRI)) {
log.debug("Bypassing HTTPS for " + parentXRI);
currentFlags.setHttps(false);
}
//// perform service selection
String authResMediaType = Tags.CONTENT_TYPE_XRDS + ";" + currentFlags.getTrustParameters();
List authResServices = selectServices(parent.getServices(), Tags.SERVICE_AUTH_RES, null, authResMediaType, currentFlags);
if (authResServices.size() < 1) {
log.debug("resolveAuthSegment - no authority resolution service found!");
throw makeResolutionException(
xrdsOut,
query,
Status.AUTH_RES_NOT_FOUND,
"Authority Resolution Service Not Found"
);
}
if (parentIsCached) {
// try retrieving from cache
String xriAuthority = XRI.fromURINormalForm(parentXRI + query).toURINormalForm();
log.debug("resolveAuthSegment - looking up in cache '" + xriAuthority + "'");
byte[] res = cache.get(xriAuthority, currentFlags.isHttps(), currentFlags.isSaml());
log.debug("resolveAuthSegment - cache " + ((res == null)? "MISS" : "HIT"));
if (res != null) {
// cache hit!
XRDS xrdsCached = null;
try {
xrdsCached = readXRDS(new ByteArrayInputStream(res));
}
catch (XRIResolutionException e) {
throw makeResolutionException(
xrdsOut,
query,
Status.INVALID_XRDS,
"Cached XRDS is invalid"
);
}
// we need to pass a Service object representing the authority resolution service
// that was selected but this only matters for SAML resolution, in which case, only
// one is allowed, so we just pass the first Service to it.
Service authRes = (Service) authResServices.get(0);
parseFetchedXRD(xrdsCached, xrdsCached.getDescriptorAt(0), parent, remainingSegment.getSubSegmentAt(0), authRes, flags);
tmpXRDS = xrdsCached;
}
}
// fetch from network if it is not cached