为什么 HTTP 状态行与请求行不同
Why is HTTP status-line different from the request-line
HTTP 请求行和状态行都有 3 个组件:
Request-Line= Method SP Request-URI SP HTTP-Version CRLF
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
状态行(服务器响应)正常:
- 它以 HTTP 版本(与任何协议一样)开头,因此解码器可以根据第一个字段调整它的解析
- 后跟一些协议定义的值(状态代码),一个单词,不需要任何 SP/CR/LF 字符
- 以任何 TEXT 字符(CR/LF 除外)作为 Reason-Phrase 结尾。
我不明白的是为什么请求行如此不同:
- HTTP 版本在最后
- 必须转义 Request-URI 以避免出现 SP/CR/LF 字符(这里是著名的 %20)
为什么它不遵循与状态行相同(干净)的模式?
Request-Line= HTTP-Version SP Method SP Request-URI CRLF
这样 Request-URI 可以是任何 TEXT 字符(CR/LF 除外)
所以它看起来像这样:
HTTP/1.1 GET /user/with space
...
HTTP/1.1 404 NOT FOUND
...
参见:
可能来自HTTP/0.9,协议早期版本
请求部分是:
GET http://www.example.com/foo.html\r\n
而响应部分是响应 body(没有 headers),因此直接以 <html>
开头的 html 响应为例。
请求行是:
METHOD OSP Absolute-Request-URL CRLF
- 有很多用于 OSP 的可选空间,例如制表符或换页符
- 位置部分也有主机部分(今天协议仍然支持)
重点是没有协议版本,也没有协议部分。在响应和请求中。
创建 HTTP/1.0 时,隐含的需求仍然支持 HTTP/0.9 请求和响应。有些服务器今天仍在做的事情。
在响应端添加了所有响应 headers 部分(例如说明响应的 MIME 类型!),并且第一行是从协议版本开始构建的响应。
在请求方添加了协议版本作为可选添加,因此您仍然可以决定制作[=51= .9 请求或新版本,最重要的是,HTTP/0.9 服务器可能仍然可以理解您的查询(并忽略 SP PROTOCOL
添加(甚至是可选的 headers 添加在要求)。
今天,如果您忘记了请求的协议部分,HTTP/0.9 兼容服务器将只解析您请求的第一行,而忽略额外的 headers.
这些是等效的查询(但第一个是在 http 0.9 中并且不会在响应中得到 headers):
# HTTP 0.9:
GET http://www.example.com/foo.html\r\n
# HTTP/1.0 version:
GET http://www.example.com/foo.html HTTP/1.0\r\n
\r\n
# or
GET /foo.html HTTP/1.0\r\n
Host: www.example.com\r\n
\r\n
#or
GET http://www.example.com/foo.html HTTP/1.0\r\n
Host: www.foo.com\r\n
\r\n
我认为他们一直在考虑解析器中需要的代码更新,并且在第一行末尾添加协议更容易实现。也许旧的解析器仍然可以向 HTTP/1.0 查询发送 0.9 响应(这很糟糕但易于编写)。
也许只是在现有线路上添加一些东西比在现有协议的线路上添加前缀更像是一种改进。
也许你此时应该已经足够大了,可以评论 RFC 并告诉他们你的方式会更优雅(这是正确的):-)
HTTP 请求行和状态行都有 3 个组件:
Request-Line= Method SP Request-URI SP HTTP-Version CRLF
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
状态行(服务器响应)正常:
- 它以 HTTP 版本(与任何协议一样)开头,因此解码器可以根据第一个字段调整它的解析
- 后跟一些协议定义的值(状态代码),一个单词,不需要任何 SP/CR/LF 字符
- 以任何 TEXT 字符(CR/LF 除外)作为 Reason-Phrase 结尾。
我不明白的是为什么请求行如此不同:
- HTTP 版本在最后
- 必须转义 Request-URI 以避免出现 SP/CR/LF 字符(这里是著名的 %20)
为什么它不遵循与状态行相同(干净)的模式?
Request-Line= HTTP-Version SP Method SP Request-URI CRLF
这样 Request-URI 可以是任何 TEXT 字符(CR/LF 除外)
所以它看起来像这样:
HTTP/1.1 GET /user/with space
...
HTTP/1.1 404 NOT FOUND
...
参见:
可能来自HTTP/0.9,协议早期版本
请求部分是:
GET http://www.example.com/foo.html\r\n
而响应部分是响应 body(没有 headers),因此直接以 <html>
开头的 html 响应为例。
请求行是:
METHOD OSP Absolute-Request-URL CRLF
- 有很多用于 OSP 的可选空间,例如制表符或换页符
- 位置部分也有主机部分(今天协议仍然支持)
重点是没有协议版本,也没有协议部分。在响应和请求中。
创建 HTTP/1.0 时,隐含的需求仍然支持 HTTP/0.9 请求和响应。有些服务器今天仍在做的事情。
在响应端添加了所有响应 headers 部分(例如说明响应的 MIME 类型!),并且第一行是从协议版本开始构建的响应。
在请求方添加了协议版本作为可选添加,因此您仍然可以决定制作[=51= .9 请求或新版本,最重要的是,HTTP/0.9 服务器可能仍然可以理解您的查询(并忽略 SP PROTOCOL
添加(甚至是可选的 headers 添加在要求)。
今天,如果您忘记了请求的协议部分,HTTP/0.9 兼容服务器将只解析您请求的第一行,而忽略额外的 headers.
这些是等效的查询(但第一个是在 http 0.9 中并且不会在响应中得到 headers):
# HTTP 0.9:
GET http://www.example.com/foo.html\r\n
# HTTP/1.0 version:
GET http://www.example.com/foo.html HTTP/1.0\r\n
\r\n
# or
GET /foo.html HTTP/1.0\r\n
Host: www.example.com\r\n
\r\n
#or
GET http://www.example.com/foo.html HTTP/1.0\r\n
Host: www.foo.com\r\n
\r\n
我认为他们一直在考虑解析器中需要的代码更新,并且在第一行末尾添加协议更容易实现。也许旧的解析器仍然可以向 HTTP/1.0 查询发送 0.9 响应(这很糟糕但易于编写)。
也许只是在现有线路上添加一些东西比在现有协议的线路上添加前缀更像是一种改进。
也许你此时应该已经足够大了,可以评论 RFC 并告诉他们你的方式会更优雅(这是正确的):-)