Explorar o código

添加HTTP相关接口文档

ithewei %!s(int64=2) %!d(string=hai) anos
pai
achega
04258102a2
Modificáronse 6 ficheiros con 401 adicións e 13 borrados
  1. 13 8
      README-CN.md
  2. 3 5
      README.md
  3. 77 0
      docs/cn/HttpClient.md
  4. 83 0
      docs/cn/HttpContext.md
  5. 103 0
      docs/cn/HttpMessage.md
  6. 122 0
      docs/cn/HttpServer.md

+ 13 - 8
README-CN.md

@@ -56,7 +56,7 @@
 - SSL/TLS加密通信(可选WITH_OPENSSL、WITH_GNUTLS、WITH_MBEDTLS)
 - HTTP服务端/客户端(支持https http1/x http2 grpc)
 - HTTP支持静态文件服务、目录服务、代理服务、同步/异步API处理函数
-- HTTP支持RESTful风格、URI路由、keep-alive长连接、chunked分块等特性
+- HTTP支持RESTful风格、路由、中间件、keep-alive长连接、chunked分块、SSE等特性
 - WebSocket服务端/客户端
 - MQTT客户端
 
@@ -272,8 +272,7 @@ int main() {
         return ctx->send(ctx->body(), ctx->type());
     });
 
-    HttpServer server;
-    server.registerHttpService(&router);
+    HttpServer server(&router);
     server.setPort(8080);
     server.setThreadNum(4);
     server.run();
