You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cordova.apache.org by "alastair (JIRA)" <ji...@apache.org> on 2015/12/04 08:08:11 UTC

[jira] [Comment Edited] (CB-10127) Internal XMLHttpRequest Error calling rest API from Android release build

    [ https://issues.apache.org/jira/browse/CB-10127?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15041173#comment-15041173 ] 

alastair edited comment on CB-10127 at 12/4/15 7:07 AM:
--------------------------------------------------------

Thanks Joe. We have a full certificate (godaddy) installed on a loadbalancer sitting in front of the web server. At the load balancer I see a request log entry like this when I try to hit our search API:
{noformat}
-|86.179.7.95| |-|-|-|0|-|-|-
{noformat}

If I hit the same API from a debug build (or from a web browser) then I see something like:
{noformat}
-|93.174.8.204|GET /search/|-|500|-|630|__qca=P0-486270448-1413890794900; __gads=ID=4c9430a67ce354fd:T=1413890795:S=ALNI_MZJ9xMO5FaXMqDiahGyDxGbwK1j6w; __utma=262668686.1107313830.1413890795.1429871657.1432219877.13; _ga=GA1.2.1107313830.1413890795; s_pers=%20s_nr%3D1447763757684%7C1450355757684%3B%20s_fid%3D20981839DE6951B9-08F4A8FCAC70E413%7C1512138812792%3B; crtg_newsquest2=; struqpref=80b23372-6d09-4167-b353-21c7635d0c27|http://localhost:8000/|Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
{noformat}

In the app, I've added some temporary code to let me debug the problem - the code looks like this (node JS app):
{noformat}
request({
	method: 'GET',
	url: apiUrl
	// , 	withCredentials: false
}
, function(error, response, body){
	if (error) {
		return console.log('====>Rental====> error returned from search API using REQUEST=' + error);
	}
	if (response.statusCode !== 200) {
		return console.log('====>Rental====> invalid status code on request ' + response.statusCode + ' response is ' + util.inspect(response, false, null));
	}
	console.log('====>Rental====> body using REQUEST=' + body);
}
);
{noformat}

It's a node JS app that is using the request module - I'm getting statuscode 0 back and the above code gives me this in my logcat:

{noformat}
I/chromium( 4721): [INFO:CONSOLE(173)] "====>Rental====> invalid status code on request 0 response is { offset: 0,
I/chromium( 4721):   readable: true,
I/chromium( 4721):   _events:
I/chromium( 4721):    { close: [ [Function], [Function], [Function] ],
I/chromium( 4721):      ready: [Function],
I/chromium( 4721):      error: [ [Function], [Function] ],
I/chromium( 4721):      end: [ [Function], [Function], [Function] ],
I/chromium( 4721):      data: [Function] },
I/chromium( 4721):   statusCode: 0,
I/chromium( 4721):   request:
I/chromium( 4721):    { _events:
I/chromium( 4721):       { error: [Function],
I/chromium( 4721):         complete: [Function],
I/chromium( 4721):         pipe: [Function],
I/chromium( 4721):         end: [ [Function], [Function] ],
I/chromium( 4721):         data: [Function] },
I/chromium( 4721):      _maxListeners: undefined,
I/chromium( 4721):      callback: [Function],
I/chromium( 4721):      method: 'GET',
I/chromium( 4721):      readable: true,
I/chromium( 4721):      writable: true,
I/chromium( 4721):      explicitMethod: true,
I/chromium( 4721):      _qs:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         lib: { stringify: [Function], parse: [Function] },
I/chromium( 4721):         useQuerystring: undefined,
I/chromium( 4721):         parseOptions: {},
I/chromium( 4721):         stringifyOptions: {} },
I/chromium( 4721):      _auth:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         hasAuth: false,
I/chromium( 4721):         sentAuth: false,
I/chromium( 4721):         bearerToken: null,
I/chromium( 4721):         user: null,
I/chromium( 4721):         pass: null },
I/chromium( 4721):      _oauth: { request: [Circular], params: null },
I/chromium( 4721):      _multipart:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         boundary: '5f571cc9-17ab-4a3a-8df7-38e29d241aff',
I/chromium( 4721):         chunked: false,
I/chromium( 4721):         body: null },
I/chromium( 4721):      _redirect:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         followRedirect: true,
I/chromium( 4721):         followRedirects: true,
I/chromium( 4721):         followAllRedirects: false,
I/chromium( 4721):         allowRedirect: [Function],
I/chromium( 4721):         maxRedirects: 10,
I/chromium( 4721):         redirects: [],
I/chromium( 4721):         redirectsFollowed: 0,
I/chromium( 4721):         removeRefererHeader: false },
I/chromium( 4721):      _tunnel:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         proxyHeaderWhiteList:
I/chromium( 4721):          [ 'accept',
I/chromium( 4721):            'accept-charset',
I/chromium( 4721):            'accept-encoding',
I/chromium( 4721):            'accept-language',
I/chromium( 4721):            'accept-ranges',
I/chromium( 4721):            'cache-control',
I/chromium( 4721):            'content-encoding',
I/chromium( 4721):            'content-language',
I/chromium( 4721):            'content-length',
I/chromium( 4721):            'content-location',
I/chromium( 4721):            'content-md5',
I/chromium( 4721):            'content-range',
I/chromium( 4721):            'content-type',
I/chromium( 4721):            'connection',
I/chromium( 4721):            'date',
I/chromium( 4721):            'expect',
I/chromium( 4721):            'max-forwards',
I/chromium( 4721):            'pragma',
I/chromium( 4721):            'referer',
I/chromium( 4721):            'te',
I/chromium( 4721):            'transfer-encoding',
I/chromium( 4721):            'user-agent',
I/chromium( 4721):            'via' ],
I/chromium( 4721):         proxyHeaderExclusiveList: [] },
I/chromium( 4721):      headers: {},
I/chromium( 4721):      setHeader: [Function],
I/chromium( 4721):      hasHeader: [Function],
I/chromium( 4721):      getHeader: [Function],
I/chromium( 4721):      removeHeader: [Function],
I/chromium( 4721):      localAddress: undefined,
I/chromium( 4721):      pool: { 'https:': {} },
I/chromium( 4721):      dests: [],
I/chromium( 4721):      __isRequestRequest: true,
I/chromium( 4721):      _callback: [Function],
I/chromium( 4721):      uri:
I/chromium( 4721):       { protocol: 'https:',
I/chromium( 4721):         slashes: true,
I/chromium( 4721):         auth: null,
I/chromium( 4721):         host: 'api.XXXXXX.com',
I/chromium( 4721):         port: 443,
I/chromium( 4721):         hostname: 'api.XXXXXX.com',
I/chromium( 4721):         hash: null,
I/chromium( 4721):         search: '?minprice=100&maxprice=10000&minbedrooms=Any&page=1',
I/chromium( 4721):         query: 'minprice=100&maxprice=10000&minbedrooms=Any&page=1',
I/chromium( 4721):         pathname: '/search/',
I/chromium( 4721):         path: '/search/?minprice=100&maxprice=10000&minbedrooms=Any&page=1',
I/chromium( 4721):         href: 'https://api.XXXXXX.com/search/?minprice=100&maxprice=10000&minbedrooms=Any&page=1' },
I/chromium( 4721):      proxy: null,
I/chromium( 4721):      tunnel: true,
I/chromium( 4721):      setHost: true,
I/chromium( 4721):      originalCookieHeader: undefined,
I/chromium( 4721):      _disableCookies: true,
I/chromium( 4721):      _jar: undefined,
I/chromium( 4721):      port: 443,
I/chromium( 4721):      host: 'api.XXXXXX.com',
I/chromium( 4721):      path: '/search/?minprice=100&maxprice=10000&minbedrooms=Any&page=1',
I/chromium( 4721):      httpModule:
I/chromium( 4721):       { request: [Function],
I/chromium( 4721):         get: [Function],
I/chromium( 4721):         Agent: { [Function] defaultMaxSockets: 4 },
I/chromium( 4721):         STATUS_CODES:
I/chromium( 4721):          { '100': 'Continue',
I/chromium( 4721):            '101': 'Switching Protocols',
I/chromium( 4721):            '102': 'Processing',
I/chromium( 4721):            '200': 'OK',
I/chromium( 4721):            '201': 'Created',
I/chromium( 4721):            '202': 'Accepted',
I/chromium( 4721):            '203': 'Non-Authoritative Information',
I/chromium( 4721):            '204': 'No Content',
I/chromium( 4721):            '205': 'Reset Content',
I/chromium( 4721):            '206': 'Partial Content',
I/chromium( 4721):            '207': 'Multi-Status',
I/chromium( 4721):            '300': 'Multiple Choices',
I/chromium( 4721):            '301': 'Moved Permanently',
I/chromium( 4721):            '302': 'Moved Temporarily',
I/chromium( 4721):            '303': 'See Other',
I/chromium( 4721):            '304': 'Not Modified',
I/chromium( 4721):            '305': 'Use Proxy',
I/chromium( 4721):            '307': 'Temporary Redirect
{noformat}

I'm not getting an unauthorised or other HTTP statuscode back - the statuscode of 0 was what made me think it's a phone side issue.

If I hit the HTTPS API in a browser then it returns correctly, if I hit it from the app running in a browser it is fine, if I hit the API from a debug build running on the phone then it is fine.

Any advice is greatly appreciated.


was (Author: allymacmac):
Thanks Joe. We have a full certificate (godaddy) installed on a loadbalancer sitting in front of the web server. At the load balancer I see a request log entry like this when I try to hit our search API:
{noformat}
-|86.179.7.95| |-|-|-|0|-|-|-
{noformat}

If I hit the same API from a debug build (or from a web browser) then I see something like:
{noformat}
-|93.174.8.204|GET /search/|-|500|-|630|__qca=P0-486270448-1413890794900; __gads=ID=4c9430a67ce354fd:T=1413890795:S=ALNI_MZJ9xMO5FaXMqDiahGyDxGbwK1j6w; __utma=262668686.1107313830.1413890795.1429871657.1432219877.13; _ga=GA1.2.1107313830.1413890795; s_pers=%20s_nr%3D1447763757684%7C1450355757684%3B%20s_fid%3D20981839DE6951B9-08F4A8FCAC70E413%7C1512138812792%3B; crtg_newsquest2=; struqpref=80b23372-6d09-4167-b353-21c7635d0c27|http://localhost:8000/|Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
{noformat}

In the app, I've added some temporary code to let me debug the problem - the code looks like this (node JS app):
{noformat}
request({
	method: 'GET',
	url: apiUrl
	// , 	withCredentials: false
}
, function(error, response, body){
	if (error) {
		return console.log('====>Rental====> error returned from search API using REQUEST=' + error);
	}
	if (response.statusCode !== 200) {
		return console.log('====>Rental====> invalid status code on request ' + response.statusCode + ' response is ' + util.inspect(response, false, null));
	}
	console.log('====>Rental====> body using REQUEST=' + body);
}
);
{noformat}

It's a node JS app that is using the request module - I'm getting statuscode 0 back and the above code gives me this in my logcat:

{noformat}
I/chromium( 4721): [INFO:CONSOLE(173)] "====>Rental====> invalid status code on request 0 response is { offset: 0,
I/chromium( 4721):   readable: true,
I/chromium( 4721):   _events:
I/chromium( 4721):    { close: [ [Function], [Function], [Function] ],
I/chromium( 4721):      ready: [Function],
I/chromium( 4721):      error: [ [Function], [Function] ],
I/chromium( 4721):      end: [ [Function], [Function], [Function] ],
I/chromium( 4721):      data: [Function] },
I/chromium( 4721):   statusCode: 0,
I/chromium( 4721):   request:
I/chromium( 4721):    { _events:
I/chromium( 4721):       { error: [Function],
I/chromium( 4721):         complete: [Function],
I/chromium( 4721):         pipe: [Function],
I/chromium( 4721):         end: [ [Function], [Function] ],
I/chromium( 4721):         data: [Function] },
I/chromium( 4721):      _maxListeners: undefined,
I/chromium( 4721):      callback: [Function],
I/chromium( 4721):      method: 'GET',
I/chromium( 4721):      readable: true,
I/chromium( 4721):      writable: true,
I/chromium( 4721):      explicitMethod: true,
I/chromium( 4721):      _qs:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         lib: { stringify: [Function], parse: [Function] },
I/chromium( 4721):         useQuerystring: undefined,
I/chromium( 4721):         parseOptions: {},
I/chromium( 4721):         stringifyOptions: {} },
I/chromium( 4721):      _auth:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         hasAuth: false,
I/chromium( 4721):         sentAuth: false,
I/chromium( 4721):         bearerToken: null,
I/chromium( 4721):         user: null,
I/chromium( 4721):         pass: null },
I/chromium( 4721):      _oauth: { request: [Circular], params: null },
I/chromium( 4721):      _multipart:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         boundary: '5f571cc9-17ab-4a3a-8df7-38e29d241aff',
I/chromium( 4721):         chunked: false,
I/chromium( 4721):         body: null },
I/chromium( 4721):      _redirect:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         followRedirect: true,
I/chromium( 4721):         followRedirects: true,
I/chromium( 4721):         followAllRedirects: false,
I/chromium( 4721):         allowRedirect: [Function],
I/chromium( 4721):         maxRedirects: 10,
I/chromium( 4721):         redirects: [],
I/chromium( 4721):         redirectsFollowed: 0,
I/chromium( 4721):         removeRefererHeader: false },
I/chromium( 4721):      _tunnel:
I/chromium( 4721):       { request: [Circular],
I/chromium( 4721):         proxyHeaderWhiteList:
I/chromium( 4721):          [ 'accept',
I/chromium( 4721):            'accept-charset',
I/chromium( 4721):            'accept-encoding',
I/chromium( 4721):            'accept-language',
I/chromium( 4721):            'accept-ranges',
I/chromium( 4721):            'cache-control',
I/chromium( 4721):            'content-encoding',
I/chromium( 4721):            'content-language',
I/chromium( 4721):            'content-length',
I/chromium( 4721):            'content-location',
I/chromium( 4721):            'content-md5',
I/chromium( 4721):            'content-range',
I/chromium( 4721):            'content-type',
I/chromium( 4721):            'connection',
I/chromium( 4721):            'date',
I/chromium( 4721):            'expect',
I/chromium( 4721):            'max-forwards',
I/chromium( 4721):            'pragma',
I/chromium( 4721):            'referer',
I/chromium( 4721):            'te',
I/chromium( 4721):            'transfer-encoding',
I/chromium( 4721):            'user-agent',
I/chromium( 4721):            'via' ],
I/chromium( 4721):         proxyHeaderExclusiveList: [] },
I/chromium( 4721):      headers: {},
I/chromium( 4721):      setHeader: [Function],
I/chromium( 4721):      hasHeader: [Function],
I/chromium( 4721):      getHeader: [Function],
I/chromium( 4721):      removeHeader: [Function],
I/chromium( 4721):      localAddress: undefined,
I/chromium( 4721):      pool: { 'https:': {} },
I/chromium( 4721):      dests: [],
I/chromium( 4721):      __isRequestRequest: true,
I/chromium( 4721):      _callback: [Function],
I/chromium( 4721):      uri:
I/chromium( 4721):       { protocol: 'https:',
I/chromium( 4721):         slashes: true,
I/chromium( 4721):         auth: null,
I/chromium( 4721):         host: 'api.s1homes.com',
I/chromium( 4721):         port: 443,
I/chromium( 4721):         hostname: 'api.s1homes.com',
I/chromium( 4721):         hash: null,
I/chromium( 4721):         search: '?minprice=100&maxprice=10000&minbedrooms=Any&page=1',
I/chromium( 4721):         query: 'minprice=100&maxprice=10000&minbedrooms=Any&page=1',
I/chromium( 4721):         pathname: '/search/',
I/chromium( 4721):         path: '/search/?minprice=100&maxprice=10000&minbedrooms=Any&page=1',
I/chromium( 4721):         href: 'https://api.s1homes.com/search/?minprice=100&maxprice=10000&minbedrooms=Any&page=1' },
I/chromium( 4721):      proxy: null,
I/chromium( 4721):      tunnel: true,
I/chromium( 4721):      setHost: true,
I/chromium( 4721):      originalCookieHeader: undefined,
I/chromium( 4721):      _disableCookies: true,
I/chromium( 4721):      _jar: undefined,
I/chromium( 4721):      port: 443,
I/chromium( 4721):      host: 'api.s1homes.com',
I/chromium( 4721):      path: '/search/?minprice=100&maxprice=10000&minbedrooms=Any&page=1',
I/chromium( 4721):      httpModule:
I/chromium( 4721):       { request: [Function],
I/chromium( 4721):         get: [Function],
I/chromium( 4721):         Agent: { [Function] defaultMaxSockets: 4 },
I/chromium( 4721):         STATUS_CODES:
I/chromium( 4721):          { '100': 'Continue',
I/chromium( 4721):            '101': 'Switching Protocols',
I/chromium( 4721):            '102': 'Processing',
I/chromium( 4721):            '200': 'OK',
I/chromium( 4721):            '201': 'Created',
I/chromium( 4721):            '202': 'Accepted',
I/chromium( 4721):            '203': 'Non-Authoritative Information',
I/chromium( 4721):            '204': 'No Content',
I/chromium( 4721):            '205': 'Reset Content',
I/chromium( 4721):            '206': 'Partial Content',
I/chromium( 4721):            '207': 'Multi-Status',
I/chromium( 4721):            '300': 'Multiple Choices',
I/chromium( 4721):            '301': 'Moved Permanently',
I/chromium( 4721):            '302': 'Moved Temporarily',
I/chromium( 4721):            '303': 'See Other',
I/chromium( 4721):            '304': 'Not Modified',
I/chromium( 4721):            '305': 'Use Proxy',
I/chromium( 4721):            '307': 'Temporary Redirect
{noformat}

I'm not getting an unauthorised or other HTTP statuscode back - the statuscode of 0 was what made me think it's a phone side issue.

If I hit the HTTPS API in a browser then it returns correctly, if I hit it from the app running in a browser it is fine, if I hit the API from a debug build running on the phone then it is fine.

Any advice is greatly appreciated.

> Internal XMLHttpRequest Error calling rest API from Android release build
> -------------------------------------------------------------------------
>
>                 Key: CB-10127
>                 URL: https://issues.apache.org/jira/browse/CB-10127
>             Project: Apache Cordova
>          Issue Type: Bug
>          Components: Android, CordovaJS
>         Environment: Node JS, cordova whitelist plugin, android release build, hybrid app
>            Reporter: alastair
>
> I have an android build that works well in debug builds, but, gives me 'Internal XMLHttpRequest Error' when I run it using an Android release build (I'm using console.log through an NPM module along with adb logcat to monitor the logs).
> Here's the set up that I have:
> * single page hybrid app with following in index.html
> {noformat}
> <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
> {noformat}
> * cordova whitelist plugin being used. Following settings in config.xml
> {noformat}
> <plugin name="cordova-plugin-whitelist" spec="^1.1.0" />
> <access origin="*" />
> {noformat}
> The app uses crosswalk to render content - it's a node JS, react app.
> On startup, the app hits a CGI hosted on an HTTP server to get JSON data - this works well in debug and in release mode.
> The app then hits REST APIs on HTTPS - this works well in debug but fails in release builds with the 'Internal XMLHttpRequest Error'. 
> The REST API call does not make it out of the phone and never hits the server, so, I assume that the problem is security related on the handset. I have tried all sorts of combinations of settings in my config.xml and in my index.html to loosen security/CSP and still see the problem with the 'relaxed' settings I have pasted in the ticket.
> Plugins that I am using:
> {noformat}
>     <plugin name="cordova-plugin-device" spec="^1.0.0" />
>     <plugin name="cordova-plugin-splashscreen" spec="^2.0.0" />
>     <plugin name="cordova-plugin-statusbar" spec="^1.0.0" />
>     <plugin name="cordova-plugin-whitelist" spec="^1.1.0" />
>     <plugin name="cordova-sqlite-storage" spec="^0.7.13" />
>     <plugin name="cordova-plugin-x-toast" spec="~2.2.1" />
>     <plugin name="cordova-plugin-x-socialsharing" spec="~5.0.5" />
>     <plugin name="phonegap-plugin-push" spec="^1.4.0" />
>     <plugin name="cordova-plugin-console" spec="^1.0.1" />
>     <plugin name="cordova-plugin-dialogs" spec="~1.1.1" />
>     <plugin name="cordova-plugin-app-version" spec="~0.1.7" />
> {noformat}
> Here's the generated config from the Android res/xmml directory:
> {noformat}
>     <preference name="loglevel" value="DEBUG" />
>     <feature name="PushPlugin">
>         <param name="android-package" value="com.plugin.gcm.PushPlugin" />
>     </feature>
>     <preference name="webView" value="org.crosswalk.engine.XWalkWebViewEngine" />
>     <preference default="15+" name="xwalkVersion" />
>     <preference default="--disable-pull-to-refresh-effect" name="xwalkCommandLine" />
>     <preference default="embedded" name="xwalkMode" />
>     <preference default="true" name="xwalkMultipleApk" />
>     <feature name="Device">
>         <param name="android-package" value="org.apache.cordova.device.Device" />
>     </feature>
>     <feature name="Notification">
>         <param name="android-package" value="org.apache.cordova.dialogs.Notification" />
>     </feature>
>     <feature name="SplashScreen">
>         <param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" />
>         <param name="onload" value="true" />
>     </feature>
>     <feature name="StatusBar">
>         <param name="android-package" value="org.apache.cordova.statusbar.StatusBar" />
>         <param name="onload" value="true" />
>     </feature>
>     <feature name="Whitelist">
>         <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin" />
>         <param name="onload" value="true" />
>     </feature>
>     <feature name="SocialSharing">
>         <param name="android-package" value="nl.xservices.plugins.SocialSharing" />
>     </feature>
>     <feature name="Toast">
>         <param name="android-package" value="nl.xservices.plugins.Toast" />
>     </feature>
>     <feature name="SQLitePlugin">
>         <param name="android-package" value="io.liteglue.SQLitePlugin" />
>     </feature>
>     <feature name="PushNotification">
>         <param name="android-package" value="com.adobe.phonegap.push.PushPlugin" />
>     </feature>
>     <feature name="AppVersion">
>         <param name="android-package" value="uk.co.whiteoctober.cordova.AppVersion" />
>     </feature>
> <....snip....removed app specific details...>
>     <content src="index.html" />
>     <preference name="DisallowOverscroll" value="true" />
>     <preference name="SplashScreen" value="screen" />
>     <preference name="SplashScreenDelay" value="10000" />
>     <preference name="AutoHideSplashScreen" value="false" />
>     <preference name="Orientation" value="portrait" />
>     <preference name="xwalkVersion" value="15+" />
>     <preference name="xwalkCommandLine" value="--disable-pull-to-refresh-effect" />
>     <preference name="xwalkMode" value="embedded" />
>     <preference name="xwalkMultipleApk" value="true" />
>     <access origin="*" />
>     <allow-intent href="tel:*" />
>     <allow-intent href="geo:*" />
> {noformat}
> Has anybody had the same problem or can anybody suggest a workaround/fix?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@cordova.apache.org
For additional commands, e-mail: issues-help@cordova.apache.org