Implementing basic authentication

void received(const x::http::requestimpl &req, bool hasbody)
{
    std::set<std::string> auths;

    req.get_basic_auth(req.www_authorization,
                       [&]
                       (const std::string &auth)
                       {
                           auths.insert(auth);
                       });

    if (auths.find("citizenkane:rosebud") == auths.end())
        x::http::responseimpl::throw_unauthorized(x::http::auth::basic, "Auth Realm");

    // ...
}

The get_basic_auth() method decodes any basic authentication scheme headers present in a request. The first parameter should be x::http::requestimpl::www_authorization if the application implements an ordinary HTTP server, or x::http::requestimpl::proxy_authorization if the application implements an HTTP proxy. The second parameter is a lambda or a functor that gets invoked with the decoded userid:password string. The functor may be called more than once if the request includes multiple basic authorization headers. Although this is allowed by RFC 2617, this is rare in practice. There will usually be just one, but this approach supports multiple challenges, and it's up to the application to figure out what to do in that case. This example is happy if one of them was the userid citizenkane and the password rosebud.

x::http::responseimpl::throw_unauthorized() throws an exception that responds to the original request with an authentication challenge. x::http::responseimpl::throw_proxy_authentication_required() sends a proxy authentication challenge response. In all other respects these two functions are the same.

x::http::responseimpl::throw_unauthorized() and x::http::responseimpl::throw_proxy_authentication_required() takes the following parameters:

The above example shows the ordinary case of a boring basic authentication scheme, just an x::http::auth::basic, and some arbitrary authentication realm label. The HTTP client displays the realm label when prompting for authentication.