HTTP 1.1 RFC学习笔记(三)--HTTP消息

1           HTTP消息:

Generic-message = start-line*(message-header CRLF) CRLF [message-body]

Start-line=Request-Line|Status-Line

服务器【应该】忽略在希望收到Request-Line地方的空行,换句话,如果服务器在读取协议流的初始消息且收到CRLF打头,则它应该忽略CRLF,已知有问题的HTTP/1.0客户端实现生成额外的CRLFPOST请求之后。重新声明,BNF明确禁止HTTP/1.1客户端一问我的CRLF引导或结束请求

1.1          Message-header

1.1.1.1    收到不同field-name头部域的顺序没有意义,然而好的实践是,首先发送general-header , 接着是 request-header或者response-header,然后是entity-header

1.1.1.2    通过追加每个后序field-value到第一个,之间用逗号分隔开,因此收到相同field-name头部域的顺序对应组合field-value的解析是有意义的,代理【禁止】在转发消息时改变这些field-value的顺序

 

1.2          Message-body (如果存在)用于携带与请求或响应相关联的entity-body,message-body只有在应用了transfer-encoding时,通过Transfer-Encoding 头部域指出,与entity-body不同

Message-body = entity-body | <按每个Transfer-Encoding编码的entity-body>

*当允许消息有message-body时的规则对应请求和响应而言是不同的

1.1.1.1    请求中存在message-body的信号有在请求的message-header中引入Content-length或者Transfer-Encoding来指示。如果请求方法规定不允许在请求中发送entity-body是,【禁止】在请求中包括message-body,服务器【应该】读取和转发任何请求上的message-body,如果请求没有包括entity-body的已定义语句,在处理请求时【应该】忽略message-body

1.1.1.2    响应消息是否包括message-body既取决于请求方法,也取决于响应状态码,对应HEAD请求方法的所有请求【禁止】包括message-body,即使存在entity-header域可能使接收方确信其中包括message-body,所有1xx(信息性)204(No content),,和304Not-modified 响应【禁止】包括message-body,所有其他响应确实包括message-body,即使其长度【可以】是0

1.2          消息长度

1.2.1     【禁止】包括message-body的任何响应(如1xx,204304响应,及对HEAD请求的任何响应)始终在头部域的首个空行后终止,而不管消息中的entity-header

1.2.2     如果存在Transfer-Encoding头部域,且其值不是”identity”,这时transfer-length由“chunked”transfer-encoding定义,除非消息由连接关闭终止

1.2.3     如存在Content-length头部域,则它的OCTET十进制既表示entity-length,又表示content-length,如果这两个长度不同时,【禁止】发送Content-length头部域,如果收到的消息既有Transfer-Encoding头部域,又有Content-length头部域,则【必须】忽略后者

1.2.4     如果消息使用”multipart/byteranges“媒体类型,且没有另外指定transfer-length,则该自定界的媒体类型定义transfer-length,除非发送方知道接收方能够解释它,否则【禁止】使用该媒体类型。1.1客户端请求中存在多个byte-range规范符的Range头部暗示该客户端能解释multipart/byteranges响应,1.0代理啃个不理解multipart/byteranges,可以转发Range头部,在这种情况下,服务器【必须】使用本节中135项定义的方法来定界消息

1.2.5     通过服务器关闭连接(不能使用关闭连接来指出请求主体的结束,由于这将引起服务器不可能回送响应)

 

为了与HTTP/1.0应用程序兼容,包含message-bodyHTTP/1.1请求【必须】包括有效的Content-length头部域,除非已知服务器与HTTP/1.1兼容,如果请求中包含message-body但没有Content-length,则服务器【应该】在不能判断消息长度时用400(Bad Request)响应,或者在希望坚持接受有效content-length时用411Length Required)响应

 

收到实体的所有HTTP/1.1应用程序【必须】接受”chunked”transfer-encoding,允许在将来不能判断长度时该机制用于消息。【禁止】消息既包括Content-length头部域,又包括非identitytransfer-encoding,如果消息确实包括非identitytransfer-encoding,则【必须】忽略content-length,当在运行message-body的消息给出content-length时,它的field-value【必须】精确匹配message-bodyOCTET数量,HTTP/1.1用户代理【必须】提醒用户接收并检测到无效长度。

 

2           General-header 

2.1          Cache-Control

2.2          Connection

2.3          Date

2.4          Pragma

2.5          Trailer

2.6          Transfer-Encoding

2.7          Upgrade

2.8          Via

2.9          Warning

3           Socket模拟HTTP协议,读取header,根据content-length,读取http body

 public static byte[] ReceiveData(Socket socket)
   {
   
   
   StringBuilder header=new StringBuilder();
   string headertext="";
   while(true)
    {
    byte[] data=new byte[1];
    //
接收一个字节
    int rece=socket.Receive(data,1,SocketFlags.None);
    
    
    //
转换为char
    char c=(char)data[0];
    
    header.Append(c);
    //
检查是否到了包头末尾,如果到了包头末尾,那么停止
    //
读取
    if(header.ToString().IndexOf("/r/n/r/n")>0)
     {
     string content="CONTENT-LENGTH:";
     int start=header.ToString().ToUpper().IndexOf(content);
     headertext=header.ToString().Substring(start+content.Length);
     int end=headertext.IndexOf("/r/n");
     headertext=headertext.Substring(0,end); //
包体长度
     break;
    }
   }
   //
   byte[] ds=ReceiveData(socket,Convert.ToInt16(headertext));
   return ds;
  }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值