1/*
2 *  Copyright 2014 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#import "ARDTURNClient+Internal.h"
12
13#import "ARDUtilities.h"
14#import "RTCIceServer+JSON.h"
15
16// TODO(tkchin): move this to a configuration object.
17static NSString *kTURNRefererURLString = @"https://appr.tc";
18static NSString *kARDTURNClientErrorDomain = @"ARDTURNClient";
19static NSInteger kARDTURNClientErrorBadResponse = -1;
20
21@implementation ARDTURNClient {
22  NSURL *_url;
23}
24
25- (instancetype)initWithURL:(NSURL *)url {
26  NSParameterAssert([url absoluteString].length);
27  if (self = [super init]) {
28    _url = url;
29  }
30  return self;
31}
32
33- (void)requestServersWithCompletionHandler:
34    (void (^)(NSArray *turnServers, NSError *error))completionHandler {
35
36  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
37  [NSURLConnection sendAsyncRequest:request
38                  completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
39      if (error) {
40        completionHandler(nil, error);
41        return;
42      }
43      NSDictionary *responseDict = [NSDictionary dictionaryWithJSONData:data];
44      NSString *iceServerUrl = responseDict[@"ice_server_url"];
45      [self makeTurnServerRequestToURL:[NSURL URLWithString:iceServerUrl]
46                 WithCompletionHandler:completionHandler];
47    }];
48}
49
50#pragma mark - Private
51
52- (void)makeTurnServerRequestToURL:(NSURL *)url
53             WithCompletionHandler:(void (^)(NSArray *turnServers,
54                                             NSError *error))completionHandler {
55  NSMutableURLRequest *iceServerRequest = [NSMutableURLRequest requestWithURL:url];
56  iceServerRequest.HTTPMethod = @"POST";
57  [iceServerRequest addValue:kTURNRefererURLString forHTTPHeaderField:@"referer"];
58  [NSURLConnection sendAsyncRequest:iceServerRequest
59                  completionHandler:^(NSURLResponse *response,
60                                      NSData *data,
61                                      NSError *error) {
62      if (error) {
63        completionHandler(nil, error);
64        return;
65      }
66      NSDictionary *turnResponseDict = [NSDictionary dictionaryWithJSONData:data];
67      NSMutableArray *turnServers = [NSMutableArray array];
68      [turnResponseDict[@"iceServers"]
69          enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
70            [turnServers addObject:[RTC_OBJC_TYPE(RTCIceServer) serverFromJSONDictionary:obj]];
71          }];
72      if (!turnServers) {
73        NSError *responseError =
74          [[NSError alloc] initWithDomain:kARDTURNClientErrorDomain
75                                     code:kARDTURNClientErrorBadResponse
76                                 userInfo:@{
77            NSLocalizedDescriptionKey: @"Bad TURN response.",
78            }];
79        completionHandler(nil, responseError);
80        return;
81      }
82      completionHandler(turnServers, nil);
83    }];
84}
85
86@end
87