C++ header-only HTTP框架cuehttp

github

cuehttp

簡介

cuehttp是一個使用Modern C++(C++14)編寫的跨平臺、高性能、易用的HTTP/WebSocket框架。基於中間件模式可以方便、高效、優雅的增加功能。cuehttp基於boost.asio開發,使用llhttp進行HTTP協議解析。內部依賴了nlohmann/json

cuehttp內部包含一組中間件函數,註冊的中間件會根據中間件的添加順序執行。在中間件中也可以選擇是否進行下一個中間件的執行或改變中間件內的行爲執行順序。

roadmap

  • multipart
  • 錯誤處理
  • http client

使用

cuehttp依賴boost,以及使用最低依賴C++14。cuehttp是header-only的,#include <cuehttp.hpp>即可使用。HTTPS需要依賴OpenSSL,並且在編譯的時候添加ENABLE_HTTPS宏。

hello cuehttp!

cuehttp是非常的簡潔易用的,使用use接口即可添加中間件。

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    cuehttp app;
    app.use([](context& ctx) {
        ctx.type("text/html");
        ctx.body(R"(<h1>Hello cuehttp!</h1>)");
        ctx.status(200);
    });
    app.listen(10000).run();

    return 0;
}

https

cuehttp支持HTTPS,並且支持HTTP和HTTPS同時使用。注:cue::http::cuehttp默認listen創建的是HTTP的,若要使用HTTPS,需要使用https::create_server創建。

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    cuehttp app;
    app.use([](context& ctx) {
        ctx.type("text/html");
        ctx.body(R"(<h1>Hello, cuehttp!</h1>)");
        ctx.status(200);
    });

    // both
    auto http_server = http::create_server(app.callback());
    http_server.listen(10000);

    auto https_server = https::create_server(app.callback(), "server.key", "server.crt");
    https_server.listen(443);

    cuehttp::run();

    return 0;
}

WebSocket

cuehttp支持WebSocket,支持ws/wss同時使用。支持wss需要開啓HTTPS(見上節)。

#include <iostream>
#include <vector>

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    cuehttp app;
    app.ws().use([](context& ctx) {
        ctx.websocket().on_open([&ctx]() {
            std::cout << "websocket on_open" << std::endl;
            ctx.websocket().send("hello");
        });
        ctx.websocket().on_close([]() {
            std::cout << "websocket on_close" << std::endl;
        });
        ctx.websocket().on_message([&ctx](std::string&& msg) {
            std::cout << "websocket msg: " << msg << std::endl;
            ctx.websocket().send(std::move(msg));
        });
    }));

    auto http_server = http::create_server(app.callback());
    http_server.listen(10000);

    auto https_server = https::create_server(app.callback(), "server.key", "server.crt");
    https_server.listen(443);

    cuehttp::run();

    return 0;
}

中間件級聯

cuehttp中的中間件通過next函數調用控制下游中間件的運行,當next函數返回,則繼續執行上游中間件。中間件的註冊分爲兩種:

  • void(context& ctx)

    中間件在執行完自身邏輯時自動調用next控制下游中間件執行。

  • void(context& ctx, std::function<void()> next)

    中間件需要調用next控制下游中間件執行,若next不調用,則下游所有中間件無法執行。

#include <iostream>

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    cuehttp app;
    app.use([](context& ctx) {
        std::cout << "0" << std::endl;
    });

    app.use([](context& ctx, std::function<void()> next) {
        std::cout << "1-1" << std::endl;
        next();
        std::cout << "1-2" << std::endl;
    });

    app.use([](context& ctx, std::function<void()> next) {
        std::cout << "2" << std::endl;
    });

    app.use([](context& ctx, std::function<void()> next) {
        std::cout << "3" << std::endl;
    });

    app.listen(10000).run();

    return 0;
}

// 0
// 1-1
// 2
// 1-2

支持多種中間件執行體(普通函數、類成員函數、operator()、std::function、lambda),支持批量添加,支持鏈式調用。

