private CacheBuffer welcomPage(File dir, String[] welcomlist) {
   CacheBuffer asyncFile = null;
   for (String welcom : welcomlist) {
     asyncFile = CacheBuffer.open(new File(dir, welcom));
     FileInfo info = asyncFile.getFileInfo();
     if (info.exists() && info.canRead() && info.isFile()) {
       return asyncFile;
     }
     asyncFile.close();
   }
   return null;
 }
  // 存在確認済みのファイルをレスポンスする。
  private boolean sendFile(
      MappingResult mapping,
      File baseDirectory,
      String path,
      String ifModifiedSince,
      CacheBuffer asyncFile) {
    if (isVelocityUse(mapping, path)) {
      // TODO ちゃんとする
      mapping.setResolvePath(path); // 加工後のpathを設定
      mapping.setDesitinationFile(baseDirectory);
      forwardHandler(Mapping.VELOCITY_PAGE_HANDLER);
      asyncFile.close();
      return false; // 委譲
    }

    // String
    // ifModifiedSince=requestParser.getHeader(HeaderParser.IF_MODIFIED_SINCE_HEADER);
    Date ifModifiedSinceDate = HeaderParser.parseDateHeader(ifModifiedSince);
    long ifModifiedSinceTime = -1;
    if (ifModifiedSinceDate != null) {
      ifModifiedSinceTime = ifModifiedSinceDate.getTime();
    }
    FileInfo fileInfo = asyncFile.getFileInfo();
    long lastModifiedTime = fileInfo.getLastModified();
    String lastModified = HeaderParser.fomatDateHeader(new Date(lastModifiedTime));
    // ファイル日付として表現できる値には、誤差があるため、表現できる時刻を取得
    lastModifiedTime = HeaderParser.parseDateHeader(lastModified).getTime();
    if (ifModifiedSinceTime >= lastModifiedTime) {
      completeResponse("304");
      asyncFile.close();
      return true;
    }
    setHeader(HeaderParser.LAST_MODIFIED_HEADER, lastModified);
    long contentLength = getContentLength(fileInfo.length());
    setContentLength(contentLength);
    String contentDisposition =
        (String) getRequestAttribute(ATTRIBUTE_RESPONSE_CONTENT_DISPOSITION);
    if (contentDisposition != null) {
      setHeader(HeaderParser.CONTENT_DISPOSITION_HEADER, contentDisposition);
    }
    String contentType = getContentType(fileInfo.getCanonicalFile());
    setContentType(contentType);
    setStatusCode("200");
    responseBodyFromFile(asyncFile);
    return false;
  }
  private boolean response() {
    HeaderParser requestHeader = getRequestHeader();
    String ifModifiedSince = requestHeader.getHeader(HeaderParser.IF_MODIFIED_SINCE_HEADER);
    String selfPath = requestHeader.getRequestUri();

    MappingResult mapping = getRequestMapping();
    File file = (File) getRequestAttribute(ATTRIBUTE_RESPONSE_FILE);
    if (file != null) { // レスポンスするファイルが、直接指定された場合
      // FileCacheInfo fileCacheInfo=null;
      boolean useCache = true;
      if (getRequestAttribute(ATTRIBUTE_RESPONSE_FILE_NOT_USE_CACHE) == null) {
        useCache = false;
      }
      CacheBuffer asyncFile = CacheBuffer.open(file, useCache);
      FileInfo fileInfo = asyncFile.getFileInfo();
      if (!fileInfo.exists()) {
        logger.debug("Not found." + file.getAbsolutePath());
        completeResponse("404", "file not exists");
        asyncFile.close();
        return true;
      }
      return sendFile(mapping, null, null, ifModifiedSince, asyncFile);
    }

    String path = mapping.getResolvePath();
    try {
      path = URLDecoder.decode(path, "utf-8");
    } catch (UnsupportedEncodingException e) {
      logger.error("URLDecoder.decode error", e);
      throw new IllegalArgumentException("URLDecoder.decode error", e);
    }
    // クエリの削除
    int pos = path.indexOf('?');
    if (pos >= 0) {
      path = path.substring(0, pos);
    }

    File baseDirectory = mapping.getDestinationFile();
    CacheBuffer asyncFile = CacheBuffer.open(new File(baseDirectory, path));
    FileInfo info = asyncFile.getFileInfo();
    if (info.isError()) {
      logger.warn("fail to getCanonicalPath.");
      completeResponse("500", "fail to getCanonicalPath.");
      asyncFile.close();
      return true;
      // TODO トラバーサル
      // }else if(!info.isInBase()){
      // //トラバーサルされたら、loggingして404
      // logger.warn("traversal error.");
      // completeResponse("404","traversal error");
      // return true;
    } else if (!info.exists() || !info.canRead()) {
      asyncFile.close();
      logger.debug("Not found." + info.getCanonicalFile());
      completeResponse("404", "file not exists");
      return true;
    }
    // welcomefile処理
    String[] welcomeFiles = getWelcomeFiles(mapping);
    if (info.isDirectory() && welcomeFiles != null) {
      File dir = info.getCanonicalFile();
      asyncFile.close();
      asyncFile = welcomPage(dir, welcomeFiles);
      if (asyncFile == null) { // welcomfileが無かった
        //				completeResponse("404", "file not exists");
        return fileListIfNessesary(mapping, selfPath, dir, "/".equals(path));
      }
      info = asyncFile.getFileInfo();
      if (info.exists() && info.canRead() && !path.endsWith("/")) {
        asyncFile.close();
        // もし、URIが"/"で終わっていなかったら相対が解決できないので、リダイレクト
        ServerParser selfServer = requestHeader.getServer();
        StringBuilder sb = new StringBuilder();
        if (isSsl()) {
          sb.append("https://");
        } else {
          sb.append("http://");
        }
        sb.append(selfServer.toString());
        sb.append(selfPath);
        sb.append("/");
        setHeader(HeaderParser.LOCATION_HEADER, sb.toString());
        completeResponse("302");
        return true;
      }
    }
    if (info.isFile()) { // ファイルだったら
      return sendFile(mapping, baseDirectory, path, ifModifiedSince, asyncFile);
    }
    asyncFile.close();
    File dir = info.getCanonicalFile();
    return fileListIfNessesary(mapping, selfPath, dir, "/".equals(path));
  }