From a190a5dc743d4076b6128db83f7c2ff77588c896 Mon Sep 17 00:00:00 2001 From: Yordan Banev Date: Mon, 21 Oct 2019 22:30:42 +0300 Subject: [PATCH] fix(android): fix onprogress payload value for data other than HashMap (#11168) request's length was not accounted for data of type different from HashMap, thus not reporting the progress properly in the callback Fixes TIMOB-27293 --- .../titanium/network/TiHTTPClient.java | 35 +++++++++++------- .../ti.network.httpclient.addontest.js | 36 +++++++++++++++++++ 2 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 tests/Resources/ti.network.httpclient.addontest.js diff --git a/android/modules/network/src/java/ti/modules/titanium/network/TiHTTPClient.java b/android/modules/network/src/java/ti/modules/titanium/network/TiHTTPClient.java index 6a1df42ecf7..57ce9487d36 100644 --- a/android/modules/network/src/java/ti/modules/titanium/network/TiHTTPClient.java +++ b/android/modules/network/src/java/ti/modules/titanium/network/TiHTTPClient.java @@ -417,13 +417,26 @@ private void fireProgress() @Override public void write(int b) throws IOException { - //Donot write if request is aborted + //Do not write if request is aborted if (!aborted) { super.write(b); transferred++; fireProgress(); } } + + // Send the last progress callback when the + // writing is done. + @Override + public void close() throws IOException + { + super.close(); + + if (!aborted && (transferred > 0)) { + lastTransferred = transferred; + listener.progress(transferred); + } + } } public TiHTTPClient(HTTPClientProxy proxy) @@ -1103,7 +1116,6 @@ public void send(Object userData) throws UnsupportedEncodingException aborted = false; // TODO consider using task manager - int totalLength = 0; needMultipart = false; if (userData != null) { @@ -1139,12 +1151,11 @@ public void send(Object userData) throws UnsupportedEncodingException } if (value instanceof TiBaseFile || value instanceof TiBlob || value instanceof HashMap) { - totalLength += addTitaniumFileAsPostData(key, value); + addTitaniumFileAsPostData(key, value); } else { String str = TiConvert.toString(value); addPostData(key, str); - totalLength += str.length(); } } else if (isGet) { @@ -1175,8 +1186,7 @@ public void send(Object userData) throws UnsupportedEncodingException Log.d(TAG, "Instantiating http request with method='" + method + "' and this url:", Log.DEBUG_MODE); Log.d(TAG, this.url, Log.DEBUG_MODE); - clientThread = - new Thread(new ClientRunnable(totalLength), "TiHttpClient-" + httpClientThreadCounter.incrementAndGet()); + clientThread = new Thread(new ClientRunnable(), "TiHttpClient-" + httpClientThreadCounter.incrementAndGet()); clientThread.setPriority(Thread.MIN_PRIORITY); clientThread.start(); @@ -1185,16 +1195,14 @@ public void send(Object userData) throws UnsupportedEncodingException private class ClientRunnable implements Runnable { - private final int totalLength; private int contentLength; private PrintWriter printWriter; private OutputStream outputStream; private String boundary; private static final String LINE_FEED = "\r\n"; - public ClientRunnable(int totalLength) + public ClientRunnable() { - this.totalLength = totalLength; this.contentLength = 0; } @@ -1278,8 +1286,11 @@ public void run() outputStream = new ProgressOutputStream(client.getOutputStream(), new ProgressListener() { public void progress(int progress) { + if (contentLength <= 0) { + return; + } KrollDict data = new KrollDict(); - double currentProgress = ((double) progress / totalLength); + double currentProgress = ((double) progress / contentLength); if (currentProgress > 1) currentProgress = 1; data.put("progress", currentProgress); @@ -1319,6 +1330,7 @@ public void progress(int progress) } else { handleURLEncodedData(form); } + printWriter.close(); } // Fix for https://jira.appcelerator.org/browse/TIMOB-23309 @@ -1495,10 +1507,9 @@ private void addFilePart(String name, ContentBody contentBody) throws IOExceptio printWriter.flush(); } - public void completeSendingMultipart() throws IOException + public void completeSendingMultipart() { printWriter.append("--" + boundary + "--").append(LINE_FEED); - printWriter.close(); } private void handleURLEncodedData(UrlEncodedFormEntity form) throws IOException diff --git a/tests/Resources/ti.network.httpclient.addontest.js b/tests/Resources/ti.network.httpclient.addontest.js new file mode 100644 index 00000000000..b4920b7c5b5 --- /dev/null +++ b/tests/Resources/ti.network.httpclient.addontest.js @@ -0,0 +1,36 @@ +/* + * Appcelerator Titanium Mobile + * Copyright (c) 2011-Present by Appcelerator, Inc. All Rights Reserved. + * Licensed under the terms of the Apache Public License + * Please see the LICENSE included with this distribution for details. + */ +/* eslint-env mocha */ +/* eslint no-unused-expressions: "off" */ +'use strict'; +var should = require('./utilities/assertions'); + +describe('Titanium.Network.HTTPClient', function () { + + it('progress event', function (finish) { + var progressVar = -1, + file = Titanium.Filesystem.getFile('SplashScreen.png'), + base64String = Ti.Utils.base64encode(file).toString(), + xhr = Ti.Network.createHTTPClient({ + onsendstream: function (e) { + try { + should(e.progress).be.above(0); + should(e.progress).be.aboveOrEqual(progressVar); + progressVar = e.progress; + } catch (error) { + finish(error); + } + }, + onload: function () { + finish(); + } + }); + xhr.open('POST', 'https://httpbin.org/post'); + xhr.send(base64String); + }); + +});