全部产品
存储与CDN 数据库 安全 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 阿里云办公 培训与认证 物联网
HTTPDNS

Android SDK手册

更新时间:2017-09-06 16:05:23

HTTPDNS Android SDK开发指南


1. 前言

本文档介绍了HTTPDNS Android SDK的使用方式。

HTTPDNS是阿里云面向移动开发者提供的移动端DNS解析服务。通过该SDK,开发者可以在自己的Android APP中获得可靠、实时、精准的DNS解析服务,彻底解决传统DNS面临的域名劫持、解析时延长、调度不精准等问题。

您可以通过获取alicloud-android-demo工程源码获得HTTPDNS服务的使用例程。

1.1 手动集成SDK

  • 您可以通过上述github demo获取HTTPDNS SDK;
  • 您可以通过访问移动服务APP列表页(https://ams.console.aliyun.com/#/appList 若您第一次访问,请创建APP),点击下图红框中的下载OneSDK,进入OneSDK下载页并勾选HTTPDNS组件获取SDKapplistsdk download

1.2 Maven集成

  • build.gradle中添加Maven仓库地址:
  1. allprojects {
  2. repositories {
  3. maven {
  4. url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
  5. }
  6. }
  7. }
  • gradle添加依赖:
  1. dependencies {
  2. compile 'com.aliyun.ams:alicloud-android-httpdns:1.1.3'
  3. }

开发时可以如上所述指定完整的版本号,也可以指定模糊版本号,gradle自动拉取满足条件的最新版本SDK,如compile 'com.aliyun.ams:alicloud-android-httpdns:1.+'

若SDK集成过程中出现UTDID冲突,请参考 阿里云-移动云产品SDK UTDID冲突解决方案


2. 应用程序初始化

2.1 获取服务实例

2.1.1 普通方式

HTTPDNS Android SDK以全局service实例的方式提供域名解析服务,您可以通过以下方式获取实例:

  1. HttpDnsService httpdns = HttpDns.getService(applicationContext, accountID);
  2. // 参数applicationContext是您Android App的Context
  3. // 参数accountID是系统分配的Account ID,当您开通HTTPDNS后,您可以在控制台获取到您对应的Account ID信息

2.1.2 鉴权方式

httpdns v1.1.3及以上版本支持鉴权方式,该方式需要去httpdns控制台进行关闭非鉴权接口(请慎重操作),详情见鉴权解析接口,您可以通过以下方式获取实例:

  1. HttpDnsService httpdns = HttpDns.getService(applicationContext, accountID, secretKey);
  2. // 参数applicationContext是您Android App的Context
  3. // 参数accountID是系统分配的Account ID,当您开通HTTPDNS后,您可以在控制台获取到您对应的Account ID信息
  4. // 参数secretKey是鉴权对应的secretKey

鉴权默认过期时间为10分钟

2.2 设置预解析域名

在您初始化程序时,可以选择性地预先向HTTPDNS SDK中注册您后续可能会使用到的域名,以便SDK提前解析,减少后续解析域名时请求的时延。您只需调用以下接口:

  1. ArrayList<String> hostList = new ArrayList<>(Arrays.asList("www.taobao.com", "www.aliyun.com"));
  2. httpdns.setPreResolveHosts(hostList);

注意预解析接口设置的同时会实时触发异步网络请求,应该在代码逻辑上确保调用预解析接口时,已经进行了必备的初始化设置。

比如:setHTTPSRequestEnabled: 需要在预解析接口之前调用,否则会导致预解析的相关 IP 采用 HTTP请求。

3. 服务API与使用示例

3.1 服务API

  1. /**
  2. * 获取HTTPDNS服务实例
  3. *
  4. * @param applicationContext 您的Android App Context
  5. * @param accountId 您的HTTPDNS租户ID
  6. */
  7. HttpDnsService getService(Context applicationContext, String accountID);
  8. /**
  9. * 将app使用到的域名预设进来,以便于HTTPDNS 进行预解析
  10. *
  11. * @param hostList 预解析列表
  12. */
  13. void setPreResolveHosts(ArrayList<String> hostList);
  14. /**
  15. * 设置网络切换时是否自动刷新所有域名解析结果,如果打开此开关,在网络切换时,会自动刷新所有域名的解析结果,但会产生一定流量消耗
  16. *
  17. * @param enable
  18. */
  19. void setPreResolveAfterNetworkChanged(boolean enable);
  20. /**
  21. * 设置降级策略,用户可定制规则降级为原生DNS解析方式
  22. *
  23. * @param filter 降级代理
  24. */
  25. void setDegradationFilter(DegradationFilter filter);
  26. public interface DegradationFilter {
  27. /**
  28. * 降级过滤器
  29. *
  30. * @param hostName 当前的目标域名(如www.aliyun.com),您可以针对域名进行降级过滤
  31. * @return 是否降级走原生DNS逻辑
  32. */
  33. boolean shouldDegradeHttpDNS(String hostName);
  34. }
  35. /**
  36. * 是否允许HTTPDNS返回TTL过期的域名
  37. * 当您允许返回TTL过期的IP时,SDK在实时返回过期IP的同时依然会进行异步更新以获取最新的IP信息
  38. *
  39. * @param enable 是否返回TTL过期域名
  40. */
  41. void setExpiredIPEnabled(boolean enable);
  42. /**
  43. * 是否允许启用持久化缓存功能
  44. *
  45. * @param enable
  46. */
  47. void setCachedIPEnabled(boolean enable);
  48. /***
  49. * 校正App签名时间
  50. * @param time time为epoch时间戳,1970年1月1日以来的秒数
  51. */
  52. void setAuthCurrentTime(long time);
  53. /**
  54. * 是否允许HTTPDNS打印Log
  55. *
  56. * @param shouldPrintLog 是否打印Log
  57. */
  58. void setLogEnabled(boolean shouldPrintLog);
  59. /**
  60. * 设置自定义请求超时时间,默认为15S
  61. *
  62. * @param timeoutInterval 单位是毫秒(ms)
  63. */
  64. void setTimeoutInterval(int timeoutInterval);
  65. /**
  66. * 设置是否通过HTTPS协议解析域名,默认通过HTTP协议解析
  67. *
  68. * @param enabled
  69. */
  70. void setHTTPSRequestEnabled(boolean enabled);
  71. /**
  72. * 异步解析接口,首先查询缓存,若存在则返回结果,若不存在返回null并且进行异步域名解析更新缓存。
  73. * 若接口返回null,,为避免影响业务请降级到local dns解析策略。
  74. *
  75. * @param host 域名(如www.aliyun.com)
  76. * @return 域名对应的解析结果
  77. */
  78. String getIpByHostAsync(String host);
  79. /**
  80. * 异步解析接口, 获取ip列表,首先查询缓存,若存在则返回结果,若不存在返回长度为0 的String 数组并且进行异步域名解析更新缓存。
  81. * 若接口返回长度为0 的String 数组,为避免影响业务请降级到local dns解析策略。
  82. *
  83. * @param host
  84. * @return 域名对应的解析结果列表
  85. */
  86. String[] getIpsByHostAsync(String host);

关于异步解析接口调用的最佳实践,请参考如何利用HTTPDNS降低DNS解析开销


HTTPDNS Android SDK已在v1.0.12版本中下线同步解析接口String getIpByHost(String host)String[] getIpsByHost(String host)。从安全角度我们强烈建议用户使用异步解析接口。在DDOS攻击等特殊场景下,HTTPDNS有可能会触发流量黑洞,此时同步接口就有可能出现短暂的请求解析超时等待,而异步接口的网络请求都是后台操作的,业务层面不会感知到请求超时的动作,能够做到对异常情况的冗余。

  1. /**
  2. * 同步解析接口,首先查询缓存,若存在则返回结果,若不存在则进行同步域名解析请求,解析完成返回最新解析结果,若解析失败返回null。
  3. *
  4. * @param host 域名(如www.aliyun.com)
  5. * @return 域名对应的解析结果
  6. */
  7. String getIpByHost(String host);
  8. /**
  9. * 同步解析接口, 获取ip列表,首先查询缓存,若存在则返回结果,若不存在则进行同步域名解析请求,解析完成返回最新解析结果,若解析失败返回长度为0 的String 数组。
  10. *
  11. * @param host
  12. * @return 域名对应的解析结果列表
  13. */
  14. String[] getIpsByHost(String host);

3.2 使用示例

您可以通过获取alicloud-android-demo工程源码获得HTTPDNS服务的使用例程。

4. 注意事项

4.1 HTTP请求头HOST字段设置

标准的HTTP协议中服务端会将HTTP请求头HOST字段的值作为请求的域名信息进行解析。使用HTTPDNS后,您可能需要将HTTP请求URL中的HOST字段替换为HTTPDNS解析获得的IP,这时标准的网络库会将您的IP赋值给HTTP请求头的HOST字段,进而导致服务端的解析异常(服务端认可的是您的域名信息,而非IP信息)。为了解决这个问题,您可以主动设置HTTP请求HOST字段的值,如:

  1. String originalUrl = "http://www.aliyun.com/";
  2. URL url = new URL(originalURL);
  3. String originalHost = url.getHost();
  4. // 异步接口获取IP
  5. String ip = httpdns.getIpsByHostAsync(originalHost);
  6. HttpURLConnection conn;
  7. if (ip != null) {
  8. // 通过HTTPDNS获取IP成功,进行URL替换和HOST头设置
  9. url = new URL(originalUrl.replaceFirst(originalHost, ip));
  10. conn = (HttpURLConnection) url.openConnection();
  11. // 设置请求HOST字段
  12. conn.setRequestProperty("Host", originHost);
  13. } else {
  14. conn = (HttpURLConnection) url.openConnection();
  15. }

部分网络库支持COOKIE的自动存储管理,当您使用HTTPDNS进行IP URL请求时,部分网络库会将您URL中的IP信息作为COOKIE对应的域名信息进行存储管理(而非HTTP请求头HOST字段信息),进而造成COOKIE管理与使用上的困扰,因此您需要关闭COOKIE的自动管理功能(默认关闭)。

4.3 HTTPS/WebView/SNI场景

4.4 代理情况下的使用

当存在中间HTTP代理时,客户端发起的请求中请求行会使用绝对路径的URL,在您开启HTTPDNS并采用IP URL进行访问时,中间代理将识别您的IP信息并将其作为真实访问的HOST信息传递给目标服务器,这时目标服务器将无法处理这类无真实HOST信息的HTTP请求。移动网关提供了X-Online-Host的私有协议字段来解决这个问题,比如:

  1. 目标URLhttp://www.aliyun.com/product/oss/
  2. 通过HTTPDNS解析出来的www.aliyun.comIP1.1.1.1
  3. 代理:10.0.0.172:80
  4. 您的HTTP请求头:
  5. GET http://1.1.1.1/product/oss/ HTTP/1.1 # 通过代理发起的HTTP请求头,请求行是一个绝对路径
  6. Host: www.aliyun.com # 这个Header会被代理网关忽略,代理网关会使用请求行绝对路径中的host字段作为源站的host,即1.1.1.1
  7. X-Online-Host: www.aliyun.com # 这个Header就是移动网关为了传递真实Host添加的私有头部,源站需要配置识别该私有头部以获取真实的Host信息

同样您可以通过setRequestProperty方法进行X-Online-Host请求头域的设置,并在服务端设置对该私有头域的解析。

在绝大多数场景下,我们建议您在代理模式下关闭HTTPDNS功能。

5. 混淆配置

  1. -keep class com.alibaba.sdk.android.**{*;}
  2. -keep class com.ut.**{*;}
  3. -keep class com.ta.**{*;}

本文导读目录