#include <iostream>
#include <vector>

#include <cuehttp.hpp>

using namespace cue::http;

void f1(context& ctx) {
    std::cout << "f1" << std::endl;
}

void f2(context& ctx, std::function<void()> next) {
    std::cout << "f2" << std::endl;
    next();
}

struct handler1 {
    void handle(context& ctx) {
        std::cout << "handler1::handle" << std::endl;
    }
};

struct handler2 {
    void handle(context& ctx, std::function<void()> next) {
        std::cout << "handler2::handle" << std::endl;
        next();
    }
};

struct operator1 {
    void operator()(context& ctx) {
        std::cout << "operator1" << std::endl;
    }
};

struct operator2 {
    void operator()(context& ctx, std::function<void()> next) {
        std::cout << "operator2" << std::endl;
        next();
    }
};

int main(int argc, char** argv) {
    cuehttp app;
    app.use(f1);
    app.use(f2);

    handler1 hr1;
    app.use(&handler1::handle, &hr1);
    app.use(&handler1::handle);

    handler2 hr2;
    app.use(&handler2::handle, &hr2);
    app.use(&handler2::handle);

    operator1 or1;
    app.use(or1);

    operator2 or2;
    app.use(or2);

    app.use([](context& ctx) {
           ctx.type("text/html");
           ctx.body(R"(<h1>Hello, cuehttp!</h1>)");
           ctx.status(200);
       })
        .use([](context& ctx, std::function<void()> next) {
            std::cout << "1-1" << std::endl;
            next();
            std::cout << "1-2" << std::endl;
        });

    const std::vector<std::function<void(context&, std::function<void()>)>> handlers{
        [](context& ctx, std::function<void()> next) {
            std::cout << "2-1" << std::endl;
            next();
            std::cout << "2-2" << std::endl;
        },
        [](context& ctx, std::function<void()> next) {
            std::cout << "3-1" << std::endl;
            std::cout << "3-2" << std::endl;
            next();
        }};
    app.use(std::move(handlers));

    app.use([](context& ctx) { std::cout << "4" << std::endl; });

    app.listen(10000).run();
    // or
    // app.listen(10000);
    // cuehttp::run();

    // or
    // http::create_server(app.callback()).listen(10000).run();

    // or
    // auto http_server = http::create_server(app.callback());
    // http_server.listen(10000);
    // cuehttp::run();

    return 0;
}

chunked

支持chunked響應。

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    router route;
    route.get("/chunked", [](context& ctx) {
        ctx.status(200);
        ctx.set("Transfer-Encoding", "chunked");
        ctx.body() << R"(<h1>Hello, cuehttp!</h1>)";
    });

    cuehttp app;
    app.use(route.routes());

    app.listen(10000).run();

    return 0;
}

API

類型說明:

string: 所有std::string值類型、引用類型或可以轉換爲std::string的類型;

map: std::map的所有值類型或引用類型。

cue::http::cuehttp

cuehttp主體程序,用於註冊中間件、啓停HTTP服務。

cue::http::cuehttp& use(…)

註冊中間件到cuehttp中,返回cuehttp對象的引用用於進行鏈式調用。具體使用參考中間件級聯內置中間件

cue::http::cuehttp& listen(unsigned port, [string host])

監聽端口,此接口爲阻塞接口,host爲可選的。

std::function<void(context&)> callback() const

返回設置給server的handler。

static void run()

運行服務。

static void stop()

停止服務。

ws_server& ws()

返回WebSocket server操作示例。

cue::http::server

cue::http::server& listen(unsigned port, [string host])

監聽端口,此接口爲阻塞接口,host爲可選的。

void run()

運行服務。

cue::http::http

cue::http::server create_server(std::function<void(context&)> handler)

創建HTTP服務,傳入handler。

using namespace cue::http;
cuehttp app;
...
auto server = http::create_server(app.callback());
server.listen(10000).run();

cue::http::https

cue::http::server create_server(std::function<void(context&)> handler, const std::string& key, const std::string& cert)

