All Products
Search
Document Center

HTTPDNS:Using HTTPDNS in iOS native scenarios

Last Updated:Jan 04, 2026

This topic describes how to implement a direct IP connection when you integrate HTTPDNS into an iOS app. For more information about how to integrate HTTPDNS on iOS, see iOS SDK integration.

1. Introduction

In mobile network environments, issues such as DNS hijacking and local DNS cache pollution often prevent domain names from resolving correctly, which leads to network request failures. For these scenarios, Alibaba Cloud HTTPDNS provides a reliable recursive domain name resolution service. This service helps mobile apps bypass the potential risks of local DNS and improves the success rate and stability of network requests.

However, using HTTPDNS on the iOS platform requires you to replace the original domain name in a request with the resolved IP address before you initiate the request. This can cause additional issues, especially in complex scenarios such as HTTPS and Server Name Indication (SNI). Therefore, before you integrate HTTPDNS, you must have a comprehensive understanding of the potential issues and viable solutions. This ensures that you can use HTTPDNS safely and correctly in your business.

This topic describes the main issues that you may encounter when using HTTPDNS on iOS. It also provides integration solutions for different scenarios, along with their pros and cons, to help developers quickly complete HTTPDNS integration.

2. Issues when using HTTPDNS on iOS

In mobile applications, if you replace the domain name in the original URL, such as example.com, with the IP address resolved by HTTPDNS, you often encounter the following issues. These problems are closely related to how the HTTPS protocol uses the Host field at different layers: the TLS/SSL layer and the HTTP layer.

  • TLS/SSL layer: In an HTTPS scenario, the client first performs a TLS/SSL handshake. The client uses the Host from the URL to complete the following tasks:

    1. Certificate verification: Verifies that the domain name of the server certificate (Common Name or Subject Alternative Name) matches the requested Host.

    2. SNI: When establishing a TLS connection, the client sends the requested domain name information (the Host in the URL) to the server. This allows the server to return the corresponding certificate.

  • HTTP layer: After the TLS handshake is complete, the client includes the Host field in the HTTP request header. This tells the server the specific site or resource for the request. If you replace the domain name in the URL with an IP address and do not manually set the Host in the HTTP header, the server may not be able to identify the actual domain name being accessed. This can cause the request to fail or return abnormal content.

Based on the role of the Host at various layers of the HTTPS protocol stack, replacing the domain name in the URL with the IP address resolved by HTTPDNS causes the following technical issues:

  1. Domain name and certificate mismatch For an HTTPS request, if you directly use the IP address resolved by HTTPDNS as the Host in the URL, the TLS layer cannot match the correct certificate domain name (Common Name or SAN additional domain name). This causes the SSL handshake to fail.

  2. SNI issues In an SNI scenario, a single server IP address may correspond to certificates for multiple domain names. If the client does not pass the correct domain name information during the SSL handshake phase and sends only the IP address, the server cannot return a certificate that matches the domain name. This causes the SSL handshake to fail. Because high-level network APIs in iOS, such as NSURLSession, do not expose an interface to directly configure SNI, SNI issues are often difficult to solve with simple methods.

  3. Host header and service addressing If you replace the domain name in the URL with an IP address but forget to explicitly set the Host in the HTTP request header to the original domain name, the server-side may not be able to identify the specific site or resource at the HTTP layer. For example, in a CDN scenario, the server relies on the Host field to distribute the correct content. If the Host is an IP address, the service becomes abnormal.

  4. Choice of underlying network library The built-in high-level APIs in iOS, such as NSURLSession, have limited extensibility for customizing SNI or manual certificate verification. If a developer wants to handle SNI or modify the TLS handshake logic, they need to use lower-level interfaces, such as CFNetwork or libcurl. However, this increases development and maintenance costs.

In summary, directly replacing the domain name in a URL with the IP address resolved by HTTPDNS affects certificate verification and SNI transmission at the TLS layer in HTTPS scenarios. It may also cause Host header information to be abnormal at the HTTP layer. Therefore, when you integrate HTTPDNS on iOS, you must solve these issues in a targeted manner to ensure the reliability and security of network requests.

