Skip to content

Commit 7747e42

Browse files
- bumped AFNetworking to fix a few issues
- added support for large responses on Android - added typings (and scripts to generate those)
1 parent 599a558 commit 7747e42

File tree

17 files changed

+3515
-69
lines changed

17 files changed

+3515
-69
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# NativeScript-HTTPS
22

3-
> Forked by Eddy Verbruggen to be able to install from GitHub (include .js files), just in casenpm isbehind and we desperately need the latest changes.
4-
53
### The definitive way to hit HTTP based APIs in Nativescript.
64
Easily integrate the most reliable native networking libraries with the latest and greatest HTTPS security features.
75
#### A drop-in replacement for the [default http module](https://docs.nativescript.org/cookbook/http#get-response-status-code).

demo/app/App_Resources/iOS/build.xcconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
// CODE_SIGN_IDENTITY = iPhone Distribution
44
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
55
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
6+
7+
DEVELOPMENT_TEAM = 8Q5F6M3TNS

demo/app/assets/httpbin.org.cer

1 Byte
Binary file not shown.

demo/app/main-page.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
1-
21
import * as Observable from 'tns-core-modules/data/observable'
32
import * as Page from 'tns-core-modules/ui/page'
43
import * as fs from 'tns-core-modules/file-system'
54
import * as dialogs from 'tns-core-modules/ui/dialogs'
65
import * as Https from 'nativescript-https'
76

8-
9-
107
export function onNavigatingTo(args: Page.NavigatedData) {
118
let page = args.object as Page.Page
129
page.bindingContext = Observable.fromObject({ enabled: false })
1310
}
1411

