forked from eczarny/xmlrpc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathXMLRPCHTTPTransport.m
153 lines (125 loc) · 4.79 KB
/
XMLRPCHTTPTransport.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#import "XMLRPCHTTPTransport.h"
#import "XMLRPCRequest.h"
#import "XMLRPCResponse.h"
#import "Parsing.h"
#import "ClientOperation.h"
@interface XMLRPCClientHTTPTransport () {
NSURL* _url;
}
@end
@interface HTTPClientOperation : ClientOperation <NSURLConnectionDelegate> {
@public
XMLRPCRequest* _request;
NSMutableData* _data;
NSURLConnection* _connection;
NSURLRequest* _urlRequest;
NSURL* _url;
NSString* _userAgent;
id<XMLRPCClientDelegate> _delegate;
}
@end
@implementation XMLRPCClientHTTPTransport
- (id) initWithURL:(NSURL*)url {
if(self = [self init]) {
_url = url;
}
return self;
}
- (NSOperation<XMLRPCClientTransportOperation>*)sendRequest:(XMLRPCRequest*)request delegate: (id<XMLRPCClientDelegate>)delegate {
HTTPClientOperation* op = [HTTPClientOperation new];
op->_delegate = delegate;
op->_request = request;
op->_url = _url;
op->_userAgent = self.userAgent;
return op;
}
- (BOOL)supportsConcurrentRequests {
return YES;
}
@end
@implementation HTTPClientOperation
- (BOOL)isAsynchronous {
return YES;
}
- (void)cancel {
[_connection cancel];
[super cancel];
}
- (void)start {
NSData *content = [[_request body] dataUsingEncoding: NSUTF8StringEncoding];
NSMutableURLRequest* r = [NSMutableURLRequest requestWithURL:_url];
[r setHTTPMethod: @"POST"];
NSString* mime = [_request mimeType];
if(mime) {
[r addValue: mime forHTTPHeaderField: @"Content-Type"];
[r addValue: mime forHTTPHeaderField: @"Accept"];
}
if (_userAgent) {
[r addValue: _userAgent forHTTPHeaderField:@"User-Agent"];
}
[r addValue:[NSString stringWithFormat:@"%lu", (unsigned long)[content length]] forHTTPHeaderField: @"Content-Length"];
[r setHTTPBody: content];
_urlRequest = r;
[super start];
}
- (void)main {
_data = [NSMutableData data];
_connection = [NSURLConnection connectionWithRequest:_urlRequest delegate:self];
_urlRequest = nil;
[_connection scheduleInRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
[_connection start];
}
- (void)connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response {
if([response respondsToSelector: @selector(statusCode)]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if(statusCode >= 400) {
NSError *error = [NSError errorWithDomain: @"HTTP" code: statusCode
userInfo: @{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"HTTP error code %ld", (long)statusCode]}];
[_connection cancel];
_connection = nil;
[_delegate request: _request didFailWithError: error];
[self finishWithResponse:nil error:error];
}
}
[_data setLength: 0];
}
- (void)connection: (NSURLConnection *)connection didReceiveData: (NSData *)data {
[_data appendData: data];
}
- (void)connection: (NSURLConnection *)connection didSendBodyData: (NSInteger)bytesWritten totalBytesWritten: (NSInteger)totalBytesWritten totalBytesExpectedToWrite: (NSInteger)totalBytesExpectedToWrite {
if ([_delegate respondsToSelector: @selector(request:didSendBodyData:)]) {
float percent = totalBytesWritten / (float)totalBytesExpectedToWrite;
[_delegate request:_request didSendBodyData:percent];
}
}
- (void)connection: (NSURLConnection *)connection didFailWithError: (NSError *)error {
[_delegate request: _request didFailWithError: error];
_connection = nil;
[self finishWithResponse:nil error:error];
}
#pragma mark -
- (BOOL)connection: (NSURLConnection *)connection canAuthenticateAgainstProtectionSpace: (NSURLProtectionSpace *)protectionSpace {
return [_delegate request: _request canAuthenticateAgainstProtectionSpace: protectionSpace];
}
- (void)connection: (NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
[_delegate request: _request didReceiveAuthenticationChallenge: challenge];
}
- (void)connection: (NSURLConnection *)connection didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
[_delegate request: _request didCancelAuthenticationChallenge: challenge];
}
- (void)connectionDidFinishLoading: (NSURLConnection *)connection {
_connection = nil;
if ([_data length] > 0) {
[Parsing parseXMLRPCResponseAsyncFromData:_data withCompletion:^(XMLRPCResponse *response) {
response.userObject = _request.userObject;
[_delegate request:_request didReceiveResponse:response];
[self finishWithResponse:response error:nil];
}];
}
else {
[_delegate request:_request didReceiveResponse:nil];
[self finishWithResponse:nil error:nil];
}
}
@end