Skip to content

Commit 33ff958

Browse files
committed
feat(): enable devtools
1 parent e9255cf commit 33ff958

File tree

2 files changed

+174
-33
lines changed

2 files changed

+174
-33
lines changed

src/http/http.android.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Headers, HttpError, HttpRequestOptions } from './http-request-common';
22
import * as types from 'tns-core-modules/utils/types';
3+
import { NetworkAgent } from 'tns-core-modules/debugger';
34

45
export type CancellablePromise = Promise<any> & { cancel: () => void };
56

@@ -10,6 +11,49 @@ export enum HttpResponseEncoding {
1011
GBK
1112
}
1213

14+
const statuses = {
15+
100: 'Continue',
16+
101: 'Switching Protocols',
17+
200: 'OK',
18+
201: 'Created',
19+
202: 'Accepted',
20+
203: 'Non - Authoritative Information',
21+
204: 'No Content',
22+
205: 'Reset Content',
23+
206: 'Partial Content',
24+
300: 'Multiple Choices',
25+
301: 'Moved Permanently',
26+
302: 'Found',
27+
303: 'See Other',
28+
304: 'Not Modified',
29+
305: 'Use Proxy',
30+
307: 'Temporary Redirect',
31+
400: 'Bad Request',
32+
401: 'Unauthorized',
33+
402: 'Payment Required',
34+
403: 'Forbidden',
35+
404: 'Not Found',
36+
405: 'Method Not Allowed',
37+
406: 'Not Acceptable',
38+
407: 'Proxy Authentication Required',
39+
408: 'Request Timeout',
40+
409: 'Conflict',
41+
410: 'Gone',
42+
411: 'Length Required',
43+
412: 'Precondition Failed',
44+
413: 'Request Entity Too Large',
45+
414: 'Request - URI Too Long',
46+
415: 'Unsupported Media Type',
47+
416: 'Requested Range Not Satisfiable',
48+
417: 'Expectation Failed',
49+
500: 'Internal Server Error',
50+
501: 'Not Implemented',
51+
502: 'Bad Gateway',
52+
503: 'Service Unavailable',
53+
504: 'Gateway Timeout',
54+
505: 'HTTP Version Not Supported'
55+
};
56+
1357
function parseJSON(source: string): any {
1458
const src = source.trim();
1559
if (src.lastIndexOf(')') === src.length - 1) {
@@ -22,6 +66,7 @@ function parseJSON(source: string): any {
2266
}
2367

2468
const requestCallbacks = new Map();
69+
let requestIdCounter = 0;
2570

2671
export class Http {
2772
constructor() {
@@ -79,10 +124,18 @@ export class Http {
79124
const headers: Headers = {};
80125
let statusCode = 0;
81126
let id;
127+
const counter = requestIdCounter;
82128
const request = <CancellablePromise>new Promise<any>((resolve, reject) => {
83129
try {
130+
84131
// initialize the options
85132
const javaOptions = this.buildJavaOptions(options);
133+
134+
// @ts-ignore
135+
if (global.__inspector && global.__inspector.isConnected) {
136+
NetworkAgent.requestWillBeSent(requestIdCounter, options);
137+
}
138+
86139
const callback = new com.github.triniwiz.async.Async.Http.Callback({
87140
onCancel(param: any): void {
88141
reject({
@@ -93,8 +146,10 @@ export class Http {
93146
},
94147
onComplete(result: any): void {
95148
let content;
149+
let isString = false;
96150
if (result.content instanceof org.json.JSONObject || result.content instanceof org.json.JSONArray) {
97151
content = deserialize(result.content);
152+
isString = true;
98153
} else {
99154
content = result.content;
100155
}
@@ -106,6 +161,57 @@ export class Http {
106161
addHeader(headers, pair.key, pair.value);
107162
}
108163
}
164+
// send response data (for requestId) to network debugger
165+
166+
167+
let contentType = headers['Content-Type'];
168+
if (contentType == null) {
169+
contentType = headers['content-Type'];
170+
}
171+
let acceptHeader;
172+
173+
if (contentType == null) {
174+
acceptHeader = headers['Accept'];
175+
} else {
176+
acceptHeader = contentType;
177+
}
178+
179+
let returnType = 'text/plain';
180+
if (acceptHeader != null) {
181+
let acceptValues = acceptHeader.split(',');
182+
let quality = [];
183+
let defaultQuality = [];
184+
let customQuality = [];
185+
for (let value of acceptValues) {
186+
if (value.indexOf(';q=') > -1) {
187+
customQuality.push(value);
188+
} else {
189+
defaultQuality.push(value);
190+
}
191+
}
192+
customQuality = customQuality.sort((a, b) => {
193+
const a_quality = parseFloat(a.substring(a.indexOf(';q=')).replace(';q=', ''));
194+
const b_quality = parseFloat(b.substring(b.indexOf(';q=')).replace(';q=', ''));
195+
return (b_quality - a_quality);
196+
});
197+
quality.push(...defaultQuality);
198+
quality.push(...customQuality);
199+
returnType = quality[0];
200+
}
201+
202+
result['statusCode'] = statusCode;
203+
// send response data (for requestId) to network debugger
204+
// @ts-ignore
205+
if (global.__inspector && global.__inspector.isConnected) {
206+
NetworkAgent.responseReceived(counter, {
207+
url: result.url,
208+
statusCode,
209+
headers,
210+
responseAsString: isString ? result.content.toString(): null,
211+
responseAsImage: null // TODO needs base64 Image
212+
}, headers);
213+
}
214+
109215
resolve({
110216
url: result.url,
111217
content,
@@ -155,6 +261,7 @@ export class Http {
155261
});
156262
id = com.github.triniwiz.async.Async.Http.makeRequest(javaOptions, callback);
157263
requestCallbacks.set(id, callback);
264+
requestIdCounter++;
158265
} catch (ex) {
159266
reject({
160267
type: HttpError.Error,

src/http/http.ios.ts

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as types from 'tns-core-modules/utils/types';
22
import { Headers, HttpError, HttpRequestOptions } from './http-request-common';
3+
import * as domainDebugger from 'tns-core-modules/debugger';
34

45
export type CancellablePromise = Promise<any> & { cancel: () => void };
56

@@ -50,8 +51,10 @@ class NSURLSessionTaskDelegateImpl extends NSObject
5051
private _url: string = '';
5152
private _request;
5253
private _loadingSent: boolean;
53-
54-
public static initWithRequestResolveRejectCallbackHeadersLoadingListener(
54+
private _debuggerRequest;
55+
private _response;
56+
public static initWithDebuggerRequestResolveRejectCallbackHeadersLoadingListener(
57+
debuggerRequest,
5558
request,
5659
resolve,
5760
reject,
@@ -67,6 +70,7 @@ class NSURLSessionTaskDelegateImpl extends NSObject
6770
delegate._onHeaders = onHeaders;
6871
delegate._onLoading = onLoading;
6972
delegate._data = NSMutableData.new();
73+
delegate._debuggerRequest = debuggerRequest;
7074
return delegate;
7175
}
7276

@@ -116,8 +120,8 @@ class NSURLSessionTaskDelegateImpl extends NSObject
116120
total: this._lastProgress.total
117121
});
118122
}
119-
}else{
120-
if(this._data){
123+
} else {
124+
if (this._data) {
121125
this._data.appendData(data);
122126
}
123127
}
@@ -165,6 +169,7 @@ class NSURLSessionTaskDelegateImpl extends NSObject
165169
completionHandler(NSURLSessionResponseDisposition.Allow);
166170
this._statusCode = (response as any).statusCode;
167171
this._url = response.URL.absoluteString;
172+
this._response = response;
168173
const method = this._request.HTTPMethod.toLowerCase();
169174
if (method !== 'post' && method !== 'put') {
170175
if (this._onHeaders) {
@@ -279,7 +284,7 @@ class NSURLSessionTaskDelegateImpl extends NSObject
279284
acceptHeader = contentType;
280285
}
281286

282-
let returnType = 'text/html';
287+
let returnType = 'text/plain';
283288
if (acceptHeader != null) {
284289
let acceptValues = acceptHeader.split(',');
285290
let quality = [];
@@ -312,6 +317,22 @@ class NSURLSessionTaskDelegateImpl extends NSObject
312317
content = this._data;
313318
}
314319

320+
if (this._debuggerRequest) {
321+
this._debuggerRequest.mimeType = this._response.MIMEType;
322+
this._debuggerRequest.data = this._data;
323+
const debugResponse = {
324+
url: this._url,
325+
status: this._statusCode,
326+
statusText: NSHTTPURLResponse.localizedStringForStatusCode(this._statusCode),
327+
headers: headers,
328+
mimeType: this._response.MIMEType,
329+
fromDiskCache: false
330+
};
331+
this._debuggerRequest.responseReceived(debugResponse);
332+
this._debuggerRequest.loadingFinished();
333+
}
334+
335+
315336
this._resolve({
316337
url: this._url,
317338
content,
@@ -368,6 +389,10 @@ export class Http {
368389
}
369390

370391
try {
392+
393+
const network = domainDebugger.getNetwork();
394+
const debugRequest = network && network.create();
395+
371396
const urlRequest = NSMutableURLRequest.requestWithURL(
372397
NSURL.URLWithString(options.url)
373398
);
@@ -415,7 +440,8 @@ export class Http {
415440

416441
let session = NSURLSession.sessionWithConfigurationDelegateDelegateQueue(
417442
sessionConfig,
418-
NSURLSessionTaskDelegateImpl.initWithRequestResolveRejectCallbackHeadersLoadingListener(
443+
NSURLSessionTaskDelegateImpl.initWithDebuggerRequestResolveRejectCallbackHeadersLoadingListener(
444+
debugRequest,
419445
urlRequest,
420446
resolve,
421447
reject,
@@ -428,6 +454,14 @@ export class Http {
428454

429455
const task = session.dataTaskWithRequest(urlRequest);
430456
Http._tasks.set(id, task);
457+
if (options.url && debugRequest) {
458+
const request = {
459+
url: options.url,
460+
method: 'GET',
461+
headers: options.headers
462+
};
463+
debugRequest.requestWillBeSent(request);
464+
}
431465
task.resume();
432466
} catch (ex) {
433467
reject({
@@ -448,34 +482,34 @@ export class Http {
448482

449483

450484
function deserialize(nativeData) {
451-
if (types.isNullOrUndefined(nativeData)) {
452-
// some native values will already be js null values
453-
// calling types.getClass below on null/undefined will cause crash
454-
return null;
455-
} else {
456-
switch (types.getClass(nativeData)) {
457-
case 'NSNull':
485+
if (types.isNullOrUndefined(nativeData)) {
486+
// some native values will already be js null values
487+
// calling types.getClass below on null/undefined will cause crash
458488
return null;
459-
case 'NSMutableDictionary':
460-
case 'NSDictionary':
461-
let obj = {};
462-
const length = nativeData.count;
463-
const keysArray = nativeData.allKeys as NSArray<any>;
464-
for (let i = 0; i < length; i++) {
465-
const nativeKey = keysArray.objectAtIndex(i);
466-
obj[nativeKey] = deserialize(nativeData.objectForKey(nativeKey));
467-
}
468-
return obj;
469-
case 'NSMutableArray':
470-
case 'NSArray':
471-
let array = [];
472-
const len = nativeData.count;
473-
for (let i = 0; i < len; i++) {
474-
array[i] = deserialize(nativeData.objectAtIndex(i));
489+
} else {
490+
switch (types.getClass(nativeData)) {
491+
case 'NSNull':
492+
return null;
493+
case 'NSMutableDictionary':
494+
case 'NSDictionary':
495+
let obj = {};
496+
const length = nativeData.count;
497+
const keysArray = nativeData.allKeys as NSArray<any>;
498+
for (let i = 0; i < length; i++) {
499+
const nativeKey = keysArray.objectAtIndex(i);
500+
obj[nativeKey] = deserialize(nativeData.objectForKey(nativeKey));
501+
}
502+
return obj;
503+
case 'NSMutableArray':
504+
case 'NSArray':
505+
let array = [];
506+
const len = nativeData.count;
507+
for (let i = 0; i < len; i++) {
508+
array[i] = deserialize(nativeData.objectAtIndex(i));
509+
}
510+
return array;
511+
default:
512+
return nativeData;
475513
}
476-
return array;
477-
default:
478-
return nativeData;
479514
}
480-
}
481515
}

0 commit comments

Comments
 (0)