15-
function getRequest(url: string) {
12+
function getRequest(url: string, allowLargeResponse = false) {
13+
Https.request({
14+
url,
15+
method: 'GET',
16+
allowLargeResponse
17+
}).then(function(response) {
18+
console.log('Https.request response', response)
19+
}).catch(function(error) {
20+
console.error('Https.request error', error)
21+
dialogs.alert(error)
22+
})
23+
}
24+
25+
function postRequest(url: string, body: any) {
1626
Https.request({
17-
url, method: 'GET',
27+
url,
28+
method: 'POST',
29+
body
1830
}).then(function(response) {
1931
console.log('Https.request response', response)
2032
}).catch(function(error) {
@@ -23,7 +35,9 @@ function getRequest(url: string) {
2335
})
2436
}
2537

38+
export function postHttpbin() { postRequest('https://httpbin.org/post', {"foo": "bar", "baz": undefined, "plaz": null}) }
2639
export function getHttpbin() { getRequest('https://httpbin.org/get') }
40+
export function getHttpbinLargeResponse() { getRequest('https://httpbin.org/bytes/100000', true) }
2741
export function getMockbin() { getRequest('https://mockbin.com/request') }
2842

2943
export function enableSSLPinning(args: Observable.EventData) {

demo/app/main-page.xml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55

66
<StackLayout class="p-20">
77
<Label class="h1 text-center" color="{{ enabled ? 'green' : 'red' }}" text="{{ enabled ? 'Httpbin SSL Pinning Enabled' : 'SSL Pinning Disabled' }}" />
8-
<Button text="Httpbin" tap="getHttpbin" class="t-20 btn btn-primary btn-active" />
9-
<Button text="Mockbin" tap="getMockbin" class="t-20 btn btn-primary btn-active" />
8+
<Button text="GET Mockbin" tap="getMockbin" class="t-20 btn btn-primary btn-active" />
9+
<Button text="GET Httpbin" tap="getHttpbin" class="t-20 btn btn-primary btn-active" />
10+
<Button text="GET Httpbin (large response)" tap="getHttpbinLargeResponse" class="t-20 btn btn-primary btn-active" />
11+
<Button text="POST Httpbin " tap="postHttpbin" class="t-20 btn btn-primary btn-active" />
1012
<Button text="Enable Httpbin SSL Pinning" tap="enableSSLPinning" class="t-20 btn btn-primary btn-active" />
1113
<Button text="Disable SSL Pinning" tap="disableSSLPinning" class="t-20 btn btn-primary btn-active" />
14+
<Label text="Here's a spinner to show the main thread is not blocked by network IO" textWrap="true" class="m-20"/>
15+
<ActivityIndicator busy="true" />
1216
</StackLayout>
1317

1418
</Page>

demo/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
"id": "org.nativescript.demo",
44
"tns-android": {
55
"version": "5.1.0"
6+
},
7+
"tns-ios": {
8+
"version": "5.1.1"
69
}
710
},
811
"dependencies": {

demo/tsconfig.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,9 @@
3131
}
3232
},
3333
"include": [
34-
"../src",
3534
"**/*"
3635
],
3736
"exclude": [
38-
"../src/node_modules",
3937
"node_modules",
4038
"platforms"
4139
],

src/https.android.ts

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,5 @@
1-
21
import * as Https from './https.common'
3-
import * as application from 'tns-core-modules/application'
4-
import { HttpRequestOptions, Headers, HttpResponse } from 'tns-core-modules/http'
5-
import { isDefined, isNullOrUndefined } from 'tns-core-modules/utils/types'
6-
7-
8-
9-
// declare var java: any
10-
// declare var javax: any
11-
// java.security.cert.Certificate as any
12-
// declare module java {
13-
// export module security {
14-
// export module cert {
15-
// export interface Certificate { }
16-
// }
17-
// }
18-
// export module io {
19-
// export interface FileInputStream { }
20-
// }
21-
// }
22-
23-
2+
import { isDefined } from 'tns-core-modules/utils/types'
243

254
interface Ipeer {
265
enabled: boolean
@@ -30,6 +9,7 @@ interface Ipeer {
309
certificate?: string
3110
x509Certificate?: java.security.cert.Certificate
3211
}
12+
3313
let peer: Ipeer = {
3414
enabled: false,
3515
allowInvalidCertificates: false,
@@ -70,15 +50,14 @@ export function enableSSLPinning(options: Https.HttpsSSLPinningOptions) {
7050
getClient(true)
7151
console.log('nativescript-https > Enabled SSL pinning')
7252
}
53+
7354
export function disableSSLPinning() {
7455
peer.enabled = false
7556
getClient(true)
7657
console.log('nativescript-https > Disabled SSL pinning')
7758
}
7859
console.info('nativescript-https > Disabled SSL pinning by default')
7960

80-
81-
8261
let Client: okhttp3.OkHttpClient
8362
function getClient(reload: boolean = false): okhttp3.OkHttpClient {
8463
// if (!Client) {
@@ -161,11 +140,6 @@ function getClient(reload: boolean = false): okhttp3.OkHttpClient {
161140
return Client
162141
}
163142

164-
// We have to allow networking on the main thread because larger responses will crash the app with an NetworkOnMainThreadException.
165-
// Note that it would be better to offload it to an AsyncTask but that has to run natively to work properly.
166-
// No time for that now, and actually it only concerns the '.string()' call of response.body().string() below.
167-
const strictModeThreadPolicyPermitAll = new android.os.StrictMode.ThreadPolicy.Builder().permitAll().build()
168-
169143
export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsResponse> {
170144
return new Promise(function(resolve, reject) {
171145
try {
@@ -208,8 +182,13 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
208182
))
209183
}
210184

211-
// enable our policy
212-
android.os.StrictMode.setThreadPolicy(strictModeThreadPolicyPermitAll)
185+
186+
// We have to allow networking on the main thread because larger responses will crash the app with an NetworkOnMainThreadException.
187+
// Note that it would probably be better to offload it to a Worker or (natively running) AsyncTask.
188+
// Also note that once set, this policy remains active until the app is killed.
189+
if (opts.allowLargeResponse) {
190+
android.os.StrictMode.setThreadPolicy(android.os.StrictMode.ThreadPolicy.LAX)
191+
}
213192

214193
client.newCall(request.build()).enqueue(new okhttp3.Callback({
215194
onResponse: function(task, response) {

src/https.common.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
2-
import { HttpRequestOptions, Headers } from 'tns-core-modules/http'
3-
4-
1+
import { Headers } from 'tns-core-modules/http'
52

63
export interface HttpsSSLPinningOptions {
74
host: string
@@ -19,7 +16,13 @@ export interface HttpsRequestOptions {
1916
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD'
2017
headers?: Headers
2118
params?: HttpsRequestObject
22-
body?: HttpsRequestObject
19+
body?: HttpsRequestObject,
20+
/**
21+
* On Android large responses may crash the app (fi. https://httpbin.org/bytes/10000).
22+
* By setting this to true we allow large responses on the main thread (which this plugin currently does).
23+
* Note that once set to true, this policy remains active until the app is killed.
24+
*/
25+
allowLargeResponse?: boolean;
2326
}
2427

2528
export interface HttpsResponse {

src/https.ios.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
21
import * as Https from './https.common'
3-
import * as application from 'tns-core-modules/application'
4-
import { HttpRequestOptions, Headers, HttpResponse } from 'tns-core-modules/http'
52
import { isDefined, isNullOrUndefined, isObject } from 'tns-core-modules/utils/types'
63

7-
8-
94
interface Ipolicies {
105
def: AFSecurityPolicy
116
secured: boolean
@@ -42,8 +37,6 @@ export function disableSSLPinning() {
4237
}
4338
console.info('nativescript-https > Disabled SSL pinning by default')
4439

45-
46-
4740
function AFSuccess(resolve, task: NSURLSessionDataTask, data: NSDictionary<string, any> & NSData & NSArray<any>) {
4841
// console.log('AFSuccess')
4942
let content: any
@@ -140,7 +133,7 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
140133
return new Promise(function(resolve, reject) {
141134
try {
142135

143-
let manager = AFHTTPSessionManager.manager()
136+
const manager = AFHTTPSessionManager.alloc().initWithBaseURL(NSURL.URLWithString(opts.url));
144137

145138
if (opts.headers && opts.headers['Content-Type'] == 'application/json') {
146139
manager.requestSerializer = AFJSONRequestSerializer.serializer()

0 commit comments

Comments
 (0)