創建HTTPS服務,傳入handler。

using namespace cue::http;
cuehttp app;
...
auto server = https::create_server(app.callback(), "server.key", "server.crt");
server.listen(10000).run();

cue::http::ws_server

cue::http::ws_server& use(…)

註冊中間件到WebSocket server中,返回ws_server對象的引用用於進行鏈式調用。具體使用參考中間件級聯內置中間件

void broadcast(std::string_view msg, [ws_send::options options])

對所有連接的客戶端進行消息廣播。

ws_send::options 類型 描述 默認值
fin bool 發送的消息是否爲最後結束幀 true
mask bool payload是否需要掩碼加密 true
binary bool 可以訪問此cookie的域名 false

std::function<void(context&)> callback()

返回設置給WebSocket處理中間件handler。

cue::http::context

chehttp中間件接口的HTTP處理上下文。

cue::http::request& req()

獲取會話中的HTTP請求結構的引用。

cue::http::response& res()

獲取會話中的響應結構的引用。

cue::http::websocket& websocket()

獲取會話中的websocket結構的引用。

const std::map<std::string, std::string>& headers() const

獲取請求攜帶的header信息,header的field以及value鍵值對組。

std::string_view get(std::string_view field) const

獲取請求中header信息中對應field的value,無則返回空字符串。

std::string_view method() const

獲取請求的method。

std::string_view host() const

獲取請求中host。hostname:port。

127.0.0.1:1000

std::string_view hostname() const

獲取請求中的hostname。

127.0.0.1

std::string_view url() const

獲取請求的url。

/get?sid=hosdghtsdvojoj

std::string_view origin() const

獲取請求的url來源,包含protocol和host。

http://127.0.0.1:10000

std::string_view href() const

獲取請求的完整url,包含protocol、host、url。

http://127.0.0.1:10000/get?sid=hosdghtsdvojoj

std::string_view path() const

獲取請求路徑名。

/get

std::string_view querystring() const

獲取請求查詢字符串。

sid=hosdghtsdvojoj

unsigned status() const

獲取響應的status。

void status(unsigned status)

設置響應的status。

void redirect(string url)

重定向到對應url,默認status爲302,若修改默認的302則在redirect前調用status。

void message(string message)

設置響應的信息,對應status。

void set(string field, string value)

向響應中添加header。

void set(map<std::string, std::string> headers)

向響應中添加一組header。

void remove(std::string_view field)

將響應中對應field的header刪除。

void type(string content_type)

設置響應體的類型。

void length(std::uint64_t content_length)

設置響應體的長度。若爲chunked類型響應,則此項不設置。

cookies& cookies()

獲取cookies操作對象。

bool has_body() const

響應中是否已經設置body。

void body(string body)

設置響應體。

void body(const char* buffer, std::size_t size)

設置響應體,傳入buffer和buffer大小。

std::ostream& body()

獲取響應體流操作對象(std::ostream),用於以流的方式設置響應體,調用接口時發送響應header,流操作時發送響應體。

ctx.body() << "hello cuehttp";

cue::http::request

std::string_view get(std::string_view field) const

獲取請求中header信息中對應field的value,無則返回空字符串。

const std::map<std::string, std::string>& headers() const

獲取請求攜帶的header信息,header的field以及value鍵值對組。

std::string_view method() const

獲取請求的method。

std::string_view host() const

獲取請求中host。hostname:port。

127.0.0.1:1000

std::string_view hostname() const

獲取請求中的hostname。

127.0.0.1

std::string_view url() const

獲取請求的url。

/get?sid=hosdghtsdvojoj

std::string_view origin() const

獲取請求的url來源,包含protocol和host。

http://127.0.0.1:10000

std::string_view href() const

獲取請求的完整url,包含protocol、host、url。

http://127.0.0.1:10000/get?sid=hosdghtsdvojoj

std::string_view path() const

獲取請求路徑名。

/get

std::string_view querystring() const

獲取請求查詢字符串。

