当前位置: 首页 > 工具软件 > cpp-netlib > 使用案例 >

cpp-netlib笔记三-Cookie支持测试

乐正秦斩
2023-12-01

Title:cpp-netlib笔记三-Cookie支持测试

Author:Kagula

Date:2017-06-02

Environment:

[1]Boost 1.64

本机安装目录 D:\SDK\boost_1_64_0

[2]Windows10、VS2017 Update2

[3]OpenCL 1.0.2k本机安装目录 

D:\SDK\OpenSSL_1_0_2k_vc2007

[4]CMake 3.8.1

[5]cpp-netlib-0.12.0-final

本机安装目录 D:\SDK\cpp-netlib-0.12.0-final

[6]Python 3.6.1

[7]ActivePerl 5.16

[8]IE11、Chrome 58.0.3029.110 、Postman

Introduction: 

     测试cpp-netlib对Cookie的支持,直接贴代码。 

源码清单

#include <thread>
#include <boost/network/protocol/http/server.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

#include <iostream>
#include <map>
#include <string>
#include <algorithm>
#include <sstream>
#include <iomanip>
using namespace std;

namespace http = boost::network::http;
namespace utils = boost::network::utils;

struct counter_server;
typedef http::server<counter_server> server;

//用来存放每个seesion对应的计数值。
//由于这里的代码目的是做技术可行性分析,所以没做线程同步控制.
map<string, int> g_session;

//在Cookie中标记我们session的key
string g_sessionKey("CSessionID");

//用于为每个session分配不同的编号
unsigned g_sessionIndex = 0;

/*
《http状态码一览表以及HTTP响应的返回头信息(支持跳转》
http://blog.sina.com.cn/s/blog_415bd7070100en9i.html
*/

//
struct counter_server {
	explicit counter_server() {}

	void operator()(server::request const &request,
		server::connection_ptr connection) {

		//找Cookie.
		string cookie;
		for (const auto& header : request.headers) {
			std::string lowerCaseName;
			lowerCaseName.resize(header.name.size());
			std::transform(header.name.begin(), header.name.end(), 
				lowerCaseName.begin(), ::tolower);
			if (lowerCaseName == "cookie")
			{
				cookie = header.value;
				break;
			}//if
		}//for

		 //如果有Cookie,把session id分离出来。
		std::string sessionID;
		if (cookie.empty() == false)
		{
			std::vector<std::string> vecRec;
			boost::split(vecRec, cookie, boost::is_any_of(";"));
			for (unsigned i = 0; i < vecRec.size(); i++)
			{
				std::vector<std::string> vecSub;
				boost::split(vecSub, vecRec[i], boost::is_any_of("="));
				if (vecSub.size() == 2)
				{
					boost::trim_if(vecSub[0], boost::is_any_of("\" \n\r\t'"));
					boost::trim_if(vecSub[1], boost::is_any_of("\" \n\r\t'"));

					if (vecSub[0] == g_sessionKey)
					{
						sessionID = vecSub[1];
						break;
					}
				}//end if
			}//end for
		}//end if

		//如果没有session id,分配一个session id
		if (sessionID.empty()||g_session.find(sessionID)==g_session.end())
		{
			g_sessionIndex++;
			sessionID = std::to_string(g_sessionIndex);

			g_session[sessionID] = 0;
		}

		g_session[sessionID]++;

		string content = [](const std::string &sessionID)->string{
			stringstream ss;
       		ss << "sessionID=" << sessionID << "," << "counter=" << g_session[sessionID];
			return ss.str();
		}(sessionID);
		

		static server::response_header headers[] = {
			{ "Server", "cpp-netlib-0.12.0-final" },
			{ "Connection", "close" },
			{ "Content-Type", "text/plain" },//Content-Type: text/html; charset=UTF-8
			{ "Set-Cookie", "" },
			{ "Content-Length", "0" },
			{ "Access-Control-Allow-Origin", "*" }, //没有这个设定chrome每次会让服务端这个方法进入两次。
			{ "Cache-Control", "no-cache" },
			{ "Date", "Fri, 02 Jun 2017 01:24:55 GMT" }
		};
		stringstream ss;
		ss << g_sessionKey << "=" << sessionID << "; path=/";
		headers[3].value = ss.str();
		//Set-Cookie: lasthandler=1247645572; expires=Wed, 15-Jul-2009 09:12:52 GMT; path=/; domain=yoka.com

		headers[4].value = std::to_string(content.size());

		headers[7].value = []() ->string{
			using namespace boost::gregorian;
			date today(day_clock::universal_day());//获取GMT日期

			const boost::posix_time::ptime now(today,
				boost::posix_time::second_clock::universal_time().time_of_day());
			const boost::posix_time::time_duration td = now.time_of_day();

			stringstream ss;
			ss << today.day_of_week() << ", " << today.day() << " " << today.month() << " " << today.year() << " ";
			ss << setw(2) << setfill('0') << td.hours() << ":";
			ss << setw(2) << setfill('0') << td.minutes() << ":";
			ss << setw(2) << setfill('0') << td.seconds() << " GMT";
			return ss.str();
		}();

		connection->set_status(server::connection::ok);//200
		connection->set_headers(
			boost::make_iterator_range(headers, headers + 8));
		connection->write(content);
	}
};


#ifdef _WIN32
#pragma comment(lib, "cppnetlib-server-parsers.lib")
#endif


int main(int argc, char** argv)
{
	cout << "技术可行性测试!" << endl;
	cout << "通过一个计数器Demo,来测试Cookie的支持!" << endl;

	try {
		counter_server handler;
		server::options options(handler);
		server instance(options.thread_pool(std::make_shared<utils::thread_pool>(4))
			.address("0.0.0.0")
			.port("8080"));
		instance.run();
	}
	catch (std::exception &e) {
		std::cerr << e.what() << std::endl;
	}

	return 0;
}


总结 

通过这个示例,证实cpp-netlib支持session是没有问题的。

 类似资料: