Chapter 7
Functions and Futures: Patterns for Distributed Services

At the end of the last chapter, we implemented the core of a fully asynchronous web server based on a C binding for the libuv event loop. In this chapter, we’ll extend those techniques and implement a highly capable asynchronous HTTP client based on the celebrated C library, libcurl.[37]

In many ways, we’ll be retracing the steps we took in Chapter 3, Writing a Simple HTTP Client, where we implemented a blocking HTTP client using just the low-level UNIX socket API and some simple regular expressions with scanf. However, our client had limitations to its efficiency and capabilities: its blocking nature limited its applicability to many highly parallel use cases, and the simple parser couldn’t handle more sophisticated protocol variants such as HTTPS.

We’ve come a long way since Chapter 3. With what we know about C library bindings and nonblocking I/O, we’re now prepared to design and build an HTTP client with far greater power. Before we dive into implementation, though, let’s take a step back and design our API. Having a clear goal in mind will help us as we integrate libcurl and libuv and deal with their various quirks and gotchas.