2014-11-19 00:06:40 +08:00
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include "http_download.h"
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>̶߳<DFB3>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DOWN_CTX <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
CTX_T_REQ_HDR, // Ϊ HTTP <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
|
|
|
|
|
CTX_T_RES_HDR, // Ϊ HTTP <20><>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD>
|
|
|
|
|
CTX_T_CONTENT_LENGTH, // Ϊ HTTP <20><>Ӧ<EFBFBD><D3A6><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
|
|
|
|
|
CTX_T_PARTIAL_LENGTH, // Ϊ HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
|
|
|
|
|
CTX_T_END
|
|
|
|
|
} ctx_t;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>̶߳<DFB3>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳̽<DFB3><CCBD>մ<EFBFBD><D5B4><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
struct DOWN_CTX
|
|
|
|
|
{
|
|
|
|
|
ctx_t type;
|
|
|
|
|
long long int length;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD>뼶<EFBFBD><EBBCB6>
|
|
|
|
|
static double stamp_sub(const struct timeval *from,
|
|
|
|
|
const struct timeval *sub_by)
|
|
|
|
|
{
|
|
|
|
|
struct timeval res;
|
|
|
|
|
|
|
|
|
|
memcpy(&res, from, sizeof(struct timeval));
|
|
|
|
|
|
|
|
|
|
res.tv_usec -= sub_by->tv_usec;
|
|
|
|
|
if (res.tv_usec < 0)
|
|
|
|
|
{
|
|
|
|
|
--res.tv_sec;
|
|
|
|
|
res.tv_usec += 1000000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res.tv_sec -= sub_by->tv_sec;
|
|
|
|
|
return (res.tv_sec * 1000.0 + res.tv_usec/1000.0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
void http_download::rpc_run()
|
|
|
|
|
{
|
|
|
|
|
acl::http_request req(addr_); // HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Ϣ
|
|
|
|
|
req.request_header().set_url(url_.c_str())
|
|
|
|
|
.set_content_type("text/html")
|
|
|
|
|
.set_host(addr_.c_str())
|
|
|
|
|
.set_method(acl::HTTP_METHOD_GET);
|
|
|
|
|
|
|
|
|
|
req.request_header().build_request(req_hdr_);
|
|
|
|
|
DOWN_CTX* ctx = new DOWN_CTX;
|
|
|
|
|
ctx->type = CTX_T_REQ_HDR;
|
|
|
|
|
rpc_signal(ctx); // ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD> HTTP <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
struct timeval begin, end;;
|
|
|
|
|
gettimeofday(&begin, NULL);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (req.request(NULL, 0) == false)
|
|
|
|
|
{
|
|
|
|
|
logger_error("send request error");
|
|
|
|
|
error_ = false;
|
|
|
|
|
gettimeofday(&end, NULL);
|
|
|
|
|
total_spent_ = stamp_sub(&end, &begin);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
|
|
|
|
|
acl::http_client* conn = req.get_client();
|
|
|
|
|
assert(conn);
|
|
|
|
|
|
|
|
|
|
(void) conn->get_respond_head(&res_hdr_);
|
|
|
|
|
ctx = new DOWN_CTX;
|
|
|
|
|
ctx->type = CTX_T_RES_HDR;
|
|
|
|
|
rpc_signal(ctx); // ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD> HTTP <20><>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
ctx = new DOWN_CTX;
|
|
|
|
|
ctx->type = CTX_T_CONTENT_LENGTH;
|
|
|
|
|
|
|
|
|
|
ctx->length = conn->body_length(); // <20><><EFBFBD><EFBFBD> HTTP <20><>Ӧ<EFBFBD><D3A6><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>峤<EFBFBD><E5B3A4>
|
|
|
|
|
content_length_ = ctx->length;
|
|
|
|
|
rpc_signal(ctx); // ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD> HTTP <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
|
|
|
|
|
|
|
|
|
acl::string buf(8192);
|
|
|
|
|
int real_size;
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
// <20><> HTTP <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int ret = req.read_body(buf, true, &real_size);
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
{
|
|
|
|
|
ctx = new DOWN_CTX;
|
|
|
|
|
ctx->type = CTX_T_END;
|
|
|
|
|
ctx->length = ret;
|
|
|
|
|
rpc_signal(ctx); // ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
ctx = new DOWN_CTX;
|
|
|
|
|
ctx->type = CTX_T_PARTIAL_LENGTH;
|
|
|
|
|
ctx->length = real_size;
|
|
|
|
|
// ֪ͨ<CDA8><D6AA><EFBFBD>̵߳<DFB3>ǰ<EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD>صĴ<D8B5>С
|
|
|
|
|
rpc_signal(ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><D8B9><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
|
|
|
|
gettimeofday(&end, NULL);
|
|
|
|
|
total_spent_ = stamp_sub(&end, &begin);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>̵߳<DFB3> rpc_onover <20><><EFBFBD>̽<EFBFBD><CCBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
http_download::http_download(const char* addr, const char* url,
|
|
|
|
|
rpc_callback* callback)
|
|
|
|
|
: addr_(addr)
|
|
|
|
|
, url_(url)
|
|
|
|
|
, callback_(callback)
|
|
|
|
|
, error_(false)
|
|
|
|
|
, total_read_(0)
|
|
|
|
|
, content_length_(0)
|
|
|
|
|
, total_spent_(0)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD>Ϣ
|
|
|
|
|
void http_download::rpc_onover()
|
|
|
|
|
{
|
|
|
|
|
logger("http download(%s) over, <20><> %I64d <20>ֽڣ<D6BD><DAA3><EFBFBD>ʱ %.3f <20><><EFBFBD><EFBFBD>",
|
|
|
|
|
url_.c_str(), total_read_, total_spent_);
|
|
|
|
|
callback_->OnDownloadOver(total_read_, total_spent_);
|
|
|
|
|
delete this; // <20><><EFBFBD>ٱ<EFBFBD><D9B1><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>̵߳<DFB3>֪ͨ<CDA8><D6AA>Ϣ
|
|
|
|
|
void http_download::rpc_wakeup(void* ctx)
|
|
|
|
|
{
|
|
|
|
|
DOWN_CTX* down_ctx = (DOWN_CTX*) ctx;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3>д<EFBFBD><D0B4><EFBFBD><EFBFBD>IJ<EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>ؽν<D7B6><CEBD>д<EFBFBD><D0B4><EFBFBD>
|
|
|
|
|
|
|
|
|
|
switch (down_ctx->type)
|
|
|
|
|
{
|
|
|
|
|
case CTX_T_REQ_HDR:
|
|
|
|
|
callback_->SetRequestHdr(req_hdr_.c_str());
|
|
|
|
|
break;
|
|
|
|
|
case CTX_T_RES_HDR:
|
|
|
|
|
callback_->SetResponseHdr(res_hdr_.c_str());
|
|
|
|
|
break;
|
|
|
|
|
case CTX_T_CONTENT_LENGTH:
|
|
|
|
|
break;
|
|
|
|
|
case CTX_T_PARTIAL_LENGTH:
|
|
|
|
|
total_read_ += down_ctx->length;
|
|
|
|
|
callback_->OnDownloading(content_length_, total_read_);
|
|
|
|
|
break;
|
|
|
|
|
case CTX_T_END:
|
|
|
|
|
logger("%s: read over", addr_.c_str());
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
logger_error("%s: ERROR", addr_.c_str());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3>ж<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>
|
|
|
|
|
delete down_ctx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|