// File: /workspace/github_cpp_makefile_star2_O2/DMLfor[P]TinyWebServer/./Handler.hpp
// Function: void start_server<WebServer::Server<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::execution::any_executor<boost::asio::execution::context_as_t<boost::asio::execution_context&>, boost::asio::execution::detail::blocking::never_t<0>, boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0>>>>>>>(WebServer::Server<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::execution::any_executor<boost::asio::execution::context_as_t<boost::asio::execution_context&>, boost::asio::execution::detail::blocking::never_t<0>, boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0>>>>>>&)
void start_server(SERVER_TYPE &server)
{
	// 向服务器增加请求资源的处理方法
	//
	// 处理访问 /string 的 POST 请求, 返回 POST 的字符串
	server.resource["^/string/?$"]["POST"] = [](std::ostream &response, Request &request)
	{
		// 从 istream 中获得字符串(*request.content)
		stringstream ss;
		// 将请求内容读取到 stringstream
		*request.content >> ss.rdbuf();
		string content = ss.str();
		// 直接返回请求结果
		response << "HTTP/1.1 200 Ok\r\nContent-Length: "<< content.length() << "\r\n\r\n" <<content;
	};
	// 处理访问 /info GET 的请求，返回请求的信息
	server.resource["^/info/?$"]["GET"] = [](ostream &response, Request &request)
	{
		stringstream content_stream;
		content_stream << "<h1>Request:</h1>";
		content_stream << request.method << " " <<request.path << " HTTP/" << request.http_version << "<br>";
		for(auto &header: request.header){
			content_stream << header.first << ": "<<header.second << "<br>";
		}
		//　获得 content_stream 的长度(使用 content.tellp()　获得)
		content_stream.seekp(0, ios::end);

		response << "HTTP/1.1 200 ok\r\nContent-Length: "<< content_stream.tellp() << "\r\n\r\n" << content_stream.rdbuf();
	};
	// 处理访问 /match/[字母+数字组成的字符串] 的 GET 请求，　例如执行 GET /match/abc123,　将返回 abc123
	server.resource["^/match/([0-9a-zA-Z]+)/?$"]["GET"] = [](ostream &response, Request & request)
	{
		string number = request.path_match[1];
		response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
	};
	
	// 处理默认的 GET请求,如果没有其他匹配成功, 则这个匿名函数会被调用
	// 将应答 web/ 目录及其子目录中的文件
	// 默认文件 : index.html
	server.default_resource["^/?(.*)$"]["GET"] = [](ostream &response, Request & request)
	{
		string filename = "web/";

		string path = request.path_match[1];
		
		//　防止使用'..' 来访问 web/　目录外的内容
		size_t last_pos = path.rfind(".");
		size_t current_pos = 0;
		size_t pos;
		while((pos=path.find('.', current_pos)) != string::npos && pos != last_pos)
		{
			current_pos = pos;
			path.erase(pos, 1);
			last_pos --;
		}

		filename += path;
		ifstream ifs;
		//　简单的平台无关的文件或目录检查
		if(filename.find('.') == string::npos)
		{
			if(filename[filename.length()-1] != '/')
				filename += '/';
			filename += "index.html";
		}

		ifs.open(filename, ifstream::in);

		if(ifs)
		{
			ifs.seekg(0, ios::end);
			size_t length = ifs.tellg();

			ifs.seekg(0, ios::beg);
			
			//　文件内容将拷贝到 response-stream 中，不应该用较大的文件
			response << "HTTP/1.1 200 OK\r\nContent-Length: " << length << "\r\n\r\n" << ifs.rdbuf();
			ifs.close();
		}
		else
		{
			// 文件不存在时，返回无法打开文件
			string content = "Could not open file" + filename;

			response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
		}
	};
	// 运行 HTTP 服务器
	server.start();
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x50, %rsp
movq %rdi, %rbx
leaq 0x2109b(%rip), %rsi     # 0x2c3e3
leaq 0x30(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0xa2f0
leaq 0x8(%rbx), %r14
leaq 0x30(%rsp), %rsi
movq %r14, %rdi
callq 0x28f94
movq %rax, %r15
leaq 0x2107d(%rip), %rsi     # 0x2c3ef
leaq 0x10(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0xa2f0
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq 0x295ac
leaq 0xf(%rsp), %rsi
movq %rax, %rdi
callq 0x28ffa
leaq 0x10(%rsp), %rdi
callq 0xa370
leaq 0x30(%rsp), %rdi
callq 0xa370
leaq 0x2103e(%rip), %rsi     # 0x2c3f4
leaq 0x30(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0xa2f0
leaq 0x30(%rsp), %rsi
movq %r14, %rdi
callq 0x28f94
movq %rax, %r15
leaq 0x21022(%rip), %rsi     # 0x2c3fe
leaq 0x10(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0xa2f0
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq 0x295ac
leaq 0xf(%rsp), %rsi
movq %rax, %rdi
callq 0x2903e
leaq 0x10(%rsp), %rdi
callq 0xa370
leaq 0x30(%rsp), %rdi
callq 0xa370
leaq 0x20fe2(%rip), %rsi     # 0x2c402
leaq 0x30(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0xa2f0
leaq 0x30(%rsp), %rsi
movq %r14, %rdi
callq 0x28f94
movq %rax, %r14
leaq 0x20fb8(%rip), %rsi     # 0x2c3fe
leaq 0x10(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0xa2f0
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x295ac
leaq 0xf(%rsp), %rsi
movq %rax, %rdi
callq 0x29082
leaq 0x10(%rsp), %rdi
callq 0xa370
leaq 0x30(%rsp), %rdi
callq 0xa370
leaq 0x20f92(%rip), %rsi     # 0x2c41c
leaq 0x30(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0xa2f0
leaq 0x38(%rbx), %rdi
leaq 0x30(%rsp), %rsi
callq 0x28f94
movq %rax, %r14
leaq 0x20f4d(%rip), %rsi     # 0x2c3fe
leaq 0x10(%rsp), %rdi
leaq 0xd(%rsp), %rdx
callq 0xa2f0
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x295ac
leaq 0xf(%rsp), %rsi
movq %rax, %rdi
callq 0x290c6
leaq 0x10(%rsp), %rdi
callq 0xa370
leaq 0x30(%rsp), %rdi
callq 0xa370
movq %rbx, %rdi
callq 0x2910a
addq $0x50, %rsp
popq %rbx
popq %r14
popq %r15
retq
jmp 0xb518
jmp 0xb529
jmp 0xb529
jmp 0xb538
jmp 0xb518
jmp 0xb529
jmp 0xb529
jmp 0xb538
jmp 0xb518
jmp 0xb529
jmp 0xb529
jmp 0xb538
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0xa370
jmp 0xb52c
jmp 0xb529
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0xa370
jmp 0xb53b
movq %rax, %rbx
movq %rbx, %rdi
callq 0xaac0
nop