3. Integration solutions for plain HTTP and HTTPS (non-SNI) scenarios

For plain HTTP or HTTPS + non-SNI scenarios, you can typically continue to use the system's built-in NSURLSession and regular network request logic with some relatively simple adjustments. Note that plain HTTP scenarios do not involve a TLS handshake or certificate verification. In contrast, HTTPS + non-SNI scenarios require certificate verification, which you can handle by hooking the verification process in NSURLSession.

3.1 Plain HTTP scenarios

For plain HTTP requests, there is no TLS/SSL handshake or certificate verification in the network link. Therefore, the core operation for integrating HTTPDNS is performed only at the HTTP layer:

  1. Replace the Host in the request URL with the IP address resolved by HTTPDNS.

    • For example, if the original request URL is http://example.com/api and HTTPDNS resolves it to the IP address 1.2.3.4, you can change the URL to http://1.2.3.4/api.

  2. Explicitly set the Host in the HTTP header to the original domain name.

    • If you use NSMutableURLRequest, you can add request.allHTTPHeaderFields[@"Host"] = @"example.com"; to the request header. This ensures that the server can identify the correct domain name at the application layer.

Note

Pros: Simple to implement. It only requires replacing the Host and setting the header in the existing HTTP request, which means low development effort.

Cons: Only applicable to the plain HTTP protocol. It cannot solve certificate verification and SNI-related issues in HTTPS scenarios.

3.2 HTTPS (non-SNI) scenarios

For HTTPS sites that do not use the SNI mechanism or contain only a few fixed domain names (the certificate covers only these domains), you can integrate HTTPDNS and perform certificate verification at the NSURLSession layer as follows:

  1. Replace the Host in the request URL with the IP address resolved by HTTPDNS.

    • For example, if the original request URL is https://example.com/api and HTTPDNS resolves it to the IP address 1.2.3.4, you can change the URL to https://1.2.3.4/api.

  2. Explicitly set the Host in the HTTP header to the original domain name.

    • Similarly, you can set request.allHTTPHeaderFields[@"Host"] = @"example.com"; in NSMutableURLRequest.

  3. Hooking the certificate verification process

    • Because this is an HTTPS request, certificate verification is required during the TLS handshake. At this point, if you directly use the IP address as the Host for the check, a domain name and certificate mismatch issue occurs.

    • In the NSURLSessionDelegate callback method URLSession:didReceiveChallenge:completionHandler:, when you verify the serverTrust obtained from the system, you can replace the IP address with the original domain name (example.com). This allows the certificate verification to pass.

    • Code example:

      - (void)URLSession:(NSURLSession *)session
                    task:(NSURLSessionTask *)task
      didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
        completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
                                    NSURLCredential *credential))completionHandler {
          if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
              NSString *originalHost = [self getOriginalHostFromRequest:task.originalRequest];
              SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
              if ([self evaluateServerTrust:serverTrust forDomain:originalHost]) {
                  // The certificate is verified.
                  NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
                  completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
              } else {
                  // Certificate verification failed. Use the default handler.
                  completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
              }
          } else {
              completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
          }
      }
      
      - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain {
          // Create a certificate verification policy.
          NSMutableArray *policies = [NSMutableArray array];
          if (domain) {
              [policies addObject:(__bridge_transfer id) SecPolicyCreateSSL(true, (__bridge CFStringRef) domain)];
          } else {
              [policies addObject:(__bridge_transfer id) SecPolicyCreateBasicX509()];
          }
      
          // Bind the verification policy to the server certificate.
          SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef) policies);
          // Evaluate whether the current serverTrust is trusted. Apple recommends that the serverTrust can be verified if the result is kSecTrustResultUnspecified or kSecTrustResultProceed. For more information, see https://developer.apple.com/library/ios/technotes/tn2232/_index.html.
          // For more information about SecTrustResultType, see SecTrust.h.
          SecTrustResultType result;
          SecTrustEvaluate(serverTrust, &result);
          return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
      }

Note

Pros:

  • You do not need to import additional third-party libraries. You can directly use the native system NSURLSession and certificate verification logic.

  • The implementation cost is relatively manageable, which is suitable for scenarios that do not involve SNI or require only a small number of domain name certificates.

