文章目录

  • 简单的同步HTTP客户端示例
  • 简单的异步HTTP客户端示例
  • 完整的HTTP客户端示例

简单的同步HTTP客户端示例

同步http客户端接口模拟实现了pythonrequests

#include "requests.h"int main() {auto resp = requests::get("http://www.example.com");if (resp == NULL) {printf("request failed!\n");} else {printf("%d %s\r\n", resp->status_code, resp->status_message());printf("%s\n", resp->body.c_str());}resp = requests::post("127.0.0.1:8080/echo", "hello,world!");if (resp == NULL) {printf("request failed!\n");} else {printf("%d %s\r\n", resp->status_code, resp->status_message());printf("%s\n", resp->body.c_str());}return 0;
}

简单的异步HTTP客户端示例

示例代码参考examples/http_client_test.cpp

#include "requests.h"#include "hthread.h" // import hv_gettidstatic void test_http_async_client(int* finished) {printf("test_http_async_client request thread tid=%ld\n", hv_gettid());HttpRequestPtr req(new HttpRequest);req->method = HTTP_POST;req->url = "127.0.0.1:8080/echo";req->headers["Connection"] = "keep-alive";req->body = "this is an async request.";req->timeout = 10;http_client_send_async(req, [finished](const HttpResponsePtr& resp) {printf("test_http_async_client response thread tid=%ld\n", hv_gettid());if (resp == NULL) {printf("request failed!\n");} else {printf("%d %s\r\n", resp->status_code, resp->status_message());printf("%s\n", resp->body.c_str());}*finished = 1;});
}int main() {int finished = 0;test_http_async_client(&finished);// demo wait async ResponseCallbackwhile (!finished) {hv_delay(100);}printf("finished!\n");return 0;
}

完整的HTTP客户端示例

完整的http客户端示例代码参考examples/curl.cpp,模拟实现了curl命令行程序。

测试步骤:

git clone https://github.com/ithewei/libhv.git
cd libhv
make httpd curlbin/httpd -h
bin/httpd -d
#bin/httpd -c etc/httpd.conf -s restart -d
ps aux | grep httpd# http web service
bin/curl -v localhost:8080# http indexof service
bin/curl -v localhost:8080/downloads/# http api service
bin/curl -v localhost:8080/ping
bin/curl -v localhost:8080/echo -d "hello,world!"
bin/curl -v localhost:8080/query?page_no=1\&page_size=10
bin/curl -v localhost:8080/kv   -H "Content-Type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'
bin/curl -v localhost:8080/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}'
bin/curl -v localhost:8080/form -F "user=admin pswd=123456"
bin/curl -v localhost:8080/upload -F "file=@LICENSE"bin/curl -v localhost:8080/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello'
bin/curl -v localhost:8080/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}'
bin/curl -v localhost:8080/test -F 'bool=1 int=123 float=3.14 string=hello'
# RESTful API: /group/:group_name/user/:user_id
bin/curl -v -X DELETE localhost:8080/group/test/user/123

更多HTTP消息使用方式请参考头文件 HttpMessage.h

class HttpMessage {// 设置/获取头部void SetHeader(const char* key, const std::string& value);std::string GetHeader(const char* key, const std::string& defvalue = hv::empty_string);// 添加/获取cookievoid 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 {// 设置/获取methodvoid SetMethod(const char* method);const char* Method();// 设置URLvoid SetUrl(const char* url);// 获取URLconst std::string& Url();// 解析URLvoid ParseUrl();// 获取Hoststd::string Host();// 获取Pathstd::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();
};

Tips:

  • 关于大文件的下载可以参考 examples/wget.cpp,使用Range分片的方式请求下载,方便做下载进度展示,也可做断点续传(中途连接断了或者暂停了可以从文件末尾位置继续下载而不用全部重新下载)。

