Tomcat源码8

来源:互联网 发布:ug编程培训 编辑:程序博客网 时间:2024/05/01 18:47
 这一节说说tomcat如何解析请求的头部的。这一节要介绍的东西比较多,先给出tomcat解析头部的大概思路,然后再从各个细节进行突破。
 解析头部的大概思路还是比较清晰的,首先头部的信息是以键值对来进行存储的,那么只要把键和值给分离开来就OK了,然后根据具体的key,来对value进行设置。
 设置到HttpRequestImpl中的信息有:authorization,accept-language,cookie,content-length,content-type,host,connection,close,expect,100-continue,transfer-encoding,具体看下面代码的注释!
 /**
     * Parse the incoming HTTP request headers, and set the appropriate
     * request headers.
     *
     * @param input The input stream connected to our socket
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a parsing error occurs
     */
    private void parseHeaders(SocketInputStream input)
        throws IOException, ServletException {

        while (true) {

            HttpHeader header = request.allocateHeader();//创建一个内容为空的HttpHeader实例

            // Read the next header
            //将该HttpHeader实例传入SocketInputStream实例中的readHeader()方法中,若所有的请求都已经读取过了,
            //则readHeader()方法不会再给HttpHeader实例位置name属性了。这时就可以退出parseHeader()方法了。
            input.readHeader(header);
            //如果header.nameEnd的长度与header.valueEnd为0,则返回,因为没有头部信息读取
            if (header.nameEnd == 0) {
                if (header.valueEnd == 0) {
                    return;
                } else {
                    throw new ServletException
                        (sm.getString("httpProcessor.parseHeaders.colon"));
                }
            }

            String value = new String(header.value, 0, header.valueEnd);//否则将头部信息转化为字符串
            if (debug >= 1)
                log(" Header " + new String(header.name, 0, header.nameEnd)
                    + " = " + value);

            // Set the corresponding request headers
            //设置Authorization
            if (header.equals(DefaultHeaders.AUTHORIZATION_NAME)) {
                request.setAuthorization(value);
            } else if (header.equals(DefaultHeaders.ACCEPT_LANGUAGE_NAME)) {//设置ACCEPT_LANGUAGE_NAME
                parseAcceptLanguage(value);
            } else if (header.equals(DefaultHeaders.COOKIE_NAME)) {//设置COOKIE_NAME
                Cookie cookies[] = RequestUtil.parseCookieHeader(value);//解析Cookie
                for (int i = 0; i < cookies.length; i++) {
                    if (cookies[i].getName().equals
                        (Globals.SESSION_COOKIE_NAME)) {
                        // Override anything requested in the URL
                        if (!request.isRequestedSessionIdFromCookie()) {
                            // Accept only the first session id cookie
                            request.setRequestedSessionId
                                (cookies[i].getValue());//设置SessionID
                            request.setRequestedSessionCookie(true);//如果SessionID是通过cookies传送过来的,那么这个标志设置为true
                            request.setRequestedSessionURL(false);//如果SessionID不是通过URI传送过来的,那么这个标志设置为false
                            if (debug >= 1)
                                log(" Requested cookie session id is " +
                                    ((HttpServletRequest) request.getRequest())
                                    .getRequestedSessionId());
                        }
                    }
                    if (debug >= 1)
                        log(" Adding cookie " + cookies[i].getName() + "=" +
                            cookies[i].getValue());
                    request.addCookie(cookies[i]);//将cookies加入到数组容器中
                }
            } else if (header.equals(DefaultHeaders.CONTENT_LENGTH_NAME)) {//如果在http请求头中发现"content-length"
                int n = -1;
                try {
                    n = Integer.parseInt(value);
                } catch (Exception e) {
                    throw new ServletException
                        (sm.getString
                         ("httpProcessor.parseHeaders.contentLength"));
                }
                request.setContentLength(n);//设置文本长度
            } else if (header.equals(DefaultHeaders.CONTENT_TYPE_NAME)) {//如果在http请求头中发现"content-type"
                request.setContentType(value);//设置请求文本类型
            } else if (header.equals(DefaultHeaders.HOST_NAME)) {//如果在http请求头中发现"host"
                int n = value.indexOf(':');//获取协议方式
                if (n < 0) {
                    if (connector.getScheme().equals("http")) {
                        request.setServerPort(80);//如果是http那么监听80端口
                    } else if (connector.getScheme().equals("https")) {
                        request.setServerPort(443);//如果是https那么监听443端口
                    }
                    if (proxyName != null)
                        request.setServerName(proxyName);//设置代理服务器名字
                    else
                        request.setServerName(value);//设置服务器名字
                } else {
                    if (proxyName != null)
                        request.setServerName(proxyName);
                    else
                        request.setServerName(value.substring(0, n).trim());
                    if (proxyPort != 0)
                        request.setServerPort(proxyPort);//设置代理端口号
                    else {
                        int port = 80;
                        try {
                            port =
                                Integer.parseInt(value.substring(n+1).trim());
                        } catch (Exception e) {
                            throw new ServletException
                                (sm.getString
                                 ("httpProcessor.parseHeaders.portNumber"));
                        }
                        request.setServerPort(port);//设置端口号
                    }
                }
            } else if (header.equals(DefaultHeaders.CONNECTION_NAME)) {//如果在http请求头中发现"connection"
                if (header.valueEquals
                    (DefaultHeaders.CONNECTION_CLOSE_VALUE)) {//如果在http请求头中发现"close"
                    keepAlive = false;//说明不持久连接
                    response.setHeader("Connection", "close");
                }
                //request.setConnection(header);
                /*
                  if ("keep-alive".equalsIgnoreCase(value)) {
                  keepAlive = true;
                  }
                */
            } else if (header.equals(DefaultHeaders.EXPECT_NAME)) {//如果在http请求头中发现"expect"
                if (header.valueEquals(DefaultHeaders.EXPECT_100_VALUE))//并且在http请求头中发现"100-continue"
                    sendAck = true;//允许分块发送
                else
                    throw new ServletException
                        (sm.getString
                         ("httpProcessor.parseHeaders.unknownExpectation"));
            } else if (header.equals(DefaultHeaders.TRANSFER_ENCODING_NAME)) {
                //request.setTransferEncoding(header);
            }

            request.nextHeader();//读取下一个请求头

        }

    }
        接下来会继续分析这串代码中的细节部分!


原创粉丝点击