Пример #1
0
void http_client::fprint_header(ostream& out, const char* prompt)
{
	ACL_VSTREAM* fp = out.get_vstream();
	if (fp == NULL)
	{
		logger_error("fp stream null");
		return;
	}
	if (hdr_res_)
		http_hdr_fprint(fp, &hdr_res_->hdr, prompt ? prompt : "dummy");
	else if (hdr_req_)
		http_hdr_fprint(fp, &hdr_req_->hdr, prompt ? prompt : "dummy");
}
Пример #2
0
bool CMsnContactManager::GetAddresses(const CMsnTicket& ticket,
	acl::http_client& client)
{
	acl::string request_body;
	if (BuildGetAddressRequest(ticket, request_body) == false)
		return (false);

	///////////////////////////////////////////////////////////////////////
	// 向 MSN CONTACT 服务器发送请求数据

	// 创建 HTTP 请求头

	acl::http_header header;
	header.set_method(acl::HTTP_METHOD_POST);
	header.set_url(MSN_ADDRESS_BOOK_POST_URL);
	header.set_content_type("text/xml; charset=utf-8");
	header.set_host(MSN_CONTACT_SERVER);
	header.set_content_length(request_body.length());
	header.set_keep_alive(false);
	header.add_entry("SOAPAction", MSN_GET_ADDRESS_SOAP_ACTION);
	header.add_entry("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
	header.add_entry("Accept", "*/*");
	header.add_entry("Cache-Control", "no-cache");
	header.accept_gzip(true);

	// 发送 HTTP 请求头

	acl::string header_buf;
	header.build_request(header_buf);

	// 记录发送头
	logger_format("send header: %s\r\n", header_buf.c_str());

	if (client.get_ostream().write(header_buf) == -1)
	{
		logger_error("write http header error");
		return (false);
	}

	// 发送 HTTP 请求体

	// 记录发送体
	logger_format("send body: %s\r\n", request_body.c_str());

	if (client.get_ostream().write(request_body) == -1)
	{
		logger_error("write http body error");
		return (false);
	}

	///////////////////////////////////////////////////////////////////////
	// 从 MSN CONTACT 服务器读取响应数据

	if (client.read_head() == false)
	{
		logger_error("read http respond head error");
		return (false);
	}

	const HTTP_HDR_RES* hdr_res = client.get_respond_head(NULL);

	if (debug_fpout_)
		http_hdr_fprint(debug_fpout_, &hdr_res->hdr, "GetAddresses read header: ");

	if (hdr_res->hdr.content_length == 0
		|| (hdr_res->hdr.content_length == -1
		&& !hdr_res->hdr.chunked
		&& hdr_res->reply_status > 300
		&& hdr_res->reply_status < 400))
	{
		logger_error("http respond no body");
		http_hdr_print(&hdr_res->hdr, "error");
		return (false);
	}

	/* 读书 HTTP 响应体 */

	acl::string buf;

	ACL_SLICE_POOL* slice = acl_slice_pool_create(16, 50,
					ACL_SLICE_FLAG_GC2 |
					ACL_SLICE_FLAG_RTGC_OFF |
					ACL_SLICE_FLAG_LP64_ALIGN);
	ACL_XML* body = acl_xml_alloc1(slice);
	int   ret;
	while(true)
	{
		ret = client.read_body(buf);
		if (ret < 0)
			break;
		else if (client.body_finish())
			break;
		acl_xml_update(body, buf.c_str());
		logger_format("read body: %s\r\n", buf.c_str());
	}

	//acl_xml_dump(body, ACL_VSTREAM_OUT);
	ParseAddresses(body);

	///////////////////////////////////////////////////////////////////////

	double j = ACL_METER_TIME("---begin---");
	//acl_xml_free(body);
	acl_slice_pool_destroy(slice);
	double k = ACL_METER_TIME("---end---");
	return (true);
}
Пример #3
0
bool CMsnContactManager::GetContacts(const CMsnTicket& ticket,
	acl::http_client& client)
{
	// 创建请求体
	acl::string request_body;
	if (BuildGetContactRequest(ticket, request_body) == false)
		return (false);

	//////////////////////////////////////////////////////////////////////////
	// 向 MSN CONTACT 服务器发送请求数据

	// 创建 HTTP 请求头
	acl::http_header header;
	header.set_method(acl::HTTP_METHOD_POST);
	header.set_url(MSN_GET_CONTACT_POST_URL);
	header.set_host(MSN_CONTACT_SERVER);
	header.set_content_length(request_body.length());
	header.set_content_type("text/xml; charset=utf-8");
	header.set_keep_alive(false);
	header.add_entry("SOAPAction", MSN_GET_CONTACT_SOAP_ACTION);
	header.add_entry("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
	header.add_entry("Accept", "*/*");
	header.add_entry("Cache-Control", "no-cache");
	// 现在ACL_CPP的压缩库仅支持HTTP传输中的GZIP方式
	header.accept_gzip(true);

	// 发送 HTTP 请求头

	acl::string header_buf;
	header.build_request(header_buf);

	// 记日志
	logger_format("send: %s\r\n", header_buf.c_str());

	if (client.get_ostream().write(header_buf) == -1)
	{
		logger_error("write http header error");
		return (false);
	}

	// 发送 HTTP 请求体

	// 记录发送体
	logger_format("send: %s\r\n", request_body.c_str());

	if (client.get_ostream().write(request_body) == -1)
	{
		logger_error("write http body error");
		return (false);
	}

	//////////////////////////////////////////////////////////////////////////
	// 从 MSN CONTACT 服务器读取响应数据

	if (client.read_head() == false)
	{
		logger_error("read http respond head error");
		return (false);
	}

	const HTTP_HDR_RES* hdr_res = client.get_respond_head(NULL);
	acl_assert(hdr_res);

	// 记录响应头
	if (debug_fpout_)
		http_hdr_fprint(debug_fpout_, &hdr_res->hdr, "GetContacts read hdr: ");

	// 如果没有数据体,则认为失败
	if (hdr_res->hdr.content_length == 0
		|| (hdr_res->hdr.content_length == -1
		&& !hdr_res->hdr.chunked
		&& hdr_res->reply_status > 300
		&& hdr_res->reply_status < 400))
	{
		logger_error("http respond no body");
		http_hdr_print(&hdr_res->hdr, "error");
		return (false);
	}

	/* 读书 HTTP 响应体 */

	ACL_XML* body = acl_xml_alloc();
	int   ret;
	acl::string plain;

	acl::ofstream fp;
	fp.open_write("zip_list.text");

	int  len = 0;
	while(true)
	{
		// 读 HTTP 响应数据体
		ret = client.read_body(plain);
		if (ret < 0)
			break;
		else if (client.body_finish())
			break;
		fp.write(plain);
		acl_xml_update(body, plain.c_str());
	}

	//acl_xml_dump(body, ACL_VSTREAM_OUT);
	// 分析联系人列表
	if (ParseContacts(body) == false)
	{
		acl_xml_free(body);
		return (false);
	}

	acl_xml_free(body);
	return (true);
}
Пример #4
0
static void get_url(const char *method, const char *url,
	const char *proxy, const char *dump)
{
	/* 创建 HTTP 请求头 */
	HTTP_HDR_REQ *hdr_req = http_hdr_req_create(url, method, "HTTP/1.1");
	ACL_VSTREAM *stream;
	ACL_VSTRING *buf = acl_vstring_alloc(256);
	HTTP_HDR_RES *hdr_res;
	HTTP_RES *res;
	ACL_FILE *fp = NULL;
	const char *ptr;
	int   ret;

	/* 输出 HTTP 请求头内容 */

	http_hdr_print(&hdr_req->hdr, "---request hdr---");

	/* 如果设定代理服务器,则连接代理服务器地址,
	 * 否则使用 HTTP 请求头里指定的地址
	 */

	if (*proxy)
		acl_vstring_strcpy(buf, proxy);
	else
		acl_vstring_strcpy(buf, http_hdr_req_host(hdr_req));

	/* 获得远程 HTTP 服务器的连接地址 */

	ptr = acl_vstring_memchr(buf, ':');
	if (ptr == NULL)
		acl_vstring_strcat(buf, ":80");
	else {
		int   port;
		ptr++;
		port = atoi(ptr);
		if (port <= 0 || port >= 65535) {
			printf("http server's addr(%s) invalid\n", acl_vstring_str(buf));
			acl_vstring_free(buf);
			http_hdr_req_free(hdr_req);
			return;
		}
	}

	/* 连接远程 http 服务器 */

	stream = acl_vstream_connect(acl_vstring_str(buf) /* 服务器地址 */,
			ACL_BLOCKING /* 采用阻塞方式 */,
			10 /* 连接超时时间为 10 秒 */,
			10 /* 网络 IO 操作超时时间为 10 秒 */,
			4096 /* stream 流缓冲区大小为 4096 字节 */);
	if (stream == NULL) {
		printf("connect addr(%s) error(%s)\n",
			acl_vstring_str(buf), acl_last_serror());
		acl_vstring_free(buf);
		http_hdr_req_free(hdr_req);
		return;
	}

	/* 构建 HTTP 请求头数据 */

	http_hdr_build_request(hdr_req, buf);

	/* 向 HTTP 服务器发送请求 */

	ret = acl_vstream_writen(stream, acl_vstring_str(buf), ACL_VSTRING_LEN(buf));
	if (ret == ACL_VSTREAM_EOF) {
		printf("write to server error(%s)\n", acl_last_serror());
		acl_vstream_close(stream);
		acl_vstring_free(buf);
		http_hdr_req_free(hdr_req);
		return;
	}

	/* 创建一个 HTTP 响应头对象 */

	hdr_res = http_hdr_res_new();

	/* 读取 HTTP 服务器响应头*/

	ret = http_hdr_res_get_sync(hdr_res, stream, 10 /* IO 超时时间为 10 秒 */);
	if (ret < 0) {
		printf("get http reply header error(%s)\n", acl_last_serror());
		http_hdr_res_free(hdr_res);
		acl_vstream_close(stream);
		acl_vstring_free(buf);
		http_hdr_req_free(hdr_req);
		return;
	}

	if (http_hdr_res_parse(hdr_res) < 0) {
		printf("parse http reply header error\n");
		http_hdr_print(&hdr_res->hdr, "--- reply http header ---");
		http_hdr_res_free(hdr_res);
		acl_vstream_close(stream);
		acl_vstring_free(buf);
		http_hdr_req_free(hdr_req);
		return;
	}

	/* 如果需要转储至磁盘则需要先打开文件 */

	if (dump != NULL) {
		fp = acl_fopen(dump, "w+");
		if (fp == NULL)
			printf("open file(%s) error(%s)\n",
				dump, acl_last_serror());
	}

	/* 如果 HTTP 响应没有数据体则仅输出 HTTP 响应头即可 */

	if (hdr_res->hdr.content_length == 0
		|| (hdr_res->hdr.content_length == -1
			&& !hdr_res->hdr.chunked
			&& hdr_res->reply_status > 300
			&& hdr_res->reply_status < 400))
	{
		if (fp)
			http_hdr_fprint(ACL_FSTREAM(fp), &hdr_res->hdr,
				"--- reply http header ---");
		else
			http_hdr_fprint(ACL_VSTREAM_OUT, &hdr_res->hdr,
				"--- reply http header ---");
		http_hdr_res_free(hdr_res);
		acl_vstream_close(stream);
		acl_vstring_free(buf);
		http_hdr_req_free(hdr_req);
		return;
	}

	/* 输出 HTTP 响应头 */

	http_hdr_print(&hdr_res->hdr, "--- reply http header ---");

	/* 创建 HTTP 响应体对象 */

	res = http_res_new(hdr_res);

	/* 如果有数据体则开始读取 HTTP 响应数据体部分 */
	while (1) {
		http_off_t  n;
		char  buf2[4096];
		
		n = http_res_body_get_sync(res, stream, buf2, sizeof(buf2) - 1);
		if (n <= 0)
			break;

		if (fp) {
			if (acl_fwrite(buf2, (size_t) n, 1, fp) == (size_t) EOF) {
				printf("write to dump file(%s) error(%s)\n",
					dump, acl_last_serror());
				break;
			}
		} else {
			buf2[n] = 0;
			printf("%s", buf2);
		}
	}

	if (fp)
		acl_fclose(fp);
	http_res_free(res);  /* 释放 HTTP 响应对象, hdr_res 会在此函数内部自动被释放 */
	acl_vstream_close(stream);  /* 关闭网络流 */
	acl_vstring_free(buf);  /* 释放内存区 */
	http_hdr_req_free(hdr_req);  /* 释放 HTTP 请求头对象 */
}