2
votes

My goal:

I want to make a get request to the RestApi that is running on the device in my local network to retrieve JSON data generated by the device.

What happens

The RestApi correctly responds to the browser call from every other device in the network. Bash's curl also works, however when I try to access the data through dart's http.get the program fails to retrieve the JSON data - I'm getting Statuscode 400.

Browser call result

What I have tried:

  • Messing with URL to make sure it's written correctly,
  • Setting up headers {"content" : "application/json"}
  • Using no (default) headers
  • Running the API call from separate dart file and from function embedded in flutter app. Both resulted in Statuscode 400, though flutter provided some more bug information: Unhandled Exception: SocketException: OS Error: No route to host, errno = 113. I believe I have also seen the errno = 111 when I tried something else.
  • Using lower level HttpClient instead of Http

In the flutter app, I can connect to the data stored on firebase through http.get easily enough, but call to the device in local network results in the scenario described above.

Stand-alone dart file

import 'package:dart_http/dart_http.dart' as dart_http;
import 'package:http/http.dart' as http;
import 'dart:io';
import 'dart:convert';

main(List<String> arguments) async {

  var url = 'http://192.168.0.5/api/device/state';

  http.Response response1 =
      await http.get(url, headers: {"content": "application/json"});
  print('Response status: ${response1.statusCode}');
  print('Response body: ${response1.body}');
  print('Response body: ${response1.headers}');
  print('Response body: ${response1.reasonPhrase}');
  print('Response body: ${response1.request}');

  HttpClient()
      .getUrl(Uri.parse(
          'http://192.168.0.5/api/device/state/')) // produces a request object
      .then((request) => request.close()) // sends the request
      .then((response) {
    print(response);
    response.transform(Utf8Decoder()).listen(print);
  }); // transforms and prints the response
}

Call-embedded in flutter project

 Future<Map<String, String>> getAirSensorStatus() async {
    print("Getting Air Sensor");
http.Response response =
        await http.get('http://192.168.0.5/api/device/state');
        print(response);
        print("Status code  " + "${response.statusCode}");

    try {
      if (response.statusCode != 200 && response.statusCode != 201) {
        print("Something went wrong. Status not 200 and not 201 for AirSensor");
        return null;
      }
      final responseData = json.decode(response.body);

      return responseData;
    } catch (error) {
      print(error);
      return null;
    }
  }

I'm expecting to get statuscode 200 and JSON data in the response. Instead, only a response object is created and no connection established.

Could you help me figure out why is that?

The link to the documentation of the API I'm trying to access:

https://technical.blebox.eu/

1
Did you maybe fall trap to flutter_test overriding the HTTP client and then defaults to returning HTTP 400? - AndiDog

1 Answers

0
votes

The issue seems likely to be caused by the client unable to reach the local server on the request. HTTP error 400 is labelled as "Bad request" and "No route to host, errno = 113" usually caused by network error. A common fix to this issue is to ensure that the client is on the same network the local server is hosted in.