Browse Source

Add IOS increment HTTP request support and JSON stream lib

Ben Hsieh 7 years ago
parent
commit
801685dcbe

+ 4
- 2
src/index.js View File

@@ -22,6 +22,7 @@ import getUUID from './utils/uuid'
22 22
 import base64 from 'base-64'
23 23
 import polyfill from './polyfill'
24 24
 import android from './android'
25
+import JSONStream from './json-stream'
25 26
 const {
26 27
   RNFetchBlobSession,
27 28
   readStream,
@@ -126,7 +127,7 @@ function fetch(...args:any):Promise {
126 127
     // on progress event listener
127 128
     subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
128 129
       if(e.taskId === taskId && promise.onProgress) {
129
-        promise.onProgress(e.written, e.total)
130
+        promise.onProgress(e.written, e.total, e.chunk)
130 131
       }
131 132
     })
132 133
 
@@ -398,5 +399,6 @@ export default {
398 399
   session,
399 400
   fs,
400 401
   wrap,
401
-  polyfill
402
+  polyfill,
403
+  JSONStream
402 404
 }

+ 11
- 1
src/ios/RNFetchBlobNetwork.m View File

@@ -36,6 +36,7 @@ NSMutableDictionary * uploadProgressTable;
36 36
     long bodyLength;
37 37
     NSMutableDictionary * respInfo;
38 38
     NSInteger respStatus;
39
+    BOOL isInrement;
39 40
 }
40 41
 
41 42
 @end
@@ -125,6 +126,7 @@ NSOperationQueue *taskQueue;
125 126
     self.expectedBytes = 0;
126 127
     self.receivedBytes = 0;
127 128
     self.options = options;
129
+    isInrement = [options valueForKey:@"increment"] == nil ? NO : [[options valueForKey:@"increment"] boolValue];
128 130
 
129 131
     NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
130 132
     NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
@@ -284,6 +286,13 @@ NSOperationQueue *taskQueue;
284 286
 {
285 287
     NSNumber * received = [NSNumber numberWithLong:[data length]];
286 288
     receivedBytes += [received longValue];
289
+    NSString * chunkString = @"";
290
+    
291
+    if(isInrement == YES)
292
+    {
293
+        chunkString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
294
+    }
295
+    
287 296
     if(respFile == NO)
288 297
     {
289 298
         [respData appendData:data];
@@ -300,7 +309,8 @@ NSOperationQueue *taskQueue;
300 309
          body:@{
301 310
                 @"taskId": taskId,
302 311
                 @"written": [NSString stringWithFormat:@"%d", receivedBytes],
303
-                @"total": [NSString stringWithFormat:@"%d", expectedBytes]
312
+                @"total": [NSString stringWithFormat:@"%d", expectedBytes],
313
+                @"chunk": chunkString
304 314
             }
305 315
          ];
306 316
     }

+ 16
- 0
src/json-stream.js View File

@@ -0,0 +1,16 @@
1
+import Oboe from './lib/oboe-browser.min.js'
2
+import XMLHttpRequest from './polyfill/XMLHttpRequest'
3
+
4
+const OboeExtended = (arg: string | object) => {
5
+  
6
+  window.XMLHttpRequest = XMLHttpRequest
7
+  window.location = ''
8
+
9
+  if(typeof arg === 'string')
10
+    arg = 'JSONStream://' + arg
11
+  else if(typeof arg === 'object')
12
+    arg = Object.assign(arg, { url : 'JSONStream://' + arg.url })
13
+  return Oboe(arg)
14
+}
15
+
16
+export default OboeExtended

+ 16
- 3
src/polyfill/XMLHttpRequest.js View File

@@ -11,7 +11,7 @@ import ProgressEvent from './ProgressEvent.js'
11 11
 const log = new Log('XMLHttpRequest')
12 12
 
13 13
 log.disable()
14
-// log.level(2)
14
+// log.level(3)
15 15
 
16 16
 const UNSENT = 0
17 17
 const OPENED = 1
@@ -30,8 +30,9 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
30 30
 
31 31
   // readonly
32 32
   _readyState : number = UNSENT;
33
+  _uriType : 'net' | 'file' = 'net';
33 34
   _response : any = '';
34
-  _responseText : any = null;
35
+  _responseText : any = '';
35 36
   _responseHeaders : any = {};
36 37
   _responseType : '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' = '';
37 38
   // TODO : not suppoted ATM
@@ -42,6 +43,7 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
42 43
   _timeout : number = 60000;
43 44
   _sendFlag : boolean = false;
44 45
   _uploadStarted : boolean = false;
46
+  _increment : boolean = false;
45 47
 
46 48
   // RNFetchBlob compatible data structure
47 49
   _config : RNFetchBlobConfig = {};
@@ -122,7 +124,10 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
122 124
     this._method = method
123 125
     this._url = url
124 126
     this._headers = {}
127
+    this._increment = /^JSONStream\:\/\//.test(this._url)
128
+    this._url = this._url.replace(/^JSONStream\:\/\//, '')
125 129
     this._dispatchReadStateChange(XMLHttpRequest.OPENED)
130
+    
126 131
   }
127 132
 
128 133
   /**
@@ -130,7 +135,9 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
130 135
    * @param  {any} body Body in RNfetchblob flavor
131 136
    */
132 137
   send(body) {
138
+
133 139
     this._body = body
140
+
134 141
     if(this._readyState !== XMLHttpRequest.OPENED)
135 142
       throw 'InvalidStateError : XMLHttpRequest is not opened yet.'
136 143
     let promise = Promise.resolve()
@@ -164,10 +171,12 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
164 171
       for(let h in _headers) {
165 172
         _headers[h] = _headers[h].toString()
166 173
       }
174
+
167 175
       this._task = RNFetchBlob
168 176
                     .config({
169 177
                       auto: true,
170 178
                       timeout : this._timeout,
179
+                      increment : this._increment,
171 180
                       binaryContentTypes : XMLHttpRequest.binaryContentTypes
172 181
                     })
173 182
                     .fetch(_method, _url, _headers, body)
@@ -271,7 +280,7 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
271 280
     this.upload.dispatchEvent('progress', new ProgressEvent(true, send, total))
272 281
   }
273 282
 
274
-  _progressEvent(send:number, total:number) {
283
+  _progressEvent(send:number, total:number, chunk:string) {
275 284
     log.verbose(this.readyState)
276 285
     if(this._readyState === XMLHttpRequest.HEADERS_RECEIVED)
277 286
       this._dispatchReadStateChange(XMLHttpRequest.LOADING)
@@ -279,6 +288,10 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
279 288
     if(total && total >= 0)
280 289
         lengthComputable = true
281 290
     let e = new ProgressEvent(lengthComputable, send, total)
291
+
292
+    if(this._increment) {
293
+      this._responseText += chunk
294
+    }
282 295
     this.dispatchEvent('progress', e)
283 296
   }
284 297
 

+ 1
- 0
src/polyfill/XMLHttpRequestEventTarget.js View File

@@ -8,6 +8,7 @@ import Log from '../utils/log.js'
8 8
 const log = new Log('XMLHttpRequestEventTarget')
9 9
 
10 10
 log.disable()
11
+// log.level(3)
11 12
 
12 13
 export default class XMLHttpRequestEventTarget extends EventTarget {
13 14