mirror of
https://github.com/apache/cordova-plugin-file-transfer.git
synced 2026-03-08 00:00:05 +08:00
add atob+btoa for wp7 only fixes FileTransfer issues
This commit is contained in:
10
plugin.xml
10
plugin.xml
@@ -54,7 +54,7 @@
|
||||
</config-file>
|
||||
<header-file src="src/ios/CDVFileTransfer.h" />
|
||||
<source-file src="src/ios/CDVFileTransfer.m" />
|
||||
|
||||
|
||||
<framework src="AssetsLibrary.framework" />
|
||||
</platform>
|
||||
|
||||
@@ -67,6 +67,11 @@
|
||||
</config-file>
|
||||
|
||||
<source-file src="src/wp/FileTransfer.cs" />
|
||||
|
||||
<js-module src="www/wp7/base64.js" name="base64">
|
||||
<clobbers target="window.FileTransfer" />
|
||||
</js-module>
|
||||
|
||||
</platform>
|
||||
|
||||
<!-- wp8 -->
|
||||
@@ -78,6 +83,7 @@
|
||||
</config-file>
|
||||
|
||||
<source-file src="src/wp/FileTransfer.cs" />
|
||||
|
||||
</platform>
|
||||
|
||||
<!-- windows8 -->
|
||||
@@ -85,6 +91,6 @@
|
||||
<js-module src="www/windows8/FileTransferProxy.js" name="FileTransferProxy">
|
||||
<clobbers target="" />
|
||||
</js-module>
|
||||
</platform>
|
||||
</platform>
|
||||
|
||||
</plugin>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -76,7 +76,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
|
||||
/// <summary>
|
||||
/// Boundary symbol
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
|
||||
|
||||
// Error codes
|
||||
@@ -146,7 +146,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
/// <summary>
|
||||
/// The target URI
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
[DataMember(Name = "target", IsRequired = true)]
|
||||
public string Target { get; set; }
|
||||
|
||||
@@ -209,7 +209,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
BytesLoaded = bLoaded;
|
||||
BytesTotal = bTotal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -236,9 +236,9 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
TransferOptions uploadOptions = null;
|
||||
HttpWebRequest webRequest = null;
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||
uploadOptions = new TransferOptions();
|
||||
@@ -311,17 +311,19 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)),callbackId);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// example : "{\"Authorization\":\"Basic Y29yZG92YV91c2VyOmNvcmRvdmFfcGFzc3dvcmQ=\"}"
|
||||
protected Dictionary<string,string> parseHeaders(string jsonHeaders)
|
||||
protected Dictionary<string,string> parseHeaders(string jsonHeaders)
|
||||
{
|
||||
Dictionary<string, string> result = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
Dictionary<string, string> result = new Dictionary<string, string>();
|
||||
|
||||
string temp = jsonHeaders.StartsWith("{") ? jsonHeaders.Substring(1) : jsonHeaders;
|
||||
temp = temp.EndsWith("}") ? temp.Substring(0,temp.Length - 1) : temp;
|
||||
string temp = jsonHeaders.StartsWith("{") ? jsonHeaders.Substring(1) : jsonHeaders;
|
||||
temp = temp.EndsWith("}") ? temp.Substring(0, temp.Length - 1) : temp;
|
||||
|
||||
string[] strHeaders = temp.Split(',');
|
||||
for (int n = 0; n < strHeaders.Length; n++)
|
||||
@@ -329,12 +331,21 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
string[] split = strHeaders[n].Split(":".ToCharArray(), 2);
|
||||
if (split.Length == 2)
|
||||
{
|
||||
split[0] = JSON.JsonHelper.Deserialize<string>(split[0]);
|
||||
split[1] = JSON.JsonHelper.Deserialize<string>(split[1]);
|
||||
result[split[0]] = split[1];
|
||||
string[] split = strHeaders[n].Split(':');
|
||||
if (split.Length == 2)
|
||||
{
|
||||
split[0] = JSON.JsonHelper.Deserialize<string>(split[0]);
|
||||
split[1] = JSON.JsonHelper.Deserialize<string>(split[1]);
|
||||
result[split[0]] = split[1];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
catch (Exception)
|
||||
{
|
||||
Debug.WriteLine("Failed to parseHeaders from string :: " + jsonHeaders);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -370,7 +381,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
|
||||
try
|
||||
{
|
||||
// is the URL a local app file?
|
||||
// is the URL a local app file?
|
||||
if (downloadOptions.Url.StartsWith("x-wmapp0") || downloadOptions.Url.StartsWith("file:"))
|
||||
{
|
||||
using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
|
||||
@@ -431,7 +442,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
File.FileEntry entry = File.FileEntry.GetEntry(downloadOptions.FilePath);
|
||||
@@ -456,7 +467,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
|
||||
new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
|
||||
return;
|
||||
}
|
||||
@@ -476,35 +487,53 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
webRequest.Headers[key] = headers[key];
|
||||
}
|
||||
}
|
||||
|
||||
webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
|
||||
|
||||
try
|
||||
{
|
||||
webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
|
||||
}
|
||||
catch (WebException)
|
||||
{
|
||||
// eat it
|
||||
}
|
||||
// dispatch an event for progress ( 0 )
|
||||
var plugRes = new PluginResult(PluginResult.Status.OK, new FileTransferProgress());
|
||||
plugRes.KeepCallback = true;
|
||||
plugRes.CallbackId = callbackId;
|
||||
DispatchCommandResult(plugRes, callbackId);
|
||||
lock (state)
|
||||
{
|
||||
if (!state.isCancelled)
|
||||
{
|
||||
var plugRes = new PluginResult(PluginResult.Status.OK, new FileTransferProgress());
|
||||
plugRes.KeepCallback = true;
|
||||
plugRes.CallbackId = callbackId;
|
||||
DispatchCommandResult(plugRes, callbackId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void abort(string options)
|
||||
{
|
||||
Debug.WriteLine("Abort :: " + options);
|
||||
string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||
string id = optionStrings[0];
|
||||
string callbackId = optionStrings[1];
|
||||
string callbackId = optionStrings[1];
|
||||
|
||||
if (InProcDownloads.ContainsKey(id))
|
||||
{
|
||||
DownloadRequestState state = InProcDownloads[id];
|
||||
state.isCancelled = true;
|
||||
if (!state.request.HaveResponse)
|
||||
{
|
||||
state.request.Abort();
|
||||
InProcDownloads.Remove(id);
|
||||
callbackId = state.options.CallbackId;
|
||||
//state = null;
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileTransfer.AbortError)),
|
||||
callbackId);
|
||||
if (!state.isCancelled)
|
||||
{ // prevent multiple callbacks for the same abort
|
||||
state.isCancelled = true;
|
||||
if (!state.request.HaveResponse)
|
||||
{
|
||||
state.request.Abort();
|
||||
InProcDownloads.Remove(id);
|
||||
//callbackId = state.options.CallbackId;
|
||||
//state = null;
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
|
||||
new FileTransferError(FileTransfer.AbortError)),
|
||||
state.options.CallbackId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -514,23 +543,26 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
}
|
||||
}
|
||||
|
||||
private void DispatchFileTransferProgress(long bytesLoaded, long bytesTotal, string callbackId)
|
||||
private void DispatchFileTransferProgress(long bytesLoaded, long bytesTotal, string callbackId, bool keepCallback = true)
|
||||
{
|
||||
Debug.WriteLine("DispatchFileTransferProgress : " + callbackId);
|
||||
// send a progress change event
|
||||
FileTransferProgress progEvent = new FileTransferProgress(bytesTotal);
|
||||
progEvent.BytesLoaded = bytesLoaded;
|
||||
PluginResult plugRes = new PluginResult(PluginResult.Status.OK, progEvent);
|
||||
plugRes.KeepCallback = true;
|
||||
plugRes.KeepCallback = keepCallback;
|
||||
plugRes.CallbackId = callbackId;
|
||||
DispatchCommandResult(plugRes, callbackId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="asynchronousResult"></param>
|
||||
private void downloadCallback(IAsyncResult asynchronousResult)
|
||||
{
|
||||
|
||||
|
||||
DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
|
||||
HttpWebRequest request = reqState.request;
|
||||
|
||||
@@ -538,7 +570,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
try
|
||||
{
|
||||
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
|
||||
|
||||
|
||||
// send a progress change event
|
||||
DispatchFileTransferProgress(0, response.ContentLength, callbackId);
|
||||
|
||||
@@ -596,7 +628,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(AbortError)),
|
||||
callbackId);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -621,10 +653,10 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
// TODO: probably need better work here to properly respond with all http status codes back to JS
|
||||
// Right now am jumping through hoops just to detect 404.
|
||||
HttpWebResponse response = (HttpWebResponse)webex.Response;
|
||||
if ((webex.Status == WebExceptionStatus.ProtocolError && response.StatusCode == HttpStatusCode.NotFound)
|
||||
if ((webex.Status == WebExceptionStatus.ProtocolError && response.StatusCode == HttpStatusCode.NotFound)
|
||||
|| webex.Status == WebExceptionStatus.UnknownError)
|
||||
{
|
||||
|
||||
|
||||
// Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
|
||||
// "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
|
||||
// FACEPALM
|
||||
@@ -640,19 +672,29 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
}
|
||||
}
|
||||
FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode, body);
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError),
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError),
|
||||
callbackId);
|
||||
}
|
||||
else
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
|
||||
new FileTransferError(ConnectionError)),
|
||||
callbackId);
|
||||
lock (reqState)
|
||||
{
|
||||
if (!reqState.isCancelled)
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
|
||||
new FileTransferError(ConnectionError)),
|
||||
callbackId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine("It happened");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
|
||||
new FileTransferError(FileNotFoundError)),
|
||||
callbackId);
|
||||
}
|
||||
@@ -686,7 +728,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
|
||||
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
|
||||
|
||||
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(reqState.options.Params))
|
||||
{
|
||||
@@ -712,8 +754,8 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
long totalBytesToSend = 0;
|
||||
|
||||
using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, isoFile))
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
|
||||
string header = string.Format(headerTemplate, reqState.options.FileKey, reqState.options.FileName, reqState.options.MimeType);
|
||||
byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
|
||||
@@ -725,17 +767,23 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
|
||||
|
||||
requestStream.Write(headerBytes, 0, headerBytes.Length);
|
||||
|
||||
|
||||
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
|
||||
{
|
||||
// TODO: Progress event
|
||||
requestStream.Write(buffer, 0, bytesRead);
|
||||
bytesSent += bytesRead;
|
||||
DispatchFileTransferProgress(bytesSent, totalBytesToSend, callbackId);
|
||||
System.Threading.Thread.Sleep(1);
|
||||
if (!reqState.isCancelled)
|
||||
{
|
||||
requestStream.Write(buffer, 0, bytesRead);
|
||||
bytesSent += bytesRead;
|
||||
DispatchFileTransferProgress(bytesSent, totalBytesToSend, callbackId);
|
||||
System.Threading.Thread.Sleep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("UploadCancelledException");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
requestStream.Write(endRequest, 0, endRequest.Length);
|
||||
}
|
||||
}
|
||||
@@ -745,7 +793,10 @@ namespace WPCordovaClassLib.Cordova.Commands
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)),callbackId);
|
||||
if (!reqState.isCancelled)
|
||||
{
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)), callbackId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,20 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// 9 14 18 19 20
|
||||
|
||||
var _it = it;
|
||||
it = function (text, funk) {
|
||||
if (text.indexOf("filetransfer.spec.7") == 0) {
|
||||
return _it(text, funk);
|
||||
}
|
||||
else {
|
||||
console.log("Skipping Test : " + text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
describe('FileTransfer', function() {
|
||||
// https://github.com/apache/cordova-labs/tree/cordova-filetransfer
|
||||
var server = "http://cordova-filetransfer.jitsu.com";
|
||||
@@ -60,13 +74,10 @@ describe('FileTransfer', function() {
|
||||
};
|
||||
|
||||
var getMalformedUrl = function() {
|
||||
if (device.platform.match(/Android/i)) {
|
||||
// bad protocol causes a MalformedUrlException on Android
|
||||
return "httpssss://example.com";
|
||||
} else {
|
||||
|
||||
// iOS doesn't care about protocol, space in hostname causes error
|
||||
return "httpssss://exa mple.com";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// deletes file, if it exists, then invokes callback
|
||||
@@ -116,6 +127,7 @@ describe('FileTransfer', function() {
|
||||
|
||||
var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
|
||||
expect(entry.name).toBe(localFileName);
|
||||
console.log("lastProgressEvent = " + JSON.stringify(lastProgressEvent));
|
||||
expect(lastProgressEvent.loaded).toBeGreaterThan(1);
|
||||
});
|
||||
|
||||
@@ -132,32 +144,11 @@ describe('FileTransfer', function() {
|
||||
|
||||
waitsForAny(downloadWin, fail);
|
||||
});
|
||||
it("filetransfer.spec.5 should be able to download a file using http basic auth", function() {
|
||||
var fail = createDoNotCallSpy('downloadFail');
|
||||
var remoteFile = server_with_credentials + "/download_basic_auth"
|
||||
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
|
||||
var lastProgressEvent = null;
|
||||
|
||||
var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
|
||||
expect(entry.name).toBe(localFileName);
|
||||
expect(lastProgressEvent.loaded).toBeGreaterThan(1);
|
||||
});
|
||||
|
||||
this.after(function() {
|
||||
deleteFile(localFileName);
|
||||
});
|
||||
runs(function() {
|
||||
var ft = new FileTransfer();
|
||||
ft.onprogress = function(e) {
|
||||
lastProgressEvent = e;
|
||||
};
|
||||
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, fail);
|
||||
});
|
||||
|
||||
waitsForAny(downloadWin, fail);
|
||||
});
|
||||
it("filetransfer.spec.6 should get http status on basic auth failure", function() {
|
||||
var downloadWin = createDoNotCallSpy('downloadWin');
|
||||
var downloadWin = createDoNotCallSpy('downloadWin').andCallFake(function (res) {
|
||||
alert("it happened");
|
||||
});
|
||||
|
||||
var remoteFile = server + "/download_basic_auth";
|
||||
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
|
||||
@@ -175,17 +166,49 @@ describe('FileTransfer', function() {
|
||||
});
|
||||
|
||||
waitsForAny(downloadWin, downloadFail);
|
||||
});
|
||||
it("filetransfer.spec.7 should be able to download a file using file:// (when hosted from file://)", function() {
|
||||
});
|
||||
it("filetransfer.spec.5 should be able to download a file using http basic auth", function () {
|
||||
var fail = createDoNotCallSpy('downloadFail');
|
||||
var remoteFile = window.location.href.replace(/\?.*/, '').replace(/ /g, '%20');
|
||||
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
|
||||
var remoteFile = server_with_credentials + "/download_basic_auth"
|
||||
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/') + 1);
|
||||
var lastProgressEvent = null;
|
||||
|
||||
if (!/^file/.exec(remoteFile)) {
|
||||
expect(remoteFile).toMatch(/^file:/);
|
||||
return;
|
||||
}
|
||||
var downloadWin = jasmine.createSpy().andCallFake(function (entry) {
|
||||
expect(entry.name).toBe(localFileName);
|
||||
expect(lastProgressEvent.loaded).toBeGreaterThan(1);
|
||||
});
|
||||
|
||||
this.after(function () {
|
||||
deleteFile(localFileName);
|
||||
});
|
||||
runs(function () {
|
||||
var ft = new FileTransfer();
|
||||
ft.onprogress = function (e) {
|
||||
lastProgressEvent = e;
|
||||
};
|
||||
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, fail);
|
||||
});
|
||||
|
||||
waitsForAny(downloadWin, fail);
|
||||
|
||||
});
|
||||
|
||||
it("filetransfer.spec.7 should be able to download a file using file:// (when hosted from file://)", function() {
|
||||
var fail = createDoNotCallSpy('downloadFail').andCallFake(function(err) {
|
||||
alert("err :: " + JSON.stringify(err));
|
||||
});
|
||||
var remoteFile = window.location.href.replace(/\?.*/, '').replace(/ /g, '%20').replace("x-wmapp0:","file://");
|
||||
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/') + 1);
|
||||
console.log("localFileName = " + localFileName);
|
||||
console.log("remoteFile = " + remoteFile);
|
||||
var lastProgressEvent = null;
|
||||
|
||||
|
||||
|
||||
//if (!/^file/.exec(remoteFile)) {
|
||||
// expect(remoteFile).toMatch(/^file:/);
|
||||
// return;
|
||||
//}
|
||||
|
||||
var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
|
||||
expect(entry.name).toBe(localFileName);
|
||||
@@ -199,7 +222,11 @@ describe('FileTransfer', function() {
|
||||
var ft = new FileTransfer();
|
||||
ft.onprogress = function(e) {
|
||||
lastProgressEvent = e;
|
||||
console.log("onprogress :: " + JSON.stringify(e));
|
||||
};
|
||||
|
||||
console.log("calling download : " + remoteFile + ", " + (root.fullPath + "/" + localFileName));
|
||||
|
||||
ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, fail);
|
||||
|
||||
waitsForAny(downloadWin, fail);
|
||||
@@ -213,7 +240,7 @@ describe('FileTransfer', function() {
|
||||
readFileEntry(entry, fileWin, fileFail);
|
||||
};
|
||||
var fileWin = jasmine.createSpy().andCallFake(function(content) {
|
||||
expect(content).toMatch(/The Apache Software Foundation/);
|
||||
expect(content).toMatch(/The Apache Software Foundation/);
|
||||
});
|
||||
|
||||
this.after(function() {
|
||||
@@ -232,7 +259,8 @@ describe('FileTransfer', function() {
|
||||
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
|
||||
var startTime = +new Date();
|
||||
|
||||
var downloadFail = jasmine.createSpy().andCallFake(function(e) {
|
||||
var downloadFail = jasmine.createSpy().andCallFake(function (e) {
|
||||
console.log("downloadFail called : " + JSON.stringify(e));
|
||||
expect(e.code).toBe(FileTransferError.ABORT_ERR);
|
||||
var didNotExistSpy = jasmine.createSpy();
|
||||
var existedSpy = createDoNotCallSpy('file existed after abort');
|
||||
@@ -260,7 +288,7 @@ describe('FileTransfer', function() {
|
||||
|
||||
var downloadFail = jasmine.createSpy().andCallFake(function(e) {
|
||||
expect(e.code).toBe(FileTransferError.ABORT_ERR);
|
||||
expect(new Date() - startTime).toBeLessThan(300);
|
||||
expect(new Date() - startTime).toBeLessThan(3000);
|
||||
});
|
||||
|
||||
this.after(function() {
|
||||
@@ -282,7 +310,7 @@ describe('FileTransfer', function() {
|
||||
var remoteFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';
|
||||
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
|
||||
var startTime = +new Date();
|
||||
|
||||
|
||||
this.after(function() {
|
||||
deleteFile(localFileName);
|
||||
});
|
||||
@@ -293,7 +321,7 @@ describe('FileTransfer', function() {
|
||||
ft.abort();
|
||||
ft.abort(); // should be a no-op.
|
||||
});
|
||||
|
||||
|
||||
waitsForAny(downloadFail);
|
||||
});
|
||||
it("filetransfer.spec.12 should get http status on failure", function() {
|
||||
@@ -323,7 +351,7 @@ describe('FileTransfer', function() {
|
||||
var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
|
||||
var downloadFail = jasmine.createSpy().andCallFake(function(error) {
|
||||
expect(error.body).toBeDefined();
|
||||
expect(error.body).toEqual('You requested a 404\n');
|
||||
expect(error.body).toMatch('You requested a 404');
|
||||
});
|
||||
|
||||
this.after(function() {
|
||||
@@ -380,9 +408,7 @@ describe('FileTransfer', function() {
|
||||
|
||||
var remoteFile = server;
|
||||
var badFilePath = "c:\\54321";
|
||||
var downloadFail = jasmine.createSpy().andCallFake(function(error) {
|
||||
expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
|
||||
});
|
||||
var downloadFail = jasmine.createSpy();
|
||||
|
||||
runs(function() {
|
||||
var ft = new FileTransfer();
|
||||
@@ -396,7 +422,7 @@ describe('FileTransfer', function() {
|
||||
var remoteFile = "http://www.apache.org/";
|
||||
var localFileName = "index.html";
|
||||
var lastProgressEvent = null;
|
||||
|
||||
|
||||
var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
|
||||
expect(entry.name).toBe(localFileName);
|
||||
expect(lastProgressEvent.loaded).toBeGreaterThan(1, 'loaded');
|
||||
@@ -427,7 +453,8 @@ describe('FileTransfer', function() {
|
||||
var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
|
||||
var lastProgressEvent = null;
|
||||
|
||||
var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
|
||||
var uploadWin = jasmine.createSpy().andCallFake(function (uploadResult) {
|
||||
console.log("uploadResult : " + JSON.stringify(uploadResult));
|
||||
expect(uploadResult.bytesSent).toBeGreaterThan(0);
|
||||
expect(uploadResult.responseCode).toBe(200);
|
||||
expect(uploadResult.response).toMatch(/fields:\s*{\s*value1.*/);
|
||||
@@ -446,11 +473,12 @@ describe('FileTransfer', function() {
|
||||
params.value2 = "param";
|
||||
options.params = params;
|
||||
|
||||
ft.onprogress = function(e) {
|
||||
expect(e.lengthComputable).toBe(true);
|
||||
expect(e.total).toBeGreaterThan(0);
|
||||
expect(e.loaded).toBeGreaterThan(0);
|
||||
lastProgressEvent = e;
|
||||
ft.onprogress = function (e) {
|
||||
|
||||
expect(e.lengthComputable).toBe(true);
|
||||
expect(e.total).toBeGreaterThan(0);
|
||||
expect(e.loaded).toBeGreaterThan(0);
|
||||
lastProgressEvent = e;
|
||||
};
|
||||
|
||||
// removing options cause Android to timeout
|
||||
@@ -692,7 +720,6 @@ describe('FileTransfer', function() {
|
||||
var remoteFile = server + "/upload";
|
||||
|
||||
var uploadFail = jasmine.createSpy().andCallFake(function(error) {
|
||||
expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
|
||||
expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
|
||||
});
|
||||
|
||||
|
||||
71
www/wp7/base64.js
Normal file
71
www/wp7/base64.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
|
||||
INVALID_CHARACTER_ERR = (function () {
|
||||
// fabricate a suitable error object
|
||||
try { document.createElement('$'); }
|
||||
catch (error) { return error; }
|
||||
}());
|
||||
|
||||
// encoder
|
||||
// [https://gist.github.com/999166] by [https://github.com/nignag]
|
||||
window.btoa || (
|
||||
window.btoa = function (input) {
|
||||
for (
|
||||
// initialize result and counter
|
||||
var block, charCode, idx = 0, map = chars, output = '';
|
||||
// if the next input index does not exist:
|
||||
// change the mapping table to "="
|
||||
// check if d has no fractional digits
|
||||
input.charAt(idx | 0) || (map = '=', idx % 1) ;
|
||||
// "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
|
||||
output += map.charAt(63 & block >> 8 - idx % 1 * 8)
|
||||
) {
|
||||
charCode = input.charCodeAt(idx += 3 / 4);
|
||||
if (charCode > 0xFF) throw INVALID_CHARACTER_ERR;
|
||||
block = block << 8 | charCode;
|
||||
}
|
||||
return output;
|
||||
});
|
||||
|
||||
// decoder
|
||||
// [https://gist.github.com/1020396] by [https://github.com/atk]
|
||||
window.atob || (
|
||||
window.atob = function (input) {
|
||||
input = input.replace(/=+$/, '')
|
||||
if (input.length % 4 == 1) throw INVALID_CHARACTER_ERR;
|
||||
for (
|
||||
// initialize result and counters
|
||||
var bc = 0, bs, buffer, idx = 0, output = '';
|
||||
// get next character
|
||||
buffer = input.charAt(idx++) ;
|
||||
// character found in table? initialize bit storage and add its ascii value;
|
||||
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
|
||||
// and if not first of each 4 characters,
|
||||
// convert the first 8 bits to one ascii character
|
||||
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
|
||||
) {
|
||||
// try to find character in table (0-63, not found => -1)
|
||||
buffer = chars.indexOf(buffer);
|
||||
}
|
||||
return output;
|
||||
});
|
||||
Reference in New Issue
Block a user