Coyote for Http11: org.apache.coyote.http11

原创 2008年09月29日 04:53:00

概述

这个包支持http1.1协议,内部分为三类:ARP、NIO、普通http,这里只对最基本的普通http(使用java的IO流,而非NIO流)作简单研究

根据上一篇提到的coyote的接口,这个包主要有以下几个类:

  • Http11Protocol,实现了ProtocolHandler接口
  • Http11Processor,实现了ActionHook接口
  • InternalInputBuffer,实现了InputBuffer接口
  • InternalOutputBuffer,实现了OutputBuffer接口
  • InputFilter和OutputFilter接口,具体的实现类在 org.apache.coyote.http11.filters 中

下面是这几个类之间的关系,随便画了一幅图,凑合着看看^_^

coyote http11

大致过程如下:

  1. JIOEndpoint起到一个连接池的作用,可以启动多个socket监听,一旦收到浏览器发来的请求后,把对应的socket对象通过process方法,传递给Http11ConnectionHandler,再交给Http11Processor
  2. Http11Processor内部有个InternalInputBuffer(图上未画出),InternalInputBuffer是真正对socket中包含的字节流进行处理的,它将字节转换为Request
  3. Request流经过滤器filters,最后到达实现了Adapter接口的容器,coyote的工作就到此为止,回头继续处理下一个socket

下面是几个主要类的功能介绍

Http11Protocol

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的作用就是把所有这些和连接有关的组件包装起来,统一设置它们的属性,并负责控制它们的生命周期

Http11Processor

这个类的作用就是生成Request(当然本质上还是InternalInputBuffer完成的),交给实现了Adapter接口的容器

这个类有adapter、request、response、inputbuffer、outputbuffer等几个关键字段,其余就是和http协议有关的字段了,还有很多方法是关于http协议的,水平有限实在看不懂,估计要先详细学习一遍http协议才能读懂,这里就略过,直接看最关键的process(Socket socket) 方法

该方法依次做如下的工作:

  1. 把socket的inputstream和outputstream分别与inputbuffer和outputbuffer关联起来
  2. 通过inputBuffer.parseRequestLine() 和 inputBuffer.parseHeaders() 方法,解析socket字节流中的头字段,写到request中
  3. 通过prepareRequest方法组装filter,用于处理http消息体
  4. adapter.service(request, response) 把生成的request和response交给容器处理
  5. 如果一切顺利,开始处理socket中的下一个请求(因为http1.1是支持持续连接的,所以一个socket中可能包含多个请求),循环回到第一步
  6. 如果出错,则设置response的响应码,并终止循环

