|
@@ -16,6 +16,7 @@ import type {
|
16
|
16
|
RNFetchBlobStream,
|
17
|
17
|
RNFetchBlobResponseInfo
|
18
|
18
|
} from './types'
|
|
19
|
+import URIUtil from './utils/uri'
|
19
|
20
|
import StatefulPromise from './class/StatefulPromise.js'
|
20
|
21
|
import fs from './fs'
|
21
|
22
|
import getUUID from './utils/uuid'
|
|
@@ -100,6 +101,86 @@ function config (options:RNFetchBlobConfig) {
|
100
|
101
|
return { fetch : fetch.bind(options) }
|
101
|
102
|
}
|
102
|
103
|
|
|
104
|
+/**
|
|
105
|
+ * Fetch from file system, use the same interface as RNFB.fetch
|
|
106
|
+ * @param {RNFetchBlobConfig} [options={}] Fetch configurations
|
|
107
|
+ * @param {string} method Should be one of `get`, `post`, `put`
|
|
108
|
+ * @param {string} url A file URI string
|
|
109
|
+ * @param {string} headers Arguments of file system API
|
|
110
|
+ * @param {any} body Data to put or post to file systen.
|
|
111
|
+ * @return {Promise}
|
|
112
|
+ */
|
|
113
|
+function fetchFile(options = {}, method, url, headers = {}, body):Promise {
|
|
114
|
+
|
|
115
|
+ if(!URIUtil.isFileURI(url)) {
|
|
116
|
+ throw `could not fetch file from an invalid URI : ${url}`
|
|
117
|
+ }
|
|
118
|
+
|
|
119
|
+ url = URIUtil.unwrapFileURI(url)
|
|
120
|
+
|
|
121
|
+ let promise = null
|
|
122
|
+ let cursor = 0
|
|
123
|
+ let total = -1
|
|
124
|
+ let cacheData = ''
|
|
125
|
+ let info = null
|
|
126
|
+
|
|
127
|
+ let _progress, _uploadProgress, _stateChange
|
|
128
|
+
|
|
129
|
+ switch(method.toLowerCase()) {
|
|
130
|
+
|
|
131
|
+ case 'post':
|
|
132
|
+ break
|
|
133
|
+
|
|
134
|
+ case 'put':
|
|
135
|
+ break
|
|
136
|
+
|
|
137
|
+ // read data from file system
|
|
138
|
+ default:
|
|
139
|
+ promise = fs.stat(url)
|
|
140
|
+ .then((stat) => {
|
|
141
|
+ total = stat.size
|
|
142
|
+ return fs.readStream(url, headers.encoding || 'utf8', Math.floor(headers.bufferSize) || 4096)
|
|
143
|
+ })
|
|
144
|
+ .then((stream) => new Promise((resolve, reject) => {
|
|
145
|
+ stream.open()
|
|
146
|
+ info = {
|
|
147
|
+ state : "2",
|
|
148
|
+ headers : { 'source' : 'system-fs' },
|
|
149
|
+ status : 200,
|
|
150
|
+ respType : 'text',
|
|
151
|
+ rnfbEncode : headers.encoding || 'utf8'
|
|
152
|
+ }
|
|
153
|
+ _stateChange(info)
|
|
154
|
+ stream.onData((chunk) => {
|
|
155
|
+ _progress && _progress(cursor, total, chunk)
|
|
156
|
+ if(headers.noCache)
|
|
157
|
+ return
|
|
158
|
+ cacheData += chunk
|
|
159
|
+ })
|
|
160
|
+ stream.onError((err) => { reject(err) })
|
|
161
|
+ stream.onEnd(() => {
|
|
162
|
+ resolve(new FetchBlobResponse(null, info, cacheData))
|
|
163
|
+ })
|
|
164
|
+ }))
|
|
165
|
+ break
|
|
166
|
+ }
|
|
167
|
+
|
|
168
|
+ promise.progress = (fn) => {
|
|
169
|
+ _progress = fn
|
|
170
|
+ return promise
|
|
171
|
+ }
|
|
172
|
+ promise.stateChange = (fn) => {
|
|
173
|
+ _stateChange = fn
|
|
174
|
+ return promise
|
|
175
|
+ }
|
|
176
|
+ promise.uploadProgress = (fn) => {
|
|
177
|
+ _uploadProgress = fn
|
|
178
|
+ return promise
|
|
179
|
+ }
|
|
180
|
+
|
|
181
|
+ return promise
|
|
182
|
+}
|
|
183
|
+
|
103
|
184
|
/**
|
104
|
185
|
* Create a HTTP request by settings, the `this` context is a `RNFetchBlobConfig` object.
|
105
|
186
|
* @param {string} method HTTP method, should be `GET`, `POST`, `PUT`, `DELETE`
|
|
@@ -119,9 +200,15 @@ function fetch(...args:any):Promise {
|
119
|
200
|
let options = this || {}
|
120
|
201
|
let subscription, subscriptionUpload, stateEvent
|
121
|
202
|
let respInfo = {}
|
|
203
|
+ let [method, url, headers, body] = [...args]
|
|
204
|
+
|
|
205
|
+ // fetch from file system
|
|
206
|
+ if(URIUtil.isFileURI(url)) {
|
|
207
|
+ return fetchFile(options, method, url, headers, body)
|
|
208
|
+ }
|
122
|
209
|
|
|
210
|
+ // from remote HTTP(S)
|
123
|
211
|
let promise = new Promise((resolve, reject) => {
|
124
|
|
- let [method, url, headers, body] = [...args]
|
125
|
212
|
let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'
|
126
|
213
|
|
127
|
214
|
// on progress event listener
|