HTTP Client
Overview
This tutorial will show you how to implement an HTTP client using Mongoose Library.
Build and run
Follow the Build Tools tutorial to setup your development environment. Then start a command prompt / terminal and enter the following:
git clone https://github.com/cesanta/mongoose
cd mongoose/tutorials/http/http-client
make
Done! The full source code for this tutorial is at https://github.com/cesanta/mongoose/tree/master/tutorials/http/http-client
By default, the http-client example connects to http://info.cern.ch/ -
the very first web server on the planet. You can use any other URL: make ARGS=http://my-site.com
. If your URL is HTTPS, then make sure to build this
example with TLS support - see below.
A basic HTTP client
Let's start with a minimal Mongoose template that initialises and starts an event manager, but does nothing:
#include "mongoose.h"
int main(int argc, char *argv[]) {
struct mg_mgr mgr;
mg_mgr_init(&mgr); // Init manager
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
mg_mgr_free(&mgr); // Cleanup
return 0;
}
Now, let's create an HTTP client connection before the event loop starts. We will fetch the very first web page in history - a page from CERN, where the Web was invented by Tim Bernes-Lee. That web page is still alive! Let's create a variable that holds a URL:
// First web page in history
static const char *s_url = "http://info.cern.ch/";
Client connection
Now, add a client connection. We need an event handler function for it. That
event handler function is going to get an MG_EV_HTTP_MSG
event when a full
page content gets downloaded.
A client connection is created by the
mg_http_connect() function. An
important aspect of that function is that it only creates a TCP connection
to the server, but does not send a request. The reason for this is that an HTTP
request could be quite complex; therefore it is our responsibility to
construct the request. We do it when we receive an MG_EV_CONNECT
event.
There, we extract a hostname from the URL to form a valid Host
header, which
is mandatory for HTTP/1.1, using the mg_url_host() function.
We also make use of the mg_url_uri() function to point to the URI part in the URL.
Finally, we send a simple GET
request using mg_printf():
#include "mongoose.h"
// First web page in history
static const char *s_url = "http://info.cern.ch/";
static void fn(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_CONNECT) {
struct mg_str host = mg_url_host(s_url);
// Send request
mg_printf(c,
"GET %s HTTP/1.0\r\n"
"Host: %.*s\r\n"
"\r\n",
mg_url_uri(s_url), (int) host.len, host.buf);
} if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
printf("%.*s", (int) hm->message.len, hm->message.buf);
}
}
int main(int argc, char *argv[]) {
struct mg_mgr mgr;
mg_mgr_init(&mgr); // Init manager
mg_http_connect(&mgr, s_url, fn, NULL); // Create client connection
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
mg_mgr_free(&mgr); // Cleanup
return 0;
}
Error handling
Connection failures will trigger an MG_EV_ERROR
event; an error reason is passed as a char *
pointer in parameter ev_data
.
Check the error handling tutorial for more information
Build with TLS support
Check the "How to build" section of the TLS tutorial for specific information on building options for your OS
Now you can pass an HTTPS URL to the compiled example.
For more information on developing TLS clients, check the TLS tutorial