zoukankan      html  css  js  c++  java
  • request获取容器过程

    
    获取容器过程
    
    CoyoteAdapter.postParseRequest(org.apache.coyote.Request req, Request request,
                org.apache.coyote.Response res, Response response)
    
    connector.getService().getMapper().map(serverName, decodedURI,
                        version, request.getMappingData());
    
    Mapper.map
    
    public void map(MessageBytes host, MessageBytes uri, String version,
                        MappingData mappingData) throws IOException {
    
            if (host.isNull()) {
                host.getCharChunk().append(defaultHostName);
            }
            host.toChars();
            uri.toChars();
            internalMap(host.getCharChunk(), uri.getCharChunk(), version,
                    mappingData);
        }
    
    Mapper.internalMap
    
     private final void internalMap(CharChunk host, CharChunk uri,
                String version, MappingData mappingData) throws IOException {
    
            if (mappingData.host != null) {
                // The legacy code (dating down at least to Tomcat 4.1) just
                // skipped all mapping work in this case. That behaviour has a risk
                // of returning an inconsistent result.
                // I do not see a valid use case for it.
                throw new AssertionError();
            }
    
            uri.setLimit(-1);
            // Virtual host mapping
            MappedHost[] hosts = this.hosts;
    //根据host域名精确查找host
            MappedHost mappedHost = exactFindIgnoreCase(hosts, host);
            if (mappedHost == null) {
                // Note: Internally, the Mapper does not use the leading * on a
                //       wildcard host. This is to allow this shortcut.
    //*.apache.org --> .apache.org,通过这个去查找
                int firstDot = host.indexOf('.');
                if (firstDot > -1) {
                    int offset = host.getOffset();
                    try {
                        host.setOffset(firstDot + offset);
                        mappedHost = exactFindIgnoreCase(hosts, host);
                    } finally {
                        // Make absolutely sure this gets reset
                        host.setOffset(offset);
                    }
                }
                if (mappedHost == null) {
                    mappedHost = defaultHost;//如果没有找到就使用默认host
                    if (mappedHost == null) {
                        return;
                    }
                }
            }
            mappingData.host = mappedHost.object;
    
            // Context mapping 前缀匹配
            ContextList contextList = mappedHost.contextList;
            MappedContext[] contexts = contextList.contexts;
            int pos = find(contexts, uri);
            if (pos == -1) {
                return;
            }
    
            int lastSlash = -1;
            int uriEnd = uri.getEnd();
            int length = -1;
            boolean found = false;
            MappedContext context = null;
            while (pos >= 0) {
                context = contexts[pos];
                if (uri.startsWith(context.name)) {
    //如果长度一样直接表示找到匹配的对象
                    length = context.name.length();
                    if (uri.getLength() == length) {
                        found = true;
                        break;
                    } else if (uri.startsWithIgnoreCase("/", length)) {
                        found = true;
                        break;
                    }
                }
    //查找最后一个/的位置(匹配最长的路径),然后从开始到这个点进行匹配
                if (lastSlash == -1) {
                    lastSlash = nthSlash(uri, contextList.nesting + 1);
                } else {
                    lastSlash = lastSlash(uri);
                }
                uri.setEnd(lastSlash);
                pos = find(contexts, uri);
            }
            uri.setEnd(uriEnd);
    
            if (!found) {
    //如果没有找打,使用默认的context,如果连默认的都没有直接返回null
                if (contexts[0].name.equals("")) {
                    context = contexts[0];
                } else {
                    context = null;
                }
            }
            if (context == null) {
                return;
            }
    
            mappingData.contextPath.setString(context.name);
    
            ContextVersion contextVersion = null;
            ContextVersion[] contextVersions = context.versions;
            final int versionCount = contextVersions.length;
            if (versionCount > 1) {
                Context[] contextObjects = new Context[contextVersions.length];
                for (int i = 0; i < contextObjects.length; i++) {
                    contextObjects[i] = contextVersions[i].object;
                }
                mappingData.contexts = contextObjects;
                if (version != null) {
    //精确查找版本
                    contextVersion = exactFind(contextVersions, version);
                }
            }
            if (contextVersion == null) {
                // Return the latest version
                // The versions array is known to contain at least one element
                contextVersion = contextVersions[versionCount - 1];
            }
            mappingData.context = contextVersion.object;
            mappingData.contextSlashCount = contextVersion.slashCount;
    
            // Wrapper mapping
            if (!contextVersion.isPaused()) {
                internalMapWrapper(contextVersion, uri, mappingData);
            }
    
        }
    
    
    Mapper.internalMapWrapper
    
    
    private final void internalMapWrapper(ContextVersion contextVersion,
                                              CharChunk path,
                                              MappingData mappingData) throws IOException {
    
            int pathOffset = path.getOffset();
            int pathEnd = path.getEnd();
            boolean noServletPath = false;
    
            int length = contextVersion.path.length();
            if (length == (pathEnd - pathOffset)) {
                noServletPath = true;//如果请求路径和context路径一样长,那么就表示没有servletPath,这种路径一般是使用默认的index页面
            }
            int servletPath = pathOffset + length;
            path.setOffset(servletPath);//设置servlet路径,比如localhost:8080/test/index --> servlet路径为index,那么偏移地址为index第一个字符的下标
    
            // Rule 1 -- Exact Match 精确匹配
            MappedWrapper[] exactWrappers = contextVersion.exactWrappers;
            internalMapExactWrapper(exactWrappers, path, mappingData);
    
            // Rule 2 -- Prefix Match 前缀匹配,这里的匹配和context的匹配方式一样
            boolean checkJspWelcomeFiles = false;
            MappedWrapper[] wildcardWrappers = contextVersion.wildcardWrappers;
            if (mappingData.wrapper == null) {
                internalMapWildcardWrapper(wildcardWrappers, contextVersion.nesting,
                                           path, mappingData);
                if (mappingData.wrapper != null && mappingData.jspWildCard) {
                    char[] buf = path.getBuffer();
                    if (buf[pathEnd - 1] == '/') {
                        /*
                         * Path ending in '/' was mapped to JSP servlet based on
                         * wildcard match (e.g., as specified in url-pattern of a
                         * jsp-property-group.
                         * Force the context's welcome files, which are interpreted
                         * as JSP files (since they match the url-pattern), to be
                         * considered. See Bugzilla 27664.
                         */
                        mappingData.wrapper = null;
                        checkJspWelcomeFiles = true;
                    } else {
                        // See Bugzilla 27704
                        mappingData.wrapperPath.setChars(buf, path.getStart(),
                                                         path.getLength());
                        mappingData.pathInfo.recycle();
                    }
                }
            }
    
            if(mappingData.wrapper == null && noServletPath &&
                    contextVersion.object.getMapperContextRootRedirectEnabled()) {
                // The path is empty, redirect to "/"
                path.append('/');
                pathEnd = path.getEnd();
                mappingData.redirectPath.setChars
                    (path.getBuffer(), pathOffset, pathEnd - pathOffset);
                path.setEnd(pathEnd - 1);
                return;
            }
    
            // Rule 3 -- Extension Match
            MappedWrapper[] extensionWrappers = contextVersion.extensionWrappers;
            if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
                internalMapExtensionWrapper(extensionWrappers, path, mappingData,
                        true);
            }
    
            // Rule 4 -- Welcome resources processing for servlets
            if (mappingData.wrapper == null) {
                boolean checkWelcomeFiles = checkJspWelcomeFiles;
                if (!checkWelcomeFiles) {
                    char[] buf = path.getBuffer();
                    checkWelcomeFiles = (buf[pathEnd - 1] == '/');
                }
                if (checkWelcomeFiles) {
                    for (int i = 0; (i < contextVersion.welcomeResources.length)
                             && (mappingData.wrapper == null); i++) {
                        path.setOffset(pathOffset);
                        path.setEnd(pathEnd);
                        path.append(contextVersion.welcomeResources[i], 0,
                                contextVersion.welcomeResources[i].length());
                        path.setOffset(servletPath);
    
                        // Rule 4a -- Welcome resources processing for exact macth
                        internalMapExactWrapper(exactWrappers, path, mappingData);
    
                        // Rule 4b -- Welcome resources processing for prefix match
                        if (mappingData.wrapper == null) {
                            internalMapWildcardWrapper
                                (wildcardWrappers, contextVersion.nesting,
                                 path, mappingData);
                        }
    
                        // Rule 4c -- Welcome resources processing
                        //            for physical folder
                        if (mappingData.wrapper == null
                            && contextVersion.resources != null) {
                            String pathStr = path.toString();
                            WebResource file =
                                    contextVersion.resources.getResource(pathStr);
                            if (file != null && file.isFile()) {
                                internalMapExtensionWrapper(extensionWrappers, path,
                                                            mappingData, true);
                                if (mappingData.wrapper == null
                                    && contextVersion.defaultWrapper != null) {
                                    mappingData.wrapper =
                                        contextVersion.defaultWrapper.object;
                                    mappingData.requestPath.setChars
                                        (path.getBuffer(), path.getStart(),
                                         path.getLength());
                                    mappingData.wrapperPath.setChars
                                        (path.getBuffer(), path.getStart(),
                                         path.getLength());
                                    mappingData.requestPath.setString(pathStr);
                                    mappingData.wrapperPath.setString(pathStr);
                                }
                            }
                        }
                    }
    
                    path.setOffset(servletPath);
                    path.setEnd(pathEnd);
                }
    
            }
    
            /* welcome file processing - take 2
             * Now that we have looked for welcome files with a physical
             * backing, now look for an extension mapping listed
             * but may not have a physical backing to it. This is for
             * the case of index.jsf, index.do, etc.
             * A watered down version of rule 4
             */
            if (mappingData.wrapper == null) {
                boolean checkWelcomeFiles = checkJspWelcomeFiles;
                if (!checkWelcomeFiles) {
                    char[] buf = path.getBuffer();
                    checkWelcomeFiles = (buf[pathEnd - 1] == '/');
                }
                if (checkWelcomeFiles) {
                    for (int i = 0; (i < contextVersion.welcomeResources.length)
                             && (mappingData.wrapper == null); i++) {
                        path.setOffset(pathOffset);
                        path.setEnd(pathEnd);
                        path.append(contextVersion.welcomeResources[i], 0,
                                    contextVersion.welcomeResources[i].length());
                        path.setOffset(servletPath);
                        internalMapExtensionWrapper(extensionWrappers, path,
                                                    mappingData, false);
                    }
    
                    path.setOffset(servletPath);
                    path.setEnd(pathEnd);
                }
            }
    
    
            // Rule 7 -- Default servlet
            if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
                if (contextVersion.defaultWrapper != null) {
                    mappingData.wrapper = contextVersion.defaultWrapper.object;
                    mappingData.requestPath.setChars
                        (path.getBuffer(), path.getStart(), path.getLength());
                    mappingData.wrapperPath.setChars
                        (path.getBuffer(), path.getStart(), path.getLength());
                    mappingData.matchType = MappingMatch.DEFAULT;
                }
                // Redirection to a folder
                char[] buf = path.getBuffer();
                if (contextVersion.resources != null && buf[pathEnd -1 ] != '/') {
                    String pathStr = path.toString();
                    WebResource file;
                    // Handle context root
                    if (pathStr.length() == 0) {
                        file = contextVersion.resources.getResource("/");
                    } else {
                        file = contextVersion.resources.getResource(pathStr);
                    }
                    if (file != null && file.isDirectory() &&
                            contextVersion.object.getMapperDirectoryRedirectEnabled()) {
                        // Note: this mutates the path: do not do any processing
                        // after this (since we set the redirectPath, there
                        // shouldn't be any)
                        path.setOffset(pathOffset);
                        path.append('/');
                        mappingData.redirectPath.setChars
                            (path.getBuffer(), path.getStart(), path.getLength());
                    } else {
                        mappingData.requestPath.setString(pathStr);
                        mappingData.wrapperPath.setString(pathStr);
                    }
                }
            }
    
            path.setOffset(pathOffset);
            path.setEnd(pathEnd);
        }
  • 相关阅读:
    Atitit 得到mybatis 实际 sql 1.1. 使用mybatis工具提供的,只能出现问号一大堆不行 1 1.2. 配置log 打印sql依然不行,里面有问号。。 4 1.3. 配置p
    atitit 技术选型之道. attilax著 艾龙著 1. 标准 2 1.1. 符合趋势度 2 1.2. 简单易用 2 1.3. 文档丰富度 2 1.4. 下载便利性 2 1.5. 性能 2 1.
    Atitit 算法之道 attilax著 1. 编码算法 3 1.1. Base64 htmlencode urlencode 3 2. Ui方面的算法 3 2.1. 软键盘算法 计算软键盘上下
    Atitit attilax提出的软件开发发展趋势与概念 1. 长期化 复用化 跨平台 可移植性 1 2. 通用化 通用 化的渠道至少有3种 1 2.1. 模块化 1 2.2. 标准化接口 1 2
    Atitit java 原生 客户端 native desktop桌面 javafx 浏览器环境 导入jar jfxrt.jar 17M package com.attilax.ui;
    Atitit 并发技术的选项 attilax总结 艾龙 著 1. 三大并发模型 1 2. 从可读性考虑 优先使用 并行工作者 多线程模式,不要使用异步流水线模式 2 2.1. 多线程模式方便全局
    Atitit 物化视图与触发器性能测试方法 attilax总结 1.1. 触发器主要影响更新性能。。。 1 1.2. 临时打开关闭触发器,如果db不支持可以更改条件使其不触发 1 1.3. 打开定时
    Atitit.java线程池使用总结attilax 1.1. 动态更改线程数量 1 1.2. code 1 三、线程池的原理 其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下
    Atitit 军事学 之 军事思想学与打猎学总结以及在软件行业中的应用 attilax著 1. 军事思想在软件行业技术开发中的想通之处 1 1.1. 软件开发本质上是一种作战,敌人是时间与费用成本
    Atitit 艺术与编程艺术 项目工程艺术 1. 艺术可以分为造型艺术、表演艺术、综合艺术和语言艺术四大类。 1 2. 造型艺术 10 2 2.1. (一) 绘画和雕塑  11 2 2.2. (二
  • 原文地址:https://www.cnblogs.com/honger/p/10363078.html
Copyright © 2011-2022 走看看