prepareRequest方法,用于准备inputbuffer的filter,这里简单写一下。关于filter的机理,请看:

  1. 根据之前对http头字段的解析,分别检查protocol、method、expect、user-agent和MIMEheaders,此外还检查URI的格式(是否符合:protocol://host:port/ 的格式)
  2. 准备加载filter
  3. 如果有transfer-encoding这个头字段(貌似是编码格式,可以有多个,逗号分割),则分别设置不同编码的filter
  4. 校验content-length头字段

InternalInputBuffer

研究这个类可以从Http11Processor的process方法入手

这个类的主要功能是:从socket中获取字节流,将字节读入一个缓冲区buf,然后从缓冲区逐个解析http请求头以及内容

主要的字段:

  • request:Request对象,从缓冲区中解析出的信息会写入request中
  • buf:缓冲区,从socket的inputstream读取的字节放入此缓冲区中
  • headers : MimeHeaders,保存以键值对出现的报头,也就是除去请求报文第一行之后的所有头部

具体的http请求报头的规范,可以参考W3C,或者
http://www.yuanma.org/data/2008/0827/article_3143.htm

parseRequestLine()

解析请求报头的第一行,形如:GET http://class/download.microtool.de:80/somedata.exe,包括请求方法(GET or POST)、协议(http)、URI。解析后,放入request中

parseHeader()

解析刚才parseRequestLine()之后的报头,由于RequestLine之后的报头都是以“:”分隔的键值对,因此每执行一次本方法,则在headers 中加入一个键值对,如果格式错误则返回false

endRequest()

结束一个request的处理,把多余的字节清空

nextRequest()

准备下一个request的处理,这个方法主要用来对所有的标记位和指针进行复位

fill()

从socket的inputstream中读出一定数量的字节,填充buf,在很多方法中都有用到。例如解析报头时,当发现buf已经读取完了,就调用fill重新填充buf,如果inputstream已经读完了,fill返回false

InternalOutputBuffer的一些疑问

根据inputbuffer的理解,可以大致猜到,这个类是用来从response中读取信息,然后写入socket的outputstream中,返回给客户端的

类里面的方法许多也和inputbuffer一样,但令人纳闷的是居然还有nextRequest()、endRequest()方法,而里面做的事情却是针对response的(OutputBuffer本来就只有response),看不出任何与request有关的东西。难道是作者拷代码过来的时候忘了改方法名称?

最后,觉得这个类和InternalInputBuffer实在有太多相似之处,为什么不抽象出一个父类呢?

org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header

07-Jan-2018 14:28:44.765 INFO [http-nio-8080-exec-8] org.apache.coyote.http11.Http11Processor.servic...
  • myth_g
  • myth_g
  • 2018年01月07日 16:26
  • 379

Error parsing HTTP request header

原文地址:http://www.w2bc.com/Article/15349 手机客户端向服务器提交Http请求时,Tomcat抛出错误: 十二月 31, 2014 2:32:45 下午 o...
  • qxd100
  • qxd100
  • 2015年10月10日 10:02
  • 19010

Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors

tomcat进行http request解析的时候报错,并将错误返回给客户端了,具体的错误如下: org.apache.coyote.http11.AbstractHttp11Processor....
  • hsbirenjie
  • hsbirenjie
  • 2015年02月02日 13:54
  • 55200

Error parsing HTTP request header

做的项目,ie总是无法访问,火狐、谷歌可以访问。 表单提交部分代码: tomcat 报错: Error parsing HTTP request header  Note: further occu...
  • efine_dxq
  • efine_dxq
  • 2017年03月05日 21:47
  • 25739

tomcat报错Error parsing HTTP request header处理

Error parsing HTTP request header
  • qq_35592011
  • qq_35592011
  • 2017年05月18日 12:05
  • 4747

tomcat优化-有改protocol 和 缓存 集群方案 转载自http://passover.blog.51cto.com/2431658/732629

在线上环境中我们是采用了tomcat作为Web服务器,它的处理性能直接关系到用户体验,在平时的工作和学习中,归纳出以下七种调优经验。 1. 服务器资源     服务器所能提供CPU、内存、硬盘的性...
  • super_marioli
  • super_marioli
  • 2014年05月27日 22:44
  • 13003

tomcat启动一直报空指针错误

今天部署项目的时候报出这样的错误: 十一月 28, 2013 2:30:02 下午 org.apache.coyote.http11.AbstractHttp11Processor process ...
  • jueshengtianya
  • jueshengtianya
  • 2014年01月10日 18:52
  • 5043

tomcat 内存溢出问题

from: http://www.iteye.com/problems/10072 最近客户反映经常抛出内存溢出的异常,在下面贴出一部分异常信息,希望大家能帮我分析一下,找出原因,万分感激!...
  • nomad2
  • nomad2
  • 2012年01月01日 19:17
  • 6695

org.apache.catalina.core.StandardHostValve.customException Processing ErrorPage[errorCode=500, locat

Confluence Wiki启动报错: 05-Sep-2016 03:28:41.105 SEVERE[http-nio-8090-exec-1] org.apache.catalina.core...
  • proaway
  • proaway
  • 2016年09月05日 11:07
  • 2310

Http11: org.apache.coyote.http11

noclassdef   Http11: org.apache.coyote.http11 两种解决方法。。 一是换jdk。 二是少jar...
  • www19940501a
  • www19940501a
  • 2014年03月06日 16:41
  • 1478
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Coyote for Http11: org.apache.coyote.http11
举报原因:
原因补充:

(最多只允许输入30个字)