http服务器:
1.目的:通过浏览器,发送一个标准的http请求,得到标准的http响应。
如果请求的是HTML网页,响应后可以在浏览器看到请求的网页内容。
接收请求:
a)GET请求
b)POST请求
响应请求:
a)根据url返回服务器上的静态文件(html/css/JavaScript/图片……)
b)根据请求的参数动态响应一个页面(CGI)
2.设计:模块化设计代码
a)初始化模块
因为http是基于tcp实现的,所以首先要实现一个TCP服务器。
b)请求响应模块
多线程处理并发请求
i.读取请求——操作
ii.解析请求——反序列化
iii.根据请求类型计算
1.静态页面——直接返回页面内容
2.动态页面——使用CGI动态生成页面内容
iv.返回响应——操作、拼接字符串
c)日志模块
http服务器的日志:[E1534349……]…………
方框中首字母表示日志类型,后面的数字表示时间戳。
i.CRITICAL——严重错误
ii.ERROR——一般错误
iii.WARNING——警告
iv.INFO——一般信息
v.DEBUG——调试信息
http_server.h
#pragma once
#include <unordered_map>
namespace http_server{
typedef std::unordered_map<std::string,std::string> Header;
//声明
class HttpServer;
struct Request{
std::string method;
std::string url;
std::string url_path;
std::string query_string; //URL键值对参数 kwd="cpp"
Header header;
std::string body;
};
struct Response{
int code;
std::string desc; //状态码描述
//静态页面响应
Header header;
std::string body;
//动态页面响应
std::string cgi_resp;
};
//上下文
struct Context{
Request req;
Response resp;
int new_sock;
int file_fd;
HttpServer* server;
};
class HttpServer{
public:
int Start(const std::string& ip,short port);
private:
int ReadOneRequest(Context* context);
int WriteOneResponse(context* context);
int HandleRequest(Context* context);
int Process404(Context* context);
int ProcessStaticFile(Context*context);
int ProcessCGI(Context* context);
void GetFilePath(const std::string& url_path,std::string* file_path);
static void* ThreadEntry(void* arg);//线程入口函数
int ParseFirstLine(const std::string& first_line,std::string* method,std::string* url);
int ParseUrl(const std::string& url,std::string* url_path,std::string*query_string);
int ParseHeader(const std::string& header_line,Header* header);
//test
void PrintRequest(const Request& req);
};
}//end of http_server
http_server.cc