diff --git a/apps/tests/http-tests.ts b/apps/tests/http-tests.ts index 23cd5b74b..6f0a92846 100644 --- a/apps/tests/http-tests.ts +++ b/apps/tests/http-tests.ts @@ -2,6 +2,7 @@ import TKUnit = require("./TKUnit"); import http = require("http"); import types = require("utils/types"); +import fs = require("file-system"); require("globals"); // @@ -225,6 +226,82 @@ export var test_getImage_fail_when_result_is_not_image = function (done) { }); }; +export var test_getFile_isDefined = function () { + TKUnit.assert(typeof (http.getFile) !== "undefined", "Method http.getFile() should be defined!"); +}; + +export var test_getFile = function (done) { + var result; + + // + // ### Get File from URL. By default the file will be saved in Documents folder. + // ``` JavaScript + http.getFile("https://raw.githubusercontent.com/NativeScript/NativeScript/master/apps/tests/logo.png").then(function (r) { + //// Argument (r) is File! + // + result = r; + try { + TKUnit.assert(result instanceof fs.File, "Result from getFile() should be valid File object!"); + done(null); + } + catch (err) { + done(err); + } + // + }, function (e) { + //// Argument (e) is Error! + // + done(e); + // + }); + // ``` + // +}; + +export var test_getContentAsFile = function (done) { + var result; + + // + // ### Get content as File from URL. You can specify where the file should be saved. + // ``` JavaScript + var filePath = fs.path.join(fs.knownFolders.documents().path, "test.png"); + http.getFile("https://httpbin.org/image/png", filePath).then(function (r) { + //// Argument (r) is File! + // + result = r; + try { + TKUnit.assert(result instanceof fs.File, "Result from getFile() should be valid File object!"); + done(null); + } + catch (err) { + done(err); + } + // + }, function (e) { + //// Argument (e) is Error! + // + done(e); + // + }); + // ``` + // +}; + +export var test_getFile_fail = function (done) { + var result; + + http.getImage({ url: "hgfttp://raw.githubusercontent.com/NativeScript/NativeScript/master/apps/tests/logo.png", method: "GET", timeout: 2000 }).catch(function (e) { + result = e; + try { + TKUnit.assert(result instanceof Error, "Result from getFile().catch() should be Error! Current type is " + typeof result); + done(null); + } + catch (err) { + done(err); + } + }); +}; + export var test_request_isDefined = function () { TKUnit.assert(typeof (http["request"]) !== "undefined", "Method http.request() should be defined!"); }; @@ -403,6 +480,40 @@ export var test_request_responseContentToImageShouldReturnCorrectImage = functio }); }; +export var test_request_responseContentToFileFromUrlShouldReturnCorrectFile = function (done) { + var result; + + http.request({ url: "https://raw.githubusercontent.com/NativeScript/NativeScript/master/apps/tests/logo.png", method: "GET" }).then(function (response) { + result = response.content.toFile(); + try { + TKUnit.assert(result instanceof fs.File, "Result from toFile() should be valid File object!"); + done(null); + } + catch (err) { + done(err); + } + }, function (e) { + done(e); + }); +}; + +export var test_request_responseContentToFileFromContentShouldReturnCorrectFile = function (done) { + var result; + + http.request({ url: "https://httpbin.org/image/png", method: "GET" }).then(function (response) { + result = response.content.toFile(); + try { + TKUnit.assert(result instanceof fs.File, "Result from toFile() should be valid File object!"); + done(null); + } + catch (err) { + done(err); + } + }, function (e) { + done(e); + }); +}; + export var test_request_headersSentAndReceivedProperly = function (done) { var result; diff --git a/http/http-request.android.ts b/http/http-request.android.ts index a532260f6..8ff4478ea 100644 --- a/http/http-request.android.ts +++ b/http/http-request.android.ts @@ -5,6 +5,7 @@ import types = require("utils/types"); import * as utilsModule from "utils/utils"; import * as imageSourceModule from "image-source"; import * as platformModule from "platform"; +import * as fsModule from "file-system"; // this is imported for definition purposes only import http = require("http"); @@ -74,6 +75,28 @@ function onRequestComplete(requestId: number, result: com.tns.Async.Http.Request rejectImage(new Error("Response content may not be converted to an Image")); } }); + }, + toFile: (destinationFilePath?: string) => { + var fs: typeof fsModule = require("file-system"); + var fileName = callbacks.url; + if (!destinationFilePath) { + destinationFilePath = fs.path.join(fs.knownFolders.documents().path, fileName.substring(fileName.lastIndexOf('/') + 1)); + } + var stream: java.io.FileOutputStream; + try { + var javaFile = new java.io.File(destinationFilePath); + stream = new java.io.FileOutputStream(javaFile); + stream.write(result.raw.toByteArray()); + return fs.File.fromPath(destinationFilePath); + } + catch (exception) { + throw new Error(`Cannot save file with path: ${destinationFilePath}.`); + } + finally { + if (stream) { + stream.close(); + } + } } }, statusCode: result.statusCode, @@ -134,6 +157,7 @@ export function request(options: http.HttpRequestOptions): Promise { + var fs: typeof fsModule = require("file-system"); + var fileName = options.url; + if (!destinationFilePath) { + destinationFilePath = fs.path.join(fs.knownFolders.documents().path, fileName.substring(fileName.lastIndexOf('/') + 1)); + } + if (data instanceof NSData) { + data.writeToFileAtomically(destinationFilePath, true); + return fs.File.fromPath(destinationFilePath); + } else { + reject(new Error(`Cannot save file with path: ${destinationFilePath}.`)); + } } }, statusCode: response.statusCode, diff --git a/http/http.d.ts b/http/http.d.ts index 6154a6836..7fcd259c6 100644 --- a/http/http.d.ts +++ b/http/http.d.ts @@ -3,7 +3,7 @@ */ declare module "http" { import image = require("image-source"); - + import fs = require("file-system"); /** * Downloads the content from the specified URL as a string. @@ -41,6 +41,20 @@ declare module "http" { */ export function getImage(options: HttpRequestOptions): Promise + /** + * Downloads the content from the specified URL and attempts to save it as file. + * @param url The URL to request from. + * @param destinationFilePath Optional. The downloaded file path. + */ + export function getFile(url: string, destinationFilePath?: string): Promise + + /** + * Downloads the content from the specified URL and attempts to save it as file. + * @param options An object that specifies various request options. + * @param destinationFilePath Optional. The downloaded file path. + */ + export function getFile(options: HttpRequestOptions, destinationFilePath?: string): Promise + /** * Makes a generic http request using the provided options and returns a HttpResponse Object. * @param options An object that specifies various request options. @@ -120,5 +134,10 @@ declare module "http" { * Gets the response body as ImageSource. */ toImage: () => Promise; + + /** + * Gets the response body as file. + */ + toFile: (destinationFilePath?: string) => fs.File; } } \ No newline at end of file diff --git a/http/http.ts b/http/http.ts index e34de3aab..9178bb7e0 100644 --- a/http/http.ts +++ b/http/http.ts @@ -38,4 +38,18 @@ export function getImage(arg: any): Promise { r.content.toImage().then(source => resolve(source), e => reject(e)); }, e => reject(e)); }); +} + +export function getFile(arg: any, destinationFilePath?: string): Promise { + return new Promise((resolve, reject) => { + httpRequest.request(typeof arg === "string" ? { url: arg, method: "GET" } : arg) + .then(r => { + try { + var file = r.content.toFile(destinationFilePath); + resolve(file); + } catch (e) { + reject(e); + } + }, e => reject(e)); + }); } \ No newline at end of file