Cons:

  • Cannot handle SNI scenarios. If multiple domain names are deployed on the same IP address, such as in a CDN scenario, the handshake still fails because the server returns the wrong certificate.

4. Integration solutions for HTTPS (SNI) scenarios

For SNI (single IP with multiple HTTPS domain names) scenarios, the simple NSURLSession solution cannot send the correct domain name information during the SSL handshake phase, which causes the handshake to fail. To solve this issue, you need to modify or specify the SNI field at a lower Socket level. The following are three common methods:

4.1 Custom NSURLProtocol implementation

iOS allows developers to intercept network requests initiated by the system by inheriting NSURLProtocol. You can then implement the HTTP/HTTPS request logic at a lower level. You can manually complete all network operations based on interfaces such as CFNetwork or NSInputStream/NSOutputStream:

  1. Intercept requests

    • In the canInitWithRequest: method, you can determine whether to intercept the current request.

    • In the startLoading method, you can replace the domain name in the original request URL with the IP address. You must retain the original domain name for subsequent certificate verification and SNI settings.

  2. Set SNI

    • Using CFStream-related APIs or the SecureTransport interface, you can specify kCFStreamSSLPeerName as the original domain name. This ensures that the underlying layer includes the correct domain name information during the SSL handshake phase.

  3. Verify certificates

    • You can manually execute the certificate verification process to ensure that the domain name included in the certificate matches the original domain name.

Note

Pros: Does not depend on third-party libraries. It is entirely based on low-level system APIs and offers high flexibility.

Cons: High implementation cost. Developers need to manually handle redirection, cookies, caching, encoding, and traffic statistics. It does not support connection reuse, which results in average performance. It also carries a high maintenance risk and requires extra adaptation when the system or network environment is upgraded.

For a reference example, see the HttpDnsNSURLProtocolImpl.m sample implementation that Alibaba Cloud provides in httpdns_ios_demo. You can modify or reuse it as needed.

4.2 Using libcurl for network requests

libcurl is a cross-platform network library implemented in C. It supports manually setting the SNI field to pass the correct domain name information during the SSL handshake. This completes certificate verification in scenarios where multiple domain names share the same IP address. The general process is as follows:

  1. Resolve the domain name to obtain the corresponding IP address.

    • For example, you can use an HTTPDNS API operation such as resolveHostSyncNonBlocking: to obtain the IP address of the target domain name.

  2. Configure the SNI and IP mapping.

    • Use CURLOPT_RESOLVE or other APIs to add the "domain:port:resolved_IP" mapping to curl's internal DNS cache.

    • Continue to use the original domain name for CURLOPT_URL. This ensures that the correct domain name is included in the TLS handshake.

  3. Verify certificates.

    • libcurl enables certificate verification by default. You can also use corresponding callbacks for more fine-grained checks on certificates as needed.

The following core code snippet (pseudocode) demonstrates how to use the result of HTTPDNS resolution with libcurl to complete a request in iOS:

CURL *curl_handle = curl_easy_init();
if (curl_handle) {
    // For example, get IP = 1.2.3.4 from HTTPDNS, target domain name = example.com, port = 443
    struct curl_slist *dnsResolve = NULL;
    dnsResolve = curl_slist_append(dnsResolve, "example.com:443:1.2.3.4");
    // Set the domain-to-IP mapping.
    curl_easy_setopt(curl_handle, CURLOPT_RESOLVE, dnsResolve);

    // Continue to use the original domain name as the URL.
    curl_easy_setopt(curl_handle, CURLOPT_URL, "https://example.com");

    // Enable SSL verification.
    curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 1L);
    curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2L);

    // Initiate the request.
    CURLcode res = curl_easy_perform(curl_handle);

    // Check the result.
    if (res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    }

    // Clean up.
    curl_easy_cleanup(curl_handle);
    curl_slist_free_all(dnsResolve);
}
Note

Pros:

  • Mature and stable, supports a rich set of protocols, and can adapt to complex network environments. It has built-in support for SNI scenarios.

