acl  3.5.3.0
http_download.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include "../stdlib/noncopyable.hpp"
4 
5 namespace acl {
6 
7 class http_client;
8 class http_request;
9 class http_header;
10 
12 {
13 public:
14  /**
15  * 构造函数
16  * @param url {const char*} 文件在服务器上的 url 地址
17  * @param addr {const char*} 非空时,设置服务器地址(格式为:
18  * ip[|domain]:port,否则服务器地址从 url 中提取
19  */
20  http_download(const char* url, const char* addr = NULL);
21  virtual ~http_download();
22 
23  /**
24  * 在调用 run 之前可以通过本函数获得请求头对象,便于用户设置
25  * 自己的请求头字段(但 set_method/set_range 是内部自动设置的)
26  * @return {http_header*} 返回 NULL 表示输入的 URL 非法
27  */
28  http_header* request_header() const;
29 
30  /**
31  * 调用此函数可以获得 http_request 对象,便于设置或查询请求头
32  * 或返回数据中的参数
33  * @return {http_request*} 返回 NULL 表示输入的 URL 非法
34  */
35  http_request* request() const;
36 
37  /**
38  * 下载文件,当 range_from >= 0 且 range_to >= range_from 时自动
39  * 采用分段下载方式,否则采用全部下载方式
40  * @param range_from {acl_int64} 下载起始偏移位置,下标从 0 开始,
41  * 当该值 >= 0 且 range_to >= 本值时才采用分段下载方式
42  * @param range_to {acl_int64} 下载结束偏移位置
43  * @param req_body {const char*} 请求的数据体
44  * @param len {size_t} req_body 非空时指明其长度
45  * @return {bool} 下载是否成功,如果返回 true 则表示下载成功,否则
46  * 可能是输入参数非法,或 URL 不存在,或服务器不支持断点传输,或
47  * 在下载过程中子类返回 false 禁止继续下载
48  */
49 #if defined(_WIN32) || defined(_WIN64)
50  bool get(__int64 range_from = -1, __int64 range_to = -1,
51  const char* req_body = NULL, size_t len = 0);
52 #else
53  bool get(long long int range_from = -1, long long int range_to = -1,
54  const char* req_body = NULL, size_t len = 0);
55 #endif
56 
57  /**
58  * 重置内部请求状态
59  * @param url {const char*} 非空时则用此 URL 替代构造函数中输入的 URL,
60  * 否则依然使用构造函数中使用的 url
61  * @param addr {const char*} 非空时,设置服务器地址(格式为:
62  * ip[|domain]:port,否则服务器地址从 url 中提取
63  * @return {bool} 返回 false 表示 url 非法
64  */
65  bool reset(const char* url = NULL, const char* addr = NULL);
66 
67  /**
68  * 取得由构造函数或 reset 函数输入的 url
69  * @return {const char*} 返回 NULL 表示输入的 url 非法
70  */
71  const char* get_url() const;
72 
73  /**
74  * 取得由构造函数或 reset 函数输入的 url 所得到的服务器地址,格式为:
75  * ip[|domain]:port
76  * @return {const char*} 返回 NULL 表示输入的 url 非法
77  */
78  const char* get_addr() const;
79 
80 protected:
81  /**
82  * 当发送完 HTTP 请求数据后,读到 HTTP 服务器响应头后的回调函数
83  * @param conn {http_client*}
84  * @return {bool} 若子类返回 false 则停止继续下载
85  */
86  virtual bool on_response(http_client* conn);
87 
88  /**
89  * 当得到服务器返回完整文件长度后的回调函数
90  * @param n {__int64} 完整文件长度
91  * @return {bool} 若子类返回 false 则停止继续下载
92  */
93 #if defined(_WIN32) || defined(_WIN64)
94  virtual bool on_length(__int64 n);
95 #else
96  virtual bool on_length(long long int n);
97 #endif
98 
99  /**
100  * 下载过程中,边下载边通知子类下载的数据及数据长度
101  * @param data {const void*} 下载的数据地址
102  * @param len {size_t} 下载的数据长度
103  * @return {bool} 若子类返回 false 则停止继续下载
104  */
105  virtual bool on_save(const void* data, size_t len) = 0;
106 
107 private:
108  char* url_;
109  char addr_[128];
110  http_request* req_;
111 
112  // 从头开始下载整个文件
113  bool save_total(const char* body, size_t len);
114 
115  // 断点下载部分文件
116 #if defined(_WIN32) || defined(_WIN64)
117  bool save_range(const char* body, size_t len,
118  __int64 range_from, __int64 range_to);
119 #else
120  bool save_range(const char* body, size_t len,
121  long long int range_from, long long int range_to);
122 #endif
123 
124  // 开始下载
125  bool save(http_request* req);
126 };
127 
128 } // namespace acl
#define ACL_CPP_API