mirror of
https://github.com/silkimen/cordova-plugin-advanced-http.git
synced 2026-05-31 00:00:07 +08:00
Merge branch 'chuchuva-raw-request-body'
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## 2.4.0
|
||||
|
||||
- Feature #291: add support for sending 'raw' requests (thanks to jachstet-sea and chuchuva)
|
||||
|
||||
## 2.3.1
|
||||
|
||||
- Fixed #275: getAllCookies() is broken because of a typo (thanks ath0mas)
|
||||
|
||||
@@ -91,10 +91,21 @@ cordova.plugin.http.setDataSerializer('urlencoded');
|
||||
```
|
||||
|
||||
You can choose one of these:
|
||||
* `urlencoded`: send data as url encoded content in body (content type "application/x-www-form-urlencoded")
|
||||
* `json`: send data as JSON encoded content in body (content type "application/json")
|
||||
* `utf8`: send data as plain UTF8 encoded string in body (content type "plain/text")
|
||||
* `multipart`: send FormData objects as multipart content in body (content type "multipart/form-data")
|
||||
* `urlencoded`: send data as url encoded content in body
|
||||
* default content type "application/x-www-form-urlencoded"
|
||||
* data must be an dictionary style `Object`
|
||||
* `json`: send data as JSON encoded content in body
|
||||
* default content type "application/json"
|
||||
* data must be an `Array` or an dictionary style `Object`
|
||||
* `utf8`: send data as plain UTF8 encoded string in body
|
||||
* default content type "plain/text"
|
||||
* data must be a `String`
|
||||
* `multipart`: send FormData objects as multipart content in body
|
||||
* default content type "multipart/form-data"
|
||||
* data must be an `FormData` instance
|
||||
* `raw`: send data as is, without any processing
|
||||
* default content type "application/octet-stream"
|
||||
* data must be an `Uint8Array` or an `ArrayBuffer`
|
||||
|
||||
This defaults to `urlencoded`. You can also override the default content type headers by specifying your own headers (see [setHeader](#setHeader)).
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-plugin-advanced-http",
|
||||
"version": "2.3.1",
|
||||
"version": "2.4.0",
|
||||
"description": "Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning",
|
||||
"scripts": {
|
||||
"updatecert": "node ./scripts/update-e2e-server-cert.js && node ./scripts/update-e2e-client-cert.js",
|
||||
@@ -50,7 +50,7 @@
|
||||
"pvsaikrishna",
|
||||
"cvillerm",
|
||||
"hideov",
|
||||
"Mobisys"
|
||||
"silkimen"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
</feature>
|
||||
</config-file>
|
||||
<header-file src="src/ios/CordovaHttpPlugin.h"/>
|
||||
<header-file src="src/ios/BinaryRequestSerializer.h"/>
|
||||
<header-file src="src/ios/BinaryResponseSerializer.h"/>
|
||||
<header-file src="src/ios/TextResponseSerializer.h"/>
|
||||
<header-file src="src/ios/TextRequestSerializer.h"/>
|
||||
@@ -43,6 +44,7 @@
|
||||
<header-file src="src/ios/AFNetworking/AFURLSessionManager.h"/>
|
||||
<header-file src="src/ios/SDNetworkActivityIndicator/SDNetworkActivityIndicator.h"/>
|
||||
<source-file src="src/ios/CordovaHttpPlugin.m"/>
|
||||
<source-file src="src/ios/BinaryRequestSerializer.m"/>
|
||||
<source-file src="src/ios/BinaryResponseSerializer.m"/>
|
||||
<source-file src="src/ios/TextResponseSerializer.m"/>
|
||||
<source-file src="src/ios/TextRequestSerializer.m"/>
|
||||
|
||||
@@ -143,6 +143,8 @@ abstract class CordovaHttpBase implements Runnable {
|
||||
request.contentType("application/json", "UTF-8");
|
||||
} else if ("utf8".equals(this.serializer)) {
|
||||
request.contentType("text/plain", "UTF-8");
|
||||
} else if ("raw".equals(this.serializer)) {
|
||||
request.contentType("application/octet-stream");
|
||||
} else if ("urlencoded".equals(this.serializer)) {
|
||||
// intentionally left blank, because content type is set in HttpRequest.form()
|
||||
} else if ("multipart".equals(this.serializer)) {
|
||||
@@ -159,6 +161,8 @@ abstract class CordovaHttpBase implements Runnable {
|
||||
request.send(this.data.toString());
|
||||
} else if ("utf8".equals(this.serializer)) {
|
||||
request.send(((JSONObject) this.data).getString("text"));
|
||||
} else if ("raw".equals(this.serializer)) {
|
||||
request.send(Base64.decode((String)this.data, Base64.DEFAULT));
|
||||
} else if ("urlencoded".equals(this.serializer)) {
|
||||
request.form(JsonUtils.getObjectMap((JSONObject) this.data));
|
||||
} else if ("multipart".equals(this.serializer)) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "AFURLRequestSerialization.h"
|
||||
|
||||
@interface BinaryRequestSerializer : AFHTTPRequestSerializer
|
||||
|
||||
+ (instancetype)serializer;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,53 @@
|
||||
#import "BinaryRequestSerializer.h"
|
||||
|
||||
@implementation BinaryRequestSerializer
|
||||
|
||||
+ (instancetype)serializer
|
||||
{
|
||||
BinaryRequestSerializer *serializer = [[self alloc] init];
|
||||
return serializer;
|
||||
}
|
||||
|
||||
#pragma mark - AFURLRequestSerialization
|
||||
|
||||
- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
|
||||
withParameters:(id)parameters
|
||||
error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
NSParameterAssert(request);
|
||||
|
||||
if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
|
||||
return [super requestBySerializingRequest:request withParameters:parameters error:error];
|
||||
}
|
||||
|
||||
NSMutableURLRequest *mutableRequest = [request mutableCopy];
|
||||
|
||||
[self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
|
||||
if (![request valueForHTTPHeaderField:field]) {
|
||||
[mutableRequest setValue:value forHTTPHeaderField:field];
|
||||
}
|
||||
}];
|
||||
|
||||
if (parameters) {
|
||||
if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
|
||||
[mutableRequest setValue:@"application/octet-stream" forHTTPHeaderField:@"Content-Type"];
|
||||
}
|
||||
|
||||
[mutableRequest setHTTPBody: parameters];
|
||||
}
|
||||
|
||||
return mutableRequest;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,5 +1,6 @@
|
||||
#import "CordovaHttpPlugin.h"
|
||||
#import "CDVFile.h"
|
||||
#import "BinaryRequestSerializer.h"
|
||||
#import "BinaryResponseSerializer.h"
|
||||
#import "TextResponseSerializer.h"
|
||||
#import "TextRequestSerializer.h"
|
||||
@@ -31,6 +32,8 @@
|
||||
manager.requestSerializer = [AFJSONRequestSerializer serializer];
|
||||
} else if ([serializerName isEqualToString:@"utf8"]) {
|
||||
manager.requestSerializer = [TextRequestSerializer serializer];
|
||||
} else if ([serializerName isEqualToString:@"raw"]) {
|
||||
manager.requestSerializer = [BinaryRequestSerializer serializer];
|
||||
} else {
|
||||
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
|
||||
}
|
||||
|
||||
+26
-1
@@ -34,6 +34,7 @@ const helpers = {
|
||||
setUtf8StringSerializer: function (resolve) { resolve(cordova.plugin.http.setDataSerializer('utf8')); },
|
||||
setUrlEncodedSerializer: function (resolve) { resolve(cordova.plugin.http.setDataSerializer('urlencoded')); },
|
||||
setMultipartSerializer: function (resolve) { resolve(cordova.plugin.http.setDataSerializer('multipart')); },
|
||||
setRawSerializer: function(resolve) { resolve(cordova.plugin.http.setDataSerializer('raw')); },
|
||||
disableFollowingRedirect: function (resolve) { resolve(cordova.plugin.http.setFollowRedirect(false)); },
|
||||
enableFollowingRedirect: function(resolve) { resolve(cordova.plugin.http.setFollowRedirect(true)); },
|
||||
getWithXhr: function (done, url, type) {
|
||||
@@ -843,7 +844,31 @@ const tests = [
|
||||
const b64Logo = rawLogo.toString('base64');
|
||||
JSON.parse(result.data.data).files.CordovaLogo.should.be.equal('data:image/png;base64,' + b64Logo);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
description: 'should send raw byte array correctly (POST) #291',
|
||||
expected: 'resolved: {"status":200,"data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUg ...',
|
||||
before: helpers.setRawSerializer,
|
||||
func: function (resolve, reject) {
|
||||
helpers.getWithXhr(function(buffer) {
|
||||
cordova.plugin.http.post('http://httpbin.org/anything', buffer, {}, resolve, reject);
|
||||
}, './res/cordova_logo.png', 'arraybuffer');
|
||||
},
|
||||
validationFunc: function (driver, result) {
|
||||
helpers.checkResult(result, 'resolved');
|
||||
result.data.status.should.be.equal(200);
|
||||
|
||||
// httpbin.org encodes posted binaries in base64 and echoes them back
|
||||
// therefore we need to check for base64 string with mime type prefix
|
||||
const fs = require('fs');
|
||||
const rawLogo = fs.readFileSync('./test/e2e-app-template/www/res/cordova_logo.png');
|
||||
const b64Logo = rawLogo.toString('base64');
|
||||
const parsed = JSON.parse(result.data.data);
|
||||
|
||||
parsed.headers['Content-Type'].should.be.equal('application/octet-stream');
|
||||
parsed.data.should.be.equal('data:application/octet-stream;base64,' + b64Logo);
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: not ready yet
|
||||
// {
|
||||
|
||||
@@ -589,6 +589,15 @@ describe('Common helpers', function () {
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
it('processes data correctly when serializer "raw" is configured', (cb) => {
|
||||
const byteArray = new Uint8Array([1,2,3]);
|
||||
helpers.processData(byteArray, 'raw', (data) => {
|
||||
data.should.be.a('ArrayBuffer');
|
||||
data.should.be.equal(byteArray.buffer);
|
||||
cb();
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
module.exports = function init(global, jsUtil, cookieHandler, messages, base64, errorCodes, dependencyValidator, ponyfills) {
|
||||
var validSerializers = ['urlencoded', 'json', 'utf8', 'multipart'];
|
||||
var validSerializers = ['urlencoded', 'json', 'utf8', 'raw', 'multipart'];
|
||||
var validCertModes = ['default', 'nocheck', 'pinned', 'legacy'];
|
||||
var validClientAuthModes = ['none', 'systemstore', 'buffer'];
|
||||
var validHttpMethods = ['get', 'put', 'post', 'patch', 'head', 'delete', 'upload', 'download'];
|
||||
@@ -365,6 +365,8 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
|
||||
return ['Object'];
|
||||
case 'json':
|
||||
return ['Array', 'Object'];
|
||||
case 'raw':
|
||||
return ['Uint8Array', 'ArrayBuffer'];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
@@ -400,6 +402,8 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
|
||||
switch (dataSerializer) {
|
||||
case 'utf8':
|
||||
return cb({ text: data });
|
||||
case 'raw':
|
||||
return cb(currentDataType === 'Uint8Array' ? data.buffer : data);
|
||||
case 'multipart':
|
||||
return processFormData(data, cb);
|
||||
default:
|
||||
|
||||
@@ -6,6 +6,8 @@ module.exports = {
|
||||
return 'Array';
|
||||
case '[object Blob]':
|
||||
return 'Blob';
|
||||
case '[object Uint8Array]':
|
||||
return 'Uint8Array';
|
||||
case '[object ArrayBuffer]':
|
||||
return 'ArrayBuffer';
|
||||
case '[object Boolean]':
|
||||
|
||||
Reference in New Issue
Block a user