完全不会做,只能记录一下了。
代码语言:javascript复制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。
代码语言:javascript复制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 服务器开发中,我们通常希望服务某些满足某个条件的路由。正则表达式便是完成这一目标的工具之一。
给定如下请求结构:
代码语言:javascript复制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;
};
请求的资源类型:
代码语言:javascript复制typedef std::map<
std::string, std::unordered_map<
std::string,std::function<void(std::ostream&, Request&)>>> resource_type;
以及服务端模板:
代码语言:javascript复制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 OKrnContent-Length: " << number.length() << "rnrn" << 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();
}