• HTTP 请求
    • 请求行
    • 请求头

    HTTP 请求

    首先,我们看一下这个 HTTP 请求:

    1. 行数 内容
    2. 1 GET /serv/login.php?lang=en&profile=2 HTTP/1.1
    3. 2 Host: www.mydomain.com
    4. 3 User-agent: my small browser
    5. 4 Accept: image/jpeg, image/gif
    6. 5 Accept: image/png

    请求行

    第一行是请求行,它总是由三部分组成:

    • METHOD:GET
    • URI:/serv/login.php?lang=en&profile=2
    • version tag:HTTP/1.1它们被一个叫 LWS(Linear White Spaces)的标准所分隔,也就是我们常见的空格,不过也可以由制表符或 CR/LF 加上空格/制表符所分隔。

    这些方法本身无法包含“:”字符,它只能由字母组成。所有这些增加可描述性的表达形式都是 HAProxy 自行分割,避免了用户去编写复杂而可能不准确的正则表达式来匹配它们。

    URI 可以有多种表达形式:

    • 相对 URI:比如/serv/login.php?lang=en&profile=2是一个不含域名的完整 URL,它通常会被服务器、反向代理、透明代理接受。
    • 绝对 URI:比如http://192.168.0.12:8080/serv/login.php?lang=en&profile=2,也称为 URL,它由一种“图式”组成:(协议名称后跟着://)首先是一个域名或地址(有时会加上:后跟着端口号),后面加上/和一个相对 URI。通常一个代理会接受此类形式,支持 HTTP/1.1 的服务器也会接受这种形式。
    • 一个星号(“*”):此形式是不可靠的,仅在和OPTIONS方法联合使用时才会被接受,用于适配查询下一跳。
    • 地址加端口号:比如192.168.0.1:8080,用于CONNECT方法来和一个 HTTP 代理建立 TCP 隧道,通常用于 HTTPS 协议,但也可能是其他协议。在一个相对 URI 中,有两个部分是被确定好的:?前面的部分称为路径(path),通常是服务器上某个静态对象的相对路径;?后面的部分称为查询字符串(query string),大多用来发送GET请求给动态脚本或指定语言、框架、应用程序等。

    请求头

    从第二行开始就是请求头。它由键名 + : + 组成。传统上,冒号的后面会加上一个 LWS,不过并没有强制要求。

    如果请求头有多个键名相同的值,它们可能会被合并到一行,然后用逗号,分隔开多个值,在Cookie:这个键就常见这种情况。如果一个请求头的开头是一个 LWS,那么它可能会跨越多行,本文上面例子的第 4、5 行Accept:就定义了三个值。

    与我们通常认知相反的是,请求头的键和值对大小写并不敏感。

    请求头中的第一个空行标记头部的结束。很多人认为末尾会有两个 LF,但这种说法不是很准确,尽管两个 LF 确实代表一个合法的空行。

    幸运的是,HAProxy 对组合复杂的请求头作了细致的检查、计算和分析,所以我们不用担心请求头会被写成什么样子。但如果一个应用因为用了不寻常的东西而充满 Bug,那指责他也无可厚非。

    请注意:

    基于 RFC7231 的建议,HAProxy 用 LWS 替换请求头中的换行符来连接多行请求头,这对纠正分析结果、优化 HTTP 解析器效率、简化复杂结构颇有帮助。