UP | HOME

http-the-definitive-guide

Table of Contents

Chapter 01: Overiew of HTTP

  • 世界上的web应用程序,无论是服务器还是浏览器等,都是通过HTTP协议联系在一起的

HTTP: The Internet's Multimedia Courier

  • HTTP 底层使用了"reliable"的协议(TCP), 所以即便是地球另外一端传来的数据,也可 以保证其正确性

Web Clients and Servers

  • 网络上的信息大部分存储在服务器.存放这些信息的服务器使用的是HTTP协议.所以这样 的服务器也叫做HTTP server
  • client向server发送HTTP request请求.server使用HTTP reponse返回请求.
  • 浏览器就是一直种HTTP client

Resources

  • web resources是存储在服务器文件系统上的资源:
    • 要么是static的图片啦, 视频啦
    • 要么是一些程序,这些程序能根据你的输入来动态的产生内容

Media Type

  • 因为在HTTP上传输的文件类型很多.HTTP决定对他们进行分类.HTTP没有自己创建一个 方法,而是使用了电子邮件的"资源分类法": MIME(Multipurpose Internet Mail Extensions)
  • MIME type是一个文字的标签,比较常见的几个标签:
    • text/html: HTML文件
    • text/plain: ASCII text document
    • image/jpeg: JPEG类型图片
    • image/gif: GIF类型文件
    • video/quicktime: 苹果公司QuickTime视频
    • application/vnd.ms-powerpoint: 微软公司ppt文件

URIs

  • 每一个web resource都有一个"全名",告诉人家他的位置,这个"全名"叫做:URI
    Uniform Resource Identifer
    
  • 比如下面就是一个图片的URI, 它是全世界唯一的!
    http://www.joes-hardware.com/specials/saw-blade.gif
    

URL

  • URL的全称是
    Uniform Resource Location
    
  • 今天来看,几乎所有的URI都是URL

URN

  • URN是URI除了URL的另一种形式.
  • 好了,你可以忘记URN的存在了

Transactions

Methods

  • 每一个HTTP request都包含一个HTTP method, 常见的HTTP method如下
    HTTP method Description
    GET Send named resource from the server to the client
    PUT Store data from client into a named server resource
    DELETE Delete the named resource from a server
    POST Send client data into a server gateway application
    HEAD Send just the HTTP headers from the response for the named resource

Status Codes

  • 相对于HTTP request的method, 每一个HTTP response都有一个status code. 这个status code只有三位数字,表达一个状态. 常见的有:
    HTTP Status Code Description
    200 OK. Document returned correctly
    302 Redirect. Go someplace else to get the resource
    404 Not Found. Can't find this resource
  • HTTP response也会发送一些"reason phrase"给对方,但是程序一般只分析Status Code

Web Pages Can Consist of Multiple Objects

  • 打开一个网页的过程其实包含很多的HTTP request,比如网页中有两个图片,那么就是 两次的HTTP请求.而且这两个请求还可能在不同的服务器上

Messages TODO

Connections

TCP/IP

  • 前面说到的HTTP的"可靠"的底层通讯机制,就是TCP/IP

Connections, IP Addresses, and Port Numbers

  • HTTP传输之前要先建立TCP连接.我们知道TCP连接是一个建立在hostname和port number 基础上的协议. hostname可以在URL里面得到. 如果URL里面没有指定port number的话, port number就是80
  • 下面是一个HTTP传输的过程:
    • 浏览器从URL里面解析出hostname
    • 浏览器把hostname解析成IP地址
    • 浏览器解析port number(默认是80)
    • 浏览器建立TCP连接
    • 浏览器发送HTTP request message到server
    • 服务器发送HTTP response给浏览器
    • TCP connection被关闭.浏览器显示内容

A Real Example Using Telnet #TODO#

Protocol Versions

  • HTTP协议到现在有多个版本同时存在,应用程序需要根据版本进行处理:
    • HTTP/0.9: 1991版本,错误较多,很快被HTTP/1.0代替
    • HTTP/1.0: 第一个大规模部署的版本.
    • HTTP/1.0+: 在1.0版本身上加了很多的非正式的特性
    • HTTP/1.1: 现在广泛使用的版本.

Architectural Components of the Web

  • 在网络上,除了client和server还有很多其他的web application:
    • Proxies: 在client和server中间的中介
    • Caches: 存储了热门的网站服务器
    • Gateways: 特殊的web server, 它会连接其他应用程序
    • Tunnels: 特殊的,盲目的转发HTTP的proxies
    • Agents: "半智能"web client,可以自动发送HTTP request

Proxies

  • 代理是处在client和server之间,它接受了client的HTTP request之后,会把这个request 传递给server
  • 还有一些代理会在client和server之间起到保证传输内容安全的目的

