Browse Source

Add IOS increment HTTP request support and JSON stream lib

Ben Hsieh 8 years ago
parent
commit
801685dcbe

+ 4
- 2
src/index.js View File

22
 import base64 from 'base-64'
22
 import base64 from 'base-64'
23
 import polyfill from './polyfill'
23
 import polyfill from './polyfill'
24
 import android from './android'
24
 import android from './android'
25
+import JSONStream from './json-stream'
25
 const {
26
 const {
26
   RNFetchBlobSession,
27
   RNFetchBlobSession,
27
   readStream,
28
   readStream,
126
     // on progress event listener
127
     // on progress event listener
127
     subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
128
     subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
128
       if(e.taskId === taskId && promise.onProgress) {
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
   session,
399
   session,
399
   fs,
400
   fs,
400
   wrap,
401
   wrap,
401
-  polyfill
402
+  polyfill,
403
+  JSONStream
402
 }
404
 }

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

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

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

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

8
 const log = new Log('XMLHttpRequestEventTarget')
8
 const log = new Log('XMLHttpRequestEventTarget')
9
 
9
 
10
 log.disable()
10
 log.disable()
11
+// log.level(3)
11
 
12
 
12
 export default class XMLHttpRequestEventTarget extends EventTarget {
13
 export default class XMLHttpRequestEventTarget extends EventTarget {
13
 
14