Cons:

  • Requires compiling libcurl into the iOS project and using a pure C interface, which has a learning curve for Objective-C/Swift developers.

  • It also requires you to handle custom request flows or encapsulate HTTP logic, such as for cookies, redirection, and caching.

4.3 Using EMASCurl

To lower the barrier to entry for using libcurl directly on iOS, the Alibaba Cloud EMAS team provides the EMASCurl library. It encapsulates libcurl and supports direct integration with HTTPDNS.

  1. Installation and interception

    • It provides two main usage methods: 1) Intercept an NSURLSession created with a specific NSURLSessionConfiguration. 2) Intercept the system's global [NSURLSession sharedSession].

    • For more information about API interfaces, see the README file on GitHub.

  2. Integration with HTTPDNS

    • You can implement the EMASCurlProtocolDNSResolver protocol to pass the HTTPDNS resolution result to EMASCurl.

    • In the resolveDomain: method, you can call [HttpDnsService resolveHostSyncNonBlocking:] to obtain the IP address. Then, you can return the IP address to EMASCurl to complete the subsequent SNI setting and request sending.

  3. Certificate verification

    • EMASCurl relies on the certificate verification mechanism of libcurl. Developers can also extend or customize certificate verification through corresponding interfaces to meet business requirements.

  4. HTTP/3 support

    • EMASCurl provides EMASCurl/HTTP3, an encapsulated version based on a QUIC-enabled libcurl. Developers can integrate it as needed to use HTTP/3 capabilities without extra adaptation.

Note

Pros:

  • Encapsulates the underlying capabilities of libcurl, with an API that is more familiar to iOS developers.

  • Easily integrates with HTTPDNS through a DNS Hook mechanism.

  • Solves both the domain name transmission and certificate verification issues in SNI scenarios and reduces integration costs.

  • Supports HTTP/3 out-of-the-box, with no need for self-compilation and adaptation.

Cons:

  • Depends on third-party libraries (EMASCurl and libcurl), so you need to pay attention to compatibility, version upgrades, and other factors.

  • For very complex HTTP attributes or custom requirements, you may still need to read and understand the internal encapsulation of EMASCurl to ensure business availability.

Important
  • When you integrate EMASCurl, you must test common HTTP/HTTPS attributes, such as redirection, cookies, and concurrent requests, to ensure that they meet your business requirements.

  • If your business has strict security or network performance requirements, you must evaluate the performance of EMASCurl on the current iOS system version.

  • You must ensure that requests and handshakes can be completed normally in different network environments, such as Wi-Fi, cellular networks, and proxies.

5. Summary

You can choose a solution based on your business needs, such as whether you need to support SNI, multiple domain names, and certificate verification. The following table compares the different solutions:

Solution

Scenarios

Pros

Cons

Set Host and Header only

Plain HTTP scenarios

- Lowest integration cost

- Only for plain HTTP protocol

NSURLSession + Hook certificate verification

(Still requires setting Host and Header)

HTTPS (non-SNI) scenarios

- Low integration cost

- Uses system APIs, no extra libraries needed

- Does not support SNI

Custom NSURLProtocol

All scenarios

Requires more flexible low-level control

- Completely based on low-level system APIs

- High flexibility

- High development and maintenance costs

- No connection reuse, average performance

- Requires manual handling of redirection, cookies, caching, encoding, and other special cases

libcurl

All scenarios

Cross-platform or custom HTTP flows

- Mature and stable

- Supports SNI field setting and rich protocols

- Flexible certificate verification extension

- C interface has a learning curve for Objective-C/Swift developers

- Requires manual encapsulation for cookies, redirection, caching, etc.

EMASCurl

All scenarios

For simple integration on iOS

- Good encapsulation of libcurl

- Simple integration with HTTPDNS

- Implements SNI and certificate verification

- Supports HTTP/3

- Depends on third-party libraries, requires attention to compatibility and upgrades

- Special requirements may need custom development by reading the source code

You can evaluate these solutions based on your business's multi-domain needs, network security requirements, compatibility, maintenance costs, and acceptance of third-party libraries. You must choose the most suitable integration solution and thoroughly test the availability and security of network requests before the solution is published.