Compare commits

..
Author SHA1 Message Date
Tobias Becht 4ef17d1af5 fix: handle 'missing' options 2023-02-09 11:48:37 +01:00
Tobias Becht 767f638635 feat: upload file without formdata 2023-02-08 17:25:57 +01:00
28 changed files with 354 additions and 1531 deletions
-6
View File
@@ -1,6 +0,0 @@
node_modules
temp
platforms
**/*.min.js
www/umd-tough-cookie.js
www/lodash.js
-25
View File
@@ -1,25 +0,0 @@
{
"env": {
"browser": true,
"node": true,
"es2020": true
},
"extends": [
"eslint:recommended"
],
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "script"
},
"overrides": [
{
"files": [
"test/**/*.js",
"www/**/*.js"
],
"env": {
"mocha": true
}
}
]
}
+25 -119
View File
@@ -1,47 +1,21 @@
name: Cordova HTTP Plugin CI
on:
push:
workflow_dispatch:
inputs:
ci_reason:
description: "Optional note for manual runs"
required: false
on: [push]
env:
node_version: "22.x"
java_distribution: "zulu"
java_version: "17"
gradle_version: "7.6.1"
nodejs: "16.x"
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.node_version }}
cache: npm
cache-dependency-path: package-lock.json
- name: Install node modules
run: npm ci
- name: Run ESLint
run: npm run lint
test-www-interface:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install node.js
uses: actions/setup-node@v4
- name: Install Node.js ${{ env.nodejs }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.node_version }}
cache: npm
cache-dependency-path: package-lock.json
node-version: ${{ env.nodejs }}
- name: Install node modules
run: npm ci
- name: Run WWW interface tests
@@ -49,118 +23,50 @@ jobs:
build-ios:
runs-on: macOS-latest
outputs:
run-tests: ${{ steps.should-run-tests.outputs.run_tests }}
steps:
- uses: actions/checkout@v1
- name: Install node.js
uses: actions/setup-node@v4
- name: Install Node.js ${{ env.nodejs }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.node_version }}
cache: npm
cache-dependency-path: package-lock.json
- id: should-run-tests
# need to find a solution for signing iOS App so we can build for device target instead simulator
# for now we skip iOS tests on BrowserStack
run: echo "run_tests=false" >> "$GITHUB_OUTPUT"
node-version: ${{ env.nodejs }}
- name: Install node modules
run: npm ci
- name: Update test cert for httpbin.org
run: npm run update:cert
# need to find a solution for signing iOS App so we can build for device target instead simulator
- name: Build test app
run: scripts/build-test-app.sh --ios --emulator
- name: Upload artifact to BrowserStack
if: steps.should-run-tests.outputs.run_tests == 'true'
if: env.BROWSERSTACK_USERNAME != ''
run: scripts/upload-browserstack.sh --ios
test-ios:
needs: build-ios
if: needs.build-ios.outputs.run-tests == 'true'
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- name: Install node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.node_version }}
cache: npm
cache-dependency-path: package-lock.json
- name: Install node modules
run: npm ci
- name: Run e2e tests (iOS)
run: scripts/test-app.sh --ios --device
# need to have an App for device target
# - name: Run e2e tests
# if: env.BROWSERSTACK_USERNAME != ''
# run: scripts/test-app.sh --ios --device
build-android:
runs-on: ubuntu-latest
outputs:
run-tests: ${{ steps.should-run-tests.outputs.run_tests }}
steps:
- uses: actions/checkout@v1
- name: Install node.js
uses: actions/setup-node@v4
- name: Install Node.js ${{ env.nodejs }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.node_version }}
cache: npm
cache-dependency-path: package-lock.json
- id: should-run-tests
run: |
if [ -n "${BROWSERSTACK_USERNAME}" ]; then
echo "run_tests=true" >> "$GITHUB_OUTPUT"
else
echo "run_tests=false" >> "$GITHUB_OUTPUT"
fi
node-version: ${{ env.nodejs }}
- name: Install node modules
run: npm ci
- name: Install JDK
uses: actions/setup-java@v2
- name: Install JDK 1.8
uses: actions/setup-java@v1
with:
distribution: ${{ env.java_distribution }}
java-version: ${{ env.java_version }}
java-package: jdk
- name: Ensure Android build-tools 33.0.2
run: yes | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "build-tools;33.0.2"
- name: Install Gradle
run: |
set -euo pipefail
curl -sSL "https://services.gradle.org/distributions/gradle-${{ env.gradle_version }}-bin.zip" -o gradle.zip
unzip -q gradle.zip -d "$HOME/gradle"
echo "$HOME/gradle/gradle-${{ env.gradle_version }}/bin" >> "$GITHUB_PATH"
rm gradle.zip
java-version: 1.8
- name: Update test cert for httpbin.org
run: npm run update:cert
- name: Shim missing DX binaries (https://stackoverflow.com/a/68430992)
run: |
set -euo pipefail
BUILD_TOOLS_PATH="$(ls -d $ANDROID_HOME/build-tools/*/ | sort -V | tail -n 1)"
D8_BIN="${BUILD_TOOLS_PATH}d8"
DX_BIN="${BUILD_TOOLS_PATH}dx"
D8_JAR="${BUILD_TOOLS_PATH}lib/d8.jar"
DX_JAR="${BUILD_TOOLS_PATH}lib/dx.jar"
if [ -f "$D8_BIN" ] && [ ! -e "$DX_BIN" ]; then
ln -s "$D8_BIN" "$DX_BIN"
fi
if [ -f "$D8_JAR" ] && [ ! -e "$DX_JAR" ]; then
ln -s "$D8_JAR" "$DX_JAR"
fi
- name: Add workaround for missing DX files in build-tools 32 (https://stackoverflow.com/a/68430992)
run: ln -s $ANDROID_HOME/build-tools/32.0.0/d8 $ANDROID_HOME/build-tools/32.0.0/dx && ln -s $ANDROID_HOME/build-tools/32.0.0/lib/d8.jar $ANDROID_HOME/build-tools/32.0.0/lib/dx.jar
- name: Build test app
run: scripts/build-test-app.sh --android --device
- name: Upload artifact to BrowserStack
if: steps.should-run-tests.outputs.run_tests == 'true'
if: env.BROWSERSTACK_USERNAME != ''
run: scripts/upload-browserstack.sh --android
test-android:
needs: build-android
if: needs.build-android.outputs.run-tests == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.node_version }}
cache: npm
cache-dependency-path: package-lock.json
- name: Install node modules
run: npm ci
- name: Run e2e tests (Android)
- name: Run e2e tests
if: env.BROWSERSTACK_USERNAME != ''
run: scripts/test-app.sh --android --device
+39 -80
View File
@@ -3,101 +3,60 @@
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
name: "CodeQL"
on:
push:
branches: ["master"]
branches: [master]
pull_request:
branches: ["master"]
# The branches below must be a subset of the branches above
branches: [master]
schedule:
- cron: "0 0 * * 0"
- cron: '0 20 * * 3'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: java-kotlin
build-mode: none # This mode only analyzes Java. Set this to 'autobuild' or 'manual' to analyze Kotlin too.
- language: javascript-typescript
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: ['javascript']
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout repository
uses: actions/checkout@v2
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- name: Run manual build steps
if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
+55
View File
@@ -0,0 +1,55 @@
cache:
directories:
- node_modules
addons:
sauce_connect: true
matrix:
include:
- name: "iOS Build & Test"
language: objective-c
os: osx
osx_image: xcode12.5
before_install:
- export LANG=en_US.UTF-8 &&
nvm use 14
install:
- npm install
script:
- npm run test:js &&
npm run update:cert &&
scripts/build-test-app.sh --ios --emulator &&
scripts/upload-saucelabs.sh --ios &&
scripts/test-app.sh --ios --emulator;
- name: "Android Build & Test"
language: android
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -rf $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
before_install:
- export LANG=en_US.UTF-8 &&
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &&
sudo apt-get install -y nodejs
- yes | sdkmanager "tools" "build-tools;30.0.3" "platforms;android-30" "extras;android;m2repository" "extras;google;m2repository"
install:
- npm install
script:
- npm run test:js &&
npm run update:cert &&
scripts/build-test-app.sh --android --emulator &&
scripts/upload-saucelabs.sh --android &&
scripts/test-app.sh --android --emulator;
+6 -1
View File
@@ -73,5 +73,10 @@ If we suggest changes or the [CI build fails](#cibuild), then:
That's it! Thank you for your contribution!
### <a name="cibuild"></a> Pull Request Feedback
You can always check the results of the latest CI builds on [Github Actions](https://github.com/silkimen/cordova-plugin-advanced-http/actions).
You can always check the results of the latest CI builds on
[Travis CI](https://travis-ci.org/silkimen/cordova-plugin-advanced-http/).
You can use this information to inspect failing tests in your PR.
## Attribution
This document is adapted from
[AngularJS' Contribution Guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
+4
View File
@@ -3,8 +3,11 @@ Cordova Advanced HTTP
[![npm version](https://img.shields.io/npm/v/cordova-plugin-advanced-http)](https://www.npmjs.com/package/cordova-plugin-advanced-http?activeTab=versions)
[![MIT Licence](https://img.shields.io/badge/license-MIT-blue?style=flat)](https://opensource.org/licenses/mit-license.php)
[![downloads/month](https://img.shields.io/npm/dm/cordova-plugin-advanced-http.svg)](https://www.npmjs.com/package/cordova-plugin-advanced-http)
[![Travis Build Status](https://img.shields.io/travis/com/silkimen/cordova-plugin-advanced-http/master?label=Travis%20CI)](https://app.travis-ci.com/silkimen/cordova-plugin-advanced-http)
[![GitHub Build Status](https://img.shields.io/github/actions/workflow/status/silkimen/cordova-plugin-advanced-http/.github/workflows/ci.yml?branch=master)](https://github.com/silkimen/cordova-plugin-advanced-http/actions)
Cordova / Phonegap plugin for communicating with HTTP servers. Supports iOS, Android and [Browser](#browserSupport).
This is a fork of [Wymsee's Cordova-HTTP plugin](https://github.com/wymsee/cordova-HTTP).
@@ -511,6 +514,7 @@ We made a few modifications to the networking libraries.
This plugin uses amazing cloud services to maintain quality. CI Builds and E2E testing are powered by:
* [GitHub Actions](https://github.com/features/actions)
* [Travis CI](https://travis-ci.org/)
* [BrowserStack](https://www.browserstack.com/)
* [Sauce Labs](https://saucelabs.com/)
* [httpbin.org](https://httpbin.org/)
+13 -1138
View File
File diff suppressed because it is too large Load Diff
+1 -3
View File
@@ -7,7 +7,6 @@
"build:browser": "./scripts/build-test-app.sh --browser",
"build:android": "./scripts/build-test-app.sh --android --emulator",
"build:ios": "./scripts/build-test-app.sh --ios --emulator",
"lint": "eslint . --ext .js",
"test:android": "npm run update:cert && npm run build:android && ./scripts/test-app.sh --android --emulator",
"test:ios": "npm run update:cert && npm run build:ios && ./scripts/test-app.sh --ios --emulator",
"test:app": "npm run test:android && npm run test:ios",
@@ -62,10 +61,9 @@
"chai": "4.3.6",
"colors": "1.4.0",
"cordova": "11.0.0",
"eslint": "^8.57.0",
"mocha": "9.2.2",
"umd-tough-cookie": "3.0.0",
"wd": "1.14.0",
"xml2js": "0.5.0"
"xml2js": "0.4.23"
}
}
+7 -14
View File
@@ -17,20 +17,13 @@ if [ $PLATFORM = "android" ]; then
-F "file=@$TEMP/platforms/android/app/build/outputs/apk/debug/app-debug.apk" \
-F "data={\"custom_id\": \"HttpTestAppAndroid\"}"
else
rm -rf "$TEMP/HttpDemo.ipa"
IOS_BUILD_DIR="$TEMP/platforms/ios/build/Debug-iphonesimulator"
APP_PATH="$IOS_BUILD_DIR/HttpDemo.app"
if [ ! -d "$APP_PATH" ]; then
echo "Unable to locate $APP_PATH" >&2
exit 1
fi
PAYLOAD_DIR="$TEMP/Payload"
rm -rf "$PAYLOAD_DIR"
mkdir -p "$PAYLOAD_DIR"
cp -R "$APP_PATH" "$PAYLOAD_DIR/HttpDemo.app"
(cd "$TEMP" && zip -qr HttpDemo.ipa Payload)
rm -rf "$PAYLOAD_DIR"
rm -rf $TEMP/HttpDemo.ipa
pushd $TEMP/platforms/ios/build/emulator
rm -rf ./Payload
mkdir -p ./Payload
cp -r ./HttpDemo.app ./Payload/HttpDemo.app
zip -r $TEMP/HttpDemo.ipa ./Payload
popd
curl -u $BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY \
-X POST \
@@ -133,6 +133,7 @@ abstract class CordovaHttpBase implements Runnable {
request.followRedirects(this.followRedirects);
request.connectTimeout(this.connectTimeout);
request.readTimeout(this.readTimeout);
request.acceptCharset("UTF-8");
request.uncompress(true);
if (this.tlsConfiguration.getHostnameVerifier() != null) {
@@ -163,12 +163,17 @@ public class CordovaHttpPlugin extends CordovaPlugin implements Observer {
int readTimeout = args.getInt(5) * 1000;
boolean followRedirect = args.getBoolean(6);
String responseType = args.getString(7);
Integer reqId = args.getInt(8);
JSONObject transmitOptions = args.getJSONObject(8);
Integer reqId = args.getInt(9);
// new file transmission options
String transmitFileType = transmitOptions.getString("transmitFileAs");
boolean submitRaw = transmitFileType.equalsIgnoreCase("BINARY");
CordovaObservableCallbackContext observableCallbackContext = new CordovaObservableCallbackContext(callbackContext, reqId);
CordovaHttpUpload upload = new CordovaHttpUpload(url, headers, filePaths, uploadNames, connectTimeout, readTimeout, followRedirect,
responseType, this.tlsConfiguration, this.cordova.getActivity().getApplicationContext(), observableCallbackContext);
responseType, this.tlsConfiguration, submitRaw, this.cordova.getActivity().getApplicationContext(), observableCallbackContext);
startRequest(reqId, observableCallbackContext, upload);
@@ -25,18 +25,40 @@ class CordovaHttpUpload extends CordovaHttpBase {
private JSONArray uploadNames;
private Context applicationContext;
private boolean submitRaw = false;
public CordovaHttpUpload(String url, JSONObject headers, JSONArray filePaths, JSONArray uploadNames, int connectTimeout, int readTimeout,
boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration,
boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration, boolean submitRaw,
Context applicationContext, CordovaObservableCallbackContext callbackContext) {
super("POST", url, headers, connectTimeout, readTimeout, followRedirects, responseType, tlsConfiguration, callbackContext);
this.filePaths = filePaths;
this.uploadNames = uploadNames;
this.applicationContext = applicationContext;
this.submitRaw = submitRaw;
}
@Override
protected void sendBody(HttpRequest request) throws Exception {
if (this.submitRaw) {
if (this.filePaths.length() != 1) {
throw new IllegalArgumentException("Can only transmit a single file. Multiple files are not supported in this mode.");
}
String filePath = this.filePaths.getString(0);
Uri fileURI = Uri.parse(filePath);
if (ContentResolver.SCHEME_FILE.equals((fileURI.getScheme()))) {
File file = new File(new URI(filePath));
request.send(file);
} else if (ContentResolver.SCHEME_CONTENT.equals(fileURI.getScheme())) {
InputStream inputStream = this.applicationContext.getContentResolver().openInputStream(fileURI);
request.send(inputStream);
}
return;
}
for (int i = 0; i < this.filePaths.length(); ++i) {
String uploadName = this.uploadNames.getString(i);
String filePath = this.filePaths.getString(i);
@@ -71,7 +71,7 @@ class CordovaServerTrust implements Runnable {
this.tlsConfiguration.setTrustManagers(this.noOpTrustManagers);
} else if ("pinned".equals(this.mode)) {
this.tlsConfiguration.setHostnameVerifier(null);
this.tlsConfiguration.setTrustManagers(this.getTrustManagers(this.getCertsFromBundle(getWebAssetDir() + "/certificates")));
this.tlsConfiguration.setTrustManagers(this.getTrustManagers(this.getCertsFromBundle("www/certificates")));
} else {
this.tlsConfiguration.setHostnameVerifier(null);
this.tlsConfiguration.setTrustManagers(this.getTrustManagers(this.getCertsFromKeyStore("AndroidCAStore")));
@@ -84,14 +84,6 @@ class CordovaServerTrust implements Runnable {
}
}
private String getWebAssetDir() {
return isRunningOnCapacitor()? "public" : "www";
}
private boolean isRunningOnCapacitor() {
return this.activity.getClass().getSuperclass().getName().contains("com.getcapacitor");
}
private TrustManager[] getTrustManagers(KeyStore store) throws GeneralSecurityException {
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
+11 -16
View File
@@ -193,7 +193,7 @@ function sendRequest(method, withData, opts, success, failure) {
}
switch (serializer) {
case 'json': {
case 'json':
setDefaultContentType(headers, 'application/json; charset=utf8');
processedData = serializeJsonData(data);
@@ -202,21 +202,18 @@ function sendRequest(method, withData, opts, success, failure) {
}
break;
}
case 'utf8': {
case 'utf8':
setDefaultContentType(headers, 'text/plain; charset=utf8');
processedData = data.text;
break;
}
case 'urlencoded': {
case 'urlencoded':
setDefaultContentType(headers, 'application/x-www-form-urlencoded');
processedData = serializeParams(data);
break;
}
case 'multipart': {
case 'multipart':
const contentType = getHeaderValue(headers, 'Content-Type');
// intentionally don't set a default content type
@@ -227,13 +224,11 @@ function sendRequest(method, withData, opts, success, failure) {
processedData = processMultipartData(data);
break;
}
case 'raw': {
case 'raw':
setDefaultContentType(headers, 'application/octet-stream');
processedData = data;
break;
}
}
// requesting text instead of JSON because it's parsed in the response handler
@@ -288,7 +283,7 @@ function sendRequest(method, withData, opts, success, failure) {
xhr.send(processedData);
}
function abort(opts, success) {
function abort(opts, success, failure) {
var reqId = opts[0];
var result = false;
@@ -323,19 +318,19 @@ var browserInterface = {
abort: function (success, failure, opts) {
return abort(opts, success, failure);
},
uploadFile: function (success, failure) {
uploadFile: function (success, failure, opts) {
return failure('advanced-http: function "uploadFile" not supported on browser platform');
},
uploadFiles: function (success, failure) {
uploadFiles: function (success, failure, opts) {
return failure('advanced-http: function "uploadFiles" not supported on browser platform');
},
downloadFile: function (success, failure) {
downloadFile: function (success, failure, opts) {
return failure('advanced-http: function "downloadFile" not supported on browser platform');
},
setServerTrustMode: function (success, failure) {
setServerTrustMode: function (success, failure, opts) {
return failure('advanced-http: function "setServerTrustMode" not supported on browser platform');
},
setClientAuthMode: function (success, failure) {
setClientAuthMode: function (success, failure, opts) {
return failure('advanced-http: function "setClientAuthMode" not supported on browser platform');
}
};
+104 -39
View File
@@ -460,50 +460,30 @@
NSDictionary *headers = [command.arguments objectAtIndex:1];
NSArray *filePaths = [command.arguments objectAtIndex: 2];
NSArray *names = [command.arguments objectAtIndex: 3];
NSTimeInterval connectTimeout = [[command.arguments objectAtIndex:4] doubleValue];
NSTimeInterval _connectTimeout = [[command.arguments objectAtIndex:4] doubleValue];
NSTimeInterval readTimeout = [[command.arguments objectAtIndex:5] doubleValue];
bool followRedirect = [[command.arguments objectAtIndex:6] boolValue];
NSString *responseType = [command.arguments objectAtIndex:7];
NSNumber *reqId = [command.arguments objectAtIndex:8];
[self setRequestHeaders: headers forManager: manager];
[self setTimeout:readTimeout forManager:manager];
[self setRedirect:followRedirect forManager:manager];
[self setResponseSerializer:responseType forManager:manager];
NSDictionary *transmitOptions = [command.arguments objectAtIndex:8];
NSNumber *reqId = [command.arguments objectAtIndex:9];
NSString *transmitFileType = [transmitOptions objectForKey:@"transmitFileAs"];
CordovaHttpPlugin* __weak weakSelf = self;
[[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
NSURLSessionDataTask *task = [manager POST:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
NSError *error;
for (int i = 0; i < [filePaths count]; i++) {
NSString *filePath = (NSString *) [filePaths objectAtIndex:i];
NSString *uploadName = (NSString *) [names objectAtIndex:i];
NSURL *fileURL = [NSURL URLWithString: filePath];
[formData appendPartWithFileURL:fileURL name:uploadName error:&error];
}
if (error) {
[weakSelf removeRequest:reqId];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"];
[dictionary setObject:@"Could not add file to post body." forKey:@"error"];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
return;
}
} progress:nil success:^(NSURLSessionTask *task, id responseObject) {
[weakSelf removeRequest:reqId];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
@try
{
NSURLSessionDataTask* task;
void (^setupManager)(void) = ^() {
[self setRequestHeaders: headers forManager: manager];
[self setTimeout:readTimeout forManager:manager];
[self setRedirect:followRedirect forManager:manager];
[self setResponseSerializer:responseType forManager:manager];
};
void (^onFailure)(NSURLSessionTask *, NSError *) = ^(NSURLSessionTask *task, NSError *error) {
[weakSelf removeRequest:reqId];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
@@ -512,10 +492,95 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
[manager invalidateSessionCancelingTasks:YES];
};
void (^onSuccess)(NSURLSessionTask *, id) = ^(NSURLSessionTask *task, id responseObject) {
[weakSelf removeRequest:reqId];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[manager invalidateSessionCancelingTasks:YES];
};
bool submitRaw = [transmitFileType isEqualToString:@"BINARY"];
// RAW
if (submitRaw)
{
if ([filePaths count] == 1)
{
// setup the request serializer to submit the raw file content
manager.requestSerializer = [BinaryRequestSerializer serializer];
setupManager();
NSURL *fileURL = [NSURL URLWithString:[filePaths objectAtIndex:0]];
NSError *error;
NSData *fileData = [NSData dataWithContentsOfURL:fileURL options:0 error:&error];
if (error)
{
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:nil error:error];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[manager invalidateSessionCancelingTasks:YES];
return;
}
task = [manager uploadTaskWithHTTPMethod:@"POST" URLString:url parameters:fileData progress:nil success:onSuccess failure:onFailure];
}
else
{
[NSException raise:@"ArgumentException" format:@"Can only transmit a single file. Multiple files are not supported in this mode."];
}
}
else // FALLBACK: Multipart / FormData
{
setupManager();
task = [manager
POST:url
parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
NSError *error;
for (int i = 0; i < [filePaths count]; i++)
{
NSString *filePath = (NSString *) [filePaths objectAtIndex:i];
NSString *uploadName = (NSString *) [names objectAtIndex:i];
NSURL *fileURL = [NSURL URLWithString: filePath];
[formData appendPartWithFileURL:fileURL name:uploadName error:&error];
}
if (error)
{
[weakSelf removeRequest:reqId];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"];
[dictionary setObject:@"Could not add file to post body." forKey:@"error"];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
return;
}
}
progress:nil
success:onSuccess
failure:onFailure
];
}
[self addRequest:reqId forTask:task];
}
@catch (NSException *exception) {
@catch (NSException *exception)
{
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
+2 -12
View File
@@ -155,18 +155,8 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
@implementation SM_AFSecurityPolicy
+(BOOL) isRunningOnCapacitor {
return NSClassFromString(@"CAPPlugin") != nil;
}
+ (NSSet *)certificatesInBundle:(NSBundle *)bundle {
NSString* assetDir = @"www";
if([self isRunningOnCapacitor]) {
// we are running on capacitor and its assets dir is 'public'
assetDir = @"public";
}
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory: [NSString stringWithFormat:@"%@/certificates", assetDir]];
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"www/certificates"];
NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]];
for (NSString *path in paths) {
@@ -181,7 +171,7 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
static NSSet *_defaultPinnedCertificates = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSBundle *bundle = [self isRunningOnCapacitor] ? [NSBundle mainBundle] : [NSBundle bundleForClass:[self class]];
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
_defaultPinnedCertificates = [self certificatesInBundle:bundle];
});
+5 -5
View File
@@ -10,10 +10,10 @@
"author": "Sefa Ilkimen",
"license": "Apache-2.0",
"dependencies": {
"cordova": "12.0.0",
"cordova-android": "12.0.1",
"cordova-browser": "7.0.0",
"cordova-ios": "7.1.1",
"cordova": "11.0.0",
"cordova-android": "10.1.1",
"cordova-browser": "6.0.0",
"cordova-ios": "6.2.0",
"cordova-plugin-device": "2.0.3"
},
"cordova": {
@@ -26,4 +26,4 @@
"cordova-plugin-device": {}
}
}
}
}
-2
View File
@@ -1,5 +1,3 @@
/* global hooks, tests */
const app = {
testIndex: -1,
+23 -31
View File
@@ -1,5 +1,3 @@
/* global cordova, resolveLocalFileSystemURL, should */
const hooks = {
onBeforeEachTest: function (resolve, reject) {
cordova.plugin.http.clearCookies();
@@ -94,12 +92,12 @@ const helpers = {
// abort is not working reliably; will be documented in known issues
return false;
// if (window.cordova && window.cordova.platformId === 'android') {
// var version = device.version; // NOTE will throw error if cordova is present without cordova-plugin-device
// var major = parseInt(/^(\d+)(\.|$)/.exec(version)[1], 10);
// return isFinite(major) && major >= 6;
// }
// return true;
if (window.cordova && window.cordova.platformId === 'android') {
var version = device.version; // NOTE will throw error if cordova is present without cordova-plugin-device
var major = parseInt(/^(\d+)(\.|$)/.exec(version)[1], 10);
return isFinite(major) && major >= 6;
}
return true;
},
getAbortDelay: function () { return 0; },
getDemoArrayBuffer: function(size) {
@@ -119,6 +117,7 @@ const helpers = {
};
const messageFactory = {
handshakeFailed: function() { return 'TLS connection could not be established: javax.net.ssl.SSLHandshakeException: Handshake failed' },
sslTrustAnchor: function () { return 'TLS connection could not be established: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.' },
invalidCertificate: function (domain) { return 'The certificate for this server is invalid. You might be connecting to a server that is pretending to be “' + domain + '” which could put your confidential information at risk.' }
}
@@ -231,7 +230,7 @@ const tests = [
},
{
description: 'should send JSON object correctly (POST)',
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}" ...',
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}\" ...',
before: helpers.setJsonSerializer,
func: function (resolve, reject) { cordova.plugin.http.post('http://httpbin.org/anything', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -241,7 +240,7 @@ const tests = [
},
{
description: 'should send JSON object correctly (PUT)',
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}" ...',
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}\" ...',
before: helpers.setJsonSerializer,
func: function (resolve, reject) { cordova.plugin.http.put('http://httpbin.org/anything', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -251,7 +250,7 @@ const tests = [
},
{
description: 'should send JSON object correctly (PATCH)',
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}" ...',
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}\" ...',
before: helpers.setJsonSerializer,
func: function (resolve, reject) { cordova.plugin.http.patch('http://httpbin.org/anything', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -261,7 +260,7 @@ const tests = [
},
{
description: 'should send JSON array correctly (POST) #26',
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]" ...',
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]\" ...',
before: helpers.setJsonSerializer,
func: function (resolve, reject) { cordova.plugin.http.post('http://httpbin.org/anything', [1, 2, 3], {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -271,7 +270,7 @@ const tests = [
},
{
description: 'should send JSON array correctly (PUT) #26',
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]" ...',
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]\" ...',
before: helpers.setJsonSerializer,
func: function (resolve, reject) { cordova.plugin.http.put('http://httpbin.org/anything', [1, 2, 3], {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -281,7 +280,7 @@ const tests = [
},
{
description: 'should send JSON array correctly (PATCH) #26',
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]" ...',
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]\" ...',
before: helpers.setJsonSerializer,
func: function (resolve, reject) { cordova.plugin.http.patch('http://httpbin.org/anything', [1, 2, 3], {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -292,7 +291,7 @@ const tests = [
},
{
description: 'should send url encoded data correctly (POST) #41',
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}" ...',
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}\" ...',
before: helpers.setUrlEncodedSerializer,
func: function (resolve, reject) { cordova.plugin.http.post('http://httpbin.org/anything', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -302,7 +301,7 @@ const tests = [
},
{
description: 'should send url encoded data correctly (PUT)',
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}" ...',
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}\" ...',
before: helpers.setUrlEncodedSerializer,
func: function (resolve, reject) { cordova.plugin.http.put('http://httpbin.org/anything', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -312,7 +311,7 @@ const tests = [
},
{
description: 'should send url encoded data correctly (PATCH)',
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}" ...',
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}\" ...',
before: helpers.setUrlEncodedSerializer,
func: function (resolve, reject) { cordova.plugin.http.patch('http://httpbin.org/anything', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function (driver, result) {
@@ -332,10 +331,7 @@ const tests = [
{
description: 'should not follow 302 redirect when following redirects is disabled',
expected: 'rejected: {"status": 302, ...',
before: function (resolve) {
cordova.plugin.http.setFollowRedirect(false);
resolve();
},
before: function (resolve, reject) { cordova.plugin.http.setFollowRedirect(false); resolve(); },
func: function (resolve, reject) { cordova.plugin.http.get('http://httpbingo.org/redirect-to?url=http://httpbingo.org/anything', {}, {}, resolve, reject); },
validationFunc: function (driver, result) {
result.type.should.be.equal('rejected');
@@ -432,7 +428,7 @@ const tests = [
},
{
description: 'should encode HTTP array params correctly (GET) #45',
expected: 'resolved: {"status": 200, "data": "{\\"url\\":\\"http://httpbin.org/get?myArray[]=val1&myArray[]=val2&myArray[]=val3\\"}" ...',
expected: 'resolved: {"status": 200, "data": "{\\"url\\":\\"http://httpbin.org/get?myArray[]=val1&myArray[]=val2&myArray[]=val3\\"}\" ...',
func: function (resolve, reject) {
cordova.plugin.http.get('http://httpbin.org/get', { myArray: ['val1', 'val2', 'val3'], myString: 'testString' }, {}, resolve, reject);
},
@@ -460,9 +456,8 @@ const tests = [
{
description: 'should throw an error while setting non-string value as global header #54',
expected: 'throwed: "advanced-http: header values must be strings"',
func: function (resolve) {
func: function (resolve, reject) {
cordova.plugin.http.setHeader('myTestHeader', 2);
resolve();
},
validationFunc: function (driver, result) {
result.type.should.be.equal('throwed');
@@ -501,7 +496,7 @@ const tests = [
},
{
description: 'should not send programmatically set cookies after running "clearCookies" (GET) #59',
expected: 'resolved: {"status": 200, "data": "{"headers": {"Cookie": ""...',
expected: 'resolved: {"status": 200, "data": "{\"headers\": {\"Cookie\": \"\"...',
func: function (resolve, reject) {
cordova.plugin.http.setCookie('http://httpbin.org/get', 'myCookie=myValue');
cordova.plugin.http.setCookie('http://httpbin.org/get', 'mySecondCookie=mySecondValue');
@@ -617,9 +612,7 @@ const tests = [
},
validationFunc: function (driver, result, targetInfo) {
result.type.should.be.equal('rejected');
result.data.status.should.be.equal(-2);
result.data.error.should.include(targetInfo.isAndroid ? 'javax.net.ssl.SSLHandshakeException' : 'The certificate for this server is invalid');
// result.data.should.be.eql({ status: -2, error: targetInfo.isAndroid ? messageFactory.s^slTrustAnchor() : messageFactory.invalidCertificate('sha512.badssl.com') });
result.data.should.be.eql({ status: -2, error: targetInfo.isAndroid ? messageFactory.sslTrustAnchor() : messageFactory.invalidCertificate('sha512.badssl.com') });
}
},
{
@@ -1017,7 +1010,7 @@ const tests = [
},
{
description: 'should not send any cookies after running "clearCookies" (GET) #248',
expected: 'resolved: {"status": 200, "data": "{"cookies":{}} ...',
expected: 'resolved: {"status": 200, "data": "{\"cookies\":{}} ...',
before: helpers.disableFollowingRedirect,
func: function (resolve, reject) {
cordova.plugin.http.get('https://httpbin.org/cookies/set?myCookieKey=myCookieValue', {}, {}, function () {
@@ -1182,8 +1175,7 @@ const tests = [
},
validationFunc: function (driver, result) {
result.type.should.be.equal('rejected');
result.data.status.should.be.equal(-2);
result.data.error.should.include('UNSUPPORTED_PROTOCOL');
result.data.should.be.eql({ status: -2, error: messageFactory.handshakeFailed() });
}
},
];
+3 -5
View File
@@ -60,7 +60,6 @@ const configs = {
// testing on BrowserStack
browserstackIosDevice: {
'appium-version': '1.22.0',
device: 'iPhone 12',
os_version: '14',
project: 'HTTP Test App',
@@ -69,9 +68,8 @@ const configs = {
'browserstack.networkLogs': false
},
browserstackAndroidDevice: {
'appium-version': '1.22.0',
device: 'Samsung Galaxy S22 Ultra',
os_version: '12.0',
device: 'Google Nexus 6',
os_version: '6.0',
project: 'HTTP Test App',
autoWebview: true,
app: 'HttpTestAppAndroid',
@@ -86,7 +84,7 @@ function getCaps(environment, os, runtime) {
caps.name = `cordova-plugin-advanced-http (${os})`;
return caps;
}
};
function capitalize(text) {
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
+1 -2
View File
@@ -98,7 +98,7 @@ async function validateTestIndex(driver, testIndex) {
async function validateTestTitle(driver, testTitle) {
const description = await driver.elementById('descriptionLbl').text();
const title = description.match(/\d+: (.*)/)[1];
const title = description.match(/\d+:\ (.*)/)[1];
title.should.be.equal(testTitle, 'Test description is not matching!');
}
@@ -106,7 +106,6 @@ async function validateTestTitle(driver, testTitle) {
async function waitToBeFinished(driver, timeout) {
const timeoutTimestamp = Date.now() + timeout;
// eslint-disable-next-line no-constant-condition
while (true) {
if (await driver.elementById('statusInput').getValue() === 'finished') {
return true;
+1 -1
View File
@@ -536,7 +536,7 @@ describe('Common helpers', function () {
null,
(response) => {
response.status.should.be.equal(errorCodes.POST_PROCESSING_FAILED);
response.error.should.include('Unexpected token');
response.error.should.include('Unexpected token N in JSON at position 0');
}
);
+1 -1
View File
@@ -3,7 +3,7 @@ const BlobMock = require('./Blob.mock');
module.exports = class FileMock extends BlobMock {
constructor(blob, fileName) {
super(blob, { type: blob.type });
this._fileName = fileName !== undefined ? fileName : 'blob';
this._fileName = fileName !== undefined ? fileName : 'blob';
this.__lastModifiedDate = new Date();
}
+4 -6
View File
@@ -1,5 +1,3 @@
/* global FileSystem */
module.exports = function init(global, jsUtil, cookieHandler, messages, base64, errorCodes, dependencyValidator, ponyfills) {
var validSerializers = ['urlencoded', 'json', 'utf8', 'raw', 'multipart'];
var validCertModes = ['default', 'nocheck', 'pinned', 'legacy'];
@@ -68,7 +66,7 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
for (var i = 0; i < globalKeys.length; i++) {
key = globalKeys[i];
if (!Object.prototype.hasOwnProperty.call(localHeaders, key)) {
if (!localHeaders.hasOwnProperty(key)) {
localHeaders[key] = globalHeaders[key];
}
}
@@ -363,7 +361,7 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
}
function getMatchingHostHeaders(url, headersList) {
var matches = url.match(/^https?:\/\/([^/?#]+)(?:[/?#]|$)/i);
var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1];
return headersList[domain] || null;
@@ -500,7 +498,7 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
function handleMissingOptions(options, globals) {
options = options || {};
return {
return Object.assign({}, options, {
data: jsUtil.getTypeOf(options.data) === 'Undefined' ? null : options.data,
filePath: options.filePath,
followRedirect: checkFollowRedirectValue(options.followRedirect || globals.followRedirect),
@@ -513,6 +511,6 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
connectTimeout: checkTimeoutValue(options.connectTimeout || globals.connectTimeout),
readTimeout: checkTimeoutValue(options.readTimeout || globals.readTimeout),
timeout: checkTimeoutValue(options.timeout || globals.timeout)
};
});
}
};
+5 -7
View File
@@ -164,15 +164,13 @@ module.exports = function init(ToughCookie, _) {
WebStorageCookieStore.prototype._readStore = function () {
var json = this._storage.getItem(this._storeKey);
if (json === null) {
return {};
if (json !== null) {
try {
return JSON.parse(json);
} catch (e) { }
}
try {
return JSON.parse(json);
} catch (e) {
return {};
}
return {};
};
WebStorageCookieStore.prototype._writeStore = function (store) {
+10 -4
View File
@@ -180,7 +180,13 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf
break;
case 'upload':
var fileOptions = helpers.checkUploadFileOptions(options.filePath, options.name);
exec(onSuccess, onFail, 'CordovaHttpPlugin', 'uploadFiles', [url, headers, fileOptions.filePaths, fileOptions.names, options.connectTimeout, options.readTimeout, options.followRedirect, options.responseType, reqId]);
// support uploading files as octet-stream / encoded string instead of form-data
var transmitOptions = {};
transmitOptions.transmitFileAs = options.transmitFileAs || 'FORMDATA';
// transmitOptions.transmitMethod = options.transmitMethod || 'POST';
exec(onSuccess, onFail, 'CordovaHttpPlugin', 'uploadFiles', [url, headers, fileOptions.filePaths, fileOptions.names, options.connectTimeout, options.readTimeout, options.followRedirect, options.responseType, transmitOptions, reqId]);
break;
case 'download':
var filePath = helpers.checkDownloadFilePath(options.filePath);
@@ -197,7 +203,7 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf
function post(url, data, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'post', data: data, headers: headers }, success, failure);
}
};
function put(url, data, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'put', data: data, headers: headers }, success, failure);
@@ -209,7 +215,7 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf
function get(url, params, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'get', params: params, headers: headers }, success, failure);
}
};
function del(url, params, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'delete', params: params, headers: headers }, success, failure);
@@ -221,7 +227,7 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf
function options(url, params, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'options', params: params, headers: headers }, success, failure);
}
};
function uploadFile(url, params, headers, filePath, name, success, failure) {
return publicInterface.sendRequest(url, { method: 'upload', params: params, headers: headers, filePath: filePath, name: name }, success, failure);
+2 -2
View File
@@ -6,7 +6,7 @@ module.exports = function init(jsUtil) {
}
function parseUrl(url) {
var match = url.match(/^(https?:)\/\/(([^:/?#]*)(?::([0-9]+))?)([/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
var match = url.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
return match && {
protocol: match[1],
@@ -42,7 +42,7 @@ module.exports = function init(jsUtil) {
var parts = [];
for (var key in object) {
if (!Object.prototype.hasOwnProperty.call(object, key)) {
if (!object.hasOwnProperty(key)) {
continue;
}