当前位置: 首页 > article >正文

HTTP报文格式

HTTP请求报文格式

1. 结构:
[请求行]  
[请求头]  
[空行]  
[请求体]  (可选)
  • 请求行方法 URI HTTP版本
    常见方法:GET(获取资源)、POST(提交数据)、PUT(替换资源)、DELETE(删除资源)。
    例如:GET /index.html HTTP/1.1

  • 请求头:键值对形式,传递附加信息(如客户端信息、内容类型等)。
    常见字段:

    • Host: www.example.com (目标域名,HTTP/1.1必需)
    • User-Agent: Mozilla/5.0 (客户端信息)
    • Accept: text/html (客户端可接受的响应类型)
    • Content-Type: application/json (请求体类型,POST/PUT时使用)
    • Content-Length: 27 (请求体的字节长度)
  • 请求体:仅某些方法(如POST、PUT)携带,如提交表单或JSON数据。

2. 示例(GET请求):

http

GET /page.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
3. 示例(POST请求):
POST /login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 29

username=test&password=1234
4. 判断请求头结束的方式
1. 无消息体的请求(如GET、HEAD、DELETE等)
  • 结束标志:请求头(Headers)之后紧跟两个连续的CRLF(即空行),此时请求结束。
  • 示例
    GET /index.html HTTP/1.1\r\n  
    Host: example.com\r\n  
    \r\n  
    
2. 有消息体的请求(如POST、PUT等)

对于包含消息体的请求,需通过以下方式确定结束:

a. 使用 Content-Length 头部
  • 作用:明确指定消息体的字节长度。
  • 判断方式:服务端读取完指定长度的字节后,视为请求结束。
  • 示例
    POST /upload HTTP/1.1\r\n  
    Content-Length: 1234\r\n  
    \r\n  
    <1234字节的数据>  
    
b. 使用分块传输编码(Transfer-Encoding: chunked
  • 作用:将消息体分块传输,适用于动态生成内容或无法预知内容大小的情况。
  • 判断方式
    1. 每个分块以十六进制长度开头,后跟CRLF和数据块。
    2. 以长度标识为0的块表示结束,后跟最终的CRLF。
  • 示例
    POST /data HTTP/1.1\r\n  
    Transfer-Encoding: chunked\r\n  
    \r\n  
    5\r\n  
    Hello\r\n  
    0\r\n  
    \r\n  
    
c. 无Content-LengthTransfer-Encoding的情况
  • HTTP/1.0:无持久连接时,可能依赖客户端关闭连接判断结束(不推荐用于HTTP/1.1)。
  • HTTP/1.1:规范要求必须明确指定长度或使用分块编码,否则服务器会返回400 Bad Request错误。
3. 其他注意事项
  • Expect头处理:若请求包含Expect: 100-continue,服务端需先响应100 Continue状态码,再按规则处理消息体。
  • 协议版本差异:HTTP/1.1严格要求使用Content-Length或分块编码处理持久连接中的请求,而HTTP/1.0可能允许通过关闭连接判断结束。

总结流程图

开始接收请求
├─ 读取请求头直至空行(\r\n\r\n)
├─ 判断是否存在消息体?
│   ├─ 否 → 请求结束
│   └─ 是 → 检查头部:
│       ├─ 若有Content-Length → 读取指定字节数后结束
│       ├─ 若Transfer-Encoding: chunked → 解析分块直至遇到长度0块
│       └─ 无明确标识 → 按协议版本处理(HTTP/1.1返回错误,HTTP/1.0可能读取到连接关闭)
结束

HTTP响应报文格式

1. 结构:
[状态行]  
[响应头]  
[空行]  
[响应体]  (可选)
  • 状态行HTTP版本 状态码 状态消息
    常见状态码:

    • 200 OK:成功
    • 404 Not Found:资源未找到
    • 500 Internal Server Error:服务器错误
    • 301 Moved Permanently:永久重定向
  • 响应头:提供服务器信息或资源元数据。
    常见字段:

    • Server: Apache/2.4 (服务器信息)
    • Content-Type: text/html (响应体类型)
    • Content-Length: 1024 (响应体的字节长度)
    • Set-Cookie: session=abc123 (设置Cookie)
  • 响应体:请求资源的内容(如HTML、JSON、图片等)。

  • 判断HTTP响应结束的方式

  1. Content-Length准则

    • 当响应头包含Content-Length时,消息体需精确读取指定字节数
    • 示例行为:inputStream.read(body)严格读取给定长度
  2. Chunked分块准则

    • Transfer-Encoding: chunked时,循环读取格式为:[块大小]\r\n[块数据]\r\n
    • 终止条件:读取到0\r\n表示所有分块传输完成
  3. 连接关闭准则

    • 无上述头部且非持久连接时,持续读取直到inputStream.read()返回-1
// 伪代码演示HTTP响应结束判断
class HttpResponseParser {

    void parseResponse(InputStream inputStream) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        Map<String, String> headers = new HashMap<>();
        String line;
        
        // 1. 解析响应头
        while ((line = reader.readLine()) != null) {
            if (line.isEmpty()) break; // 头部结束标记(空行)
            if (line.contains(":")) {
                String[] parts = line.split(":", 2);
                headers.put(parts[0].trim().toLowerCase(), parts[1].trim());
            }
        }

        // 2. 判断消息体结束规则
        if (headers.containsKey("content-length")) {
            // 情况1:通过Content-Length确定结束位置
            int length = Integer.parseInt(headers.get("content-length"));
            byte[] body = new byte[length];
            inputStream.read(body); // 严格读取指定长度
            processBody(body);

        } else if ("chunked".equals(headers.get("transfer-encoding"))) {
            // 情况2:通过分块编码判断结束
            while (true) {
                String chunkSizeLine = reader.readLine();
                int chunkSize = Integer.parseInt(chunkSizeLine.split(";")[0], 16); // 解析16进制长度
                if (chunkSize == 0) break; // 结束标记
                byte[] chunk = new byte[chunkSize];
                inputStream.read(chunk);
                reader.readLine(); // 丢弃块结束的CRLF
                processChunk(chunk);
            }

        } else {
            // 情况3:持续读取直到流关闭(HTTP/1.0旧模式)
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int b;
            while ((b = inputStream.read()) != -1) { // -1表示流结束
                buffer.write(b);
            }
            processBody(buffer.toByteArray());
        }
    }

    // 示例方法:处理完整消息体
    void processBody(byte[] data) { /* ... */ }

    // 示例方法:处理分块数据
    void processChunk(byte[] chunk) { /* ... */ }
}
2. 示例(成功响应HTML):

