Example #1
0
  /**
   * 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);
  }