// File: /workspace/github_cpp_makefile_star2_O3/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 %r13
pushq %r12
pushq %rbx
subq $0x50, %rsp
movq %rdi, %rbx
leaq 0x40(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0x274fc(%rip), %rsi     # 0x333d3
leaq 0x27500(%rip), %rdx     # 0x333de
leaq 0x30(%rsp), %rdi
callq 0x21ea0
leaq 0x8(%rbx), %r14
leaq 0x30(%rsp), %rsi
movq %r14, %rdi
callq 0x2ff16
movq %rax, %r15
leaq 0x20(%rsp), %r13
movq %r13, -0x10(%r13)
leaq 0x274d3(%rip), %rsi     # 0x333df
leaq 0x274d0(%rip), %rdx     # 0x333e3
leaq 0x10(%rsp), %rdi
callq 0x21ea0
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq 0x305aa
leaq 0xf(%rsp), %rsi
movq %rax, %rdi
callq 0x2ffaa
movq 0x10(%rsp), %rdi
cmpq %r13, %rdi
je 0xbf46
callq 0xa5d0
movq 0x30(%rsp), %rdi
cmpq %r12, %rdi
je 0xbf55
callq 0xa5d0
leaq 0x30(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x27480(%rip), %rsi     # 0x333e4
leaq 0x27482(%rip), %rdx     # 0x333ed
callq 0x21ea0
leaq 0x30(%rsp), %rsi
movq %r14, %rdi
callq 0x2ff16
movq %rax, %r15
leaq 0x10(%rsp), %rdi
movq %r13, (%rdi)
leaq 0x2745f(%rip), %rsi     # 0x333ee
leaq 0x2745b(%rip), %rdx     # 0x333f1
callq 0x21ea0
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq 0x305aa
leaq 0xf(%rsp), %rsi
movq %rax, %rdi
callq 0x3000a
movq 0x10(%rsp), %rdi
cmpq %r13, %rdi
je 0xbfc4
callq 0xa5d0
movq 0x30(%rsp), %rdi
cmpq %r12, %rdi
je 0xbfd3
callq 0xa5d0
leaq 0x30(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x27410(%rip), %rsi     # 0x333f2
leaq 0x27422(%rip), %rdx     # 0x3340b
callq 0x21ea0
leaq 0x30(%rsp), %rsi
movq %r14, %rdi
callq 0x2ff16
movq %rax, %r14
leaq 0x10(%rsp), %rdi
movq %r13, (%rdi)
leaq 0x273e1(%rip), %rsi     # 0x333ee
leaq 0x273dd(%rip), %rdx     # 0x333f1
callq 0x21ea0
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x305aa
leaq 0xf(%rsp), %rsi
movq %rax, %rdi
callq 0x3006a
movq 0x10(%rsp), %rdi
cmpq %r13, %rdi
je 0xc042
callq 0xa5d0
movq 0x30(%rsp), %rdi
cmpq %r12, %rdi
je 0xc051
callq 0xa5d0
leaq 0x30(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x273ac(%rip), %rsi     # 0x3340c
leaq 0x273ad(%rip), %rdx     # 0x33414
callq 0x21ea0
leaq 0x38(%rbx), %rdi
leaq 0x30(%rsp), %rsi
callq 0x2ff16
movq %rax, %r14
leaq 0x10(%rsp), %rdi
movq %r13, (%rdi)
leaq 0x27362(%rip), %rsi     # 0x333ee
leaq 0x2735e(%rip), %rdx     # 0x333f1
callq 0x21ea0
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x305aa
leaq 0xf(%rsp), %rsi
movq %rax, %rdi
callq 0x300ca
movq 0x10(%rsp), %rdi
cmpq %r13, %rdi
je 0xc0c1
callq 0xa5d0
movq 0x30(%rsp), %rdi
cmpq %r12, %rdi
je 0xc0d0
callq 0xa5d0
movq %rbx, %rdi
callq 0x3012a
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
jmp 0xc0fe
jmp 0xc114
jmp 0xc114
jmp 0xc128
jmp 0xc0fe
jmp 0xc114
jmp 0xc114
jmp 0xc128
jmp 0xc0fe
jmp 0xc114
jmp 0xc114
jmp 0xc128
movq %rax, %rbx
movq 0x10(%rsp), %rdi
cmpq %r13, %rdi
je 0xc117
callq 0xa5d0
jmp 0xc117
jmp 0xc114
movq %rax, %rbx
movq 0x30(%rsp), %rdi
cmpq %r12, %rdi
je 0xc12b
callq 0xa5d0
jmp 0xc12b
movq %rax, %rbx
movq %rbx, %rdi
callq 0xaa80
nop