Skip to content

Commit c1dff6d

Browse files
committed
feat: multi formdata support
1 parent 580c3f1 commit c1dff6d

File tree

3 files changed

+90
-35
lines changed

3 files changed

+90
-35
lines changed

src/https.android.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -243,20 +243,38 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
243243
request[methods[opts.method]]();
244244
} else {
245245
type = opts.headers && opts.headers['Content-Type'] ? <string>opts.headers['Content-Type'] : 'application/json';
246-
247-
let body;
248-
if (opts.body) {
249-
try {
250-
body = JSON.stringify(opts.body);
251-
} catch (ignore) {
246+
const MEDIA_TYPE = okhttp3.MediaType.parse(type);
247+
let okHttpBody: okhttp3.RequestBody;
248+
if (type === 'multipart/form-data') {
249+
let builder = new okhttp3.MultipartBody.Builder();
250+
builder.setType(MEDIA_TYPE);
251+
Object.keys(opts.body).forEach(k=>{
252+
const param =opts.body[k] as Https.HttpsFormDataParam;
253+
if (param.fileName && param.contentType) {
254+
const MEDIA_TYPE = okhttp3.MediaType.parse(param.contentType);
255+
builder.addFormDataPart(param.parameterName, param.fileName, okhttp3.RequestBody.create(MEDIA_TYPE, param.data));
256+
} else {
257+
builder.addFormDataPart(param.parameterName, param.data);
258+
}
259+
})
260+
okHttpBody = builder.build();
261+
} else {
262+
let body;
263+
if (opts.body) {
264+
try {
265+
body = JSON.stringify(opts.body);
266+
} catch (ignore) {
267+
}
268+
} else if (opts.content) {
269+
body = opts.content
252270
}
253-
} else if (opts.content) {
254-
body = opts.content
271+
okHttpBody = okhttp3.RequestBody.create(
272+
okhttp3.MediaType.parse(type),
273+
body
274+
)
255275
}
256-
request[methods[opts.method]](okhttp3.RequestBody.create(
257-
okhttp3.MediaType.parse(type),
258-
body
259-
));
276+
request[methods[opts.method]](okHttpBody);
277+
260278
}
261279

262280
// We have to allow networking on the main thread because larger responses will crash the app with an NetworkOnMainThreadException.

src/https.common.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,15 @@ export interface CacheOptions {
1414
memorySize?: number;
1515
}
1616

17+
export interface HttpsFormDataParam {
18+
data: any
19+
parameterName: string
20+
fileName?: string
21+
contentType?: string
22+
}
23+
1724
export interface HttpsRequestObject {
18-
[key: string]: string | number | boolean | HttpsRequestObject | Array<any>;
25+
[key: string]: string | number | boolean | HttpsRequestObject | Array<any> | HttpsFormDataParam;
1926
}
2027

2128

src/https.ios.ts

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,11 @@ function bodyToNative(cont) {
115115
export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsResponse> {
116116
return new Promise((resolve, reject) => {
117117
try {
118-
const manager = AFHTTPSessionManager.alloc().initWithBaseURL(NSURL.URLWithString(opts.url));
119-
if (opts.headers && (<any>opts.headers['Content-Type']).substring(0, 16) === 'application/json') {
118+
const manager = AFHTTPSessionManager.alloc().initWithBaseURL(
119+
NSURL.URLWithString(opts.url)
120+
);
121+
const type = opts.headers && opts.headers['Content-Type'] ? <string>opts.headers['Content-Type'] : 'application/json';
122+
if (type === "application/json") {
120123
manager.requestSerializer = AFJSONRequestSerializer.serializer();
121124
manager.responseSerializer = AFJSONResponseSerializer.serializerWithReadingOptions(NSJSONReadingOptions.AllowFragments);
122125
} else {
@@ -127,7 +130,6 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
127130
manager.securityPolicy = (policies.secured === true) ? policies.secure : policies.def;
128131

129132
if (opts.cachePolicy) {
130-
let cacheControlBuilder = new okhttp3.CacheControl.Builder();
131133
switch (opts.cachePolicy) {
132134
case "noCache":
133135
manager.setDataTaskWillCacheResponseBlock((session, task, cacheResponse) => {
@@ -158,23 +160,11 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
158160

159161
manager.requestSerializer.timeoutInterval = opts.timeout ? opts.timeout : 10;
160162

161-
let methods = {
162-
GET: "GETParametersSuccessFailure",
163-
POST: "POSTParametersSuccessFailure",
164-
PUT: "PUTParametersSuccessFailure",
165-
DELETE: "DELETEParametersSuccessFailure",
166-
PATCH: "PATCHParametersSuccessFailure",
167-
HEAD: "HEADParametersSuccessFailure",
168-
};
169-
manager[methods[opts.method]](
170-
opts.url,
171-
dict,
172-
function success(task: NSURLSessionDataTask, data: any) {
173-
AFSuccess(resolve, task, data);
174-
};
175-
176-
const failure = (task, error) => {
177-
AFFailure(resolve, reject, task, error);
163+
const success = function (task: NSURLSessionDataTask, data?: any) {
164+
AFSuccess(resolve, task, data);
165+
}
166+
const failure = function (task: NSURLSessionDataTask, error: any) {
167+
AFFailure(resolve, reject, task, error);
178168
};
179169

180170
const progress = (progress: NSProgress) => {
@@ -193,9 +183,49 @@ export function request(opts: Https.HttpsRequestOptions): Promise<Https.HttpsRes
193183
manager.PATCHParametersHeadersSuccessFailure(opts.url, dict, headers, success, failure);
194184
} else if (opts.method === "HEAD") {
195185
manager.HEADParametersHeadersSuccessFailure(opts.url, dict, headers, success, failure);
186+
}
187+
if (type === "application/json") {
188+
switch(opts.method) {
189+
case 'POST' :
190+
manager.POSTParametersConstructingBodyWithBlockSuccessFailure(opts.url, null,(formData)=>{
191+
Object.keys(opts.body).forEach(k=>{
192+
const param =opts.body[k] as Https.HttpsFormDataParam;
193+
if (param.fileName && param.contentType) {
194+
formData.appendPartWithFileDataNameFileNameMimeType(param.data, param.parameterName, param.fileName, param.contentType);
195+
} else {
196+
formData.appendPartWithFormDataName(NSString.stringWithString(param.data).dataUsingEncoding(NSUTF8StringEncoding), param.parameterName)
197+
}
198+
})
199+
}, success, failure);
200+
break;
201+
default:
202+
reject(new Error('method_not_supported_multipart'));
203+
}
204+
} else {
205+
switch(opts.method) {
206+
case 'GET' :
207+
manager.GETParametersSuccessFailure(opts.url, dict,success, failure);
208+
break;
209+
case 'POST' :
210+
manager.POSTParametersSuccessFailure(opts.url, dict,success, failure);
211+
break;
212+
case 'PUT' :
213+
manager.PUTParametersSuccessFailure(opts.url, dict,success, failure);
214+
break;
215+
case 'DELETE' :
216+
manager.DELETEParametersSuccessFailure(opts.url, dict,success, failure);
217+
break;
218+
case 'PATCH' :
219+
manager.PATCHParametersSuccessFailure(opts.url, dict,success, failure);
220+
break;
221+
case 'HEAD' :
222+
manager.HEADParametersSuccessFailure(opts.url, dict,success, failure);
223+
break;
224+
default:
225+
reject(new Error('method_not_supported_multipart'));
196226
}
197-
198-
227+
}
228+
199229
} catch (error) {
200230
reject(error);
201231
}

0 commit comments

Comments
 (0)