返回

Linux 下 C++ 轻量级 Web 服务器(三):解析请求

后端

在上一篇文章中,我们介绍了 Web 服务器的并发模型,包括 Reactor、Epoll 和线程池。我们讨论了当任务队列(请求)中有任务(请求)到达时,例如读写操作,线程池中的线程是如何解析请求并封装响应的。

这篇文章我们将深入探讨解析请求的过程,重点关注 DealRead 函数,它负责读取请求并将其封装成可供后续处理的结构。

解析请求

请求解析是 Web 服务器处理客户端请求的关键步骤。解析请求的过程涉及以下步骤:

1. 读取请求行

请求行包含三个部分:请求方法、请求路径和 HTTP 版本。例如:

GET /index.html HTTP/1.1

2. 读取请求头

请求头包含有关请求的附加信息,例如:

Host: example.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0

3. 读取请求体

请求体包含客户端发送的附加数据,例如表单数据或 JSON 负载。

DealRead 函数

DealRead 函数负责解析请求并将其封装成可供后续处理的结构。该函数接收一个套接字符作为输入,并执行以下步骤:

  1. 读取请求行。
  2. 解析请求方法、请求路径和 HTTP 版本。
  3. 读取请求头。
  4. 解析请求头中的信息。
  5. 读取请求体(如果存在)。

示例代码

以下是一个示例 DealRead 函数的代码:

#include <iostream>
#include <string>

using namespace std;

struct Request {
    string method;
    string path;
    string version;
    map<string, string> headers;
    string body;
};

Request DealRead(int sockfd) {
    Request request;

    // 读取请求行
    string line;
    getline(sockfd, line);

    // 解析请求行
    istringstream iss(line);
    iss >> request.method >> request.path >> request.version;

    // 读取请求头
    while (getline(sockfd, line) && line != "\r\n") {
        size_t pos = line.find(":");
        if (pos != string::npos) {
            request.headers[line.substr(0, pos)] = line.substr(pos + 1);
        }
    }

    // 读取请求体
    if (request.headers.count("Content-Length") > 0) {
        int contentLength = stoi(request.headers["Content-Length"]);
        char buf[contentLength];
        read(sockfd, buf, contentLength);
        request.body = string(buf, contentLength);
    }

    return request;
}

结论

解析请求是 Web 服务器处理客户端请求的基本步骤。DealRead 函数负责解析请求并将其封装成可供后续处理的结构。通过理解解析请求的过程,我们可以深入了解 Web 服务器的工作原理。