http

HTTP/1.1 200 OK
Server: Nginx
Content-Type: text/html
Content-Length: 158

<html>
  <head><title>示例页面</title></head>
  <body>Welcome!</body>
</html>
3. 示例(错误响应):

http

HTTP/1.1 404 Not Found
Content-Type: text/plain
Content-Length: 15

Page not found.
4. 示例(JSON响应):

http

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 28

{"status": "success", "data": {}}

完整交互示例

客户端访问 https://www.example.com/index.html

  1. 请求

http

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
  1. 响应

http

HTTP/1.1 200 OK
Server: Apache/2.4
Content-Type: text/html
Content-Length: 1234

<!DOCTYPE html>
<html>...</html>

关键注意事项

  1. 空行分隔:头部和主体间必须有一个仅包含CRLF的空行。
  2. 方法区分:GET一般无请求体,POST/PUT通过Content-TypeContent-Length指定请求体格式。
  3. 无状态协议:HTTP协议本身不保存状态,依赖Cookie/Session等机制。
  4. 扩展性:可通过自定义头部字段(如Authorization: Bearer token)实现扩展功能。

掌握HTTP报文格式能帮助理解Web开发、API设计和网络调试(如使用浏览器开发者工具或Fiddler抓包)。


http://www.kler.cn/a/537843.html

相关文章:

  • C# 封送和远程编程介绍
  • 开放式TCP/IP通信
  • 基于机器学习的DDoS检测系统实战
  • 【玩转 Postman 接口测试与开发2_019】第15章:利用 Postman 初探 API 性能测试(含实战截图)
  • windows蓝牙驱动开发-蓝牙无线电重置和恢复
  • 国产化创新 守护开放边界网络安全
  • 蓝桥杯---力扣题库第38题目解析
  • html css网页制作成品——HTML+CSS爷爷不泡茶的茶网页设计(7页)附源码
  • IDEA安装离线插件(目前提供了MavenHelper安装包)
  • npm中央仓库
  • pycharm ai插件
  • element-plus 解决el-dialog背后的页面滚动问题,及其内容有下拉框出现错位问题
  • 21.[前端开发]Day21-HTML5新增内容-CSS函数-BFC-媒体查询
  • < 评论 > 阿里云 与 腾讯云 国内的轻量应用服务器(VPS)产品对比
  • 【韩顺平linux】部分上课笔记整理
  • 星网锐捷 DMB-BS LED屏信息发布系统taskexport接口处存在敏感信息泄露
  • 机器学习专业毕业设计选题灵感集锦:选题建议
  • C++STL(四)——vector模拟
  • Web自动化测试:如何生成高质量的测试报告
  • Element UI 表单源码原理
  • (六)C++的函数模板与类模板
  • 使用 Nginx 搭建代理服务器(正向代理 HTTPS 网站)指南
  • LVSNAT服务搭建
  • 2024最新版Java学习路线图--Java语言进阶重点知识
  • 【Ubuntu】安装和使用Ollama的报错处理集合
  • AGP8 混淆打包,反射实例化启动闪退