【web server】HTTP协议如何解析or封装

简介: 【web server】HTTP协议如何解析or封装

HTTP协议(关于HTTP协议之前的文章有写过)如何解析or封装?

首先来看下这块的处理过程,有一个整体的概念:

void Http::process() {
  //主线程读完数据后,来到这里处理
  HTTP_CODE read_ret = process_read();
  if (read_ret == NO_REQUEST) {
    //解析完数据发现客户端没有请求,直接退出
    return ;
  }
  //如果有请求,根据刚才解析的结果,封装报文
  bool write_ret = process_write(read_ret);
  if (!write_ret) {
    close_conn();
  }
  //告诉主线程,报文已经封装好了,可以发送了!
  modfd(s_iEpollfd, m_iSockFd, EPOLLOUT);
}

主线程读数据:

bool Http::read() {
  if (m_read_idx >= READ_BUFFER_SIZE) {
    return false;
  }
  int bytes_read = 0;
  while (true) {
    bytes_read = recv(m_iSockFd, m_read_buf + m_read_idx, READ_BUFFER_SIZE - m_read_idx, 0);
    if (bytes_read == -1) {
      if (errno == EAGAIN || errno == EWOULDBLOCK) {
        break;
      }
      return false;
    } else if (bytes_read == 0) {
      return false;
    }
    m_read_idx += bytes_read;
  }
  return true;
}

读到的正是这样一行一行的数据:

将数据循环读到m_read_buf中,接着开始处理读到的数据:

Http::HTTP_CODE Http::process_read() 
{
  ...
  while (...) {
    //拿到每一行数据
    text = get_line();
    switch (m_check_state) {
        case CHECK_STATE_REQUESTLINE: {
          //处理请求行
          parse_request_line(text);
          ...
          break;
        }
        case CHECK_STATE_HEADER: {
          //处理头部字段
          parse_headers(text);
          ...
          break;
        }
        default: {
          return INTERNAL_ERROR;
        }
    }
  }
}

用一个变量m_check_state来表示分析状态:

enum CHECK_STATE {
  CHECK_STATE_REQUESTLINE = 0, //当前正在分析请求行
  CHECK_STATE_HEADER  //当前正在分析头部字段
};

以便在parse_request_line之后改变状态,之后进入parse_headers中处理。

分析请求行和头部字段,可以了解到当前客户端要请求的资源的信息以及客户端一些信息。

若在解析的过程中发现客户端请求了页面,则在服务端找到该文件,并写入内存,等待发送,比如在do_request

Http::HTTP_CODE Http::do_request() {
  ...
  //若解析出的请求行中有“/”则默认返回index.html首页面
  if (strcmp(m_url, "/") == 0) {
    strcat(m_url, "index.html");
  }
  //处理其他,比如服务端没有资源,返回404.html 等等
  ...
  //若资源存在,读到内存中,等待发送
}

解析请求行和头部字段后,发现需要返回资源,便按照响应报文的格式封装报文并发送:

bool Http::process_write(HTTP_CODE ret) {
  switch (ret) {
    ...
    case NO_RESOURCE: {
      add_status_line(404, error_404_title);
      add_headers(strlen(error_404_form));
      add_content(error_404_form);
      break;
    }
    case FILE_REQUEST: {
      add_status_line(200, ok_200_title);
      add_headers(file.size());
      add_content(file);
      break;
    }
    default: {
      return false;
    }
  }
  return true;
}

add_status_line用来添加状态行,add_headers用来添加头部字段(之后添加一行空行),add_content用来添加内容。

至此,响应报文也就封装完成了,之后通知主线程发送报文即可。

相关文章
|
1月前
|
JSON 数据格式
第三方系统或者工具通过 HTTP 请求发送给 ABAP 系统的数据,应该如何解析试读版
第三方系统或者工具通过 HTTP 请求发送给 ABAP 系统的数据,应该如何解析试读版
27 0
|
3月前
|
XML 编解码 前端开发
【web组件库系列】封装自己的字体图标库
【web组件库系列】封装自己的字体图标库
56 0
|
30天前
|
安全 数据安全/隐私保护
深入解析:HTTP和HTTPS的三次握手与四次挥手
在这些握手和挥手过程中,双方交换信息,协商参数,建立或关闭连接,以保证数据的可靠传输。HTTPS在此基础上加入了数字证书验证和加密通信,增加了安全性。这些步骤确保了HTTP和HTTPS协议的通信过程的稳定和安全。
116 0
|
1月前
|
安全 Python
Python封装:深入解析与应用
封装是Python面向对象编程的关键,通过隐藏对象属性和实现细节,提供公共访问方式,确保代码安全和可维护。实现封装主要通过类和对象,使用私有属性(__前缀)及访问器/修改器方法。封装能隐藏内部状态、统一接口、复用代码和增强扩展性。示例展示了如何用私有属性和访问器方法控制属性访问。掌握封装有助于编写高效、灵活的代码。
|
1月前
|
存储 网络安全 数据安全/隐私保护
Windows Server 2019 IIS HTTPS证书部署流程详解
Windows Server 2019 IIS HTTPS证书部署流程详解
|
1月前
|
存储 安全 API
掌握 HTTP Authorization 头:关键知识点解析
在当今的互联网世界中,安全性贯穿于 web 应用的每个方面,HTTP Authorization 头的使用在这个过程中扮演着不可或缺的角色。它是 HTTP 请求中的一个重要部分,用来在客户端和服务器之间安全地传输认证信息。用途广泛,无论是浏览器还是其他客户端应用,都依赖它来验证用户的访问权限。本文旨在详细解读 HTTP Authorization 头的定义、使用方式以及不同的认证机制。
|
1月前
|
Java 应用服务中间件
解决tomcat启动报错:无法在web.xml或使用此应用程序部署的jar文件中解析绝对的url [http:java.sun.com/jsp/jstl/core]
解决tomcat启动报错:无法在web.xml或使用此应用程序部署的jar文件中解析绝对的url [http:java.sun.com/jsp/jstl/core]
132 1
|
2月前
|
资源调度 JavaScript API
|
2月前
|
存储 JSON 数据挖掘
快手商品详情数据接口解析和封装
快手商品详情数据接口解析和封装
46 1
|
3月前
|
移动开发 自然语言处理 网络协议
Http解析实现/服务器Get请求的实现
Http解析实现/服务器Get请求的实现
47 0

推荐镜像

更多