完全不会做,只能记录一下了。
CXX = g++
EXEC_HTTP = server.http
EXEC_HTTPS = server.https
SOURCE_HTTP = main.http.cpp
SOURCE_HTTPS = main.https.cpp
OBJECTS_HTTP = main.http.o
OBJECTS_HTTPS = main.https.o
LDFLAGS_COMMON = -std=c++2a -O3 -pthread -lboost_system
LDFLAGS_HTTP =
LDFLAGS_HTTPS = -lssl -lcrypto
LPATH_COMMON = -I/usr/include/boost
LPATH_HTTP =
LPATH_HTTPS = -I/usr/local/opt/openssl/include
LLIB_COMMON = -L/usr/lib
LLIB_HTTPS = -L/usr/local/opt/openssl/lib
all:
make http
make https
http:
$(CXX) $(SOURCE_HTTP) $(LDFLAGS_COMMON) $(LDFLAGS_HTTP) $(LPATH_COMMON) $(LPATH_HTTP) $(LLIB_COMMON) $(LLIB_HTTP) -o $(EXEC_HTTP)
https:
$(CXX) $(SOURCE_HTTPS) $(LDFLAGS_COMMON) $(LDFLAGS_HTTPS) $(LPATH_COMMON) $(LPATH_HTTPS) $(LLIB_COMMON) $(LLIB_HTTPS) -o $(EXEC_HTTPS)
clean:
rm -f $(EXEC_HTTP) $(EXEC_HTTPS) *.o
修改2a为17。
shiyanlou:Code/ $ unzip 6.zip [21:48:31]
Archive: 6.zip
inflating: 6/handler.hpp
inflating: 6/main.http.cpp
inflating: 6/main.https.cpp
inflating: 6/Makefile
inflating: 6/server.base.hpp
inflating: 6/server.http.hpp
inflating: 6/server.https.hpp
creating: 6/www/
inflating: 6/www/index.html
inflating: 6/www/test.html
shiyanlou:Code/ $ cd 6 [21:48:35]
shiyanlou:6/ $ make [21:50:39]
make http
make[1]: Entering directory '/home/shiyanlou/Code/6'
g++ main.http.cpp -std=c++17 -O3 -pthread -lboost_system -I/usr/include/boost -L/usr/lib -o server.http
make[1]: Leaving directory '/home/shiyanlou/Code/6'
make https
make[1]: Entering directory '/home/shiyanlou/Code/6'
g++ main.https.cpp -std=c++17 -O3 -pthread -lboost_system -lssl -lcrypto -I/usr/include/boost -I/usr/local/opt/openssl/include -L/usr/lib -L/usr/local/opt/openssl/lib -o server.https
make[1]: Leaving directory '/home/shiyanlou/Code/6'
shiyanlou:6/ $ [21:50:56]
效果如下:
http
稍作修改:?
?
?
?
正则表达式本身,然后根据使用正则表达式的主要需求,通过一个实际的例子介绍了正则表达式库的使用。
习题
-
在 Web 服务器开发中,我们通常希望服务某些满足某个条件的路由。正则表达式便是完成这一目标的工具之一。
给定如下请求结构:
struct Request {
? ?// request method, POST, GET; path; HTTP version
? ?std::string method, path, http_version;
? ?// use smart pointer for reference counting of content
? ?std::shared_ptr<std::istream> content;
? ?// hash container, key-value dict
? ?std::unordered_map<std::string, std::string> header;
? ?// use regular expression for path match
? ?std::smatch path_match;
};
请求的资源类型:
typedef std::map<
? ?std::string, std::unordered_map<
? ? ? ?std::string,std::function<void(std::ostream&, Request&)>>> resource_type;
以及服务端模板:
template <typename socket_type>
class ServerBase {
public:
? ?resource_type resource;
? ?resource_type default_resource;
?
? ?void start() {
? ? ? ?// TODO
? }
protected:
? ?Request parse_request(std::istream& stream) const {
? ? ? ?// TODO
? }
}
请实现成员函数 start() 与 parse_request 。使得服务器模板使用者可以如下指定路由:
template<typename SERVER_TYPE>
void start_server(SERVER_TYPE &server) {
?
? ?// process GET request for /match/[digit+numbers], e.g. GET request is /match/abc123, will return abc123
? ?server.resource["fill_your_reg_ex"]["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;
? };
?
? ?// peocess default GET request; anonymous function will be called if no other matches
? ?// response files in folder web/
? ?// default: index.html
? ?server.default_resource["fill_your_reg_ex"]["GET"] = [](ostream& response, Request& request) {
? ? ? ?string filename = "www/";
?
? ? ? ?string path = request.path_match[1];
?
? ? ? ?// forbidden use `..` access content outside folder 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--;
? ? ? }
?
? ? ? ?// (...)
? };
?
? ?server.start();
}
参考原作者答案。
|