• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#if !defined(__has_feature) || !__has_feature(objc_arc)
6#error "This file requires ARC support."
7#endif
8
9#import "remoting/ios/host_refresh.h"
10
11#import "remoting/ios/authorize.h"
12#import "remoting/ios/host.h"
13#import "remoting/ios/utility.h"
14
15namespace {
16NSString* kDefaultErrorMessage = @"The Host list refresh is not available at "
17    @"this time.  Please try again later.";
18}  // namespace
19
20@interface HostRefresh (Private)
21- (void)authentication:(GTMOAuth2Authentication*)auth
22               request:(NSMutableURLRequest*)request
23                 error:(NSError*)error;
24- (void)formatErrorMessage:(NSString*)error;
25- (void)notifyDelegate;
26@end
27
28// Logic flow begins with refreshHostList, and continues until an error occurs,
29// or the host list is returned to the delegate
30@implementation HostRefresh
31
32@synthesize jsonData = _jsonData;
33@synthesize errorMessage = _errorMessage;
34@synthesize delegate = _delegate;
35
36// Override default constructor and initialize internals
37- (id)init {
38  self = [super init];
39  if (self) {
40    _jsonData = [[NSMutableData alloc] init];
41  }
42  return self;
43}
44
45// Begin the authentication and authorization process.  Begin the process by
46// creating an oAuth2 request to google api's including the needed scopes to
47// fetch the users host list.
48- (void)refreshHostList:(GTMOAuth2Authentication*)authReq
49               delegate:(id<HostRefreshDelegate>)delegate {
50
51  CHECK(_delegate == nil);  // Do not reuse an instance of this class
52
53  _delegate = delegate;
54
55  [Authorize beginRequest:authReq
56                 delegate:self
57        didFinishSelector:@selector(authentication:request:error:)];
58}
59
60// Handle completion of the authorization process. Append service credentials
61// for jabber.  If an error occurred, notify user.
62- (void)authentication:(NSObject*)auth
63               request:(NSMutableURLRequest*)request
64                 error:(NSError*)error {
65  if (error != nil) {
66    [self formatErrorMessage:error.localizedDescription];
67  } else {
68    // Add credentials for service
69    [Authorize appendCredentials:request];
70
71    // Begin connection, the returned reference is not useful right now and
72    // marked as __unused
73    __unused NSURLConnection* connection =
74        [[NSURLConnection alloc] initWithRequest:request delegate:self];
75  }
76}
77
78// @protocol NSURLConnectionDelegate, handle any error during connection
79- (void)connection:(NSURLConnection*)connection
80    didFailWithError:(NSError*)error {
81  [self formatErrorMessage:[error localizedDescription]];
82
83  [self notifyDelegate];
84}
85
86// @protocol NSURLConnectionDataDelegate, may be called async multiple times.
87// Each call appends the new data to the known data until completed.
88- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
89  [_jsonData appendData:data];
90}
91
92// @protocol NSURLConnectionDataDelegate
93// Ensure connection succeeded: HTTP 200 OK
94- (void)connection:(NSURLConnection*)connection
95    didReceiveResponse:(NSURLResponse*)response {
96  NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
97  if ([response respondsToSelector:@selector(allHeaderFields)]) {
98    NSNumber* responseCode =
99        [[NSNumber alloc] initWithInteger:[httpResponse statusCode]];
100    if (responseCode.intValue != 200) {
101      [self formatErrorMessage:[NSString
102                                   stringWithFormat:@"HTTP STATUS CODE: %d",
103                                                    [httpResponse statusCode]]];
104    }
105  }
106}
107
108// @protocol NSURLConnectionDataDelegate handle a completed connection, parse
109// received data, and return host list to delegate
110- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
111  [self notifyDelegate];
112}
113
114// Store a formatted error message to return later
115- (void)formatErrorMessage:(NSString*)error {
116  _errorMessage = kDefaultErrorMessage;
117  if (error != nil && error.length > 0) {
118    _errorMessage = [_errorMessage
119        stringByAppendingString:[@" " stringByAppendingString:error]];
120  }
121}
122
123// The connection has finished, call to delegate
124- (void)notifyDelegate {
125  if (_jsonData.length == 0 && _errorMessage == nil) {
126    [self formatErrorMessage:nil];
127  }
128
129  [_delegate hostListRefresh:[Host parseListFromJSON:_jsonData]
130                errorMessage:_errorMessage];
131}
132@end
133