Hard Fault with HttpClient library when using URL as hostname

I’m using the HttpClient library, https://github.com/nmattisson/HttpClient, on a Photon.

I can connect to a website just fine, such as www.google.com.

I have set up an API that returns JSON data on a Microsoft server and that works in the browser just fine.

When I plug that URL into the hostname variable, flash the code, I get a SOS and a single blink (hard fault). The URL is formatted like this, api.xxx.xxx.net. That shouldn’t be an issue, right?

From your pc can you ping this api.xxx.xxx ?

I can ping the api.xxx.xxx.net address just fine. HttpClient just doesn’t seem to like it the URL but I don’t know it doesn’t like it until I get the Hard Fault.

@HardWater, any other thoughts on this?

I think you are going to have to show us more code for us to help more: How are you setting up the URL and hostname with HttpClient?

Hi @craigfoo,

What version of the system are you using?

There was a fault issue that cropped up for me using 4.3 on the second request I sent there would be a SOS. The develop branch had been changed to fix that. I also did not have the problem with 4.2 but the underlying code problem might still have been there (I do not know).

If that is not the source of your problem I would suggest using something like python from your PC to send the request and look at the response just to make sure that you understand what the interaction with that server is like. Maybe that would put you on the source of the problem.

1 Like

@bko, I’m using the example code and trying to connect to my cloud instead of the www.timeapi.org from the example. I can connect to the IP of my cloud just fine but when I use the URL, it SOS’s on me. My cloud URL happens to be in the format of api.xxx.xxx.net, not sure if HttpClient doesn’t like this or not. Seems like it should be ok because it’s just a string.

Here is where it’s sending the hostname, from HttpClient.cpp:

HttpClient.cpp

if(aRequest.hostname!=NULL) {
    connected = client.connect(aRequest.hostname.c_str(), (aRequest.port) ? aRequest.port : 80 );
}   else {
    connected = client.connect(aRequest.ip, aRequest.port);
}

application.cpp (modified example)

#include "application.h"
#include "HttpClient.h"

/**
* Declaring the variables.
*/
unsigned int nextTime = 0;    // Next time to contact the server
HttpClient http;

// Headers currently need to be set at init, useful for API keys etc.
http_header_t headers[] = {
    //  { "Content-Type", "application/json" },
    //  { "Accept" , "application/json" },
    { "Accept" , "*/*"},
    { NULL, NULL } // NOTE: Always terminate headers will NULL
};

http_request_t request;
http_response_t response;

void setup() {
Serial.begin(9600);
}

void loop() {
if (nextTime > millis()) {
    return;
}

Serial.println();
Serial.println("Application>\tStart of Loop.");
// Request path and body can be set at runtime or at setup.
request.hostname = "api.xxx.xxx.net";
request.port = 80;
request.path = "/somepath";

// The library also supports sending a body with your request:
//request.body = "{\"key\":\"value\"}";

// Get request
http.get(request, response, headers);
Serial.print("Application>\tResponse status: ");
Serial.println(response.status);

Serial.print("Application>\tHTTP Response Body: ");
Serial.println(response.body);

nextTime = millis() + 10000;
}

@HardWater, I’m using the latest firmware, 0.4.3.

@craigfoo,

Please try the develop branch I am pretty confident you will see the problem go away using it.

When I manually make a request to that URL, the server is returning a 302 Redirect to “http://ww41.api.xxx.xxx.net/somepath”.

Now, that shouldn’t cause a hard fault. But the HttpClient library won’t handle redirects for you, so it’s something you need to be aware of. If you get a ‘302’ status, you’ll need to get the value of the ‘Location’ header from the response, parse that URL, and make a new client request.

1 Like

Thanks for this POST @craigfoo , I have code that behaves differently on 2 photons. One behaves perfectly and the on the other I see the exact same 2 http posts then RED SOS and crash as you describe above. I know the broke one is on 0.4.3, and I assume the one working is on 0.4.2 (wish I could easily see which version they were on using something like "particle identify") Problem for me is I am using the dashboard beta and am required to use the cloud compiler for the time being, so I am hoping the fix for this can be rolled into production very soon.

1 Like

Thanks for the help gentlemen. I have now tried Photon firmware versions 0.4.2, 0.4.3, and 0.4.4 (found this minor change on the GitHub repo, https://github.com/spark/firmware/releases). I tried loading the development branch as @HardWater mentioned but I keep running into a “Page at 0x08005000 is not writeable” error during flashing.

It seems like there are 1000 reasons why I would see an SOS, hard fault but is there any hint as to why a hard fault happens? What’s really happening there? Maybe if I understood hard faults better, it might give me a hint.

UPDATE: Found this post about the Hard Fault, What does "hard fault" mean?

@craigfoo, I have an issue posted on the develop firmware regarding this problem. I believe it is related to DNS timeouts. @AndyW did some great sleuthing here:

I am working on raising this issue with the Particle team.

@peekay123 @mdma got this fixed for me at least with the develop branch. My understanding from him was that there was a part of the wiced code that was erasing something to free up memory while another part of the code was trying to access this memory.

@HardWater, not sure that fix was related. Do you have his “fix”?

@peekay123 I cannot tell why @mdma has not published something about the change but he definitely made a change to the develop branch. We were going back and forth via PM to try and solve my SOS problem that I had with the 0.4.3 code. For you to have a precise answer as to what the change entailed it will have to come from @mdma.

@HardWater, Mat is back on Monday I believe so all will be revealed then :wink:

@bko, @peekay123, @HardWater, @anthonywebb, @dougal

I’ve been doing some testing with different flavors of firmware and the HTTPClient example (same as above post):

Photon Firmware v0.4.2
Using my cloud IP Address for hostname: Works! :+1:
Using URL format www.google.com for hostname: Works! :+1:
Using my cloud URL formatted api.thing.something.net for hostname: Hangs up on solid cyan :-1:

Photon Firmware v0.4.3
Using my cloud IP Address for hostname: Works! :+1:
Using URL format www.google.com for hostname: Works! :+1:
Using my cloud URL formatted api.thing.something.net for hostname: Hard Fault (SOS + 1 red flash) :-1:

Photon Firmware v0.4.4
Using my cloud IP Address for hostname: Works! :+1:
Using URL format www.google.com for hostname: Works! :+1:
Using my cloud URL formatted api.thing.something.net for hostname: Hard Fault (SOS + 1 red flash) :-1:

Now, api.thing.something.net is clearly not the real URL I’m trying, it’s an example. I don’t know of any other URL formatted like this to ping so I can’t say if it’s how it’s formatted or something with my cloud. I don’t suspect the ladder because the IP address for my cloud works just fine. I guess I’ll use the IP for now…

1 Like

@craigfoo, good work!

That sounds like the problem is at a lower level, in whatever part of code is doing DNS lookups.

OK there is one other thing I forgot to mention here:

If api.thing.something.net is just one name for a shared host that has many names and services many websites etc. then you must add the correct Host: header to your request. Otherwise the server won’t know which of its names you are trying to use. I don’t know what HttpClient does for hostnames but thought it would take the hostname you give it for the connection and use it.