2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 // TODO: remove when added to public cordova repository -> begin
18 var plugin_name = 'cordova-plugin-file-transfer.tizen.FileTransfer';
20 cordova.define(plugin_name, function(require, exports, module) {
21 // TODO: remove -> end
23 function getParentPath(filePath) {
24 var pos = filePath.lastIndexOf('/');
25 return filePath.substring(0, pos + 1);
28 function getFileName(filePath) {
29 var pos = filePath.lastIndexOf('/');
30 return filePath.substring(pos + 1);
33 function TizenErrCodeToErrCode(err_code) {
35 case WebAPIException.NOT_FOUND_ERR:
36 return FileTransferError.FILE_NOT_FOUND_ERR;
38 case WebAPIException.URL_MISMATCH_ERR:
39 return FileTransferError.INVALID_URL_ERR;
41 case WebAPIException.NETWORK_ERR:
42 return FileTransferError.CONNECTION_ERR;
44 case WebAPIException.ABORT_ERR:
45 return FileTransferError.ABORT_ERR;
48 return FileTransferError.NOT_MODIFIED_ERR;
52 function FileErrorCodeToErrCode(err_code) {
54 case FileError.SECURITY_ERR:
55 return FileTransferError.ABORT_ERR;
57 return FileTransferError.FILE_NOT_FOUND_ERR;
61 function checkURL(url) {
62 return url.indexOf(' ') === -1;
68 var filePrefix = 'file://';
71 upload: function(successCallback, errorCallback, args) {
72 var filePath = args[0],
74 fileKey = args[2] || 'file',
75 fileName = args[3] || 'image.jpg',
76 mimeType = args[4] || 'image/jpeg',
78 trustAllHosts = args[6], // not used
79 chunkedMode = args[7],
82 httpMethod = args[10] || 'POST';
84 if (0 !== filePath.indexOf(filePrefix)) {
85 filePath = filePrefix + filePath;
88 var fail = function(code, status, response) {
89 uploads[id] && delete uploads[id];
90 var error = new FileTransferError(code, filePath, server, status, response);
91 errorCallback && errorCallback(error);
94 if (!checkURL(server)) {
95 fail(FileTransferError.INVALID_URL_ERR);
99 function successCB(entry) {
101 // initialize XMLHTTPRequest (without starting it)
102 var xhr = uploads[id] = new XMLHttpRequest();
104 xhr.open(httpMethod, server);
107 for (var header in headers) {
108 if (headers.hasOwnProperty(header)) {
109 xhr.setRequestHeader(header, headers[header]);
113 xhr.ontimeout = function(evt) {
114 fail(FileTransferError.CONNECTION_ERR, this.status, this.response);
117 xhr.onerror = function() {
118 fail(FileTransferError.CONNECTION_ERR, this.status, this.response);
121 xhr.onabort = function () {
122 fail(FileTransferError.ABORT_ERR, this.status, this.response);
125 xhr.upload.onprogress = function (e) {
128 // end of XMLHTTPRequest initialization
130 var fullPath = entry.toURL();
133 function closeHandle() {
139 function uploadFile(blobFile) {
142 var fd = new FormData();
143 fd.append(fileKey, blobFile, fileName);
144 for (var prop in params) {
145 if(params.hasOwnProperty(prop)) {
146 fd.append(prop, params[prop]);
150 // sending already initialized request
151 // 'onload' needs to be defined here because it needs blobFile.size
152 xhr.onload = function(evt) {
153 // 2xx codes are valid
154 if (xhr.status >= 200 && xhr.status < 300) {
155 uploads[id] && delete uploads[id];
157 bytesSent: blobFile.size,
158 responseCode: xhr.status,
159 response: xhr.response
161 } else if (xhr.status === 404) {
162 fail(FileTransferError.INVALID_URL_ERR, this.status, this.response);
164 fail(FileTransferError.CONNECTION_ERR, this.status, this.response);
169 // Special case when transfer already aborted, but XHR isn't sent.
170 // In this case XHR won't fire an abort event, so we need to check if transfers record
171 // isn't deleted by filetransfer.abort and if so, call XHR's abort method again
178 fileHandle = tizen.filesystem.openFile(fullPath, 'r');
179 var fileBlob = fileHandle.readBlobNonBlocking(
183 fail(FileTransferError.ABORT_ERR, 'Could not read file ' + e);
188 fail(FileTransferError.ABORT_ERR, 'Could not read file ' + e);
193 function errorCB(error) {
194 fail(FileErrorCodeToErrCode(error.code));
197 resolveLocalFileSystemURL(filePath, successCB, errorCB);
199 download: function(successCallback, errorCallback, args) {
202 trustAllHosts = args[2], // not used
206 if (!checkURL(url)) {
207 errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR, url, filePath));
211 var dirPath = getParentPath(filePath);
212 var fileName = getFileName(filePath);
214 var xhr = downloads[id] = new XMLHttpRequest();
216 function fail(code, body) {
217 delete downloads[id];
218 errorCallback(new FileTransferError(code,
226 xhr.addEventListener('progress', function (evt) {
227 successCallback(evt);
230 xhr.addEventListener('abort', function (evt) {
231 fail(FileTransferError.ABORT_ERR, xhr.response);
234 xhr.addEventListener('error', function (evt) {
235 fail(FileTransferError.CONNECTION_ERR, xhr.response);
238 xhr.addEventListener('load', function (evt) {
239 if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
241 tizen.filesystem.resolve(dirPath, function (dir) {
243 fail(FileTransferError.FILE_NOT_FOUND_ERR);
247 function writeFile(dir) {
248 var file = dir.createFile(fileName);
253 stream.writeBytes(Array.prototype.slice.call(new Uint8Array(xhr.response)));
255 delete downloads[id];
257 resolveLocalFileSystemURL(
259 function (fileEntry) {
260 fileEntry.filesystemName = fileEntry.filesystem.name;
261 successCallback(fileEntry);
263 fail(TizenErrCodeToErrCode(err.code));
266 fail(TizenErrCodeToErrCode(err.code));
280 fail(TizenErrCodeToErrCode(err.code));
284 fail(FileTransferError.ABORT_ERR);
286 } else if (xhr.status === 404) {
287 fail(FileTransferError.INVALID_URL_ERR,
288 String.fromCharCode.apply(null, new Uint8Array(xhr.response)));
290 fail(FileTransferError.CONNECTION_ERR,
291 String.fromCharCode.apply(null, new Uint8Array(xhr.response)));
295 xhr.open('GET', url, true);
296 xhr.responseType = 'arraybuffer';
298 for (var header in headers) {
299 if (headers.hasOwnProperty(header)) {
300 xhr.setRequestHeader(header, headers[header]);
305 abort: function(successCallback, errorCallback, args) {
310 } else if (downloads[id]) {
311 downloads[id].abort();
312 delete downloads[id];
314 console.warn('Unknown file transfer ID: ' + id);
319 require("cordova/exec/proxy").add("FileTransfer", exports);
321 console.log('Loaded cordova.file-transfer API');
323 // TODO: remove when added to public cordova repository -> begin
325 // TODO: remove -> end