acl/lib_acl_cpp/include/acl_cpp/http/http_download.hpp
2024-07-22 17:07:57 +08:00

128 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "../acl_cpp_define.hpp"
#include "../stdlib/noncopyable.hpp"
namespace acl {
class http_client;
class http_request;
class http_header;
class ACL_CPP_API http_download : public noncopyable {
public:
/**
* 构造函数
* @param url {const char*} 文件在服务器上的 url 地址
* @param addr {const char*} 非空时,设置服务器地址(格式为:
* ip[|domain]:port否则服务器地址从 url 中提取
*/
http_download(const char* url, const char* addr = NULL);
virtual ~http_download();
/**
* 在调用 run 之前可以通过本函数获得请求头对象,便于用户设置
* 自己的请求头字段(但 set_method/set_range 是内部自动设置的)
* @return {http_header*} 返回 NULL 表示输入的 URL 非法
*/
http_header* request_header() const;
/**
* 调用此函数可以获得 http_request 对象,便于设置或查询请求头
* 或返回数据中的参数
* @return {http_request*} 返回 NULL 表示输入的 URL 非法
*/
http_request* request() const;
/**
* 下载文件,当 range_from >= 0 且 range_to >= range_from 时自动
* 采用分段下载方式,否则采用全部下载方式
* @param range_from {acl_int64} 下载起始偏移位置,下标从 0 开始,
* 当该值 >= 0 且 range_to >= 本值时才采用分段下载方式
* @param range_to {acl_int64} 下载结束偏移位置
* @param req_body {const char*} 请求的数据体
* @param len {size_t} req_body 非空时指明其长度
* @return {bool} 下载是否成功,如果返回 true 则表示下载成功,否则
* 可能是输入参数非法,或 URL 不存在,或服务器不支持断点传输,或
* 在下载过程中子类返回 false 禁止继续下载
*/
#if defined(_WIN32) || defined(_WIN64)
bool get(__int64 range_from = -1, __int64 range_to = -1,
const char* req_body = NULL, size_t len = 0);
#else
bool get(long long int range_from = -1, long long int range_to = -1,
const char* req_body = NULL, size_t len = 0);
#endif
/**
* 重置内部请求状态
* @param url {const char*} 非空时则用此 URL 替代构造函数中输入的 URL,
* 否则依然使用构造函数中使用的 url
* @param addr {const char*} 非空时,设置服务器地址(格式为:
* ip[|domain]:port否则服务器地址从 url 中提取
* @return {bool} 返回 false 表示 url 非法
*/
bool reset(const char* url = NULL, const char* addr = NULL);
/**
* 取得由构造函数或 reset 函数输入的 url
* @return {const char*} 返回 NULL 表示输入的 url 非法
*/
const char* get_url() const;
/**
* 取得由构造函数或 reset 函数输入的 url 所得到的服务器地址,格式为:
* ip[|domain]:port
* @return {const char*} 返回 NULL 表示输入的 url 非法
*/
const char* get_addr() const;
protected:
/**
* 当发送完 HTTP 请求数据后,读到 HTTP 服务器响应头后的回调函数
* @param conn {http_client*}
* @return {bool} 若子类返回 false 则停止继续下载
*/
virtual bool on_response(http_client* conn);
/**
* 当得到服务器返回完整文件长度后的回调函数
* @param n {__int64} 完整文件长度
* @return {bool} 若子类返回 false 则停止继续下载
*/
#if defined(_WIN32) || defined(_WIN64)
virtual bool on_length(__int64 n);
#else
virtual bool on_length(long long int n);
#endif
/**
* 下载过程中,边下载边通知子类下载的数据及数据长度
* @param data {const void*} 下载的数据地址
* @param len {size_t} 下载的数据长度
* @return {bool} 若子类返回 false 则停止继续下载
*/
virtual bool on_save(const void* data, size_t len) = 0;
private:
char* url_;
char addr_[128];
http_request* req_;
// 从头开始下载整个文件
bool save_total(const char* body, size_t len);
// 断点下载部分文件
#if defined(_WIN32) || defined(_WIN64)
bool save_range(const char* body, size_t len,
__int64 range_from, __int64 range_to);
#else
bool save_range(const char* body, size_t len,
long long int range_from, long long int range_to);
#endif
// 开始下载
bool save(http_request* req);
};
} // namespace acl