[AC-1709] HttpClient.send() changes order of POST values
| GitHub Issue | n/a |
|---|---|
| Type | Bug |
| Priority | n/a |
| Status | Closed |
| Resolution | Cannot Reproduce |
| Resolution Date | 2016-01-31T06:54:40.000+0000 |
| Affected Version/s | n/a |
| Fix Version/s | n/a |
| Components | Titanium SDK & CLI |
| Labels | HttpClient |
| Reporter | Stephen Ostrow |
| Assignee | Shak Hossain |
| Created | 2016-01-22T06:04:22.000+0000 |
| Updated | 2016-03-08T07:38:12.000+0000 |
Description
HttpClient.send() does not respect the order of the array of data given to it.
When using a pre-authorized POST url for Amazon's AWS S3 the order of the POST fields matters.
For instance
var httpClient = Ti.Network.createHTTPClient({
onload: function(e) {
Ti.API.info("Upload file responseText: " + this.responseText);
_encodedFilename = awsPolicyFields.formInputs.key;
callback(true);
},
onerror : function(e) {
Ti.API.error("Error uploading file: " + e.error);
Ti.API.debug("Upload file responseText: " + this.responseText);
callback(false);
},
onsendstream : function(e) {
var progress = parseFloat(e.progress);
Ti.API.trace("Upload progress: " + (progress * 100));
Ti.App.fireEvent('progress_update', {'progress' : progress});
},
validatesSecureCertificate : _validatesSSL
});
var args = {
'key': awsPolicyFields.formInputs['key'],
'policy' : awsPolicyFields.formInputs['policy'],
'signature' : awsPolicyFields.formInputs['signature'],
'AWSAccessKeyId' : awsPolicyFields.formInputs['AWSAccessKeyId'],
'success_action_status' : awsPolicyFields.formInputs['success_action_status'],
'x-amz-server-side-encryption' : awsPolicyFields.formInputs['x-amz-server-side-encryption'],
'Content-Type' : awsPolicyFields.formInputs['Content-Type'],
'file' : videoFile,
};
httpClient.open(awsPolicyFields.formAttributes.method, awsPolicyFields.formAttributes.action);
httpClient.send(args);
networkManager.addRequest(httpClient);
sent the following request
=============== New Request at 2016-01-22T03:02:08+00:00 ===================
POST /endpoint
x-newrelic-id: XXXXXXXXXXXX=
Accept-Encoding: identity
X-Titanium-Id: XXXXXXXXXXXXXXXXXXXX
Content-Type: multipart/form-data; boundary=j6FN2IMH7hRNiksUXnkOufIDEOdD4CH9jEHbdh
X-Requested-With: XMLHttpRequest
User-Agent: Appcelerator Titanium/5.1.2 (Android SDK built for x86_64; Android API Level: 22; en-US;)
Host: example.org
Connection: Keep-Alive
Content-Length: 279029
--------------------- php://input -----------------
--------------------- $_POST -----------------
AWSAccessKeyId: XXXXXXXXXXXXX
Content-Type: video/mp4
key: keydir/XXXXXX/sadfsdaf.mp4
signature: a+TJ/dJX/ei76vm4EURakrg7q+s=
policy: eyJleHBpcmF0aW9uIjoiMjAxNi0wMS0yMlQwNDowMTo0NloiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJXXXXXXXXXXXXXXXXXXXXXXvbl9zdGF0dXMiOiIyMDAifSx7ImtleSI6ImRlbW9cL2Z0cF91cGxvYWRzXC84LWdlbmVyYWwtbWFuYWdlclwvc2FkZnNkYWYubXA0In0seyJ4LWXXXXXXXXXXXXXXXXXXXB0aW9uIjoiQUVTMjU2In0seyJDb250ZW50LVR5cGUiOiJ2aWRlb1wvbXA0In1dfQ==
success_action_status: 200
x-amz-server-side-encryption: AES256
--------------------- $_FILE -----------------
file:
array (
'name' => 'VID_20160121_220135.mp4',
'type' => 'application/octet-stream',
'tmp_name' => '/tmp/phpOI761z',
'error' => 0,
'size' => 277413,
)
I believe this is due to ti.modules.titanium.network.TiHTTPClient using a HashMap for parts https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/network/src/java/ti/modules/titanium/network/TiHTTPClient.java#L139 A HashMap does not guarantee ordering and it appears every time you add to it you mach the ordering of it.
Hello, I tried to test the ordering of the post data using below code but couldn't reproduce it. It would be helpful if you attach a complete test code and steps to reproduce this issue. *Testing Environment:* Appcelerator Studio, build: 4.4.0.201511241829 Appcelerator Command-Line Interface, version 5.1.0 Titanium Command-Line Interface, CLI version 5.0.5, Titanium SDK version : 5.1.2 GA Mac OS X : 10.11.1 (EI Capitan) Node.js Version = 0.12.7 Java Development Kit= 1.7.0_65 VirtualBox Version = 4.3.28r100309 *Test Code:* index.xml
index.jspostdata.php$.todoWin.open(); function postData() { var xhr = Ti.Network.createHTTPClient({ onload : function() { Ti.API.info("STATUS: " + this.status); alert("TEXT: " + this.responseText); //json = JSON.parse(this.responseText); }, onerror : function(e) { Ti.API.info("STATUS: " + this.status); Ti.API.info("TEXT: " + this.responseText); Ti.API.info("ERROR: " + e.error); alert(L('network_problem')); }, timeout : 50000 }); var data = { Name : 'username', password : 'password', city : 'select city', country : 'select country', order : 'order 1' }; alert('data' + JSON.stringify(data)); xhr.open('POST', encodeURI('http://localhost/Test/postdata.php')); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(data)); }*Output:*<?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { $params = file_get_contents('php://input'); $params = json_decode(str_replace('\"', '"', $params)); echo json_encode($params); } else { echo json_encode((object) array('error' => 'invalid verb')); } ?>Thanks.{"Name":"username","password":"password","city":"select city","country":"select country","order":"order 1"}