/* * MappingResultのOptionに従ってVelocityHandlerに処理を任せる 1)"velocityUse"がfalse以外 * 2)"velocityExtentions"と拡張子が一致する TODO mapping.setOption(key, value)を使って最適化 */ private boolean isVelocityUse(MappingResult mapping, String path) { if (path == null) { return false; } String velocityUse = (String) mapping.getOption(MappingResult.PARAMETER_VELOCITY_USE); if ("false".equalsIgnoreCase(velocityUse)) { return false; } if (path.endsWith("ph-loader.js")) { // 特別扱い setRequestAttribute(ATTRIBUTE_RESPONSE_CONTENT_TYPE, "application/javascript"); return true; } String velocityExtentionsParam = (String) mapping.getOption(MappingResult.PARAMETER_VELOCITY_EXTENTIONS); String[] velocityExtentions = defaultVelocityExtentions; if (velocityExtentionsParam != null) { velocityExtentions = velocityExtentionsParam.split(","); } for (int i = 0; i < velocityExtentions.length; i++) { if (path.endsWith(velocityExtentions[i])) { return true; } } return false; }
public void onRequestHeader(HeaderParser requestHeader) { /* portal機能の場合path情報にportal機能用の情報が着いている場合がある。 * この情報は削除してproxy対象サーバにリクエスト */ MappingResult mapping = proxyHandler.getRequestMapping(); String path = mapping.getResolvePath(); Matcher matcher = null; synchronized (portalPathInfoPattern) { matcher = portalPathInfoPattern.matcher(path); } StringBuffer sb = null; String portalPathInfo = null; if (matcher.find()) { sb = new StringBuffer(); matcher.appendReplacement(sb, ""); portalPathInfo = matcher.group(1); matcher.appendTail(sb); path = sb.toString(); mapping.setResolvePath(path); requestHeader.setRequestUri(mapping.getResolvePath()); proxyHandler.setRequestAttribute(PORTAL_PATHINFO_KEY, portalPathInfo); } /* * proxyでAuthrizationヘッダを付加する作戦の場合 String basicAuthHeader = getBasicAuthHeader(mapping.isResolvedHttps(),mapping.getResolveServer()); if (basicAuthHeader != null) { requestHeader.addHeader(HeaderParser.WWW_AUTHRIZATION_HEADER, basicAuthHeader); proxyHandler.setRequestAttribute(HeaderParser.WWW_AUTHRIZATION_HEADER, basicAuthHeader); } */ }
public void startResponseReqBody() { MappingResult mapping = getRequestMapping(); if (Boolean.TRUE.equals(mapping.getOption("replay"))) { ReplayHelper helper = Config.getConfig().getReplayHelper(); // ByteBuffer[] body=bodyPage.getBuffer(); if (helper.doReplay(this, null)) { return; // replayできた,bodyは消費されている } } if (response()) { responseEnd(); // TODO必要ないと思う return; } }
private boolean isListing(MappingResult mapping) { Object listing = mapping.getOption(MappingResult.PARAMETER_FILE_LISTING); if (listing == null) { return defaultListing; } return Boolean.TRUE.toString().equalsIgnoreCase(listing.toString()); }
private String[] getWelcomeFiles(MappingResult mapping) { String welcomFiles = (String) mapping.getOption(MappingResult.PARAMETER_FILE_WELCOME_FILES); if (welcomFiles == null) { return defaultWelcomeFiles; } return welcomFiles.split(","); }
// 存在確認済みのファイルをレスポンスする。 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)); }
public void onResponseHeader(HeaderParser responseHeader) { InjectionHelper helper = config.getInjectionHelper(); MappingResult mapping = proxyHandler.getRequestMapping(); HeaderParser requestHeader = proxyHandler.getRequestHeader(); String WebAuthReplaceMark = requestHeader.getHeader(REPLACE_MARK_HEADER); String resolveUrl = mapping.getResolveUrl(); if (WebAuthReplaceMark == null) { portalSession.endBasicProcess(resolveUrl); } String statusCode = responseHeader.getStatusCode(); if ("401".equals(statusCode) /*&&injectContext==null*/) { mapping.getResolveDomain(); String authentication = responseHeader.getHeader(HeaderParser.WWW_AUTHENTICATE_HEADER); if (authentication == null) { return; } Matcher matcher; synchronized (authenticationPattern) { matcher = authenticationPattern.matcher(authentication); } if (!matcher.find()) { return; // Digestはここでチェックあうと } String realm = matcher.group(1); // 自分の持っている代理ログイン情報で、domain,realmに合致するものはないか? String resolveDomain = mapping.getResolveDomain(); CommissionAuth basicCommissionAuth = portalSession.getBasicAuth(resolveDomain, realm); if (WebAuthReplaceMark == null && !portalSession.startBasicProcess(resolveUrl, basicCommissionAuth)) { return; } if (basicCommissionAuth == null || basicCommissionAuth.isEnabled()) { String authrization = requestHeader.getHeader(HeaderParser.WWW_AUTHORIZATION_HEADER); if (WebAuthReplaceMark == null) { // ブラウザから直接出されたリクエスト responseHeader.setStatusCode("200"); proxyHandler.removeResponseHeader(HeaderParser.WWW_AUTHENTICATE_HEADER); portalSession.putRealm(resolveUrl, realm); proxyHandler.setReplace(true); injectContext = helper.getReplaceContext("WebAuthReplace.html"); proxyHandler.addResponseHeader( HeaderParser.CONTENT_TYPE_HEADER, "text/html; charset=utf-8"); proxyHandler.addResponseHeader("Pragma", "no-cache"); proxyHandler.addResponseHeader("Cache-Control", "no-cache"); proxyHandler.addResponseHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); } else if (authrization != null) { // ajaxからuser/passをつけているのに401が返却された=>認証情報が無効 responseHeader.setStatusCode("200"); proxyHandler.removeResponseHeader(HeaderParser.WWW_AUTHENTICATE_HEADER); proxyHandler.addResponseHeader("WebAuthRealm", realm); proxyHandler.setReplace(true); injectContext = helper.getReplaceContext("WebAuthFail.html"); proxyHandler.addResponseHeader(HeaderParser.CONTENT_TYPE_HEADER, "text/plain"); proxyHandler.addResponseHeader("Pragma", "no-cache"); proxyHandler.addResponseHeader("Cache-Control", "no-cache"); proxyHandler.addResponseHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); } } } else if ("200".equals(statusCode) || "404".equals(statusCode)) { String contentType = responseHeader.getContentType(); if (contentType != null && contentType.startsWith("text/html")) { injectContext = helper.getInsertContext("PortalInject.txt"); } } }