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

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 【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用来添加内容。

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

相关文章
|
17天前
|
安全 算法 网络协议
解析:HTTPS通过SSL/TLS证书加密的原理与逻辑
HTTPS通过SSL/TLS证书加密,结合对称与非对称加密及数字证书验证实现安全通信。首先,服务器发送含公钥的数字证书,客户端验证其合法性后生成随机数并用公钥加密发送给服务器,双方据此生成相同的对称密钥。后续通信使用对称加密确保高效性和安全性。同时,数字证书验证服务器身份,防止中间人攻击;哈希算法和数字签名确保数据完整性,防止篡改。整个流程保障了身份认证、数据加密和完整性保护。
|
1月前
|
缓存 安全 网络安全
代理协议解析:如何根据需求选择HTTP、HTTPS或SOCKS5?
本文详细介绍了HTTP、HTTPS和SOCKS5三种代理协议的特点、优缺点以及适用场景。通过对比和分析,可以根据具体需求选择最合适的代理协议。希望本文能帮助您更好地理解和应用代理协议,提高网络应用的安全性和性能。
64 17
|
1月前
|
网络协议 网络安全 数据安全/隐私保护
HTTP 协议浅析
通过对HTTP协议的深入了解,开发者可以更好地设计和优化Web应用,提高数据传输效率和用户体验。
121 21
|
2月前
|
缓存 网络协议 前端开发
Web 性能优化|了解 HTTP 协议后才能理解的预加载
本文旨在探讨和分享多种预加载技术及其在提升网站性能、优化用户体验方面的应用。
Web 性能优化|了解 HTTP 协议后才能理解的预加载
|
2月前
|
XML JSON 前端开发
HTTP协议,Content-Type格式介绍篇
通过理解和正确使用Content-Type头字段,可以确保数据在网络上传输时的正确性和高效性,提升网络应用的可靠性和用户体验。
258 25
|
2月前
|
XML JSON 前端开发
HTTP协议,Content-Type格式介绍篇
通过理解和正确使用Content-Type头字段,可以确保数据在网络上传输时的正确性和高效性,提升网络应用的可靠性和用户体验
146 28
|
2月前
|
XML JSON 前端开发
HTTP协议,Content-Type格式介绍篇
通过理解和正确使用Content-Type头字段,可以确保数据在网络上传输时的正确性和高效性,提升网络应用的可靠性和用户体验。
317 18
|
3月前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法
|
3月前
|
JSON 数据格式
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
101 2
|
3月前
|
缓存 网络协议 算法
从零开始掌握HTTP协议
本文介绍HTTP协议的演变,从HTTP1.0到HTTP2.0。HTTP1.0为无状态连接,每次请求独立;HTTP1.1引入持久连接、管道化请求和更多状态码;HTTP2.0采用二进制分帧、多路复用、头部压缩及服务器主动推送,大幅提升性能与用户体验。了解这些区别有助于开发者优化应用和服务。

热门文章

最新文章