HTTPClient

25 Oct 2011

Hello everyone,

I've been using the HTTPClient library with success, but I'm having difficulty with the getResponseHeader() member function. It appears to always return an empty string, no matter what header key you specify. I confirm that the accessed website is returning a response with the headers I'm expecting. This is done using Firefox Web Developer Web console. So either I am not using the member function correctly, or there is a bug within HTTPClient.

The API documentation is a little sparse to know if I am using it correctly - it reads:

Quote:

string& getResponseHeader(const string &header)

Gets a response header.

Yes, to the point! But what exactly do you pass to the function? I assume it is the HTML response header name.

Unfortunately, I cannot access the C++ class source to investigate further. The author has only published the header. So it is difficult to know if what I've done is reasonable effort.

[25/10/2011 - I have since learnt that you can edit imported libraries, and here you may reveal the source if the author has published them]

Here is the code:

#include "mbed.h"
#include "HTTPClient.h"

HTTPClient myClient;
HTTPResult myResult;
HTTPText   myText("text/html", 640);
int        myRespCode;
string     myRespHeader;
string     myUrl = "http://www.somewebsite.com";

myText.set("<some legal HTML />");
myResult = myClient.post(myUrl.c_str(), myText, NULL);
myRespCode = myClient.getHTTPResponseCode();
myRespHeader = myClient.getResponseHeader("Date");  // <-- Is this correct?

Then I print it out to see what I've got:

<stuff to instantiate an LCD>
lcd.printf("R:'%s'", myRespHeader.c_str());

If this is a C++ coding error on my part, please shout! If you've used it, do share!

24 Oct 2011

Hi Richard

Not sure what version of the library you are using (maybe an example) but if you use segundo fork of NetServices (http://mbed.org/cookbook/NetServices) then you'll be able to view source eg. here for the HTTPClient: http://mbed.org/users/segundo/libraries/NetServices/ljhqix/docs/HTTPClient_8cpp_source.html

And you can of course see this if you import into your compiler.

Regards
Daniel

25 Oct 2011

Thanks for your response, Daniel. According to the online revision control, I am meant to be using the head version already. Hmm, I see that revision control is thwarted by there being multiple copies of the library published on here!

I initially tried this one from 9/12/2010:

http://mbed.org/users/mamezu/libraries/HTTPClient/lj5do2

Now I am trying this one from 21/10/2011:

http://mbed.org/users/suupen/libraries/HTTPClient/lzcvoq

Looking at the code of the "segundo" fork, it appears that yes, I have guessed correctly, but somehow, the header I want is [probably] not saved into the hash. There are a few qualifications of the header format/type before it is saved or rejected. More debugging is required, and probably faster done by the author... I will spend some time and report back.

24 Oct 2011

I believe the way it's intended to be used is to extract HTTP standard header arguments.

Common examples sent by servers on the web:

Connection: "Keep-Alive" Content-type: "text/html" character-set: "UTF-8"

So you could call

myClient.getResponseHeader("Content-type");

and expect to get a string returned "text/html"

If you browse the server with Firefox or Opera on your PC, and have Wireshark patrolling the PC LAN connexion, you'll see which headers the page is sending.

Sad to say, the HTTPclient is not thoroughly tested, and has quite a few bugs and limitations. I ditched it and turned to Rolf's old stack, which shows how to do all this stuff using LwIP calls directly. This seems to me to work far more reliably, not to mention faster.

24 Oct 2011

Thanks Rod for your advice. I will take a closer look at the alternative library.

Regarding HTTPClient: Yes strange things do happen; it often freezes up. It would appear that memory allocation is not bulletproof on mBed, though it pains me to say it! And it causes a few headaches which detract from the "rapid prototyping" advantage with this platform. But I won't berate it too much...

I suspect many users experience a few problems caused by the heap running into the stack, and it's very easy to do with only a small amount of buffer space and a bit of C++ OO. The effect is mBed just crashes - code that should or did work, somehow freezes up. Backtrack your coding additions and it starts working again!

24 Oct 2011

Um. It only seems to return response header data if the HTTP response code is 200 (HTTP OK), and I see an "if" statement in the code to that effect...

I'm using HTTPClient with Pachube. When creating new feeds, the "Location" header tells you the feed ID within its 201 (HTTP CREATED) response. Otherwise, you have to wait up to five minutes for their servers to update your feed status information. Not ideal!

I'll fix this in the morning, now that I have a better idea.

25 Oct 2011

See how simple the direct LwIP API version of http client is:

http://mbed.org/projects/cookbook/wiki/EMAC/purehttpc

the LwIP calls are easily understood from the wiki:

http://lwip.wikia.com/wiki/Raw/TCP

This compiles and runs reliably, whether or not you update the mbed libraries to latest [28] and LwIP. My first test was 250K request/responses, back-to-back. You can put these within 20ms or so of each other, if the GET request is in the tcp_recv callback. (cp about 400ms using the official client).

Sending HTTP requests using TCP hard-coded tcp_send calls is a way to bypass the C++ of the network stack. If your requests are only heading for one server, then addressing its IP eliminates stack layers, ups reliability.

IME, this is the only way to get reliable network comms. The 'official' client seems to be unmaintained, and inadequately tested.... use with caution.

25 Oct 2011

Thanks Rod, for your contribution.

I will consider this as an alternative, but I suspect I don't know enough about IP networking to figure out how to use it in the time I have got right now...

And I suspect that resolving the URL that Pachube is expecting, into a single IP address, may be a problem here - the API expects tokens such as "?user=myaccount&someotherkey-valuepair" etc. Perhaps you could comment or correct me?

26 Oct 2011

You can still do it with LwIP direct calls:

say you want www.example.com/?page=add?key=12&user=a1

you can go through the CONNECT procedure (see Rolf's sample, above)

then tcp_send the packet with payload

GET /?page=add?key=12&user=a1\r\n Host:www.example.com\r\n\r\n

this also allows you to deal with the fact that pachube likes GET requests rather than POST, I believe. Far more detailed customisation is possible like this.

26 Oct 2011

Noted.