sid=hosdghtsdvojoj

const std::map<std::string, std::string>& query() const

獲取請求的query列表。name和value鍵值對組。

std::string_view search() const

獲取請求查詢字符串,帶?。

?sid=hosdghtsdvojoj

std::string_view type() const

獲取請求的content type。

std::string_view charset() const

獲取請求content的charset。

std::uint64_t length() const

獲取請求的content length。

std::string_view body()

獲取請求攜帶的body。

cue::http::response

unsigned status() const

獲取響應的status。

void status(unsigned status)

設置響應的status。

void message(string message)

設置響應的信息,對應status。

bool has(std::string_view field) const

獲取響應是否設置了某個header。

std::string_view get(std::string_view field) const

獲取響應中某個header,不存在返回空。

void set(string field, string value)

向響應中添加header。

void set(map<std::string, std::string> headers)

向響應中添加一組header。

void remove(std::string_view field)

將響應中對應field的header刪除。

void redirect(string url)

重定向到對應url,默認status爲302,若修改默認的302則在redirect前調用status。

void type(string content_type)

設置響應體的類型。

void length(std::uint64_t content_length)

設置響應體的長度。若爲chunked類型響應,則此項不設置。

bool has_body() const

響應中是否已經設置body。

void body(string body)

設置響應體,std::string類型。

void body(const char* buffer, std::size_t size)

設置響應體,傳入buffer和buffer大小。

std::ostream& body()

獲取響應體流操作對象(std::ostream),用於以流的方式設置響應體,調用接口時發送響應header,流操作時發送響應體。

response.body() << "hello cuehttp";

cue::http::websocket

void on_open(std::function<void()> func)

設置WebSocket連接建立回調。

void on_close(std::function<void()> func)

設置WebSocket連接關閉回調。

void on_message(std::function<void(std::string&&)> func)

設置WebSocket連接消息回調。

void send(string msg, [ws_send::options options])

