这个包支持http1.1协议,内部分为三类:ARP、NIO、普通http,这里只对最基本的普通http(使用java的IO流,而非NIO流)作简单研究
根据上一篇提到的coyote的接口,这个包主要有以下几个类:
下面是这几个类之间的关系,随便画了一幅图,凑合着看看^_^
大致过程如下:
下面是几个主要类的功能介绍
http1.1协议的ProtocolHandler实现
主要包含
Http11ConnectionHandler(内部类)
JIoEndpoint
ServerSocketFactory(J2SE)
在init方法中,将ServerSocketFactory、Http11ConnectionHandler传递给JIoEndpoint进行初始化
然后,在start、pause等方法中,同样也会调用JIoEndpoint的start、pause
JIoEndpoint可以设置最大线程数、优先级、端口等属性,根据这些属性,JIoEndpoint生成对应数量的ServerSocketFactory,用于监听相应的端口,一旦收到http请求,JIoEndpoint则将对应的Socket实例传递给Http11ConnectionHandler.process方法进行处理;而Http11ConnectionHandler里头会有一个processor实例,这个实例真正处理socket并将其中的数据转换为Request对象
因此,ProtocolHandler的作用就是把所有这些和连接有关的组件包装起来,统一设置它们的属性,并负责控制它们的生命周期
这个类的作用就是生成Request(当然本质上还是InternalInputBuffer完成的),交给实现了Adapter接口的容器
这个类有adapter、request、response、inputbuffer、outputbuffer等几个关键字段,其余就是和http协议有关的字段了,还有很多方法是关于http协议的,水平有限实在看不懂,估计要先详细学习一遍http协议才能读懂,这里就略过,直接看最关键的process(Socket socket) 方法
该方法依次做如下的工作:
prepareRequest方法,用于准备inputbuffer的filter,这里简单写一下。关于filter的机理,请看:
研究这个类可以从Http11Processor的process方法入手
这个类的主要功能是:从socket中获取字节流,将字节读入一个缓冲区buf,然后从缓冲区逐个解析http请求头以及内容
主要的字段:
具体的http请求报头的规范,可以参考W3C,或者
http://www.yuanma.org/data/2008/0827/article_3143.htm
解析请求报头的第一行,形如:GET http://class/download.microtool.de:80/somedata.exe,包括请求方法(GET or POST)、协议(http)、URI。解析后,放入request中
解析刚才parseRequestLine()之后的报头,由于RequestLine之后的报头都是以“:”分隔的键值对,因此每执行一次本方法,则在headers 中加入一个键值对,如果格式错误则返回false
结束一个request的处理,把多余的字节清空
准备下一个request的处理,这个方法主要用来对所有的标记位和指针进行复位
从socket的inputstream中读出一定数量的字节,填充buf,在很多方法中都有用到。例如解析报头时,当发现buf已经读取完了,就调用fill重新填充buf,如果inputstream已经读完了,fill返回false
根据inputbuffer的理解,可以大致猜到,这个类是用来从response中读取信息,然后写入socket的outputstream中,返回给客户端的
类里面的方法许多也和inputbuffer一样,但令人纳闷的是居然还有nextRequest()、endRequest()方法,而里面做的事情却是针对response的(OutputBuffer本来就只有response),看不出任何与request有关的东西。难道是作者拷代码过来的时候忘了改方法名称?
最后,觉得这个类和InternalInputBuffer实在有太多相似之处,为什么不抽象出一个父类呢?