Caches

  • Caches因为在client和server之间,本质上也是一直哦给你proxy server,只不过它不 是帮client的忙传递HTTP request, 它是存储了热门的网页,让"附近"的client不用 在向"远方"发送HTTP request, 直接从cache server返回热门资源

Gateway

  • gateway server是把client的输入改变成其他协议请求,让自己背后的其他server处 理,但是这些操作对client是黑盒的.client只知道发送HTTP request给gateway server, 而且这个gateway server也正常的HTTP reponse了. 它不知道,gateway server在背后,让其他server使用FTP协议把内容传递个了它

Tunnels

  • 我们知道proxy的话,都会对request或者response的内容进行一些分析的(比如做安全 作用), 但是tunnels是"blindly"的传递数据,不会去看内容.
  • HTTP tunnel通常是在HTTP connection上面传输非HTTP协议的内容.比如在HTTP connection 上面传输SSL加密协议的内容就构成了日后的HTTPS

Agents

  • user agent是一种client 程序,帮助user来发送HTTP request. 所有发送HTTP requst 的application都是user agent
  • 浏览器肯定是user agent,但是还有其他agent,比如spider(在网络上爬取内容的程序)

The End of the Beginning

  • 从略

For More Information

  • 从略

Chapter 02: URLs and Resources

Navigating the Internet's Resources

  • 前面已经说过了URL其实是URI的一种.除了URL, URI里面还有一部分是URN
  • 我们来分析一下下面这个URL
    http://www.joes-hardware.com/seasonal/index-fall.html
    
  • 其中:
    • "http"是URL scheme
    • "www.joes-hardware.com"是hostname
    • "seasonal/index-fall.html"是resource location
  • 我们来看看几个非http的URL例子
    mailto:president@whitehouse.gov
    ftp://ftp.losts-o-books.com/pub/complete-price-list.xls
    rtsp://www.joes-hardware.com:554/interview/cto_video
    

The Dark Days Before URLs

  • 在URL被引入以前,我们需要FTP加上Email的帮助才能分享信息