向客戶端發送消息。options同[options](#void broadcast(std::string_view msg, [ws_send::options options]))。

void close()

向客戶端發送關閉WebSocket連接消息。

cue::http::cookies

std::string_view get(std::string_view name) const

獲取請求中攜帶的cookie的值,無則返回空。

void set(string name, string value, [cookie::options options])

添加響應的Set-Cookie頭,每調用一次添加一個。name/value爲空則cookie無效。

cookie::options 類型 描述 默認值
max_age int cookie過期時間(單位秒),-1則不設置max-age -1
expires std::string cookie過期日期(GMT格式),與max-age同時設置時以max-age爲準
path std::string 可以訪問此cookie的頁面路徑
domain std::string 可以訪問此cookie的域名
secure bool 設置是否只能通過https來傳遞此cookie false
http_only bool 是否只能通過http訪問此cookie false

const std::vector<cue::http::cookie>& get() const

獲取設置給響應的所有cookie。

cue::http::cookie

std::string_view get(std::string_view name) const

獲取cookie的值,無則返回空。

void set(string name, string value, [cookie::options options])

設置cookie。options同[options](#void set(string name, string value, [cookie::options options]))。

std::string_view name() const

獲取cookie的鍵,無則返回空。

void name(string name)

設置cookie的鍵。

std::string_view value() const

獲取cookie的值,無則返回空。

void value(string value)

設置cookie的值。

int max_age() const

獲取cookie過期時間,無則返回-1。

void max_age(int max_age)

設置cookie過期時間。

std::string_view expires() const

獲取cookie過期日期,無則返回空。

void expires(string date)

設置cookie過期日期。

std::string_view path() const

獲取cookie允許的路徑,默認返回"/"。

void path(string path)

設置cookie允許的路徑。

std::string_view domain() const

獲取cookie允許的域名。

void domain(string domain)

設置cookie允許的域名。

bool secure() const

獲取是否只能通過https來傳遞此cookie。

void secure(bool secure)

設置是否只能通過https來傳遞此cookie。

bool http_only() const

獲取是否只能通過http訪問此cookie。

void http_only(bool http_only)

設置是否只能通過http訪問此cookie。

內置中間件

router

默認的cuehttp的server是不包含HTTP/WebSocket路由功能的,所有的HTTP請求都將回調註冊的中間件,router是cuehttp默認的路由中間件,router會根據註冊的HTTP method和path進行請求分發。router支持配置多種method、multiple、redirect等。router也可用於WebSocket server。

示例

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    router route;
    route.get("/get", [](context& ctx) {
        ctx.type("text/html");
        ctx.body(R"(<h1>Hello, cuehttp!</h1>)");
    });

    cuehttp app;
    app.use(route.routes());

    router ws_route;
    app.ws().use(ws_route.all("/ws", [](context& ctx) {
        ctx.websocket().on_open([&ctx]() {
            std::cout << "websocket on_open" << std::endl;
            ctx.websocket().send("hello");
        });
        ctx.websocket().on_close([]() { std::cout << "websocket on_close" << std::endl; });
        ctx.websocket().on_message([&ctx](std::string&& msg) {
            std::cout << "websocket msg: " << msg << std::endl;
            ctx.websocket().send(std::move(msg));
        });
    }));

    app.listen(10000).run();

    return 0;
}

API

router([string prefix])

創建router,可選prefix,默認prefix爲空。

router& prefix(string prefix)

設置prefix。

std::function<void(context&)> routes() const

生成router中間件註冊函數。

示例:

cue::http::cuehttp app;
cue::http::router route;
app.use(route.routes());
router& del|get|head|post|put|all(std::string_view path, …)

註冊對應method和path的處理函數,支持普通函數、類成員函數、operator()、std::function、lambda、multiple。

注:multiple中若參數包含next函數,需手動調用next函數,否則無法執行下游處理函數,最後一個不影響。無next參數的自動調用。

all接口將註冊所有支持的method。

示例:

void f1(context& ctx) {
    std::cout << "f1" << std::endl;
}

void f2(context& ctx, std::function<void()> next) {
    std::cout << "f2" << std::endl;
    next();
}

struct handler1 {
    void handle(context& ctx) {
        std::cout << "handler1::handle" << std::endl;
    }
};

struct handler2 {
    void handle(context& ctx, std::function<void()> next) {
        std::cout << "handler2::handle" << std::endl;
        next();
    }
};

struct operator1 {
    void operator()(context& ctx) {
        std::cout << "operator1" << std::endl;
    }
};

struct operator2 {
    void operator()(context& ctx, std::function<void()> next) {
        std::cout << "operator2" << std::endl;
        next();
    }
};

route.get("/get1", [](context& ctx) {
    ctx.type("text/html");
    ctx.body(R"(<h1>Hello, cuehttp!</h1>)");
});

route.post("/post", [](context& ctx, std::function<void()> next) {
    std::cout << "handle post: " << ctx.path() << std::endl;
    ctx.type("text/html");
    ctx.body(R"(<h1>Hello, cuehttp!</h1>)");
});

route.get("/get2", f1);
route.get("/get3", f2);

handler1 h1;
route.get("/get4", &handler1::handle, &h1);
route.get("/get5", &handler1::handle);

handler2 h2;
route.get("/get6", &handler2::handle, &h2);
route.get("/get7", &handler2::handle);

operator1 o1;
route.get("/get8", o1);

operator1 o2;
route.get("/get9", o2);

// multiple
route.get(
    "/get_multiple1",
    [](context& ctx, std::function<void()> next) {
        std::cout << "befor get" << std::endl;
        next();
    },
    [](context& ctx, std::function<void()> next) {
        std::cout << "handle get: " << ctx.path() << std::endl;
        ctx.type("text/html");
        ctx.body(R"(<h1>Hello, cuehttp!</h1>)");
        next();
    },
    [](context& ctx, std::function<void()> next) {
        std::cout << "after get" << std::endl;
    });

route.get(
    "/get_multiple2",
    [](context& ctx, std::function<void()> next) {
        std::cout << "befor get" << std::endl;
        next();
        std::cout << "after get" << std::endl;
    },
    [](context& ctx) {
        std::cout << "handle get: " << ctx.path() << std::endl;
        ctx.type("text/html");
        ctx.body(R"(<h1>Hello, cuehttp!</h1>)");
    });

handler1 hr1;
handler2 hr2;

route.get("/get_multiple3", &handler2::handle, &hr2, &handler2::handle,
          [](context& ctx) { std::cout << "after get" << std::endl; });

route.get("/get_multiple4", &handler2::handle, &handler1::handle, &hr1,
          [](context& ctx) { std::cout << "after get" << std::endl; });

route.get(
    "/get_multiple5", [](context& ctx) { std::cout << "befor get" << std::endl; },
    [](context& ctx) {
        std::cout << "handle get: " << ctx.path() << std::endl;
        ctx.type("text/html");
        ctx.body(R"(<h1>Hello, cuehttp!</h1>)");
    },
    [](context& ctx) { std::cout << "after get" << std::endl; });
router& redirect(std::string_view path, string destination, [unsigned status])

重定向接口,將path重定向到destination。默認status爲301。

相當於:

route.all(path, [](context& ctx) {
    ctx.redirect(destination);
    ctx.status(301);
});

session

cuehttp提供了簡單的session中間件。默認使用cookie進行session交互與管理。支持配置外部存儲來管理session,如redis、DB等。

示例

每訪問一次/test_session,頁面的數字就加一。

#include <iostream>

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    router route;
    route.get("/test_session", [](context& ctx) {
        int view{1};
        const auto view_str = ctx.session().get("view");
        if (view_str.empty()) {
            ctx.session().set("view", std::to_string(view));
        } else {
            view = std::stoi(view_str);
            ctx.session().set("view", std::to_string(view + 1));
        }
        ctx.type("text/html");
        ctx.body(R"(<h1>Hello, )" + std::to_string(view) + R"( cuehttp!</h1>)");
        ctx.status(200);
    });

    session::options session_opt;
    session_opt.key = "cuehttp";
    // session_opt.external_key.get = [](context& ctx) {
    //     std::cout << "external_key.get" << std::endl;
    //     return ctx.get("User-Token");
    // };
    // session_opt.external_key.set = [](context& ctx, std::string_view value) {
    //     std::cout << "external_key.set" << std::endl;
    //     return ctx.set("User-Token", value);
    // };
    // session_opt.external_key.destroy = [](context& ctx, std::string_view value) {
    //     std::cout << "external_key.destroy" << std::endl;
    //     return ctx.remove("User-Token");
    // };
    cuehttp app;
    app.use(use_session(std::move(session_opt)));
    app.use(route.routes());

    app.listen(10000).run();

    return 0;
}

