makeWebRequest not working on device

I can make simple GET requests with makeWebRequest() to https://captive.apple.com with the simulator however, when I side load the app onto a Garmin VivoActive 3 (SW Version 6.4, Connect IQ 3.0.10) which is connected via bluetooth to an Android version of the Garmin Connect App (version 4.2). The request fails with a response of -400 (INVALID_HTTP_BODY_IN_NETWORK_RESPONSE) and null data. The phone can access https://captive.apple.com via its web browser. Why would this be different on the device and how do I resolve it?

Below is the code:


using Toybox.System
using Toybox.Communications

function onReceive(responseCode, data) {
if (responseCode == 200) {
System.println("Request Successful");
System.println("Response: " + responseCode + " Data: " + data);  

}
else {
System.println("Response: " + responseCode + " Data: " + data);
}
}

function makeRequest(action) {
var
url = "https://captive.apple.com";
var params = {};
var options = { // set the options
:method => Communications.HTTP_REQUEST_METHOD_GET,
:headers => {
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED},
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN
};

var responseCallback = method(:onReceive);

Communications.makeWebRequest(url, params, options, method(:onReceive));
}

Also, If I change the URL to the non-https version (http://captive.apple.com) on the device I get a -300 (NETWORK_REQUEST_TIMED_OUT) response and null data. Is this due to the watch only allowing the use of HTTPS?

Thanks

  • The -300 would be due to HTTP vs HTTPS, and often the -400 has to do with parameters being included in the url, and not as the next argument.  Is the url you posted the same as you're using or are there parts you left off (like a security/API key)

  • As posted, no additional parameters.

  • The request you're making informs the system that the response type will be text/plain, and the data will conform to that type. When GCM app running on iOS/Android receives a response, it compares the expected content type with that of the actual response, and if they don't match it will return a -400 error code to the ConnectIQ app. I have verified (with curl) that the incoming response has a text/html content type, so this is most likely the source of the -400 you're seeing.

    As to why the simulator and the actual device show different results, this is a bit complicated. The ConnectIQ simulator has its own system for handling web requests (technically it has two completely different systems). GCM on Android and iOS each have their own code for this too. So there are three different implementations of the code for handling web requests.. This makes it easy for behaviors to vary across the various platforms and can lead to inconsistencies you're seeing here.

    Currently, the only way to guarantee consistent behavior is to be sure that the response Content-Type header matches the expected header value. In some cases, the only way to do this is to stand up an intermediary web service (like a proxy) that will receive the web request from GCM, make the request to apple.com, and then translate the response as needed to feed it back to GCM.

    I have had a service like this running in Google AppEngine for several years.

  • I have the same problem : with simulator, it's ok ; with watch, i have error -400.

    Why this page https://services.data.shom.fr/hdm/vignette/grande/PAIMPOL?locale=fr is not a text/plain ?

    At first, I used an intermediate page. But then everything goes through my page... and shom.fr had blocked my too many requests (my widget is a victim of its success :\ ).

    4 years after, a solution exist ?