[no ci] fix doc (#683)

This commit is contained in:
saipubw 2024-05-24 11:52:15 +08:00 committed by GitHub
parent 85a0d70bf5
commit ca8f1341bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 59 additions and 59 deletions

View File

@ -332,7 +332,7 @@ void basic_usage() {
coro_http is a C++20 coroutine http(https) library, include server and client, functions: get/post, websocket, multipart file upload, chunked and ranges download etc. [more examples](https://github.com/alibaba/yalantinglibs/blob/main/src/coro_http/examples/example.cpp)
### get/post
```c++
```cpp
#include "ylt/coro_http/coro_http_server.hpp"
#include "ylt/coro_http/coro_http_client.hpp"
using namespace coro_http;
@ -379,7 +379,7 @@ int main() {
```
### websocket
```c++
```cpp
async_simple::coro::Lazy<void> websocket(coro_http_client &client) {
// connect to your websocket server.
bool r = co_await client.async_connect("ws://example.com/ws");
@ -401,7 +401,7 @@ async_simple::coro::Lazy<void> websocket(coro_http_client &client) {
```
### upload/download
```c++
```cpp
async_simple::coro::Lazy<void> upload_files(coro_http_client &client) {
std::string uri = "http://example.com";

View File

@ -332,7 +332,7 @@ void basic_usage() {
coro_http is a C++20 coroutine http(https) library, include server and client, functions: get/post, websocket, multipart file upload, chunked and ranges download etc. [more examples](https://github.com/alibaba/yalantinglibs/blob/main/src/coro_http/examples/example.cpp)
### get/post
```c++
```cpp
#include "ylt/coro_http/coro_http_server.hpp"
#include "ylt/coro_http/coro_http_client.hpp"
using namespace coro_http;
@ -379,7 +379,7 @@ int main() {
```
### websocket
```c++
```cpp
async_simple::coro::Lazy<void> websocket(coro_http_client &client) {
// connect to your websocket server.
bool r = co_await client.async_connect("ws://example.com/ws");
@ -401,7 +401,7 @@ async_simple::coro::Lazy<void> websocket(coro_http_client &client) {
```
### upload/download
```c++
```cpp
async_simple::coro::Lazy<void> upload_files(coro_http_client &client) {
std::string uri = "http://example.com";

View File

@ -4,13 +4,13 @@
coro_http_cient 是yalantinglibgs 的子库yalantinglibs 是header only的下载yalantinglibgs 库之后,在自己的工程中包含目录:
```c++
```cpp
include_directories(include)
include_directories(include/ylt/thirdparty)
```
如果是gcc 编译器还需要设置以启用C++20 协程:
```c++
```cpp
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines")
#-ftree-slp-vectorize with coroutine cause link error. disable it util gcc fix.
@ -20,7 +20,7 @@ coro_http_cient 是yalantinglibgs 的子库yalantinglibs 是header only的
最后在你的工程里引用coro_http_client 的头文件即可:
```c++
```cpp
#include <iostream>
#include "ylt/coro_http/coro_http_client.hpp"
@ -41,7 +41,7 @@ int main() {
## http 同步请求
### http 同步请求接口
```c++
```cpp
/// http header
/// \param name header 名称
/// \param value header 值
@ -91,7 +91,7 @@ resp_data post(std::string uri, std::string content,
### http 同步请求的用法
简单的请求一个网站一行代码即可:
```c++
```cpp
coro_http_client client{};
auto result = client.get("http://www.example.com");
if(result.net_err) {
@ -105,7 +105,7 @@ if(result.status == 200) {
```
请求返回之后需要检查是否有网络错误和状态码如果都正常则可以处理获取的响应body和响应头了。
```c++
```cpp
void test_sync_client() {
{
std::string uri = "http://www.baidu.com";
@ -133,7 +133,7 @@ void test_sync_client() {
## http 异步请求接口
```c++
```cpp
async_simple::coro::Lazy<resp_data> async_get(std::string uri);
async_simple::coro::Lazy<resp_data> async_post(
@ -142,14 +142,14 @@ async_simple::coro::Lazy<resp_data> async_post(
async_get和get 接口参数一样async_post 和 post 接口参数一样只是返回类型不同同步接口返回的是一个普通的resp_data而异步接口返回的是一个Lazy 协程对象。事实上同步接口内部就是调用对应的协程接口用法上接近多了一个co_await 操作。
事实上你可以把任意异步协程接口通过syncAwait 方法同步阻塞调用的方式转换成同步接口以同步接口get 为例:
```c++
```cpp
resp_data get(std::string uri) {
return async_simple::coro::syncAwait(async_get(std::move(uri)));
}
```
同步请求例子:
```c++
```cpp
async_simple::coro::Lazy<void> test_async_client() {
std::string uri = "http://www.baidu.com";
@ -174,7 +174,7 @@ option(CINATRA_ENABLE_SSL "Enable ssl support" OFF)
```
client 只需要调用init_ssl 方法即可之后便可以和之前一样发起https 请求了。
```c++
```cpp
const int verify_none = SSL_VERIFY_NONE;
const int verify_peer = SSL_VERIFY_PEER;
const int verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
@ -190,7 +190,7 @@ const int verify_client_once = SSL_VERIFY_CLIENT_ONCE;
const std::string &sni_hostname = "");
```
```c++
```cpp
#ifdef CINATRA_ENABLE_SSL
void test_coro_http_client() {
coro_http_client client{};
@ -217,7 +217,7 @@ void test_coro_http_client() {
如果host 已经通过请求连接成功之后后面发请求的时候只传入path 而不用传入完整的路径这样可以获得更好的性能coro_http_client 对于已经连接的host当传入path 的时候不会再重复去解析已经解析过的uri。
```c++
```cpp
async_simple::coro::Lazy<void> test_async_client() {
std::string uri = "http://www.baidu.com";
@ -241,7 +241,7 @@ async_simple::coro::Lazy<void> test_async_client() {
## http 重连
当http 请求失败之后这个http client是不允许复用的因为内部的socket 都已经关闭了除非你调用reconnect 去重连host这样就可以复用http client 了。
```c++
```cpp
coro_http_client client1{};
// 连接了一个非法的uri 会失败
r = async_simple::coro::syncAwait(
@ -257,7 +257,7 @@ async_simple::coro::Lazy<void> test_async_client() {
# 其它http 接口
http_method
```c++
```cpp
enum class http_method {
UNKNOW,
DEL,
@ -273,7 +273,7 @@ enum class http_method {
```
coro_http_client 提供了这些http_method 对应的请求接口:
```c++
```cpp
async_simple::coro::Lazy<resp_data> async_delete(
std::string uri, std::string content, req_content_type content_type);
@ -302,7 +302,7 @@ async_simple::coro::Lazy<resp_data> async_trace(std::string uri);
除了http method 对应的接口之外coro_http_client 还提供了常用文件上传和下载接口。
## chunked 格式上传
```c++
```cpp
template <typename S, typename File>
async_simple::coro::Lazy<resp_data> async_upload_chunked(
S uri, http_method method, File file,
@ -317,7 +317,7 @@ chunked 每块的大小默认为1MB如果希望修改分块大小可以通过
multipart 上传有两个接口,一个是一步实现上传,一个是分两步实现上传。
一步上传接口
```c++
```cpp
async_simple::coro::Lazy<resp_data> async_upload_multipart(
std::string uri, std::string name, std::string filename);
```
@ -326,7 +326,7 @@ name 是multipart 里面的name 参数filename 需要上传的带路径的文
一步上传接口适合纯粹上传文件用,如果要上传多个文件,或者既有字符串也有文件的场景,那就需要两步上传的接口。
两步上传接口
```c++
```cpp
// 设置要上传的字符串key-value
bool add_str_part(std::string name, std::string content);
// 设置要上传的文件
@ -337,7 +337,7 @@ async_simple::coro::Lazy<resp_data> async_upload_multipart(std::string uri);
```
两步上传,第一步是准备要上传的字符串或者文件,第二步上传;
```c++
```cpp
std::string uri = "http://127.0.0.1:8090/multipart";
coro_http_client client{};
@ -347,7 +347,7 @@ async_simple::coro::Lazy<resp_data> async_upload_multipart(std::string uri);
```
## chunked 格式下载
```c++
```cpp
async_simple::coro::Lazy<resp_data> async_download(std::string uri,
std::string filename,
std::string range = "");
@ -356,7 +356,7 @@ async_simple::coro::Lazy<resp_data> async_download(std::string uri,
## ranges 格式下载
ranges 下载接口和chunked 下载接口相同需要填写ranges:
```c++
```cpp
coro_http_client client{};
std::string uri = "http://uniquegoodshiningmelody.neverssl.com/favicon.ico";
@ -379,7 +379,7 @@ ranges 按照"m-n,x-y,..." 的格式填写,下载的内容将会保存到文
# http client 配置项
client 配置项:
```c++
```cpp
struct config {
// 连接超时时间默认8 秒
std::optional<std::chrono::steady_clock::duration> conn_timeout_duration;
@ -413,7 +413,7 @@ client 配置项:
```
把config项设置之后调用init_config 设置http client 的参数。
```c++
```cpp
coro_http_client client{};
coro_http_client::config conf{.req_timeout_duration = 60s};
client.init_config(conf);
@ -427,15 +427,15 @@ websocket 的支持需要3步
- 读websocket 数据;
websocket 读数据接口:
```c++
```cpp
async_simple::coro::Lazy<resp_data> read_websocket();
```
websocket 连接服务器接口:
```c++
```cpp
async_simple::coro::Lazy<resp_data> connect(std::string uri);
```
websocket 发送数据接口:
```c++
```cpp
enum opcode : std::uint8_t {
cont = 0,
text = 1,
@ -464,7 +464,7 @@ async_simple::coro::Lazy<resp_data> write_websocket(std::string msg,
websocket 例子:
```c++
```cpp
coro_http_client client;
// 连接websocket 服务器
async_simple::coro::syncAwait(
@ -495,7 +495,7 @@ client 不是线程安全的要确保只有一个线程在调用client
通过多个协程去请求服务端, 每个协程都在内部线程池的某个线程中执行。去请求服务端
```c++
```cpp
std::vector<std::shared_ptr<coro_http_client>> clients;
std::vector<async_simple::coro::Lazy<resp_data>> futures;
for (int i = 0; i < 10; ++i) {
@ -514,7 +514,7 @@ for (auto &item : out) {
## 设置解析http response 的最大header 数量
默认情况下最多可以解析100 个http header如果希望解析更多http header 需要define一个宏CINATRA_MAX_HTTP_HEADER_FIELD_SIZE通过它来设置解析的最大header 数, 在include client 头文件之前定义:
```c++
```cpp
#define CINATRA_MAX_HTTP_HEADER_FIELD_SIZE 200 // 将解析的最大header 数设置为200
```
@ -535,7 +535,7 @@ cmake -DENABLE_SIMD=AARCH64 .. # arm环境下,启用neon指令集
### 快速示例
### 示例1一个简单的hello world
```c++
```cpp
#include "ylt/coro_http/coro_http_client.hpp"
#include "ylt/coro_http/coro_http_server.hpp"
using namespace coro_http;
@ -555,7 +555,7 @@ cmake -DENABLE_SIMD=AARCH64 .. # arm环境下,启用neon指令集
5行代码就可以实现一个简单http服务器了用户不需要关注多少细节直接写业务逻辑就行了。
### 示例2基本用法
```c++
```cpp
#include "ylt/coro_http/coro_http_client.hpp"
#include "ylt/coro_http/coro_http_server.hpp"
using namespace coro_http;
@ -675,7 +675,7 @@ int main() {
```
### 示例3面向切面的http服务器
```c++
```cpp
#include "ylt/coro_http/coro_http_client.hpp"
#include "ylt/coro_http/coro_http_server.hpp"
using namespace coro_http;
@ -743,7 +743,7 @@ int main() {
同时还支持任意字符的RESTful API即示例的第二种RESTful API`"/string/:id/test/:name"`,要获取到对应的参数使用`req.get_query_value`函数即可,其参数只能为注册的变量(如果不为依然运行但是有报错)例子中参数名是id和name要获取id参数调用`req.get_query_value("id")`即可。示例代码运行后,当访问`http://127.0.0.1:8080/string/params_1/test/api_test`时,浏览器会返回`api_test`字符串。
```c++
```cpp
#include "ylt/coro_http/coro_http_client.hpp"
#include "ylt/coro_http/coro_http_server.hpp"
using namespace coro_http;
@ -777,7 +777,7 @@ int main() {
目前支持random, round robin 和 weight round robin三种负载均衡三种算法设置代理服务器时指定算法类型即可。
假设需要代理的服务器有三个,分别是"127.0.0.1:9001", "127.0.0.1:9002", "127.0.0.1:9003"coro_http_server设置路径、代理服务器列表和算法类型即可实现反向代理。
```c++
```cpp
void http_proxy() {
cinatra::coro_http_server web_one(1, 9001);

View File

@ -15,7 +15,7 @@ easylog 是C++17 实现的高性能易用的 header only 日志库,它支持
# 基本用法
```c++
```cpp
// 流式输出
ELOG_INFO << "easylog " << 42;
ELOG(INFO) << "easylog " << 42;
@ -32,7 +32,7 @@ ELOGV(INFO, "easylog %d", 42);
流式输出的ELOG_INFO 等价于ELOG(INFO)。
easylog 定义了如下日志级别:
```c++
```cpp
enum class Severity {
NONE,
TRACE,
@ -58,7 +58,7 @@ easylog 默认不会每次flush 日志可以通过调用API ```easylog::flush
# 输出到文件
easylog 默认会将日志输出到控制台如果希望easylog 将日志输出到文件则需要调用easylog::init 接口做初始化。
```c++
```cpp
/// \param Id 日志实例的唯一id默认为0
/// \param min_severity 最低的日志级别
/// \param filename 日志文件名称
@ -76,7 +76,7 @@ void init_log(Severity min_severity, const std::string &filename = "",
如果日志文件大小达到了max_file_size 旧的日志文件将会被覆盖如果max_files 设置为1当大小达到了max_file_size 时,日志文件会被覆盖。
```c++
```cpp
easylog::init_log(Severity::DEBUG, filename, false, true, 5, 3);
ELOG_INFO << "long string test, long string test";
ELOG_INFO << "long string test, long string test";
@ -90,7 +90,7 @@ ELOG_INFO << "long string test, long string test";
默认的日志实例只有一个如果希望创建更多日志实例则通过唯一的日志ID 来创建新的日志实例。
```c++
```cpp
constexpr size_t Id = 2;
easylog::init_log<Id>(Severity::DEBUG, "testlog.txt");
MELOG_INFO(Id) << "test";

View File

@ -13,7 +13,7 @@ include_directories(include/ylt/thirdparty)
```
写代码的时候包含对应的头文件即可:
```c++
```cpp
#include "ylt/struct_json/json_reader.h"
#include "ylt/struct_json/json_writer.h"
```
@ -25,7 +25,7 @@ gcc9+、clang11+、msvc2019+
# json 序列化/反序列化
序列化需要先定义一个可反射的对象通过REFLECTION 可以轻松定义一个可反射对象。
```c++
```cpp
struct person
{
std::string_view name;
@ -35,7 +35,7 @@ REFLECTION(person, name, age); // 通过这个宏定义元数据让person 成为
```
通过REFLECTION 宏定义元数据之后就可以一行代码实现json 的序列化与反序列化了。
```c++
```cpp
person p = { "tom", 28 };
std::string ss;
@ -54,7 +54,7 @@ assert(p1.name == "tom");
## json 的dom 解析
json 解析也提供了dom 解析接口使用parse 接口时不需要定义json 对应的结构体。
```c++
```cpp
std::string_view str = R"(false)";
struct_json::jvalue val;
struct_json::parse(val, str.begin(), str.end());
@ -73,7 +73,7 @@ CHECK(!b);
# 最佳实践
## 零拷贝的反序列化
通过零拷贝的反序列化,可以完全消除内存分配的开销。
```c++
```cpp
struct some_obj {
std::string_view name;
struct_json::numeric_str age;
@ -109,7 +109,7 @@ void test_view(){
# xml 序列化/反序列化
和json 类似先定义xml 数据对应的结构体再通过to_xml/from_xml 实现序列化和反序列化。
```c++
```cpp
struct some_obj {
std::string_view name;
int age;
@ -134,7 +134,7 @@ void test() {
```
## pretty 格式化xml
```c++
```cpp
struct person {
std::string_view name;
int age;
@ -162,7 +162,7 @@ to_xml 模式输出的xml 字符串在一行如果希望pretty 输出则传tr
## xml 属性解析
```c++
```cpp
struct book_t {
std::string title;
std::string author;
@ -205,7 +205,7 @@ TEST_CASE("test library with attr") {
# 字段别名
一般情况下序列化/反序列化要求定义的结构体字段和被解析字符串如xml 字符串中的标签名称一一对应,比如下面的例子:
```c++
```cpp
struct some_obj {
std::string_view name;
int age;
@ -228,7 +228,7 @@ xml 标签name 和 age 对应的就是结构体some_obj::name, some_obj::age
有时候这个约束对于一些已经存在的结构体可能存在一些不便之处已有的结构体字段名可能和xml 标签名字不相同,这时候可以通过字段别名来保证正确解析。
```c++
```cpp
std::string xml_str = R"(
<?xml version="1.0" encoding="utf-8"?>
<rootnode version="1.0" type="example">
@ -261,7 +261,7 @@ REFLECTION_ALIAS 中需要填写结构体的别名和字段的别名,通过别
# 如何处理私有字段
如果类里面有私有字段在外面定义REFLECTION 宏会出错因为无法访问私有字段这时候把宏定义到类里面即可但要保证宏是public的。
```c++
```cpp
class person {
std::string name;
int age;
@ -272,7 +272,7 @@ public:
# yaml 序列化/反序列化
和jsonxml 类似:
```c++
```cpp
enum class enum_status {
start,
stop,
@ -288,7 +288,7 @@ struct plain_type_t {
REFLECTION(plain_type_t, isok, status, c, hasprice, num, price);
```
```c++
```cpp
// deserialization the structure from the string
std::string str = R"(
isok: false
@ -310,7 +310,7 @@ std::cout << ss << "\n";
# 如何将enum 作为字符串处理
一般情况下enum 将按照int 去处理如果希望将enum 按照字符串名称去处理则需要定义enum_value来做适配。
```c++
```cpp
enum class Status { STOP = 10, START };
struct enum_t {
Status a;