acl/lib_acl_cpp/samples/aio/http_client/main.cpp
2019-08-08 18:03:33 +08:00

271 lines
5.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.

#include <iostream>
#include <assert.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"
static acl::atomic_long __aio_refer = 0;
static int __success = 0, __nconnect = 0, __ndestroy = 0, __ndisconnect = 0;
static int __nheader = 0, __ntimeout = 0;
//////////////////////////////////////////////////////////////////////////////
class http_client : public acl::http_aclient
{
public:
http_client(acl::aio_handle& handle, const char* host)
: http_aclient(handle, NULL)
, host_(host)
, debug_(false)
, compressed_(false)
{
++__aio_refer;
}
~http_client(void)
{
printf("delete http_client!\r\n");
if (--__aio_refer == 0) {
printf("%s: stop aio engine now!\r\n", __FUNCTION__);
handle_.stop();
}
}
http_client& enable_debug(bool on)
{
debug_ = on;
return *this;
}
protected:
// @override
void destroy(void)
{
printf("http_client will be deleted!\r\n");
fflush(stdout);
__ndestroy++;
delete this;
}
// @override
bool on_connect(void)
{
printf("--------------- connect server ok ------------\r\n");
fflush(stdout);
printf(">>> begin send_request\r\n");
//this->ws_handshake();
this->send_request(NULL, 0);
__nconnect++;
return true;
}
// @override
void on_disconnect(void)
{
printf("disconnect from server\r\n");
fflush(stdout);
__ndisconnect++;
}
// @override
void on_connect_timeout(void)
{
printf("connect timeout\r\n");
fflush(stdout);
}
// @override
void on_connect_failed(void)
{
printf("connect failed\r\n");
fflush(stdout);
}
// @override
bool on_read_timeout(void)
{
printf("read timeout\r\n");
__ntimeout++;
return false;
}
// @override
bool on_http_res_hdr(const acl::http_header& header)
{
acl::string buf;
header.build_response(buf);
compressed_ = header.is_transfer_gzip();
__nheader++;
if (!debug_) {
return true;
}
printf("-----------%s: response header----\r\n", __FUNCTION__);
printf("[%s]\r\n", buf.c_str());
fflush(stdout);
return true;
}
// @override
bool on_http_res_body(char* data, size_t dlen)
{
if (!debug_) {
return true;
}
if (!compressed_ || this->is_unzip_body()) {
(void) write(1, data, dlen);
} else {
printf(">>>read body: %ld\r\n", dlen);
}
return true;
}
// @override
bool on_http_res_finish(bool success)
{
printf("---------------response over-------------------\r\n");
printf("http finish: keep_alive=%s, success=%s\r\n",
keep_alive_ ? "true" : "false",
success ? "ok" : "failed");
fflush(stdout);
__success++;
return keep_alive_;
}
private:
acl::string host_;
bool debug_;
bool compressed_;
};
static void usage(const char* procname)
{
printf("usage: %s -h[help]\r\n"
" -s server_addr\r\n"
" -k [use kernel event]\r\n"
" -D [if in debug mode, default: false]\r\n"
" -c cocorrent\r\n"
" -t connect_timeout[default: 5]\r\n"
" -i rw_timeout[default: 5]\r\n"
" -U url\r\n"
" -H host\r\n"
" -K [http keep_alive true]\r\n"
" -N name_server[default: 8.8.8.8:53]\r\n"
, procname);
}
int main(int argc, char* argv[])
{
int ch, conn_timeout = 5, rw_timeout = 5, cocurrent = 1;
acl::string addr("pvwu8bubc.bkt.clouddn.com:80"), name_server("8.8.8.8:53");
acl::string host("pvwu8bubc.bkt.clouddn.com"), url("/20160528212429_c2HAm.jpeg");
bool debug = false, kernel_event = false, keep_alive = false;
while ((ch = getopt(argc, argv, "hkKc:s:N:U:H:t:i:D")) > 0) {
switch (ch) {
case 'h':
usage(argv[0]);
return (0);
case 'k':
kernel_event = true;
break;
case 'K':
keep_alive = true;
break;
case 'c':
cocurrent = atoi(optarg);
break;
case 's':
addr = optarg;
break;
case 'N':
name_server = optarg;
break;
case 'U':
url = optarg;
break;
case 'H':
host = optarg;
break;
case 't':
conn_timeout = atoi(optarg);
break;
case 'i':
rw_timeout = atoi(optarg);
break;
case 'D':
debug = true;
break;
default:
break;
}
}
acl::acl_cpp_init();
acl::log::stdout_open(true);
// <20><><EFBFBD><EFBFBD> AIO <20>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
acl::aio_handle handle(kernel_event ? acl::ENGINE_KERNEL : acl::ENGINE_POLL);
//////////////////////////////////////////////////////////////////////
// <20><><EFBFBD><EFBFBD> DNS <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
handle.set_dns(name_server.c_str(), 5);
// <20><>ʼ<EFBFBD><EFBFBD><ECB2BD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6> WEB <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int i = 0; i < cocurrent; i++) {
http_client* conn = new http_client(handle, host);
if (!conn->open(addr, conn_timeout, rw_timeout)) {
printf("connect %s error\r\n", addr.c_str());
fflush(stdout);
delete conn;
return 1;
}
(*conn).enable_debug(debug); // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>õ<EFBFBD><C3B5>Է<EFBFBD>ʽ
conn->unzip_body(true); // <20><><EFBFBD><EFBFBD> HTTP <20>Զ<EFBFBD><D4B6><EFBFBD>ѹ
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Ҳ<EFBFBD>ɽ<EFBFBD><C9BD>˹<EFBFBD><CBB9>̷<EFBFBD><CCB7><EFBFBD> conn->on_connect() <20><>
acl::http_header& head = conn->request_header();
head.set_url(url)
.set_host(host)
.accept_gzip(true)
.set_keep_alive(keep_alive);
if (i > 0) {
continue;
}
acl::string buf;
head.build_request(buf);
printf("---------------request header-----------------\r\n");
printf("[%s]\r\n", buf.c_str());
fflush(stdout);
}
// <20><>ʼ AIO <20>¼<EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (true) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> false <20><><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ټ<EFBFBD><D9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>˳<EFBFBD>
if (!handle.check()) {
break;
}
}
handle.check();
printf("\r\n---------------------------------------------------\r\n");
printf("all over, success=%d, header=%d, timeout=%d, connect=%d, disconnect=%d, destroy=%d\r\n",
__success, __nheader, __ntimeout, __nconnect, __ndisconnect, __ndestroy);
return 0;
}