API

session::options
session::options 類型 描述 默認值
key std::string 用作session傳遞cookie的key cuehttp
max_age int session傳遞使用cookie的max-age,單位秒,默認一天的秒數。若置爲-1時,則cookie不設置max-age
auto_commit bool session的header更新是否自動提交 true
store session::store_t 用於配置外部存儲的操作
external_key session::external_key_t 用於配置外部管理key的管理
genid std::function<std::string()> 外部提供key生成器,默認使用uuid
prefix std::string 用於生成外部管理key的prefix
session::store_t

用於session的外部操作,若store不設置則默認時用cookie進行交互。get、set、destroy需要同時配置。

std::functionstd::string(std::string_view) get

傳入key,返回對應session的值。

std::function<void(std::string_view, std::string_view, std::uint32_t)> set

傳入key、value、過期時間(單位秒)來設置session。

std::function<void(std::string_view)> destroy

傳入key,刪除對應session的外部存儲。

session::external_key_t

用於外部提供key管理。若未配置則使用cookie管理。

std::function<std::string(context&)> get

獲取對應HTTP會話外部提供的key。

std::function<void(context&, std::string_view)> set

設置對應HTTP會話的key。

std::function<void(context&, std::string_view)> destroy

刪除對應HTTP會話的key。

gzip

