makeWebRequest worked with http, but now not with https, does INVALID_HTTP_BODY_IN_NETWORK_RESPONSE -400

Hi,

Because of Garmin not supporting http-Requests anymore, I had to change to https.

I changed my webservice an installed a SSL certificate on my Win10 PC.

In the simulator I get now a INVALID_HTTP_BODY_IN_NETWORK_RESPONSE  -400.

Why this?

You can check the webservice at https://fsmarin.mooo.com/SmappeeLocalWebApi/api/ActualPower?Smappee=http://fsmarin.mooo.com:20000

returning a JSON.  

[{"ConsumedPower":509,"SolarPower":1359,"Timestamp":"2019-09-22T14:32:47.8677179+02:00"}]

        Comm.makeWebRequest(
        	httpAddress,
            {
            },
            {
                "Content-Type" => Comm.REQUEST_CONTENT_TYPE_JSON
            },
            method(:onReceive)
        );

Do I have to set some parameters in the Webcall? (before with http, I did not set the Content-Type and it worked perfectly over month!)

Any help very appreciated

Marcel

  • 1.
    I tested my second DataField (Wind), there it works.

    Reson: Wind is sent by XML (I sent same dummy parameter for testing, without a problem)

    For the moment the XML? answer which works: https://apps.garmin.cn/en-US/apps/38f0dfb5-2f57-4725-a960-0770cd5ac29d

    XML:

    <GarminValueDTO xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/z_IchtusEF.DTO">
    <OutsideTempCVN>18.7</OutsideTempCVN>
    <OutsideTempIchtus i:nil="true"/>
    <OutsideTempYVO>16.8</OutsideTempYVO>
    <RainRateIchtus i:nil="true"/>
    <RecordTimeIchtus>2019-09-23T19:01:00</RecordTimeIchtus>
    <WaterTemperatureIchtus i:nil="true"/>
    <WaterTemperatureYVO>17.2</WaterTemperatureYVO>
    <WindDirectionDegreesCVN>270</WindDirectionDegreesCVN>
    <WindDirectionDegreesIchtus>0</WindDirectionDegreesIchtus>
    <WindDirectionDegreesYVO>243</WindDirectionDegreesYVO>
    <WindDirectionTextCVN>W</WindDirectionTextCVN>
    <WindDirectionTextIchtus>N</WindDirectionTextIchtus>
    <WindDirectionTextYVO>SW</WindDirectionTextYVO>
    <WindSpeedKnotsCVN>7.6</WindSpeedKnotsCVN>
    <WindSpeedKnotsIchtus i:nil="true"/>
    <WindSpeedKnotsYVO>4.0</WindSpeedKnotsYVO>
    </GarminValueDTO>

    2.

    But makeWebRequest does not work on my Solar (smappee=) App, where its JSON!

    [{"ConsumedPower":357,"SolarPower":-5,"Timestamp":"2019-09-26T21:18:39.2852605+02:00"}]


    I have to check, why the answers are different, it is most probalbly not a parameter therefore.
    Both webservices are written by me in CSHARP!

  • Yes, I programmed it really like this.
    But why is it working  with XML and NOT with JSON?

    I am confused, it should be the other way around

  • The documentation is saying don't do that yourself. Garmin will do it when itself.

    Yes, we will do that ourselves, but if you don't properly urlencode the query string, or if you try to pass additional parameters via the params dict, things can get messed up.

    That is why we expect the url to be the base URL (the scheme, authority, and path) without the query string and for the query parameters to be provided via the params dict. As you've noticed, GCM will not be happy if your request includes query parameters in the URL string.

    The issue that I'm seeing is that the service is not urldecoding the query string like I believe it should. If the query string parameters are not urlencoded, it seems to work. You can verify this by clicking this link:

      https://exulto.serveo.net/SmappeeLocalWebApi/api/ActualPower?Smappee=http://fsmarin.mooo.com:20000

    If I encode the query string value and try again, it does not work. Again, click the link:

      https://exulto.serveo.net/SmappeeLocalWebApi/api/ActualPower?Smappee=http%3A%2F%2Ffsmarin.mooo.com%3A20000

    This is the first time I've ever seen a service not handle urlencoded data in the query string: If I do something similar with google, it works just as I'd expect:

      https://www.google.com/?query=https://facebook.com:80

    vs

      https://www.google.com/?query=https%3A%2F%2Ffacebook.com%3A80

    It looks like this may be a web service you've created yourself? If so, you should look at urldecoding each key and value in the query string before processing.

  • Yes you are right. 
    I corrected now the WebService.
    It worked before with http, but behaviour is different on https with the paramater encoding.

    I used primitive string functions in CSharp, now I use ParameterAccessFunctions to get them.

    The serveo https tunnel seems to stop sometime, I will check if I get the widget  to run also with Lets'Encrypt certificate.
    ssh -o ServerAliveInterval=60 -R 80:localhost:80 serveo.net

    Or does somebody know, what's the best solution for a private HTTPS from my own Win10PC


    Thanks to all of you
    Marcel

    And my solar production and consumption is shown on the watch:
    https://apps.garmin.com/en-US/apps/8a249627-258a-4da7-846c-629397b3390b

  • Are you running the service on a computer on your local network and then using a tunnel to access it via a an ssh tunnel? Would it be possible to just put your code on a cloud service (google, amazon, azure, ...)? Given that your solar array is in your home you'd probably need to write something to push data out to the service periodically, but it seems that might be a cleaner setup.

  • Yes I am runnuning an ASP.NET Web Service on my local (DynDNs) Win10 Computer.

    I have 2 implementation:

    A:
    With  a lets Encrypt certificate: It runs in simulator but NOT on the watch using :  fsmarin.mooo.com/.../ActualPower
    smappeeAddress2: http://fsmarin.mooo.com:20000

    In SSL I entered the Lets'encrypt, under SSL settings "NOT Require SSL" & "Ignore". (so I can use the webservice with http and https)

    B:
    via tunnel of serveo, runs also on the watch, but serveo stopps after a while, so I made a cmd with a loop, where it restarts it always, AND it changes its "adress", now it is https://iussum.serveo.net (before  it was https://exulto.serveo.net

    => this is annoying

    so https://iussum.serveo.net/SmappeeLocalWebApi/api/ActualPower?Smappee=http://fsmarin.mooo.com:20000

    Webservices on google, amazon, azure are not for free!

    I would like to run Version A (via Lets Encrypt) but why does it not work on the watch via Android Handy?

  • You do get free azure and google webservices, depending on what you need of course. Haven’t used Amazon, so can’t vouch for it.

    I’ve been running proxies for my watch faces and widget for free in Azure the past 2 years.

    It may not appear as free, but instead you have to adhere to quotas. Google has very generous quotas, and Azure’s are a bit stricter, but still enough for my purposes.