No description
Find a file
2019-08-03 13:15:05 +09:00
example Fixed a build error with example/redirect.cc 2019-08-03 03:28:38 +09:00
test Range header support and redesign of content provider interface 2019-08-03 03:28:39 +09:00
.gitignore Update .gitignore 2019-06-30 08:02:22 -04:00
.travis.yml Removed linux and gcc from .travis.yml 2019-06-26 15:24:03 -04:00
appveyor.yml travis and appveyor configuration 2018-10-14 22:42:18 +02:00
CMakeLists.txt Fix small CMake error when looking for the header 2019-07-24 10:50:52 +02:00
httplib.h new_task_queue support 2019-08-03 13:15:05 +09:00
LICENSE Changed license to MIT 2017-12-20 17:27:36 -05:00
README.md Range header support and redesign of content provider interface 2019-08-03 03:28:39 +09:00

cpp-httplib

Build Status Bulid Status

A C++ single-file header-only cross platform HTTP/HTTPS library.

It's extremely easy to setup. Just include httplib.h file in your code!

Server Example

#include <httplib.h>

int main(void)
{
    using namespace httplib;

    Server svr;

    svr.Get("/hi", [](const Request& req, Response& res) {
        res.set_content("Hello World!", "text/plain");
    });

    svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
        auto numbers = req.matches[1];
        res.set_content(numbers, "text/plain");
    });

    svr.Get("/stop", [&](const Request& req, Response& res) {
        svr.stop();
    });

    svr.listen("localhost", 1234);
}

Post, Put, Delete and Options methods are also supported.

Bind a socket to multiple interfaces and any available port

int port = svr.bind_to_any_port("0.0.0.0");
svr.listen_after_bind();

Static File Server

svr.set_base_dir("./www");

Logging

svr.set_logger([](const auto& req, const auto& res) {
    your_logger(req, res);
});

Error Handler

svr.set_error_handler([](const auto& req, auto& res) {
    const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
    char buf[BUFSIZ];
    snprintf(buf, sizeof(buf), fmt, res.status);
    res.set_content(buf, "text/html");
});

'multipart/form-data' POST data

svr.Post("/multipart", [&](const auto& req, auto& res) {
    auto size = req.files.size();
    auto ret = req.has_file("name1"));
    const auto& file = req.get_file_value("name1");
    // file.filename;
    // file.content_type;
    auto body = req.body.substr(file.offset, file.length));
})

Stream content with Content provider

const uint64_t DATA_CHUNK_SIZE = 4;

svr.Get("/stream", [&](const Request &req, Response &res) {
  auto data = std::make_shared<std::string>("abcdefg");

  res.set_content_provider(
    data->size(), // Content length
    [data](uint64_t offset, uint64_t length, Out out) {
      const auto &d = *data;
      out(&d[offset], std::min(length, DATA_CHUNK_SIZE));
    });
});

Chunked transfer encoding

svr.Get("/chunked", [&](const Request& req, Response& res) {
  res.set_chunked_content_provider(
    [](uint64_t offset, Out out, Done done) {
       out("123", 3);
       out("345", 3);
       out("789", 3);
       done();
    }
  );
});

Client Example

GET

#include <httplib.h>
#include <iostream>

int main(void)
{
    httplib::Client cli("localhost", 1234);

    auto res = cli.Get("/hi");
    if (res && res->status == 200) {
        std::cout << res->body << std::endl;
    }
}

GET with HTTP headers

  httplib::Headers headers = {
    { "Accept-Encoding", "gzip, deflate" }
  };
  auto res = cli.Get("/hi", headers);

GET with Content Receiver

  std::string body;
  auto res = cli.Get("/large-data", [&](const char *data, size_t len) {
    body.append(data, len);
  });
  assert(res->body.empty());

POST

res = cli.Post("/post", "text", "text/plain");
res = cli.Post("/person", "name=john1&note=coder", "application/x-www-form-urlencoded");

POST with parameters

httplib::Params params;
params.emplace("name", "john");
params.emplace("note", "coder");

auto res = cli.Post("/post", params);

or

httplib::Params params{
  { "name", "john" },
  { "note", "coder" }
};

auto res = cli.Post("/post", params);

POST with Multipart Form Data

  httplib::MultipartFormDataItems items = {
    { "text1", "text default", "", "" },
    { "text2", "aωb", "", "" },
    { "file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain" },
    { "file2", "{\n  \"world\", true\n}\n", "world.json", "application/json" },
    { "file3", "", "", "application/octet-stream" },
  };

  auto res = cli.Post("/multipart", items);

PUT

res = cli.Put("/resource/foo", "text", "text/plain");

DELETE

res = cli.Delete("/resource/foo");

OPTIONS

res = cli.Options("*");
res = cli.Options("/resource/foo");

Connection Timeout

httplib::Client cli("localhost", 8080, 5); // timeouts in 5 seconds

With Progress Callback

httplib::Client client(url, port);

// prints: 0 / 000 bytes => 50% complete
std::shared_ptr<httplib::Response> res =
    cli.Get("/", [](uint64_t len, uint64_t total) {
        printf("%lld / %lld bytes => %d%% complete\n",
            len, total,
            (int)((len/total)*100));
        return true; // return 'false' if you want to cancel the request.
    }
);

progress

This feature was contributed by underscorediscovery.

Basic Authentication

httplib::Client cli("httplib.org");

auto res = cli.Get("/basic-auth/hello/world", {
  httplib::make_basic_authentication_header("hello", "world")
});
// res->status should be 200
// res->body should be "{\n  \"authenticated\": true, \n  \"user\": \"hello\"\n}\n".

Range

httplib::Client cli("httpbin.org");

auto res = cli.Get("/range/32", {
  httplib::make_range_header({{1, 10}}) // 'Range: bytes=1-10'
});
// res->status should be 206.
// res->body should be "bcdefghijk".
httplib::make_range_header({{1, 10}, {20, -1}})      // 'Range: bytes=1-10, 20-'
httplib::make_range_header({{100, 199}, {500, 599}}) // 'Range: bytes=100-199, 500-599'
httplib::make_range_header({{0, 0}, {-1, 1}})        // 'Range: bytes=0-0, -1'

OpenSSL Support

SSL support is available with CPPHTTPLIB_OPENSSL_SUPPORT. libssl and libcrypto should be linked.

#define CPPHTTPLIB_OPENSSL_SUPPORT

SSLServer svr("./cert.pem", "./key.pem");

SSLClient cli("localhost", 8080);
cli.set_ca_cert_path("./ca-bundle.crt");
cli.enable_server_certificate_verification(true);

Zlib Support

'gzip' compression is available with CPPHTTPLIB_ZLIB_SUPPORT.

The server applies gzip compression to the following MIME type contents:

  • all text types
  • image/svg+xml
  • application/javascript
  • application/json
  • application/xml
  • application/xhtml+xml

NOTE

g++ 4.8 cannot build this library since <regex> in g++4.8 is broken.

License

MIT license (© 2019 Yuji Hirose)