URL Syntax

  • 不同的URL在总体的URL组成结构上面大体是一致的
    <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
    
  • 并不是所有的部分都要齐全.最重要的"三剑客"是scheme, host, path, 其他的部分简介如下
    Component Description Default Value
    scheme Which protocol to use None
    user some scheme requires username to access a resource anonymous
    password password for the user App gives
    host hostname or IP address for server None
    port port number for the hostname Scheme-specific
    path local name for the resource on the server None
    params Used by some schemes to speicify input parameters,  
      params are name/value pairs. A URL can contain  
      multiple params fields, separated with rest of None
      the path by (;)  
    query Used by some schemes to active applications(db for  
      example).A URL can contain multiple query fields,  
      separated with rest of the path by (?) None
    frag A name for piece or part of the resource. The frag  
      field is NOT passed to the server when referencing  
      the object; it is used internally by the client.  
      It separated from the rest of the URL by (#) None

Schemes: What Protocl to Use

  • scheme当然就是告诉浏览器你使用哪个协议解析咯.
  • scheme不区分大小写

Hosts and Ports

  • host可以通过机器名或者ip地址的手段来提供

Usernames and Passwords

  • 有些协议需要用户名密码.如果不写的情况下:
    • 默认用户名是: anonymous
    • 默认密码是应用来定的: IE是IEUser, 火狐是mozilla
  • 一个常见例子
    ftp://anonymous:my_passwd@ftp.prep.ai.mit.edu/pub/gnu
    

Paths

  • path通常是server的硬盘路径.当然仅仅靠path有时候不定能成功定位资源.
  • path可以被"/"分成path segment

Parameters

  • parameter就是要为这次的"信息交流(request)"提供一些额外的参数
  • 每个paramter segment都可以有自己的参数, 而不是一个path只有最后能添加参数
    http://www.joes-hardware.com/hammers;sale=false/index.html;graphics=true
    

Query Strings

  • 我们在学习JSP的时候,会发现一个URL里面要包含
    • 后台java程序
    • 传递给这个java程序的参数.
  • 在http URL里面其实这个后台java程序叫做gateway resource
  • 而这个几个参数就是Query Strings啦,他们跟大部队通过(?)分开,然后相互之间通过 (&)分开
    http://www.joes-hardware.com/inventory-check.cgi?item=12731&color=blue
    

Fragments

  • URL fragment只在client端自己使用.其意义在于快速定位某个网页的位置.

URL Shortcuts

  • 在HTML文件内部,如果两个文件有相互的位置,那么通常是使用relative URL, 这样的 话就可以避免过长的URL在HTML文件内部了
    <HTML>
      <HEAD><TITLE>Joe's Tools</TITLE></HEAD>
      <BODY>
        <P> Joe's Hardware Online has the largest selection of
          <A href="./hammers.html">hammers
      </BODY>
    </HTML>
    

Shady Characters

The URL Character Set

  • URL 字符集的基础是US-ASCII
  • 为了安全性和完整性, URL在US-ASCII的基础上增加了escape sequence

Encoding Mechanisms

Character Restrictions

  • URL除了大部分的"良民"外,还有很多"刺儿头":
    • 在URL里面有特殊意义, 比如%, 比如@
    • US-ASCII里面没有定义, 比如大于0x7F的char, US-ASCII没有定义
    • 迷惑gateway和协议, 比如[]会迷惑gateway

A Sea of Schemes

  • 常见的scheme有以下几个:
    • http: 常规URL不加用户名密码就合适
    • https: 和http一样,只不过底层使用SSL, 端口默认是443
    • mailto: 其URL和常规不太一样
    • ftp
    • rtsp
    • file
    • news
    • telnet

The Future

Chapter 03: HTTP Messages

The Flow of Messages

  • 在HTTP应用之间传递的data叫做HTTP message, 传递的data会以一些meta-information 开头,然后来表示信息的内容和意义

Messages Commute Inbound to the Origin Server

  • Client发送给Server叫做inbound
  • Server处理完之后返回给Client叫做outbound

Messages Flow Downstream

  • HTTP message像水一样,永远都是downstream的.也就是说从client到server是downstream, 从server返回给client还是downstream
  • TODO upstream

The Parts of a Message

  • HTTP message 是一类格式化比较好的文本,下面是一个request例子
                            +-----------------------------+
                Start line  |GET /test/hello.txt HTTP/1.1 |
    +-------+               +-----------------------------+         +-------+
    |       |       Headers |Accept: text/*               |         |       |
    |CLIENT |====>          |Host: www.joes-hardware.com  | ======> |SERVER |
    |       |               |                             |         |       |
    +-------+               +-----------------------------+         +-------+
    
  • 下面是一个reponse的例子
                            +-----------------------------+
                Start line  |HTTP/1.0 200 OK              |
    +-------+               +-----------------------------+         +-------+
    |       |       Headers |Content-type: test/plain     |         |       |
    |CLIENT |<====          |Content-length: 19           | <====== |SERVER |
    |       |               |                             |         |       |
    +-------+               +-----------------------------+         +-------+
                       Body |Hi! I'm a message!           |
                            +-----------------------------+
    
  • HTTP message被分成了三部分:
    • start line:描述了这个message
    • header: 包含了属性信息:告诉你这个是个文本,其长度为19
    • body: 这个部分是可选的,主要是data,这部分也可以含有非text的内容

Message Syntax

  • 我们来总结下request message的格式
    <method> <request-URL> <version>
    <headers>
    
    <entity-body>
    
  • 下面是response message的格式
    <version> <status> <reason-pharse>
    <headers>
    <entity-body>
    
  • 下面是<>名词的解释:
    • method: client对于server的请求函数,常见的有GET, HEAD, POST
    • request-URL: 就是URL里面的path部分. server把自己作为host/port的组合加上 这个request-URL就可以找到资源啦
    • version: 就是HTTP的版本,一般是1.1
    • status-code: 三位数的状态码. 404非常著名
    • reason-hase: 为status-code做的解释,这个只是为了给用户读取.所以一切以 status-code的三位数字码为准.比如HTTP/1.0 200 OK 和HTTP/1.0 200 NOT OK两者 是一样的!
    • headers: 多个name + : + 说明的部分.需要注意的是 Headers的最后一行总是个 大白空行, 大白空行标志着header的结束
    • entity-body: 正文部分.不是必须有的部分

Start Lines

  • 上面的例子为例: request line包括三个部分,都用空格隔开:
    • GET:
    • /test/hello.txt
    • HTTP/1.1 (注意, 1.0以前,这个部分不必须)
  • reponse和request也非常相似.每个部分的各个成员,都是空格隔开.
  • 我们发现上例中的request没有body, 这是由于GET的method属性决定的.下面来看看 常见的HTTP函数和message body的对应关心
    Method Description Message body?
    GET Get a document from the server NO
    HEAD Get just headers fro a document from the server NO
    POST Send data to the server for processing YES
    PUT Store the body of the request on the server YES
    TRACE Trace the message through proxy servers to server NO
    OPTIONS Determine what methods can operate on a server NO
    DELETE Remove a document fromt the server NO
  • Status Code就好比函数的返回值,指示结果如何
  • HTTP Version是用来和对方进行交换信息,防止高版本的使用低版本没有的feature

Headers

  • headers的分类有如下:
    • General headers: request和response里面都能出现的
    • Request headers: 只能出现在request里面的
    • Response headers: 只能出现在response里面的
    • Entity headers: 只能表示body size和content
    • Extension headers: 在规范中没有被定义的header

Entity Bodies

  • entity body虽然是可以忽略的部分,但确是HTTP协议设计出来真正要传递的东西.
  • entity body可以传递各种数据: image, video, software application…等等

Methods

Safe Methods

  • 所谓"安全函数"是指这些函数不会在server端造成什么影响. GET和HEAD就是这种函 数.他们索取server的内容,但不会改变server的内容.而POST就不是"安全函数", 它 会改变server的内容.

GET

  • GET是最简单的函数,要求server提供资源
                       +-------------------------------------+
                       | GET /seasonal/index.html HTTP/1.1   |
                       | Host: www.joes-hardware.com         |
                       | Accept: *                           |
                       +-------------------------------------+
                       Request message
                 ============================================>
                 |
    +------------+                                                 +------------+
    |  CLIENT    |                                                 |  SERVER    |
    +------------+                                                 +------------+
                                         Response message          |
                       <============================================
                       +-------------------------------------+
                       | HTTP/1.1 200 OK                     |
                       | Content-Type: text/html             |
                       | Content-Length: 617                 |
                       |                                     |
                       | <HTML>                              |
                       | <HEAD><TITLE>joe</TITLE>            |
                       |  .....                              |
                       +-------------------------------------+
    

HEAD

  • HEAD和GET相似,只不过只要求资源的header部分(说是header, 但是Start line当然会 有, 不过entity body部分是肯定没有了).
                       +-------------------------------------+
                       | HEAD /seasonal/index.html HTTP/1.1  |
                       | Host: www.joes-hardware.com         |
                       | Accept: *                           |
                       +-------------------------------------+
                       Request message
                 ============================================>
                 |
    +------------+                                                 +------------+
    |  CLIENT    |                                                 |  SERVER    |
    +------------+                                                 +------------+
                                         Response message          |
                       <============================================
                       +-------------------------------------+
                       | HTTP/1.1 200 OK                     |
                       | Content-Type: text/html             |
                       | Content-Length: 617                 |
                       +-------------------------------------+
    
  • 仅仅获取资源的header有如下作用:
    • 看看资源的属性
    • 看看资源是否存在
    • 看看资源知否被更改过

PUT

  • PUT是client请求把当前的页面(内容从entity body里面取得)添加到server host name + request的<requestURL> 所在的位置
                   +-------------------------------------+
                   | PUT /product-list.txt HTTP/1.1      |
                   | Host: www.joes-hardware.com         |
                   | Content-type: text/plain            |
                   | Content-length: 34                  |
                   |                                     |
                   | Updated product list coming soon!   |
                   +-------------------------------------+
                   Request message
             ============================================>
             |
+------------+                                                 +------------+     +----------------------+
|  CLIENT    |                                                 |  SERVER    |====>|Creat txt file on disk|
+------------+                                                 +------------+     +----------------------+
                                     Response message          |
                   <============================================
                   +-------------------------------------------------------+
                   | HTTP/1.1 201 Created                                  |
                   | Location: http://www.joes-hardwar.com/product-list.txt|
                   | Content-Length: 47                                    |
                   |                                                       |
                   | http://www.joes-hardware.com/product-list.txt         |
                   +-------------------------------------------------------+
  • PUT运行你更改server内容,所以有可能需要你密码登录

POST

  • POST和PUT相似,但是:
    • PUT是要求server把我提供的数据摆放在特定的位置
    • POST是给server提供一些数据,server来利用这些数据来做server想做的事情, 没 有强迫server
  • POST最常用的场景,是我们提供一组user/password的组合给server, server拿到以后, 去数据库比对,成功后让用户登录,否则提示密码错误.
                   +-------------------------------------+
                   | POST /inventory-check.cgi HTTP/1.1  |
                   | Host: www.joes-hardware.com         |
                   | Content-type: text/plain            |
                   | Content-length: 18                  |
                   |                                     |
                   | item = bandsaw 2467                 |
                   +-------------------------------------+
                   Request message
             ============================================>
             |
+------------+                                                 +------------+ bandsaw  +------------+
|  CLIENT    |                                                 |  SERVER    |<========>| CGI Program|
+------------+                                                 +------------+  2647    +------------+
                                     Response message          |
                   <============================================
                   +-------------------------------------+
                   | HTTP/1.1 200 OK                     |
                   | Content-Type: text/html             |
                   | Content-Length: 37                  |
                   |                                     |
                   | The bandsaw model 2467 is in stock! |
                   | <HEAD><TITLE>joe</TITLE>            |
                   |  .....                              |
                   +-------------------------------------+

TRACE

  • 一个http request要达到server,会经历防火墙,代理,gateway等等.每次经过这些应用 的时候,都有可能会更改原来的HTTP request. TRACE函数允许client来看看他的request 最终到达server的时候,是个什么样子.
                +-------------------------------------+                  +-------------------------------------+
                | TRACE /product-list.txt HTTP/1.1    |                  | TRACE /product-list.txt HTTP/1.1    |
                | Accept: *                           |                  | Host: www.joes-hardware.com         |
                | Host: www.joes-hardware.com         |                  | Accept: *                           |
                +-------------------------------------+                  | Via: 1.1 proxy2.company.com         |
                                                                         +-------------------------------------+
                Request message                                          Request message
             ==========================================> +------------+ =======================================>
             |                                           |            |
+------------+                                           |            |                                           +------------+
|  CLIENT    |                                           |   PROXY    |                                           |  SERVER    |
+------------+                                           |            |                                           +------------+
                                  Response message       |            |                   Response message        |
                <======================================= +------------+ <==========================================
                +-------------------------------------+                  +-------------------------------------+
                | HTTP/1.1 200 OK                     |                  | HTTP/1.1 200 OK                     |
                | Content-Type: text/html             |                  | Content-Type: text/html             |
                | Content-Length: 96                  |                  | Content-Length: 96                  |
                | Via: 1.1 proxy3.company.com         |                  |                                     |
                |                                     |                  | TRACE /product-list.txt HTTP/1.1    |
                | TRACE /product-list.txt HTTP/1.1    |                  | Host: www.joes-hardware.com         |
                | Host: www.joes-hardware.com         |                  | Accept: *                           |
                | Accept: *                           |                  | Via: 1.1 proxy3.company.com         |
                | Via: 1.1 proxy3.company.com         |                  +-------------------------------------+
                +-------------------------------------+
  • TRACE有其局限性.因为client和server中间的,比如proxy会根据不同的method来改变 http request, 这是TRACE无法察觉的

OPTIONS

  • client可以通过这个函数来知道server的option:比如支持哪些函数
                   +-------------------------------------+
                   | OPTIONS * HTTP/1.1                  |
                   | Host: www.joes-hardware.com         |
                   | Accept: *                           |
                   +-------------------------------------+
                   Request message
             ============================================>
             |
+------------+                                                 +------------+ Since the request is for
|  CLIENT    |                                                 |  SERVER    | options on ALL resource,
+------------+                                                 +------------+ the server just returns
                                     Response message          |              the methods it supports for
                   <============================================              its resources
                   +-------------------------------------+
                   | HTTP/1.1 200 OK                     |
                   | Allow: GET, POST, PUT, OPTIONS      |
                   | Content-Length: 0                   |
                   +-------------------------------------+

DELETE

  • delete在client看来,就是非常简单了."请求"server删除client提供的位置的资源.
                       +-------------------------------------+
                       | HEAD /seasonal/index.html HTTP/1.1  |
                       | Host: www.joes-hardware.com         |
                       | Accept: *                           |
                       +-------------------------------------+
                       Request message
                 ============================================>
                 |
    +------------+                                                 +------------+
    |  CLIENT    |                                                 |  SERVER    |
    +------------+                                                 +------------+
                                         Response message          |
                       <============================================
                       +-------------------------------------+
                       | HTTP/1.1 200 OK                     |
                       | Content-Type: text/html             |
                       | Content-Length: 617                 |
                       +-------------------------------------+
    
  • 但是, client却不能保证delete行为一定能成功, 它只是"请求"server删除.具体是否 能成功,掌握在server手里.server可以override client的request(在不告知client 的情况下)

Extension Methods

  • 在规范的定义之外,还有一些extension的函数,比如LOCK, MKCOL, COPY, MOVE等
  • 这些函数proxy应该尽量"无脑传递"给后面的应用.如果不想传递下去,需要返回501(Not Implemented)这个status code

Status Codes

100-199: Informational Status Codes

  • Status Code中100表示的意义是"Continue". 它是我这么一种特殊的情形准备的
    HTTP Client想发送一个entity body给server, 但是它不确定server是否会接受,
    所以先发一个request,得到"Continue"的答复之后,再开始真正传递entity body
    
  • 但是100-Continue却会有很多种情况下被"误用", 比如你没有发送"希望发给server大 数据"的request(名字叫做Expect header),却得到了server的100-Continue的回复.
  • server收到Expect header,有三种选择:
    • 不支持"大数据",(无论client已经等不及把数据发送过来了)直接发送error code
    • 支持大数据,返回100-Continue
    • 支持大数据,但是还没有来得及发送100-Continue,Client的数据就已经到了,那么 默默的接受就好了,100-Continue不用再发给client了. 同样的,在client这边,等 了很久server还没有反应,就直接发送数据就好了.
  • 在client和server之间的proxy,当它遇到Expect header的时候:
    • 如果它知道下一个hop是支持HTTP/1.1的,那么"无脑转发"
    • 如果它"不"知道下一个hop的HTTP版本,那么"无脑转发"
    • 如果它明确知道下一个版本支持HTTP/1.1以下版本,那么直接发烧哦感417 Expectation Failed error

200-209: Success Status Code

  • 200 意味着"OK": client的request被接受,response的entity body里面包含请求的 资源
  • 201 意味着"Created": client要求创建的资源(比如PUT)已经建立成功
  • 202 意味着"Accepted": client的request已经被server所接受了,但是server不保证 什么时候会实现它!server一般会在response的entity body里面说明合适可以完成request
  • 203 意味着"Non-Authoritative Information": entity header信息有问题!
  • 204 意味着"No Content": 当前的response是有status line和header的,但是却没有 entity body,这个通常在浏览器"刷新"的时候使用
  • 205 意味着"Reset Content": 告诉浏览器清除"any HTML form elements on the current page"
  • 206 意味着"Partial Content": range request成功了(因为client就发送了"一部分" request,所以response也是一部分)

300-399: Redirection Status Code

  • 300 意味着"Multiple Choices": 比如client request了一个网页, server reponse 一个300,告诉它我们有"多个语言版本", 你要读哪个?
  • 301 意味着"Moved Permanently": client request了一个URL, 但是server reponse 给他说,这个URL已经被转移到另外一个URL里面了.(需要在response的header的Location 部分里指明这个URL)
                       +-------------------------------------+
                       | GET /pet-products.txt HTTP/1.1      |
                       | Host: www.joes-hardware.com         |
                       | Accept: *                           |
                       +-------------------------------------+
                       Request message
                 ============================================>
                 |
    +------------+                                                 +---------------------+
    |  CLIENT    |                                                 |www.joes-hardware.com|
    +------------+                                                 +---------------------+
                                         Response message          |
                       <============================================
                       +-------------------------------------+
                       | HTTP/1.1 301 OK                     |
                       | Location: http://www.gentle.com/    |
                       | Content-Type: text/html             |
                       | Content-Length: 45                  |
                       |                                     |
                       | Please go to our partner site,      |
                       | www.gentle.com                      |
                       +-------------------------------------+
    
                       +-------------------------------------+
                       | GET /pet-products.txt HTTP/1.1      |
                       | Host: www.gentle.com                |
                       | Accept: *                           |
                       +-------------------------------------+
                       Request message
                 ============================================>
                 |
    +------------+                                                 +---------------------+
    |  CLIENT    |                                                 |   www.gentle.com    |
    +------------+                                                 +---------------------+
                                         Response message          |
                       <============================================
                       +-------------------------------------+
                       | HTTP/1.1 200 OK                     |
                       | Content-Type: text/html             |
                       | Content-Length: 3307                |
                       |                                     |
                       |  .....                              |
                       +-------------------------------------+
    
  • 302 意味着"Found": 和301完全一样,只不过server返回的Location header是一个临 时的URL地址,资源并非永久的改变到了那个URL
  • 303 意味着"See Other": client request的资源应该从另外一个URL里面取得,这个URL 会被放在response的Location header里面,这个303也是为一种特别的情况准备的
    比如我们原来登陆的时候使用http://example.com/login + POST request来登陆
    网站, server验证用户名密码正确以后,需要让client 跳转到另外一个URL(而不能再是
    http://example.com/login,而应该是http://example.com/user/1234之类)
    
  • 304 意味着"Not Modified": client可能会发出一些"conditionl"的请求,比如GET 一个资源知否被修改(还可以加一些条件,比如在某个日期之后修改过么?下面例子中这 个限制条件通过一个header的tag,If-Modified-Since来实现).然后server返回304意 思就是,我们没修改
                 +-------------------------------------------------+
                 | GET /seasonal/index.html HTTP/1.1               |
                 | Host: www.joes-hardware.com                     |
                 | Accept: *                                       |
                 | If-Modified-Since: Fri, Oct 3, 1997 02:16:00 GMT|
                 +-------------------------------------------------+
                 Request message
                 ==================================================>
                 |
    +------------+                                                 +------------+
    |  CLIENT    |                                                 |  SERVER    |
    +------------+                                                 +------------+
                                         Response message          |
                       <============================================
                       +-------------------------------------+
                       | HTTP/1.1 304 Not Modified           |
                       |  .....                              |
                       +-------------------------------------+
    
  • 305 意味着"Use Proxy": 告诉client,某个资源必须通过proxy来取得. proxy的位置 被放到了Location header里面
  • 306 意味着"Unused": 还没使用
  • 307 意味着"Temporary Redirect": 和301一样,不同的是在Location header里面指定 了一个新的URL, client应该使用这个URL

400-499: Client Error Status Code

  • 下面的错误都是由于request有问题导致, server没法服务的
  • 400 意味着"Bad Request": 告诉client,你发送了恶意的请求
  • 401 意味着"Unauthorized": 告诉client,首先要经过认证,才能获取你要的资源
  • 402 意味着"Payment Required": 没有使用
  • 403 意味着"Forbidden": server拒绝了client的请求,server可以在reponse的entity body里面说明原因,也可以不说明.
  • 404 意味着"Not Found": server无法找到client提供的URL, 一般情况下server都会 在自己的entity body里面包含一个"更好看的404错误HTML页面"返回给client,进而返回 给用户
  • 405 意味着"Method Not Allowed": client发送了一个URL,外加一个method,如果server 不支持这个method的话,会返回这个status code, 外加在自己的Accept里面把自己支 持的都列举一遍.
  • 406 意味着"Not Acceptable": client会在request里面声明自己要什么类型的entity body, 如果server满足不了,就会返回这个.
  • 407 意味着"Proxy Authentication Required": 和401类似, 只是authentication需 要proxy server
  • 408 意味着"Request Timeout": 如果client的request太久了,sever可以关闭connection 并且返回这个status code
  • 409 意味着"Conflict": client的request造成了资源的conflict
  • 410 意味着"Gone": 和404一样,只不过server告诉client"自己曾经拥有过那个URL"
  • 411 意味着"Length Required": server要求在request里面包含Content-Length header
  • 412 意味着"Precondition Failed": 如果client 发送的request里面有 Expect header的话,那么这是一个Conditional Request, 但是如果其中一个condition failed的话 server就会返回这个status code
  • 413 意味着"Request Entity Too Large": client的entity大到server处理不了
  • 414 意味着"Request URI Too Long": URL太长
  • 415 意味着"Unsupported Media Type": 不支持的媒体格式
  • 416 意味着"Requested Range": client请求的range不合理
  • 417 意味着"Expectation Failed": client提出了一些expectation, 但是server满足不了

500-599: Server Error Status Code

  • 下面的错误都是由于server自己有问题导致没法服务的
  • 500 意味着"Internal Server Error": 当server遇到了自己内部的问题,无法为client服务的时候
  • 501 意味着"Not Implemented": client提出的要求超出了server的当前能力的时候
  • 502 意味着"Bad Gateway": 发出这个status code的server通常是一个proxy(也就是 中间环节), 当后面的环节联系不到的时候,它只好给client发送这个status code
  • 503 意味着"Service Unavailable": server告诉client,"我目前无法服务您,但是过 一会我就可以了". 当一个server知道资源在"不久的将来"会有的话,会返回这个status code并且会在reponse里面包含Retry-After header
  • 504 意味着"Gateway Timeout": 和408类似,但是,不是client的request太久,而是 Proxy(中间server)发送给下一级server的request实在是太慢了.
  • 505 意味着"HTTP Version Not Supported": 当server发现client发来的request里面 的HTTP版本太新了,自己不支持的时候

Headers

  • 前面我们也看到了,在method和status的部分里面,到处都充斥着header的身影,在HTTP 协议里面,header也负责传递着很多信息.

General Headers

  • 指那些提供非常基本功能的header.
  • Header Connection: 让server和client来指定request/response的option
  • Header Date: 提供message创建的时间
  • Header MIME-Version: 提供发送者MIME的版本信息
  • Header Trailer: 和chunked transfer encoding有关
  • Header Transfer-Encoding: 告诉接受者对message的解析使用什么encoding
  • Header Upgrade: 告诉server,我们client其实还可以提供的"Upgrade"的协议版本
  • Header Via: 罗列这个message经历了哪些中间件(proxies, gateways)
  • Header Cache-Control: 和message一同发送的,是自己那些部分被cache了
  • Header Pragma: 和message一同发送一些信息,不仅限于cache的部分

Request Headers

  • 指那些只能存在于request里面的header.
  • Header Client-IP: 提供了client machine的IP地址
  • Header From: 提供了client用户的电子邮箱地址
  • Header Host: client的hostname和port
  • Header Referer: 当前的URL
  • Header UA-Color: client机器的显示色彩的能力
  • Header UA-CPU: client的CPU制造商
  • Header UA-Disp: client的显示器能力
  • Header UA-OS: client的操作系统
  • Header UA-Pixels: client的屏幕像素
  • Header UA-Agent: client哪个应用发出了当前的request
Accept Headers
  • Header Accept: 告诉server,你发送哪些媒体类型,我们client可以接受
  • Header Accept-Charset: 告诉server,你发送哪些charset,我们client可以接受
  • Header Accept-Encoding: 告诉server,你发送哪些encoding,我们client可以接受
  • Header Accept-Language: 告诉server,你发送哪些language,我们client可以接受
  • Header TE: 告诉server,你发送哪些扩展名文件,我们client可以接受
Conditional request headers
  • 就像编程一样,http的数据交换也可以基于一些条件判断:比如, 一个client已有一份 doc的拷贝,它想询问一下server,这个doc有没有更新,有更新的话,再发给它一个.否 则不需要发了.
  • Header Except: 允许让client列举当前request需要让server满足哪些behavior
  • Header If-Match: 当前entity tag和document的entity tag相似的时候才获取
  • Header If-Modified-Since: 设定一个日期,在这个日期之后被修改过,才获取这个资源
  • Header If-None-Match: 和If-Match相反. document的entity tag不满足的时候,才获取
  • Header If-Range: 允许获取某个range内的document
  • Header If-Unmodifed-Since: 设定一个日期,在这个日期之后"没有"被修改过,才获取这个资源
  • Header Range: 如果server支持range request,那么取得一系列的资源
Reauest security headers
  • HTTP也自带了一些安全机制,让client在"认证"以后,才能取得某些资源
  • Header Authorization: client包含一些让server看到的"认证信息"
  • Header Cookie: client发送一个token给server: 这不是一种真正的security header, 但是有点作用
  • Header Cookie2: 展示request支持的cookies的版本
Proxy request headers
  • Header Max-Forwards: request在到达server之前,允许经过的proxy个数
  • Header Proxy-Authorization: client包含一些让中间的proxy看到的"认证信息"
  • Header Proxy-Connection: 使用proxy建立连接的时候使用

Response Headers

  • response也有自己的一些header, 主要的功能是为client提供一些信息, 让client更 了解server的功能,从而再后面优化自己的request
Negotiation headers
  • 如果server上面对client的request提供了多个版本(比如多个语言),那么就要在response 里面使用negotiation header来和client交流
  • Header Accept-Ranges: server可以接受的资源range
  • Header Vary: server方一系列的可能导致vary的header
Response security headers
  • 安全方面的response header主要是HTTP的"认证"
  • Header Proxy-Authenticate: proxy认为的对client的一系列的challenge
  • Header Set-Cookie: 用来在client端设置一个token,从而让server能够认识client
  • Header Set-Cookie2: 和Set-Cookie相似
  • Header WWW-Authenticate: Server认为的对client的一系列的challenge

Entity Headers

  • enttity header主要告诉那些entity数据的接收方,我们的entity主要是为什么服务的
  • Header Allow: 列举一下哪些request method可以在当前的entity上面进行操作
  • Header Location: 告诉client, 资源"真正"的位置.有可能是一个新的URL
Content headers
  • Header Content-Base: URL的主体部分URL (没有在RFC2616中定义)
  • Header Content-Endocing: entity body的encoding信息
  • Header Content-Language: entity body是中文,英文,还是日文
  • Header Content-Length: entity body的长度
  • Header Content-Location: 资源实际的存放地点
  • Header Content-MD5: entity的MD5 checksum
  • Header Content-Range: 从整个resource来看,entity的range
  • Header Content-Type: entity body的文件类型
Entity caching headers
  • Header ETag: entity body相关的entity tag
  • Header Expires: entity body 在某个时间点以后就会"过期": 无法从original source再读取了
  • Header Last-Modified: entity body上一次被修改的时间

Chapter 04: Connection Management

TCP Connections

  • TCP/IP是一种以"packet"交换为核心的传输层/网络层的协议.HTTP是建立在TCP/IP上 的应用层协议
  • 我们以浏览器访问http://www.joes-hardware.com:80/power-tools.html 的过程为例 来看看HTTP是如何和TCP/IP联系起来的:
    1. 从URL里面获取hostname=> www.joes-hardware.com
    2. 浏览器把上面得到的hostname通过DNS来解析得到IP=> 202.43.78.3
    3. 从URL里面得到server的端口80
    4. 浏览器建立TCP连接在=> 202.43.78.3:80
    5. TCP连接稳固建立起来以后,client发送HTTP GET request给server
    6. server收到client的GET request后,经过处理返回client以response
    7. 浏览器关闭这个TCP连接.

TCP Reliable Data Pipes

  • TCP协议能为HTTP协议保证的,其实是一个"可靠的字节传送管道"(reliable bit pipe) 在这个管道里面,client发送的字节能够以正确的顺序,完整的呈现给server
  • 换句话说,屏蔽掉TCP/IP, 在HTTP看来,连接就是能够顺序传输bit的管道

TCP Streams Are Segmented and Shipped by IP Packets

  • TCP在处理HTTP发送给它的问文本的时候,是把数据集合起来,然后又分开,分成不同的 segment, 因为每次在网络上传递的数据量不能太大.
  • 然后segment又被IP包装成不同的packet,最终在网络上传播
  • 上面两步对于HTTP来说,是完全视而不见的.
  • 所以总体来说是HTTP被包裹成TCP(有可能是多个), 然后TCP再被包过程IP(一个对一个)

    http-tcp-ip.png

    Figure 1: http-tcp-ip.png