#include #include #include "lib_acl.h" #include "lib_protocol.h" // http 协议相关 #include "acl_cpp/stream/aio_handle.hpp" #include "acl_cpp/stdlib/string.hpp" #include "acl_cpp/stream/ofstream.hpp" #include "acl_cpp/acl_cpp_init.hpp" #include "acl_cpp/http/http_service.hpp" class http_request : public acl::http_service_request { public: http_request(const char* domain, unsigned short port, acl::aio_handle* handle) : acl::http_service_request(domain, port) , handle_(handle) { read_length_ = 0; } ~http_request(void) { printf("notify aio handle to stop!\r\n"); // 通知异步事件引擎完全退出 handle_->stop(); } protected: ////////////////////////////////////////////////////////////////////////// // 基类虚接口 virtual const acl::string* get_body() { return (NULL); } // 正常读到 HTTP 响应头时的回调接口 virtual void on_hdr(const char* addr, const HTTP_HDR_RES* hdr) { printf(">>server addr: %s, http reply status: %d\n", addr, hdr->reply_status); http_hdr_print(&hdr->hdr, "http reply hdr"); content_length_ = hdr->hdr.content_length; if (content_length_ > 0) { if (out_.open_write("test.exe") == false) printf("create file error(%s)\n", acl_last_serror()); } time(&begin_); } // 正常读 HTTP 响应体时的回调函数 virtual void on_body(const char* data, size_t dlen) { if (data == NULL && dlen == 0) { #ifdef WIN32 printf("\n>> http reply body over, total: %I64d, %I64d\n", content_length_, read_length_); #else printf("\n>> http reply body over, total: %lld, %lld\n", content_length_, read_length_); #endif // 出错后,因为本类对象是动态分配的,所以需要在此处释放 time_t end = time(NULL); printf(">>spent %d seconds\n", (int)(end - begin_)); return; } read_length_ += dlen; http_off_t n = (read_length_ * 100) / content_length_; #ifdef WIN32 printf("%s(%d): n=%I64d%%\r", __FUNCTION__, __LINE__, n); #else printf("%s(%d): n=%lld%%\r", __FUNCTION__, __LINE__, n); #endif if (out_.opened()) out_.write(data, dlen); } // 当请求或响应失败时的回调函数 virtual void on_error(acl::http_status_t errnum) { printf(">> error: %d\n", (int) errnum); // 出错后,因为本类对象是动态分配的,所以需要在此处释放 } virtual void destroy() { delete this; } private: acl::ofstream out_; acl::aio_handle* handle_; http_off_t read_length_; http_off_t content_length_; time_t begin_; }; int main() { #ifdef WIN32 acl::acl_cpp_init(); #endif acl::aio_handle handle(acl::ENGINE_SELECT); acl::http_service* service = new acl::http_service(); // 使消息服务器监听 127.0.0.1 的地址 if (service->open(&handle) == false) { printf(">>open message service error!\n"); printf(">>enter any key to quit\n"); getchar(); return (1); } // 创建 HTTP 请求过程 acl::string domain; domain = "www.hexun.com"; //domain = "192.168.1.229"; //domain = "www.renwou.net"; http_request* req = new http_request(domain.c_str(), 80, &handle); req->set_url("/index.html"); //req->set_url("/download/banmau_install.exe"); req->set_host(domain); req->set_keep_alive(false); req->set_method(acl::HTTP_METHOD_GET); req->add_cookie("x-cookie-name", "cookie-value"); //req->set_redirect(1); // 设置自动重定向的次数限制 // 通知异步消息服务器处理该 HTTP 请求过程 ////////////////////////////////////////////////////////////////////////// //acl::string buf; //req->build_request(buf); //printf("-----------------------------------------------\n"); //printf("%s", buf.c_str()); //printf("-----------------------------------------------\n"); ////////////////////////////////////////////////////////////////////////// service->do_request(req); while (true) { if (handle.check() == false) { printf(">>quit aio process\n"); break; } } printf("delete http service now\r\n"); delete service; printf("delete delay aio stream\r\n"); handle.check(); printf(">>enter any key to exist\n"); getchar(); return (0); }