当前位置: 首页 > news >正文

保定公司做网站网站关键词快速优化

保定公司做网站,网站关键词快速优化,建设工程方面的资料在哪个网站下载比较方便,搜狐快站做网站教程前面提到tomcat请求处理的io交互过程,现在开始看下经过io交互后tomcat是怎么处理请求数据的。首先到AbstractProtocol.java中的process方法,注意这个方法是在tomcat线程池分配的线程调用的。生成用来对请求字节流数据进行解析的Http11Processor。 public…

前面提到tomcat请求处理的io交互过程,现在开始看下经过io交互后tomcat是怎么处理请求数据的。首先到AbstractProtocol.java中的process方法,注意这个方法是在tomcat线程池分配的线程调用的。生成用来对请求字节流数据进行解析的Http11Processor。

        public SocketState process(SocketWrapperBase<S> wrapper, SocketEvent status) {......Processor processor = (Processor) wrapper.takeCurrentProcessor();......try {......if (processor == null) {processor = recycledProcessors.pop();......}if (processor == null) {processor = getProtocol().createProcessor();register(processor);......}do {state = processor.process(wrapper, status);......} while (state == SocketState.UPGRADING);}
//默认为 Http11Processor    protected Processor createProcessor() {Http11Processor processor = new Http11Processor(this, adapter);return processor;}

然后在生成的Http11Processor的service方法中对请求字节流数据进行正式的解析。

  • 请求行解析
    请求行格式如GET / HTTP/1.1,首先跳过空行,然后读取请求方式,再读取请求url,之后解析协议版本,逻辑很清晰。注意这里是在fill(false)方法中读取nio的ByteBuffer的数据。
boolean parseRequestLine(boolean keptAlive, int connectionTimeout, int keepAliveTimeout) throws IOException {// check stateif (!parsingRequestLine) {return true;}//// Skipping blank lines// 跳过空行if (parsingRequestLinePhase < 2) {do {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (keptAlive) {// Haven't read any request data yet so use the keep-alive// timeout.wrapper.setReadTimeout(keepAliveTimeout);}//读取nio中ByteBuffer中数据if (!fill(false)) {// A read is pending, so no longer in initial stateparsingRequestLinePhase = 1;return false;}// At least one byte of the request has been received.// Switch to the socket timeout.wrapper.setReadTimeout(connectionTimeout);}if (!keptAlive && byteBuffer.position() == 0 && byteBuffer.limit() >= CLIENT_PREFACE_START.length) {boolean prefaceMatch = true;for (int i = 0; i < CLIENT_PREFACE_START.length && prefaceMatch; i++) {if (CLIENT_PREFACE_START[i] != byteBuffer.get(i)) {prefaceMatch = false;}}if (prefaceMatch) {// HTTP/2 preface matchedparsingRequestLinePhase = -1;return false;}}// Set the start time once we start reading data (even if it is// just skipping blank lines)if (request.getStartTime() < 0) {request.setStartTime(System.currentTimeMillis());}chr = byteBuffer.get();} while (chr == Constants.CR || chr == Constants.LF);byteBuffer.position(byteBuffer.position() - 1);parsingRequestLineStart = byteBuffer.position();parsingRequestLinePhase = 2;}//解析请求方式if (parsingRequestLinePhase == 2) {//// Reading the method name// Method name is a token//boolean space = false;while (!space) {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {return false;}}// Spec says method name is a token followed by a single SP but// also be tolerant of multiple SP and/or HT.int pos = byteBuffer.position();chr = byteBuffer.get();//http请求的开头字符为请求方式,以 空格(' ')或制表('\t')结尾if (chr == Constants.SP || chr == Constants.HT) {space = true;request.method().setBytes(byteBuffer.array(), parsingRequestLineStart,pos - parsingRequestLineStart);} else if (!HttpParser.isToken(chr)) {// Avoid unknown protocol triggering an additional errorrequest.protocol().setString(Constants.HTTP_11);String invalidMethodValue = parseInvalid(parsingRequestLineStart, byteBuffer);throw new IllegalArgumentException(sm.getString("iib.invalidmethod", invalidMethodValue));}}parsingRequestLinePhase = 3;}// 去除空字符if (parsingRequestLinePhase == 3) {// Spec says single SP but also be tolerant of multiple SP and/or HTboolean space = true;while (space) {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {return false;}}chr = byteBuffer.get();if (chr != Constants.SP && chr != Constants.HT) {space = false;byteBuffer.position(byteBuffer.position() - 1);}}parsingRequestLineStart = byteBuffer.position();parsingRequestLinePhase = 4;}//解析urlif (parsingRequestLinePhase == 4) {// Mark the current buffer positionint end = 0;//// Reading the URI//boolean space = false;while (!space) {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {return false;}}int pos = byteBuffer.position();prevChr = chr;chr = byteBuffer.get();if (prevChr == Constants.CR && chr != Constants.LF) {// CR not followed by LF so not an HTTP/0.9 request and// therefore invalid. Trigger error handling.// Avoid unknown protocol triggering an additional errorrequest.protocol().setString(Constants.HTTP_11);String invalidRequestTarget = parseInvalid(parsingRequestLineStart, byteBuffer);throw new IllegalArgumentException(sm.getString("iib.invalidRequestTarget", invalidRequestTarget));}if (chr == Constants.SP || chr == Constants.HT) {space = true;end = pos;} else if (chr == Constants.CR) {// HTTP/0.9 style request. CR is optional. LF is not.} else if (chr == Constants.LF) {// HTTP/0.9 style request// Stop this processing loopspace = true;// Set blank protocol (indicates HTTP/0.9)request.protocol().setString("");// Skip the protocol processingparsingRequestLinePhase = 7;if (prevChr == Constants.CR) {end = pos - 1;} else {end = pos;}} else if (chr == Constants.QUESTION && parsingRequestLineQPos == -1) {parsingRequestLineQPos = pos;} else if (parsingRequestLineQPos != -1 && !httpParser.isQueryRelaxed(chr)) {// Avoid unknown protocol triggering an additional errorrequest.protocol().setString(Constants.HTTP_11);// %nn decoding will be checked at the point of decodingString invalidRequestTarget = parseInvalid(parsingRequestLineStart, byteBuffer);throw new IllegalArgumentException(sm.getString("iib.invalidRequestTarget", invalidRequestTarget));} else if (httpParser.isNotRequestTargetRelaxed(chr)) {// Avoid unknown protocol triggering an additional errorrequest.protocol().setString(Constants.HTTP_11);// This is a general check that aims to catch problems early// Detailed checking of each part of the request target will// happen in Http11Processor#prepareRequest()String invalidRequestTarget = parseInvalid(parsingRequestLineStart, byteBuffer);throw new IllegalArgumentException(sm.getString("iib.invalidRequestTarget", invalidRequestTarget));}}if (parsingRequestLineQPos >= 0) {request.queryString().setBytes(byteBuffer.array(), parsingRequestLineQPos + 1,end - parsingRequestLineQPos - 1);request.requestURI().setBytes(byteBuffer.array(), parsingRequestLineStart,parsingRequestLineQPos - parsingRequestLineStart);} else {//把解析到的url记下来request.requestURI().setBytes(byteBuffer.array(), parsingRequestLineStart,end - parsingRequestLineStart);}// HTTP/0.9 processing jumps to stage 7.// Don't want to overwrite that here.if (parsingRequestLinePhase == 4) {parsingRequestLinePhase = 5;}}if (parsingRequestLinePhase == 5) {// Spec says single SP but also be tolerant of multiple and/or HTboolean space = true;while (space) {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {return false;}}byte chr = byteBuffer.get();if (chr != Constants.SP && chr != Constants.HT) {space = false;byteBuffer.position(byteBuffer.position() - 1);}}parsingRequestLineStart = byteBuffer.position();parsingRequestLinePhase = 6;// Mark the current buffer positionend = 0;}//协议版本if (parsingRequestLinePhase == 6) {//// Reading the protocol// Protocol is always "HTTP/" DIGIT "." DIGIT//while (!parsingRequestLineEol) {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {return false;}}int pos = byteBuffer.position();prevChr = chr;chr = byteBuffer.get();if (chr == Constants.CR) {// Possible end of request line. Need LF next else invalid.} else if (prevChr == Constants.CR && chr == Constants.LF) {// CRLF is the standard line terminatorend = pos - 1;parsingRequestLineEol = true;} else if (chr == Constants.LF) {// LF is an optional line terminatorend = pos;parsingRequestLineEol = true;} else if (prevChr == Constants.CR || !HttpParser.isHttpProtocol(chr)) {String invalidProtocol = parseInvalid(parsingRequestLineStart, byteBuffer);throw new IllegalArgumentException(sm.getString("iib.invalidHttpProtocol", invalidProtocol));}}if (end - parsingRequestLineStart > 0) {request.protocol().setBytes(byteBuffer.array(), parsingRequestLineStart, end - parsingRequestLineStart);parsingRequestLinePhase = 7;}// If no protocol is found, the ISE below will be triggered.}if (parsingRequestLinePhase == 7) {// Parsing is complete. Return and clean-up.parsingRequestLine = false;parsingRequestLinePhase = 0;parsingRequestLineEol = false;parsingRequestLineStart = 0;return true;}throw new IllegalStateException(sm.getString("iib.invalidPhase", Integer.valueOf(parsingRequestLinePhase)));}
  • 请求头解析
    http请求头格式如name:value,解析先按行读取字符串,读取到":“则认为读到一个请求头,使用MimeHeaderField封装请求头字段,并返回当前请求头的value值到headerData.headerValue,再继续读取字节,读到”\r"为止,然后转换成字符串headerData.headerValue.setBytes(byteBuffer.array(), headerData.start,headerData.lastSignificantChar - headerData.start);保存到headerData.headerValue引用指向的MimeHeaderField对象。

private HeaderParseStatus parseHeader() throws IOException {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {return HeaderParseStatus.NEED_MORE_DATA;}}prevChr = chr;chr = byteBuffer.get();if (chr == Constants.CR && prevChr != Constants.CR) {// Possible start of CRLF - process the next byte.} else if (chr == Constants.LF) {// CRLF or LF is an acceptable line terminatorreturn HeaderParseStatus.DONE;} else {if (prevChr == Constants.CR) {// Must have read two bytes (first was CR, second was not LF)byteBuffer.position(byteBuffer.position() - 2);} else {// Must have only read one bytebyteBuffer.position(byteBuffer.position() - 1);}break;}}if (headerParsePos == HeaderParsePosition.HEADER_START) {// Mark the current buffer positionheaderData.start = byteBuffer.position();headerData.lineStart = headerData.start;headerParsePos = HeaderParsePosition.HEADER_NAME;}//// Reading the header name// Header name is always US-ASCII//while (headerParsePos == HeaderParsePosition.HEADER_NAME) {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) { // parse headerreturn HeaderParseStatus.NEED_MORE_DATA;}}int pos = byteBuffer.position();chr = byteBuffer.get();if (chr == Constants.COLON) {if (headerData.start == pos) {// Zero length header name - not valid.// skipLine() will handle the errorreturn skipLine(false);}headerParsePos = HeaderParsePosition.HEADER_VALUE_START;headerData.headerValue = headers.addValue(byteBuffer.array(), headerData.start, pos - headerData.start);pos = byteBuffer.position();// Mark the current buffer positionheaderData.start = pos;headerData.realPos = pos;headerData.lastSignificantChar = pos;break;} else if (!HttpParser.isToken(chr)) {// Non-token characters are illegal in header names// Parsing continues so the error can be reported in contextheaderData.lastSignificantChar = pos;byteBuffer.position(byteBuffer.position() - 1);// skipLine() will handle the errorreturn skipLine(false);}// chr is next byte of header name. Convert to lowercase.if (chr >= Constants.A && chr <= Constants.Z) {byteBuffer.put(pos, (byte) (chr - Constants.LC_OFFSET));}}// Skip the line and ignore the headerif (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) {return skipLine(false);}//// Reading the header value (which can be spanned over multiple lines)//while (headerParsePos == HeaderParsePosition.HEADER_VALUE_START ||headerParsePos == HeaderParsePosition.HEADER_VALUE ||headerParsePos == HeaderParsePosition.HEADER_MULTI_LINE) {if (headerParsePos == HeaderParsePosition.HEADER_VALUE_START) {// Skipping spaceswhile (true) {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {// parse header// HEADER_VALUE_STARTreturn HeaderParseStatus.NEED_MORE_DATA;}}chr = byteBuffer.get();if (chr != Constants.SP && chr != Constants.HT) {headerParsePos = HeaderParsePosition.HEADER_VALUE;byteBuffer.position(byteBuffer.position() - 1);// Avoids prevChr = chr at start of header value// parsing which causes problems when chr is CR// (in the case of an empty header value)chr = 0;break;}}}if (headerParsePos == HeaderParsePosition.HEADER_VALUE) {// Reading bytes until the end of the lineboolean eol = false;while (!eol) {// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {// parse header// HEADER_VALUEreturn HeaderParseStatus.NEED_MORE_DATA;}}prevChr = chr;chr = byteBuffer.get();if (chr == Constants.CR && prevChr != Constants.CR) {// CR is only permitted at the start of a CRLF sequence.// Possible start of CRLF - process the next byte.} else if (chr == Constants.LF) {// CRLF or LF is an acceptable line terminatoreol = true;} else if (prevChr == Constants.CR) {// Invalid value - also need to delete headerreturn skipLine(true);} else if (HttpParser.isControl(chr) && chr != Constants.HT) {// Invalid value - also need to delete headerreturn skipLine(true);} else if (chr == Constants.SP || chr == Constants.HT) {byteBuffer.put(headerData.realPos, chr);headerData.realPos++;} else {byteBuffer.put(headerData.realPos, chr);headerData.realPos++;headerData.lastSignificantChar = headerData.realPos;}}// Ignore whitespaces at the end of the lineheaderData.realPos = headerData.lastSignificantChar;// Checking the first character of the new line. If the character// is a LWS, then it's a multiline headerheaderParsePos = HeaderParsePosition.HEADER_MULTI_LINE;}// Read new bytes if neededif (byteBuffer.position() >= byteBuffer.limit()) {if (!fill(false)) {// parse header// HEADER_MULTI_LINEreturn HeaderParseStatus.NEED_MORE_DATA;}}byte peek = byteBuffer.get(byteBuffer.position());if (headerParsePos == HeaderParsePosition.HEADER_MULTI_LINE) {if (peek != Constants.SP && peek != Constants.HT) {headerParsePos = HeaderParsePosition.HEADER_START;break;} else {// Copying one extra space in the buffer (since there must// be at least one space inserted between the lines)byteBuffer.put(headerData.realPos, peek);headerData.realPos++;headerParsePos = HeaderParsePosition.HEADER_VALUE_START;}}}// Set the header valueheaderData.headerValue.setBytes(byteBuffer.array(), headerData.start,headerData.lastSignificantChar - headerData.start);headerData.recycle();return HeaderParseStatus.HAVE_MORE_HEADERS;}
  • 请求体解析
    请求体获取方式如下,从请求request中拿到BufferedReader,然后调用readLine就行。
        BufferedReader reader = request.getReader();String line;while ((line=reader.readLine())!=null){System.out.println(line);}

tomcat会用CoyoteReader去封装内置的inputBuffer,生成BufferedReader。

    public BufferedReader getReader() throws IOException {if (usingInputStream) {throw new IllegalStateException(sm.getString("coyoteRequest.getReader.ise"));}if (coyoteRequest.getCharacterEncoding() == null) {Context context = getContext();if (context != null) {String enc = context.getRequestCharacterEncoding();if (enc != null) {setCharacterEncoding(enc);}}}usingReader = true;inputBuffer.checkConverter();if (reader == null) {reader = new CoyoteReader(inputBuffer);}return reader;}

其实也很简答,就是到内置的缓冲区中读取数据,然后使用编码成字符串即可。

    public String readLine() throws IOException {if (lineBuffer == null) {lineBuffer = new char[MAX_LINE_LENGTH];}String result = null;int pos = 0;int end = -1;int skip = -1;StringBuilder aggregator = null;while (end < 0) {mark(MAX_LINE_LENGTH);while ((pos < MAX_LINE_LENGTH) && (end < 0)) {int nRead = read(lineBuffer, pos, MAX_LINE_LENGTH - pos);if (nRead < 0) {if (pos == 0 && aggregator == null) {return null;}end = pos;skip = pos;}for (int i = pos; (i < (pos + nRead)) && (end < 0); i++) {if (lineBuffer[i] == LINE_SEP[0]) {end = i;skip = i + 1;char nextchar;if (i == (pos + nRead - 1)) {nextchar = (char) read();} else {nextchar = lineBuffer[i + 1];}if (nextchar == LINE_SEP[1]) {skip++;}} else if (lineBuffer[i] == LINE_SEP[1]) {end = i;skip = i + 1;}}if (nRead > 0) {pos += nRead;}}if (end < 0) {if (aggregator == null) {aggregator = new StringBuilder();}aggregator.append(lineBuffer);pos = 0;} else {reset();// No need to check return value. We know there are at least skip characters available.skip(skip);}}if (aggregator == null) {result = new String(lineBuffer, 0, end);} else {aggregator.append(lineBuffer, 0, end);result = aggregator.toString();}return result;}

文章转载自:
http://stirp.zfyr.cn
http://miquelon.zfyr.cn
http://konstanz.zfyr.cn
http://crushability.zfyr.cn
http://lochage.zfyr.cn
http://bushido.zfyr.cn
http://coincidence.zfyr.cn
http://serotinous.zfyr.cn
http://buntons.zfyr.cn
http://opportunistic.zfyr.cn
http://mummify.zfyr.cn
http://wendic.zfyr.cn
http://flytable.zfyr.cn
http://poriform.zfyr.cn
http://inherently.zfyr.cn
http://chrysoprase.zfyr.cn
http://extractor.zfyr.cn
http://fip.zfyr.cn
http://recalcitrancy.zfyr.cn
http://cruet.zfyr.cn
http://gunrunner.zfyr.cn
http://porphyropsin.zfyr.cn
http://dicty.zfyr.cn
http://seoul.zfyr.cn
http://emblaze.zfyr.cn
http://mayyan.zfyr.cn
http://inapposite.zfyr.cn
http://chlorobenzene.zfyr.cn
http://flashy.zfyr.cn
http://uncustomed.zfyr.cn
http://disposed.zfyr.cn
http://beatify.zfyr.cn
http://usableness.zfyr.cn
http://pterygotus.zfyr.cn
http://insurable.zfyr.cn
http://sulfinyl.zfyr.cn
http://bata.zfyr.cn
http://demonomancy.zfyr.cn
http://stopover.zfyr.cn
http://hydrosulphide.zfyr.cn
http://disregardfully.zfyr.cn
http://veratric.zfyr.cn
http://cerotype.zfyr.cn
http://enunciate.zfyr.cn
http://mckenney.zfyr.cn
http://countersea.zfyr.cn
http://arcuation.zfyr.cn
http://utp.zfyr.cn
http://sextyping.zfyr.cn
http://neatnik.zfyr.cn
http://deprecate.zfyr.cn
http://safranin.zfyr.cn
http://pogonip.zfyr.cn
http://symplesite.zfyr.cn
http://garnetberry.zfyr.cn
http://isthmic.zfyr.cn
http://jeopardousness.zfyr.cn
http://convertor.zfyr.cn
http://acryl.zfyr.cn
http://porterhouse.zfyr.cn
http://bitterish.zfyr.cn
http://undercapitalize.zfyr.cn
http://autochanger.zfyr.cn
http://beanbag.zfyr.cn
http://inviolately.zfyr.cn
http://tokonoma.zfyr.cn
http://structurize.zfyr.cn
http://claimant.zfyr.cn
http://predecease.zfyr.cn
http://desiccator.zfyr.cn
http://foreskin.zfyr.cn
http://gipsyhood.zfyr.cn
http://mellifluent.zfyr.cn
http://generally.zfyr.cn
http://moses.zfyr.cn
http://hijacker.zfyr.cn
http://coagulator.zfyr.cn
http://ridden.zfyr.cn
http://hamadryad.zfyr.cn
http://uprising.zfyr.cn
http://ferriferous.zfyr.cn
http://misemploy.zfyr.cn
http://mim.zfyr.cn
http://aperiodic.zfyr.cn
http://glutamine.zfyr.cn
http://bled.zfyr.cn
http://unequivocable.zfyr.cn
http://hemiretina.zfyr.cn
http://olim.zfyr.cn
http://threescore.zfyr.cn
http://phlebosclerosis.zfyr.cn
http://reprieval.zfyr.cn
http://hibernaculum.zfyr.cn
http://soapsuds.zfyr.cn
http://sley.zfyr.cn
http://meacock.zfyr.cn
http://yig.zfyr.cn
http://hookup.zfyr.cn
http://protestantize.zfyr.cn
http://luthern.zfyr.cn
http://www.dt0577.cn/news/76451.html

相关文章:

  • 制作外贸网站公司免费制作网站的软件
  • 读书wordpressseo优化课程
  • 中交建设集团网站搜索引擎哪个最好用
  • 南康建设局官方网站教育培训网站大全
  • 网站安全认证去哪做外链交换平台
  • 网站的收录率西安整站优化
  • 网站建设方案书 doc站长之家是什么
  • 像素时代网站建设手机站设计互联网营销策划是做什么的
  • 深圳十大企业排名seo网站快速排名外包
  • 建网站的专业公司seo查询外链
  • 企业网站建设 推广网站推广平台排行
  • 制作网页的收获关键词优化分析工具
  • 哪里能找到网站凡科建站怎么用
  • 4399网站做游戏赚钱最近的大新闻
  • 官方网站弹幕怎么做百度应用商店下载
  • 做枪版电影网站赚钱软文广告属于什么营销
  • 家在深圳罗湖seo有哪些作用
  • 织梦cms网站搬家海南百度推广公司有哪些
  • 山西太原制作网站人有吗爱站网关键词查询
  • 易语言 做的网站增加百度指数的四种方法
  • 一级a做愛视频网站南京seo域名
  • 有没有专门卖软件的平台seo排名关键词
  • 网站建设与维护题库windows7优化大师下载
  • 邯郸wap网站建设费用企业培训课程清单
  • 手机房屋平面设计软件百度关键词如何优化
  • b2c网站框架苏州百度推广公司地址
  • 南充营销型网站建设网站推广是干嘛的
  • 淄博网站建设有实力怎样做网站的优化、排名
  • 自己做的网站抬头在哪里改网络营销推广合同
  • 2017网站设计专业北京网站建设公司