libhv教程11--创建一个简单的HTTP客户端相关推荐

  1. libhv教程13--创建一个简单的WebSocket客户端

    文章目录 WebSocket简介 WebSocket 产生背景 WebSocket 的定义 WebSocket 握手过程 WebSocket 通信协议 示例代码 js示例代码 c++示例代码 WebS ...

  2. 用C++创建一个简单的FTP客户端

    // MFCAppFtpDlg.cpp: 实现文件 //#include "pch.h" #include "framework.h" #include &qu ...

  3. ROS2入门教程—创建一个简单的订阅者和发布者(C++版)

    ROS2入门教程-创建一个简单的订阅者和发布者(C++版) 1 创建功能包 2 创建发布者节点 3 设置发布者节点依赖项 4 设置发布者节点编译规则 5 创建订阅者 6 编译并运行   节点是通过RO ...

  4. java qq ui界面_java swing 创建一个简单的QQ界面教程

    记录自己用java swing做的第一个简易界面. LoginAction.java package com.QQUI0819; import javax.swing.*; import java.a ...

  5. 【itext学习之路】--1.创建一个简单的pdf文档

    来源:https://blog.csdn.net/tomatocc/article/details/80666011 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文 ...

  6. Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏

    Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏 即使是现在,很多初学游戏开发的同学,在谈到Unity的时候,依然会认为Unity只能用于制作3D游戏的.实际上,Unity在2013年发布 ...

  7. Scott Mitchell 的ASP.NET 2.0数据教程之一: 创建一个数据访问层

    原文 | 下载本教程中的编码例子 | 下载本教程的英文PDF版 导言 作为web开发人员,我们的生活围绕着数据操作.我们建立数据库来存储数据,写编码来访问和修改数据,设计网页来采集和汇总数据.本文是研 ...

  8. Windows下编译TensorFlow1.3 C++ library及创建一个简单的TensorFlow C++程序

    参考:https://www.cnblogs.com/jliangqiu2016/p/7642471.html Windows下编译TensorFlow1.3 C++ library及创建一个简单的T ...

  9. Spring MVC:使用基于Java的配置创建一个简单的Controller

    这是我博客上与Spring MVC相关的第一篇文章. 开端总是令人兴奋的,因此我将尽量简洁明了. Spring MVC允许以最方便,直接和快速的方式创建Web应用程序. 开始使用这项技术意味着需要Sp ...

最新文章

  1. docker常用命令行集锦
  2. Maven一:maven的下载和环境安装以及创建简单的Maven项目
  3. java设计模式教程_Java设计模式教程
  4. Ubuntu10.04下安装SQLite3
  5. 设系统中有三种类型的资源(A,B,C)的五个进程(P1,P2,P3,P4,P5)。A资源的数量为17,B资源的数量为5,C资源的数量为20。在T0时刻系统状态如表所示。
  6. 1.Nginx 简介
  7. 蓝桥杯 java 时间显示
  8. 我太机智了……30条关于数据行业内涵笑话漫画
  9. 电脑键盘为什么无法输入
  10. 你还在用截图工具,获取视频中的图片?
  11. ubuntu19.04下VirtualBox与虚拟机win7共享文件夹
  12. 捣鼓nsq - 安装和运行
  13. Springboot毕业设计毕设作品,人脸识别签到考勤系统设计与实现
  14. 科研工具篇|看完之后能提高你80%的科研工作效率
  15. 【原】在vc中实现获取汉字拼音的首字母 - lixiaosan的专栏 - CSDNBlog
  16. pacman更换中国源
  17. 双人榻榻米床高度一般是多少
  18. 短视频平台翻唱歌曲时用注明原创吗
  19. 每公里配速9分18秒,双足机器人完成5公里慢跑
  20. 干货| 时代在召唤云原生

热门文章

  1. 【HTML】html基本标签-1(文字,列表,图片标签)
  2. Vue3.0 + typescript 高仿网易云音乐 WebApp
  3. [图形学] 基于图像的照明:镜面反射
  4. 米家蓝牙温湿度计2接入树莓派并通过homeassistant显示
  5. 【源码】30ms级 labview二维码实时 检测 识别
  6. 康威生命游戏简易版python_turtle实现
  7. 关于以太坊 雷电网络 的思考
  8. [报错] SyntaxError: Missing parentheses in call to ‘exec‘
  9. 初识阿里云(云计算)--发展历程和技术架构、地域和可用区
  10. 异常点检测isolationforest