@@ -283,9 +282,9 @@ int main() {
 
 **注意**:
 
-上面示例直接运行在`main`主线程,`server.run()`会阻塞当前线程运行,所以`router`和`server`对象不会被析构,
-如使用`server.start()`内部会另起线程运行,不会阻塞当前线程,但需要注意`router`和`server`的生命周期,
-不要定义为局部变量被析构了,可定义为类成员变量或者全局变量,下面的`WebSocket`服务同理。
+上面示例直接运行在`main`主线程,`server.run()`会阻塞当前线程运行,所以`router`和`server`对象不会被析构,<br>
+如使用`server.start()`内部会另起线程运行,不会阻塞当前线程,但需要注意`router`和`server`的生命周期,<br>
+不要定义为局部变量被析构了,可定义为类成员变量或者全局变量,下面的`WebSocket`服务同理。<br>
 
 #### HTTP客户端
 见[examples/http_client_test.cpp](examples/http_client_test.cpp)
@@ -313,6 +312,13 @@ int main() {
 }
 ```
 
+附HTTP相关接口文档:
+
+- [class HttpMessage](docs/cn/HttpMessage.md)
+- [class HttpClient](docs/cn/HttpClient.md)
+- [class HttpServer](docs/cn/HttpServer.md)
+- [class HttpContext](docs/cn/HttpContext.md)
+
 ### WebSocket
 #### WebSocket服务端
 见[examples/websocket_server_test.cpp](examples/websocket_server_test.cpp)
@@ -332,8 +338,7 @@ int main(int argc, char** argv) {
         printf("onclose\n");
     };
 
-    WebSocketServer server;
-    server.registerWebSocketService(&ws);
+    WebSocketServer server(&ws);
     server.setPort(9999);
     server.setThreadNum(4);
     server.run();

+ 3 - 5
README.md

@@ -32,7 +32,7 @@ but simpler api and richer protocols.
 - SSL/TLS support: (via WITH_OPENSSL or WITH_GNUTLS or WITH_MBEDTLS)
 - HTTP client/server (support https http1/x http2 grpc)
 - HTTP supports static service, indexof service, proxy service, sync/async API handler
-- HTTP supports RESTful, URI router, keep-alive, chunked, etc.
+- HTTP supports RESTful, router, middleware, keep-alive, chunked, SSE, etc.
 - WebSocket client/server
 - MQTT client
 
@@ -227,8 +227,7 @@ int main() {
         return ctx->send(ctx->body(), ctx->type());
     });
 
-    HttpServer server;
-    server.registerHttpService(&router);
+    HttpServer server(&router);
     server.setPort(8080);
     server.setThreadNum(4);
     server.run();
@@ -280,8 +279,7 @@ int main(int argc, char** argv) {
         printf("onclose\n");
     };
 
-    WebSocketServer server;
-    server.registerWebSocketService(&ws);
+    WebSocketServer server(&ws);
     server.setPort(9999);
     server.setThreadNum(4);
     server.run();

+ 77 - 0
docs/cn/HttpClient.md

@@ -0,0 +1,77 @@
+```c++
+
+class HttpClient {
+
+    // 设置超时
+    int setTimeout(int timeout);
+
+    // 设置SSL/TLS
+    int setSslCtx(hssl_ctx_t ssl_ctx);
+    // 新建SSL/TLS
+    int newSslCtx(hssl_ctx_opt_t* opt);
+
+    // 清除全部请求头部
+    int clearHeaders();
+    // 设置请求头部
+    int setHeader(const char* key, const char* value);
+    // 删除请求头部
+    int delHeader(const char* key);
+    // 获取请求头部
+    const char* getHeader(const char* key);
+
+    // 设置http代理
+    int setHttpProxy(const char* host, int port);
+    // 设置https代理
+    int setHttpsProxy(const char* host, int port);
+    // 添加不走代理
+    int addNoProxy(const char* host);
+
+    // 同步发送
+    int send(HttpRequest* req, HttpResponse* resp);
+    // 异步发送
+    int sendAsync(HttpRequestPtr req, HttpResponseCallback resp_cb = NULL);
+
+    // 关闭连接 (HttpClient对象析构时会自动调用)
+    int close();
+
+};
+
+namespace requests {
+
+    // 同步请求
+    Response request(Request req);
+    Response request(http_method method, const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders);
+
+    // 上传文件
+    Response uploadFile(const char* url, const char* filepath, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders);
+
+    // 通过 `multipart/form-data` 格式上传文件
+    Response uploadFormFile(const char* url, const char* name, const char* filepath, std::map<std::string, std::string>& params = hv::empty_map, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders);
+
+    // 下载文件 (更详细的断点续传示例代码见`examples/wget.cpp`)
+    size_t downloadFile(const char* url, const char* filepath, download_progress_cb progress_cb = NULL);
+
+    // HEAD 请求
+    Response head(const char* url, const http_headers& headers = DefaultHeaders);
+
+    // GET 请求
+    Response get(const char* url, const http_headers& headers = DefaultHeaders);
+
+    // POST 请求
+    Response post(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders);
+
+    // PUT 请求
+    Response put(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders);
+
+    // PATCH 请求
+    Response patch(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders);
+
+    // DELETE 请求
+    Response Delete(const char* url, const http_headers& headers = DefaultHeaders);
+
+    // 异步请求
+    int async(Request req, ResponseCallback resp_cb);
+
+}
+
+```

+ 83 - 0
docs/cn/HttpContext.md

@@ -0,0 +1,83 @@
+```c++
+
+class HttpContext {
+
+    /* 获取请求信息 */
+    // 获取客户端IP
+    std::string ip();
+    // 获取客户端端口
+    int port();
+    // 获取请求method
+    http_method method();
+    // 获取请求url
+    std::string url();
+    // 获取请求path
+    std::string path();
+    // 获取请求host
+    std::string host();
+    // 获取请求头部
+    const http_headers& headers();
+    std::string header(const char* key, const std::string& defvalue = hv::empty_string);
+    // 获取请求参数
+    const hv::QueryParams& params();
+    std::string param(const char* key, const std::string& defvalue = hv::empty_string);
+    // 获取请求cookie
+    const HttpCookie& cookie(const char* name);
+    // 获取请求 `Content-Length`
+    int length();
+    // 获取请求 `Content-Type`
+    http_content_type type();
+    // 判断请求 `Content-Type`
+    bool is(http_content_type content_type);
+    // 获取请求body
+    std::string& body();
+    // 获取 `application/json` 格式数据
+    const hv::Json& json();
+    // 获取 `multipart/form-data` 格式数据
+    const hv::MultiPart& form();
+    std::string form(const char* name, const std::string& defvalue = hv::empty_string);
+    // 获取 `application/x-www-urlencoded` 格式数据
+    const hv::KeyValue& urlencoded();
+    std::string urlencoded(const char* key, const std::string& defvalue = hv::empty_string);
+    // 根据 `Content-Type` 获取对应格式数据
+    template<typename T>
+    T get(const char* key, T defvalue = 0);
+    std::string get(const char* key, const std::string& defvalue = hv::empty_string);
+
+    /* 设置响应信息 */
+    // 设置响应状态码
+    void setStatus(http_status status);
+    // 设置响应 `Content-Type`
+    void setContentType(http_content_type type);
+    // 设置响应头部
+    void setHeader(const char* key, const std::string& value);
+    // 设置响应cookie
+    void setCookie(const HttpCookie& cookie);
+    // 设置响应body
+    void setBody(const std::string& body);
+    template<typename T>
+    // 根据 `Content-Type` 设置对应格式数据
+    void set(const char* key, const T& value);
+
+    // 发送
+    int send();
+    int send(const std::string& str, http_content_type type = APPLICATION_JSON);
+    // 发送文本数据
+    int sendString(const std::string& str);
+    // 发送二进制数据
+    int sendData(void* data, int len, bool nocopy = true);
+    // 发送文件
+    int sendFile(const char* filepath);
+    // 发送json数据
+    template<typename T>
+    int sendJson(const T& t);
+
+    // 重定向
+    int redirect(const std::string& location, http_status status = HTTP_STATUS_FOUND);
+
+    // 主动关闭连接
+    int close();
+
+};
+
+```

+ 103 - 0
docs/cn/HttpMessage.md

@@ -0,0 +1,103 @@
+```c++
+
+class HttpMessage {
+    // 设置/获取头部
+    void SetHeader(const char* key, const std::string& value);
+    std::string GetHeader(const char* key, const std::string& defvalue = hv::empty_string);
+
+    // 添加/获取cookie
+    void AddCookie(const HttpCookie& cookie);
+    const HttpCookie& GetCookie(const std::string& name);
+
+    // 设置/获取 `Content-Type`
+    void SetContentType(http_content_type type);
+    http_content_type ContentType();
+
+    // 获取 `Content-Length`
+    size_t ContentLength();
+
+    // 填充数据
+    void SetBody(const std::string& body);
+    // 获取数据
+    const std::string& Body();
+    // 解析数据
+    int  ParseBody();
+
+    // 填充/获取 `application/json` 格式数据
+    template<typename T>
+    int Json(const T& t);
+    const hv::Json& GetJson();
+
+    // 填充/获取 `multipart/form-data` 格式数据
+    template<typename T>
+    void SetFormData(const char* name, const T& t);
+    void SetFormFile(const char* name, const char* filepath);
+    std::string GetFormData(const char* name, const std::string& defvalue = hv::empty_string);
+    int SaveFormFile(const char* name, const char* path);
+
+    // 填充/获取 `application/x-www-urlencoded` 格式数据
+    template<typename T>
+    void SetUrlEncoded(const char* key, const T& t);
+    std::string GetUrlEncoded(const char* key, const std::string& defvalue = hv::empty_string);
+
+    // 根据 `Content-Type` 填充对应格式数据
+    template<typename T>
+    void Set(const char* key, const T& value);
+    // 根据 `Content-Type` 获取对应格式数据
+    template<typename T>
+    T Get(const char* key, T defvalue = 0);
+    // 根据 `Content-Type` 获取对应格式数据并转换成字符串
+    std::string GetString(const char* key, const std::string& = "");
+    // 根据 `Content-Type` 获取对应格式数据并转换成Boolean类型
+    bool GetBool(const char* key, bool defvalue = 0);
+    // 根据 `Content-Type` 获取对应格式数据并转换成整型
+    int64_t GetInt(const char* key, int64_t defvalue = 0);
+    // 根据 `Content-Type` 获取对应格式数据并转换成浮点数
+    double GetFloat(const char* key, double defvalue = 0);
+};
+
+// HttpRequest 继承自 HttpMessage
+class HttpRequest : public HttpMessage {
+    // 设置/获取method
+    void SetMethod(const char* method);
+    const char* Method();
+
+    // 设置URL
+    void SetUrl(const char* url);
+    // 获取URL
+    const std::string& Url();
+    // 解析URL
+    void ParseUrl();
+    // 获取Host
+    std::string Host();
+    // 获取Path
+    std::string Path();
+
+    // 设置/获取参数
+    template<typename T>
+    void SetParam(const char* key, const T& t);
+    std::string GetParam(const char* key, const std::string& defvalue = hv::empty_string);
+
+    // 设置代理
+    void SetProxy(const char* host, int port);
+
+    // 设置请求超时
+    void SetTimeout(int sec);
+    // 设置连接超时
+    void SetConnectTimeout(int sec);
+    // 允许重定向
+    void AllowRedirect(bool on = true);
+    // 设置重试
+    void SetRetry(int count = DEFAULT_HTTP_FAIL_RETRY_COUNT,
+                  int delay = DEFAULT_HTTP_FAIL_RETRY_DELAY);
+};
+
+// HttpResponse 继承自 HttpMessage
+class HttpResponse : public HttpMessage {
+    // 状态码
+    http_status status_code;
+    // 状态字符串
+    const char* status_message();
+};
+
+```

+ 122 - 0
docs/cn/HttpServer.md

@@ -0,0 +1,122 @@
+```c++
+
+// HTTP服务类
+class HttpServer {
+
+    // 注册HTTP业务类
+    void registerHttpService(HttpService* service);
+
+    // 设置监听主机
+    void setHost(const char* host = "0.0.0.0");
+    // 设置监听端口
+    void setPort(int port = 0, int ssl_port = 0);
+    // 设置监听文件描述符
+    void setListenFD(int fd = -1, int ssl_fd = -1);
+
+    // 设置IO进程数 (仅`linux`下有效)
+    void setProcessNum(int num);
+    // 设置IO线程数
+    void setThreadNum(int num);
+
+    // 设置SSL/TLS
+    int setSslCtx(hssl_ctx_t ssl_ctx);
+    // 新建SSL/TLS
+    int newSslCtx(hssl_ctx_opt_t* opt);
+
+    // 占用当前线程运行
+    int run(bool wait = true);
+
+    // 不占用当前线程运行
+    int start();
+
+    // 停止服务
+    int stop();
+
+};
+
+// HTTP业务类
+class HttpService {
+
+    // 添加静态资源映射
+    void Static(const char* path, const char* dir);
+
+    // 允许跨越访问
+    void AllowCORS();
+
+    // 开启转发代理
+    void EnableForwardProxy();
+
+    // 添加反向代理映射
+    void Proxy(const char* path, const char* url);
+
+    // 添加中间件
+    void Use(Handler handlerFunc);
+
+    // 添加路由
+    void Handle(const char* httpMethod, const char* relativePath, Handler handlerFunc);
+
+    // 添加`HEAD`路由
+    void HEAD(const char* relativePath, Handler handlerFunc);
+
+    // 添加`GET`路由
+    void GET(const char* relativePath, Handler handlerFunc);
+
+    // 添加`POST`路由
+    void POST(const char* relativePath, Handler handlerFunc);
+
+    // 添加`PUT`路由
+    void PUT(const char* relativePath, Handler handlerFunc);
+
+    // 添加`DELETE`路由
+    void Delete(const char* relativePath, Handler handlerFunc);
+
+    // 添加`PATCH`路由
+    void PATCH(const char* relativePath, Handler handlerFunc);
+
+    // 添加任意`HTTP method`路由
+    void Any(const char* relativePath, Handler handlerFunc);
+
+    // 返回注册的路由路径列表
+    hv::StringList Paths();
+
+    // 处理流程:前处理器 -> 中间件 -> 处理器 -> 后处理器
+    // preprocessor -> middleware -> processor -> postprocessor
+
+    // 数据成员
+    http_handler    preprocessor;   // 前处理器
+    http_handlers   middleware;     // 中间件
+    http_handler    processor;      // 处理器
+    http_handler    postprocessor;  // 后处理器
+    std::string     base_url;       // 基本路径
+    std::string     document_root;  // 文档根目录
+    std::string     home_page;      // 主页
+    std::string     error_page;     // 默认错误页
+    std::string     index_of;       // 目录
+    http_handler    errorHandler;   // 错误处理器
+
+    int proxy_connect_timeout;      // 代理连接超时
+    int proxy_read_timeout;         // 代理读超时
+    int proxy_write_timeout;        // 代理写超时
+
+    int keepalive_timeout;          // 长连接保活超时
+    int max_file_cache_size;        // 最多缓存小文件的数量
+    int file_cache_stat_interval;   // 文件缓存stat间隔,查询文件是否修改
+    int file_cache_expired_time;    // 文件缓存过期时间,过期自动释放
+
+};
+
+/* 几种`handler`处理函数区别说明: */
+
+// 同步`handler`运行在IO线程
+typedef std::function<int(HttpRequest* req, HttpResponse* resp)>                            http_sync_handler;
+
+// 异步`handler`运行在`hv::async`全局线程池,可通过`hv::async::startup`设置线程池属性
+typedef std::function<void(const HttpRequestPtr& req, const HttpResponseWriterPtr& writer)> http_async_handler;
+
+// 上下文`handler`运行在IO线程,你可以很方便的将`HttpContextPtr`智能指针抛到你的消费者线程/线程池去处理
+typedef std::function<int(const HttpContextPtr& ctx)>                                       http_ctx_handler;
+
+// 中间状态`handler`运行在IO线程,用来实现大数据量的边接收边处理
+typedef std::function<int(const HttpContextPtr& ctx, http_parser_state state, const char* data, size_t size)> http_state_handler;
+
+```