/** * Static builder. It wraps out a {@link SRVRecord} by extracting relevant data. * * @param srvRecord A {@link SRVRecord} instance to be worked out * @return An instance of <code>ServiceRecord</code> */ public static ServiceRecord build(SRVRecord srvRecord) { String proto = "N/A"; String owner = srvRecord.getName().toString(); if (owner.contains(Constants.TCP)) proto = Constants.TCP.replace("_", "").toUpperCase(); else if (owner.contains(Constants.UDP)) proto = Constants.UDP.replace("_", "").toUpperCase(); return new ServiceRecord( srvRecord.getName().toString(), srvRecord.getTarget().toString(), proto, srvRecord.getPort(), srvRecord.getPriority(), srvRecord.getWeight(), srvRecord.getTTL()); }
/** * Finds the initial service URL from a given base URI (HTTP[S] or mailto URI, user name, * password) * * @param serverInfo User-given service information (including base URI, i.e. HTTP[S] URL+user * name+password or mailto URI and password) * @param serviceName Service name ("carddav" or "caldav") * @return Initial service URL (HTTP/HTTPS), without user credentials * @throws URISyntaxException when the user-given URI is invalid */ public URI getInitialContextURL(ServerInfo serverInfo, String serviceName) throws URISyntaxException { String scheme, domain; int port = -1; String path = "/"; URI baseURI = serverInfo.getBaseURI(); if ("mailto".equalsIgnoreCase(baseURI.getScheme())) { // mailto URIs String mailbox = serverInfo.getBaseURI().getSchemeSpecificPart(); // determine service FQDN int pos = mailbox.lastIndexOf("@"); if (pos == -1) throw new URISyntaxException(mailbox, "Missing @ sign"); scheme = "https"; domain = mailbox.substring(pos + 1); if (domain.isEmpty()) throw new URISyntaxException(mailbox, "Missing domain name"); } else { // HTTP(S) URLs scheme = baseURI.getScheme(); domain = baseURI.getHost(); port = baseURI.getPort(); path = baseURI.getPath(); } // try to determine FQDN and port number using SRV records try { String name = "_" + serviceName + "s._tcp." + domain; Log.d(TAG, "Looking up SRV records for " + name); Record[] records = new Lookup(name, Type.SRV).run(); if (records != null && records.length >= 1) { SRVRecord srv = selectSRVRecord(records); scheme = "https"; domain = srv.getTarget().toString(true); port = srv.getPort(); Log.d( TAG, "Found " + serviceName + "s service for " + domain + " -> " + domain + ":" + port); if (port == 443) // no reason to explicitly give the default port port = -1; // SRV record found, look for TXT record too (for initial context path) records = new Lookup(name, Type.TXT).run(); if (records != null && records.length >= 1) { TXTRecord txt = (TXTRecord) records[0]; for (Object o : txt.getStrings().toArray()) { String segment = (String) o; if (segment.startsWith("path=")) { path = segment.substring(5); Log.d( TAG, "Found initial context path for " + serviceName + " at " + domain + " -> " + path); break; } } } } } catch (TextParseException e) { throw new URISyntaxException(domain, "Invalid domain name"); } return new URI(scheme, null, domain, port, path, null, null); }