自己来做一个简单的web服务器(一)理解基本的http协议
来源:互联网 发布:联合办公 知乎 编辑:程序博客网 时间:2024/05/17 06:37
简介
本部分我们将简单学习一下http协议,才能为后面的web服务器的开发打好基础。
一个Http协议,涉及到请求Request和应答Response,这里就从这两者入手对协议进行一个简单的讲解。
后面将以一个实际的java程序来实现一个简单的web服务器。
请求
官方协议文档地址为https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html。
请求是从客户端,一般是浏览器,发送给服务器,
下面是一次请求的简单结构:
Request = Request-Line
*(( general-header
| request-header
| entity-header )CRLF)
CRLF
[ message-body ]
一次Request,由Request-Line,一些头信息,以及消息体message-body来组成。
Request-Line在消息的第一行里,包括请求的Method方法(作用到资源上),资源标识符Request-URI以及使用的协议版本号HTTP-Version,后面跟着回车换行符CRLF。具体格式如下所示:
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
这里的SP就是空格分割符。
Method
这个Method代表的是要作用在用Request-URI标记的资源上面的操作,是大小写敏感的。常见的Method包括:"OPTIONS","GET","HEAD","POST","PUT","DELETE","TRACE","CONNECT"和extension-method。
某一个资源,在其上面能够允许进行的操作是不一样的。服务器端针对该http请求的回应里面,有一个代码,可以表示是否允许该操作作用于该资源上面。比如操作代码405(Method Not Allowed),就是表示该method不允许操作Request-URI标记的资源。而501(Not Implemented)则表示该method的操作在服务端没有实现。
对于web服务器而言,必须支持GET和HEAD命令,其他命令支持是可选的。在Allowheader字段,会列出来这个资源允许支持的命令列表。
Request-URI
Request-URI代表的是统一资源定位符,标记Method要进行操作的资源。
Request-URI = "*" | absoluteURI | abs_path |authority
Request-URI支持4种URI标记方法,根据request的不同,使用这4种URI标记方法。
星号表示该请求并不适用于特定的资源,而是适用于服务器本身。这个只适合于那些不特定针对某个资源的方法。
当请求被用于一个代理时,使用absoluteURI。代理将把请求进行转发,然后返回一个响应。
Authority这里只是被CONNECT方法所使用。
我们日常最常见的,用来标识在服务器上的resource,就是传递abs_path,是URI的绝对路径:对于http请求而言,Request-URI给出这个URI的绝对路径,而Host代表的是服务器的主机,必须在Hostheader字段进行标记。Request-URI不能为空。例如:
GET/pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org
如果初始的URI为空的话,必须设置为"/",这个代表的是服务器的根。
另外,Request-URI可能被进行16进制编码,而如果Request-URI被16进制编码的话,server侧必须进行解码才能正确的解析请求。对于无效的Request-URI,server必须以合适的状态码给予回应。
对于一次internet请求标记的资源,由Request-URI和Hostheader字段来标记。而服务器简单遵循下列规则进行处理:
1. 如果Request-URI是一个绝对的URL,里面已经包含了主机的信息,那么请求中任何主机头Hostheader字段值都必须被忽略。
2. 如果Request-URI不是一个绝对URL,请求包括一个Hostheader主机请求头,要访问的主机由hostheader主机请求头的字段值决定。
3. 如果按照规则1和规则2确定下来的主机是一个无效的主机的话,服务器必须返回400(Bad Request) 无效请求。
RequestHeader字段
请求头字段允许客户传递一些关于请求的额外信息,这些信息用来描述请求request,以及关于client。充当请求修饰符的作用。
服务器的响应Response
关于Response的规范协议,参考的协议地址为:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
在收到和解析一个请求消息后,服务器端用一个response消息来进行回应。
服务器端的response,其格式定义如下:
Response = Status-Line
*(( general-header
| response-header
| entity-header ) CRLF)
CRLF
[ message-body ]
Status-Line状态行
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
Status-Line是状态行,包含的字段包括:HTTP-Version, Status-Code和Reason-Phrase。这些字段之间通过空格来进行分隔。
状态代码字段,即Status-Code,由3位数字组成,而原因字段Reason-Phrase以人们更加容易理解的方式来描述状态代码值Status-Code。
要注意的是,状态代码字段的第1个数字,代表的是响应的类别。
常见的状态码包括如下:
- 1xx: 通告类 – 表示收到请求,将继续处理
- 2xx: 成功 – 表示收到请求,理解并接受该命令
- 3xx: 重定向- 要完成该请求,必须进一步的处理
- 4xx: 客户端发生错误- 请求语法错误或者无法完成。
- 5xx: 服务器端错误- 服务器端出错,无法完成一个有效的请求。
下面是具体的状态代码
Status-Code =
"100" ; Continue
| "101" ; Switching Protocols
| "200" ; OK
| "201" ; Created
| "202" ; Accepted
| "203" ; Non-Authoritative Information
| "204" ; No Content
| "205" ; Reset Content
| "206" ; Partial Content
| "300" ; Multiple Choices
| "301" ; Moved Permanently
| "302" ; Found
| "303" ; See Other
| "304" ; Not Modified
| "305" ; Use Proxy
| "307" ; Temporary Redirect
| "400" ; Bad Request
| "401" ; Unauthorized
| "402" ; Payment Required
| "403" ; Forbidden
| "404" ; Not Found
| "405" ; Method Not Allowed
| "406" ; Not Acceptable
| "407" ; Proxy Authentication Required
| "408" ; Request Time-out
| "409" ; Conflict
| "410" ; Gone
| "411" ; Length Required
| "412" ; Precondition Failed
| "413" ; Request Entity Too Large
| "414" ; Request-URI Too Large
| "415" ; Unsupported Media Type
| "416" ; Requested range not satisfiable
| "417" ; Expectation Failed
| "500" ; Internal Server Error
| "501" ; Not Implemented
| "502" ; Bad Gateway
| "503" ; Service Unavailable
| "504" ; Gateway Time-out
| "505" ; HTTP Version not supported
| extension-code
extension-code = 3DIGIT
Reason-Phrase = *<TEXT, excluding CR, LF>
Response Header 响应头字段
Response-header字段允许服务器传递关于response的额外信息,这些信息又不能放在Status-Line里。这些头字段提供一些server以及Request-URI要访问的信息。
response-header = Accept-Ranges
| Age
| ETag
| Location
| Proxy-Authenticate
| Retry-After
| Server
| Vary
| WWW-Authenticate
- 自己来做一个简单的web服务器(一)理解基本的http协议
- 利用http协议实现一个简单的web服务器
- 【Python】 做一个简单的 http 服务器
- 利用socket自己实现基于HTTP协议的Web服务器
- 打造自己的Web(HTTP)服务器
- 如何在自己的计算机上做一个web服务器
- 简单的http协议理解
- Http协议的简单理解
- 简单的理解HTTP协议
- 用C编写一个简单的、基本的http服务器
- 自己模拟的一个简单的web服务器
- 自己实现一个简单的支持并发的Web服务器
- Nodejs做web服务器的一个简单逻辑和实现
- 用一行python代码做一个简单的web服务器
- 自己写一个简单的Web服务器(附Demo)
- 用W7100,做自己的HTTP服务器
- 一个简单的Http服务器
- 一个简单的HTTP服务器
- mysql数据库,mariadb数据库优化
- 爬楼梯
- Auxre RP学习笔记
- 在ubantu搭建FSL环境并配置HTconcor所遇问题
- 深入浅出 OkHttp 源码
- 自己来做一个简单的web服务器(一)理解基本的http协议
- Python多进程
- final关键字
- 深入剖析 ORA-04031 的前世今生
- 线程创建的两种方式和区别
- 折半查找(二分查找)
- opencv使用vector erase 去除部分边界
- Echarts使用心得(增加全屏按钮,点击一个图另外一个图变化,双环内外环关联,全屏左右切换)
- C++学习5:类的构造函数