以下网站是对http报文如何解析的详细解释,是一种协议约定,服务器需要按这个约定实现: https://httpwg.org/specs/rfc7230.html#rfc.section.3.3.3
其中以下内容是关于服务器应该如何解析报文正体的,不论请求类型是参数还是文件:
…
If a Transfer-Encoding header field is present in a response and the chunked transfer coding is not the final encoding, the message body length is determined by reading the connection until it is closed by the server. If a Transfer-Encoding header field is present in a request and the chunked transfer coding is not the final encoding, the message body length cannot be determined reliably; the server MUST respond with the 400 (Bad Request) status code and then close the connection.
…
请求头中如果不指定 [Content-Length],那么必须要指定[Transfer-Encoding]。
服务器在解析报文时,需要知道开头和结尾在哪里,因为http报文开头格式是固定的,所以很容易判断正文的开头;但因为正文格式不固定,比如客户端可能发送普通参数,也可能发送文件,像图片、视频等。如果是文件,服务器是不需要解析正文内容的,只需要知道开头和结尾,以数据流的形式向下传输就行。
如果请求头中包含[Content-Length],那么只要按这个值大小读取正文即可(超过这个大小以后的报文可以抛弃也可以返回一个错误,具体看不同服务的实现);
如果没有[Content-Length],那么必须要指定[Transfer-Encoding],但是[Transfer-Encoding]只是一种编码格式,还是没办法知道正文结束的地方(服务器按流或者字节读取,并不解析含义,即使正文末尾定义一个结束符,服务器也解析不到),所以就需要在[Transfer-Encoding]中同时指定分块传输,而分块传输的每个数据块在发送前都会先发送一个当前数据块的大小值,这样服务器就很容易知道何时正文结束了。
如果不指定分块传输,服务器只能默认从开头往后的所有报文都是正文(假设正文是个文件,而发送端在报文末端写了结束符,那么服务端接受这个文件时就会把结束符也写入到文件中,从而出错),但这样是不可靠的,所以像上面所说,最好办法是直接报错,返回一个400错误代码。
|