使用gzip壓縮HTTP body。使用gzip需要開啓ENABLE_GZIP宏,並依賴zlib。

示例

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    cuehttp app;
    app.use(use_compress());
    app.use([](context& ctx) {
        ctx.type("text/html");
        ctx.body(R"(<h1>Hello cuehttp!</h1>)");
        ctx.status(200);
    });
    app.listen(10000).run();

    return 0;
}

API

compress::options
compress::options 類型 描述 默認值
threshold std::uint64_t 配置body使用gzip壓縮的臨界字節大小 2048
level int 壓縮等級 8
bool compress::deflate(std::string_view src, std::string& dst, int level = 8)

內容壓縮接口。

send_file

cuehttp的靜態文件發送中間件。爲cuehttp提供離線文件請求支持。

示例

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    router route;
    // 當請求http://ip:port/cpp.pptx時返回C:/Users/xcyl/Desktop/cpp11.pptx
    route.get("/cpp.pptx", [](context& ctx) {
        send::options opt;
        opt.root = "C:/Users/xcyl/Desktop/";
        send_file(ctx, "cpp11.pptx", opt);
    });

    // 當請求http://ip:port/book時返回C:/Users/xcyl/Desktop/C++Templates.pdf
    route.get("/book", [](context& ctx) {
        send_file(ctx, "C:/Users/xcyl/Desktop/C++Templates.pdf");
    });

    cuehttp app;
    app.use(route.routes());
    app.listen(10000).run();

    return 0;
}

API

void send_file(context& ctx, string path, [send::options options])

傳入HTTP會話context對象,需要發送的文件或目錄。options爲可選的,當options不使用時path需要配置文件全路徑。傳遞options時,path可以爲文件或目錄。

send::options
send::options 類型 描述 默認值
root std::string 配置發送文件的根目錄
hidden bool 是否支持目錄中的隱藏文件發送,認爲.開頭的目錄以及文件是隱藏的 false
index std::string 配置目錄訪問的默認文件
extensions std::vector<std::string> 配置目錄中的文件訪問匹配擴展名,按照內部順序進行優先匹配
chunked_threshold std::size_t 文件發送Transfer-Encoding是否使用chunked,當大於此值時使用chunked,否則不配置chunked 5,242,880(5MB大小)
cross_domain bool 是否允許跨域,允許跨域時添加允許跨域header。
Access-Control-Allow-Origin: * Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: GET,POST,OPTIONS
false
threshold std::uint64_t 配置body使用gzip壓縮的臨界字節大小 2048
level int 壓縮等級 8

static

基於send_file中間件的靜態文件訪問中間件。

示例

#include <cuehttp.hpp>

using namespace cue::http;

int main(int argc, char** argv) {
    cuehttp app;
    app.use(use_static("C:/Users/xcyl/Desktop"));

    app.listen(10000).run();

    return 0;
}

API

std::function<void(context&, std::function<void()>)> use_static(string root, [static_file::options options])

生成靜態文件訪問中間件,root爲指定目錄,靜態文件訪問的根目錄,options爲相關配置(可選)。

static_file::options
static_file::options 類型 描述 默認值
hidden bool 是否支持目錄中的隱藏文件發送,認爲.開頭的目錄以及文件是隱藏的 false
delay bool 此中間件是否延遲執行,true爲延遲爲下游中間件執行後執行,否則先執行此中間件再執行下游中間件 false
index std::string 配置目錄訪問的默認文件 index.html
extensions std::vector<std::string> 配置目錄中的文件訪問匹配擴展名,按照內部順序進行優先匹配
cross_domain bool 是否允許跨域,允許跨域時添加允許跨域header。
Access-Control-Allow-Origin: * Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: GET,POST,OPTIONS
false
threshold std::uint64_t 配置body使用gzip壓縮的臨界字節大小 2048
level int 壓縮等級 8
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章