Skip to content

Commit b1030ec

Browse files
Merge pull request #64 from kefahB/master
[IOS] Keeping response standard between AFSuccess and AFFailure
2 parents 29c50b8 + c585dd4 commit b1030ec

File tree

4 files changed

+87
-40
lines changed

4 files changed

+87
-40
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ Option | Description
115115
`certificate: string` | The uri path to your `.cer` certificate file.
116116
`allowInvalidCertificates?: boolean` | Default: `false`. This should **always** be `false` if you are using SSL pinning. Set this to `true` if you're using a self-signed certificate.
117117
`validatesDomainName?: boolean` | Default: `true`. Determines if the domain name should be validated with your pinned certificate.
118+
`useLegacy?: boolean` | Default: `false`. [IOS only] set to true in order to get the response data (when status >= 300)in the `content` directly instead of `response.body.content`.
118119

119120
## Webpack / bundling
120121
Since you're probably shipping a certificate with your app (like [our demo does](https://github.com/EddyVerbruggen/nativescript-https/tree/master/demo/app/assets)),

src/https.common.d.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Headers } from 'tns-core-modules/http';
2+
export interface HttpsSSLPinningOptions {
3+
host: string;
4+
certificate: string;
5+
allowInvalidCertificates?: boolean;
6+
validatesDomainName?: boolean;
7+
commonName?: string;
8+
useLegacy?: boolean;
9+
}
10+
export interface HttpsRequestObject {
11+
[key: string]: string | number;
12+
}
13+
export interface HttpsRequestOptions {
14+
url: string;
15+
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD';
16+
headers?: Headers;
17+
params?: HttpsRequestObject;
18+
body?: HttpsRequestObject;
19+
allowLargeResponse?: boolean;
20+
timeout?: number;
21+
}
22+
export interface HttpsResponse {
23+
headers?: Headers;
24+
statusCode?: number;
25+
content?: any;
26+
reason?: string;
27+
reject?: boolean;
28+
failure?: any;
29+
}

src/https.common.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export interface HttpsSSLPinningOptions {
66
allowInvalidCertificates?: boolean;
77
validatesDomainName?: boolean;
88
commonName?: string;
9+
useLegacy?: boolean;
910
}
1011

1112
export interface HttpsRequestObject {
@@ -36,4 +37,5 @@ export interface HttpsResponse {
3637
content?: any;
3738
reason?: string;
3839
reject?: boolean;
40+
failure?: any;
3941
}

src/https.ios.ts

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ interface Ipolicies {
77
secure?: AFSecurityPolicy;
88
}
99

10+
let useLegacy: boolean = false;
11+
1012
let policies: Ipolicies = {
1113
def: AFSecurityPolicy.defaultPolicy(),
1214
secured: false,
@@ -23,6 +25,7 @@ export function enableSSLPinning(options: Https.HttpsSSLPinningOptions) {
2325
let data = NSData.dataWithContentsOfFile(options.certificate);
2426
policies.secure.pinnedCertificates = NSSet.setWithObject(data);
2527
}
28+
useLegacy = (isDefined(options.useLegacy)) ? options.useLegacy : false;
2629
policies.secured = true;
2730
console.log('nativescript-https > Enabled SSL pinning');
2831
}
@@ -35,51 +38,41 @@ export function disableSSLPinning() {
3538
console.info('nativescript-https > Disabled SSL pinning by default');
3639

3740
function AFSuccess(resolve, task: NSURLSessionDataTask, data?: NSDictionary<string, any> & NSData & NSArray<any>) {
38-
let content: any;
39-
if (data && data.class) {
40-
if (data.enumerateKeysAndObjectsUsingBlock || (<any>data) instanceof NSArray) {
41-
let serial = NSJSONSerialization.dataWithJSONObjectOptionsError(data, NSJSONWritingOptions.PrettyPrinted);
42-
content = NSString.alloc().initWithDataEncoding(serial, NSUTF8StringEncoding).toString();
43-
} else if ((<any>data) instanceof NSData) {
44-
content = NSString.alloc().initWithDataEncoding(data, NSASCIIStringEncoding).toString();
45-
} else {
46-
content = data;
47-
}
48-
49-
try {
50-
content = JSON.parse(content);
51-
} catch (ignore) {
52-
}
53-
54-
} else {
55-
content = data;
56-
}
57-
41+
let content = getData(data);
5842
resolve({task, content});
5943
}
6044

6145
function AFFailure(resolve, reject, task: NSURLSessionDataTask, error: NSError) {
62-
let data: NSData = error.userInfo.valueForKey(AFNetworkingOperationFailingURLResponseDataErrorKey);
63-
let body = NSString.alloc().initWithDataEncoding(data, NSUTF8StringEncoding).toString();
64-
65-
try {
66-
body = JSON.parse(body);
67-
} catch (ignore) {
68-
}
69-
70-
let content: any = {
71-
body,
72-
description: error.description,
73-
reason: error.localizedDescription,
74-
url: error.userInfo.objectForKey('NSErrorFailingURLKey').description
75-
};
76-
77-
if (policies.secured === true) {
78-
content.description = 'nativescript-https > Invalid SSL certificate! ' + content.description;
79-
}
46+
let data: NSDictionary<string, any> & NSData & NSArray<any> = error.userInfo.valueForKey(AFNetworkingOperationFailingURLResponseDataErrorKey);
47+
let parsedData = getData(data);
48+
if (useLegacy) {
49+
let failure: any = {
50+
body: parsedData,
51+
description: error.description,
52+
reason: error.localizedDescription,
53+
url: error.userInfo.objectForKey('NSErrorFailingURLKey').description
54+
};
55+
if (policies.secured === true) {
56+
failure.description = 'nativescript-https > Invalid SSL certificate! ' + error.description;
57+
}
58+
let reason = error.localizedDescription;
59+
let content = parsedData;
60+
resolve({task: task, content: content, reason: reason, failure: failure});
61+
} else {
62+
let content: any = {
63+
body: parsedData,
64+
description: error.description,
65+
reason: error.localizedDescription,
66+
url: error.userInfo.objectForKey('NSErrorFailingURLKey').description
67+
};
68+
69+
if (policies.secured === true) {
70+
content.description = 'nativescript-https > Invalid SSL certificate! ' + content.description;
71+
}
8072

81-
let reason = error.localizedDescription;
82-
resolve({task, content, reason});
73+
let reason = error.localizedDescription;
74+
resolve({task, content, reason});
75+
}
8376
}
8477

8578
export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsResponse> {
@@ -174,3 +167,25 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
174167
return Promise.resolve(sendi);
175168
});
176169
}
170+
171+
function getData(data) {
172+
let content: any;
173+
if (data && data.class) {
174+
if (data.enumerateKeysAndObjectsUsingBlock || (<any>data) instanceof NSArray) {
175+
let serial = NSJSONSerialization.dataWithJSONObjectOptionsError(data, NSJSONWritingOptions.PrettyPrinted);
176+
content = NSString.alloc().initWithDataEncoding(serial, NSUTF8StringEncoding).toString();
177+
} else if ((<any>data) instanceof NSData) {
178+
content = NSString.alloc().initWithDataEncoding(data, NSASCIIStringEncoding).toString();
179+
} else {
180+
content = data;
181+
}
182+
183+
try {
184+
content = JSON.parse(content);
185+
} catch (e) {
186+
}
187+
} else {
188+
content = data;
189+
}
190+
return content;
191+
}

0 commit comments

Comments
 (0)