客户端验证服务器的webhook响应数据

@param appId
APP ID

@param appSecretKey
APP Secret
@param body
webhook响应具体数据。考虑到request中只能获取到body一次，故而需要在方法外获取并传递给此方法
@param request
服务端向客户端发起的请求
@throws IOException
数据流异常
@return 验证结果： true-是服务器发送给客户端的数据；false-验证失败
@since 2.0.0
970324
public static boolean verify(String appId, String appSecretKey, byte[] body, HttpServletRequest request)
            throws IOException {
        HmacSignatureBuilder builder = new HmacSignatureBuilder();

        String signitSignature = request.getHeader("X-Signit-Signature");
        builder.scheme(request.getHeader("X-Signit-Scheme"))
                .apiKey(appId)
                .apiSecret(appSecretKey.getBytes())
                .method(request.getMethod()
                        .toUpperCase())
                .payload(body)
                .contentType(request.getContentType())
                .host(Validator.isEmpty(request.getHeader("X-Signit-Host")) ? "" : request.getHeader("X-Signit-Host"))
                .resource(Validator.isEmpty(request.getHeader("X-Signit-Resource")) ? ""
                        : request.getHeader("X-Signit-Resource"))
                .nonce(Validator.isEmpty(request.getHeader("X-Signit-Nonce")) ? ""
                        : request.getHeader("X-Signit-Nonce"))
                .date(Validator.isEmpty(request.getHeader("X-Signit-Date")) ? "" : request.getHeader("X-Signit-Date"));
        String selfBuiltHmac = builder.getDefaultAlgorithm() + " " + appId + ":" + builder.buildAsBase64();
        return selfBuiltHmac.equals(signitSignature);
    }
583748
private void doResults(HttpServletRequest req, HttpServletResponse resp) throws IOException, JsonGenerationException, JsonMappingException
  {
    Map<String, Object> result = new HashMap<String, Object>();

    String requestIds = req.getParameter("ids");
    if (!isEmpty(requestIds))
    {
      List<Map<String, Object>> requests = new ArrayList<Map<String, Object>>();
      for (String requestId : requestIds.split(","))
      {
        requestId = requestId.trim();
        @SuppressWarnings("unchecked")
        Map<String, Object> requestData = (Map<String, Object>) ms.get(String.format(MiniProfilerFilter.MEMCACHE_KEY_FORMAT_STRING, requestId));
        if (requestData != null)
        {
          Map<String, Object> request = new HashMap<String, Object>();
          request.put("id", requestId);
          request.put("redirect", requestData.get("redirect"));
          request.put("requestURL", requestData.get("requestURL"));
          request.put("timestamp", requestData.get("timestamp"));
          request.put("profile", requestData.get("profile"));
          if (requestData.containsKey("appstatsId"))
          {
            Map<String, Object> appstatsMap = MiniProfilerAppstats.getAppstatsDataFor((String) requestData.get("appstatsId"), maxStackFrames);
            request.put("appstats", appstatsMap != null ? appstatsMap : null);
          } else
          {
            request.put("appstats", null);
          }
          requests.add(request);
        }
      }
      result.put("ok", true);
      result.put("requests", requests);
    } else
    {
      result.put("ok", false);
    }

    resp.setContentType("application/json");
    resp.setHeader("Cache-Control", "no-cache");

    ObjectMapper jsonMapper = new ObjectMapper();
    jsonMapper.writeValue(resp.getOutputStream(), result);
  }
309235
public static String getAppURL(HttpServletRequest request) {
		StringBuffer url = new StringBuffer();
		int port = request.getServerPort();
		if (port < 0) {
			port = 80; // Work around java.net.URL bug
		}
		String scheme = request.getScheme();
		url.append(scheme);
		url.append("://");
		url.append(request.getServerName());
		if ((scheme.equals("http") && (port != 80)) || (scheme.equals("https") && (port != 443))) {
			url.append(':');
			url.append(port);
		}
		return url.toString();
	}
866256
function(params, callback) {
                var keyId;

                if (params) {
                    if (params.keyId != 'undefined') {
                        keyId = params.keyId;
                    }
                }

                var httpRequestParams = {
                    url: SERVICE_ADDRESSES.SSO_ADDRESS + SERVICES_PATH.SSO_GET_KEY + keyId,
                    method: 'GET',
                    headers: {
                        'Authorization': 'Bearer ' + token
                    }
                };

                httpRequest(httpRequestParams, function(result) {
                    if (!result.hasError) {
                        try {
                            var response = JSON.parse(result.result.responseText);
                        }
                        catch (e) {
                            console.log(e);
                        }

                        callback && callback({
                            hasError: false,
                            secretKey: response.secretKey
                        });
                    }
                    else {
                        callback && callback({
                            hasError: true,
                            code: result.errorCode,
                            message: result.errorMessage
                        });

                        fireEvent('error', {
                            code: result.errorCode,
                            message: result.errorMessage,
                            error: result
                        });
                    }
                });
            }
306806
public static void init(final String appid,final String secret,int initialDelay,int delay){
		if(scheduledExecutorService == null){
			initScheduledExecutorService();
		}
		if(firestAppid == null){
			firestAppid = appid;
		}
		if(futureMap.containsKey(appid)){
			futureMap.get(appid).cancel(true);
		}
		//立即执行一次
		if(initialDelay == 0){
			doRun(appid, secret);
		}
		ScheduledFuture<?> scheduledFuture =  scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
			@Override
			public void run() {
				doRun(appid, secret);
			}
		},initialDelay == 0 ? delay : initialDelay,delay,TimeUnit.SECONDS);
		futureMap.put(appid, scheduledFuture);
		logger.info("appid:{}",appid);
	}
604360
function ( appRequest, appResponse ) {
    var cacheHtml = null,
        cacheJson = null,
        cacheName = null,
        slugged = slug( appRequest.params[ 0 ].replace( /\//g, "-" ).replace( /-$/g, "" ) ),
        reqSlug = ( slugged === "" ) ? "-homepage" : slugged,
        url = appRequest.params[ 0 ],
        qrs = {};

    cacheName = ("page" + reqSlug);

    // Querystring?
    for ( var i in appRequest.query ) {
        qrs[ i ] = appRequest.query[ i ];

        // Unique cache file name including queries
        if ( i !== "format" && i !== "password" && i !== "nocache" ) {
            cacheName += ("-" + i + "--" + qrs[ i ]);
        }
    }

    cacheHtml = sqsCache.get( (cacheName + ".html") );
    cacheJson = sqsCache.get( (cacheName + ".json") );

    // 404 JSON?
    if ( cacheJson && !pageNotFoundJson ) {
        setPageNotFoundJson( cacheJson );
    }

    // Nocache?
    if ( appRequest.query.nocache !== undefined ) {
        cacheJson = null;
        cacheHtml = null;

        sqsCache.remove( (cacheName + ".html") );
        sqsCache.remove( (cacheName + ".json") );
        sqsCache.remove( (cacheName + "-main-content.html") );
    }

    // Search?
    if ( slugged === "search" ) {
        if ( cacheHtml ) {
            appResponse.status( 200 ).send( cacheHtml );

        } else {
            sqsWare.getHtml( url, qrs, function ( error, data ) {
                if ( !error ) {
                    appResponse.status( 200 ).send( data.html );

                    sqsCache.set( (cacheName + ".html"), data.html );

                } else {
                    // Handle errors
                    nsl.log( "error", ("Error requesting system search page => " + error) );
                }
            });
        }

        return;
    }

    // Cache?
    if ( cacheJson && cacheHtml && !rJson.test( appRequest.query.format ) ) {
        sqsTemplate.renderTemplate( qrs, cacheJson, cacheHtml, function ( tpl ) {
            appResponse.status( 200 ).send( tpl );
        });

        return;
    }

    // JSON?
    // Supports `json` and `json-pretty`
    if ( rJson.test( appRequest.query.format ) ) {
        if ( cacheJson ) {
            cacheJson.nodeServer = true;

            appResponse.status( 200 ).json( cacheJson );

        } else {
            sqsWare.getJson( url, qrs, function ( error, json ) {
                if ( !error ) {
                    json.json.nodeServer = true;

                    sqsCache.set( (cacheName + ".json"), json.json );

                    appResponse.status( 200 ).json( json.json );

                } else {
                    // Handle errors
                    nsl.log( "error", ("Error requesting page json => " + error) );
                }
            });
        }

    // Main-Content
    } else if ( appRequest.query.format === "main-content" ) {
        cacheHtml = sqsCache.get( (cacheName + "-main-content.html") );

        if ( cacheHtml ) {
            appResponse.status( 200 ).send( cacheHtml );

        } else {
            sqsWare.getHtml( url, qrs, function ( error, data ) {
                if ( !error ) {
                    appResponse.status( 200 ).send( data.html );

                    sqsCache.set( (cacheName + "-main-content.html"), data.html );

                } else {
                    // Handle errors
                    nsl.log( "error", ("Error requesting main-content for page => " + error) );
                }
            });
        }

    // Request page?
    } else {
        sqsWare.getJsonAndHtml( url, qrs, function ( error, data ) {
            if ( !error ) {
                sqsCache.set( (cacheName + ".json"), data.json.json );
                sqsCache.set( (cacheName + ".html"), data.html.html );

                // 404 JSON?
                if ( !pageNotFoundJson ) {
                    setPageNotFoundJson( data.json.json );
                }

                sqsTemplate.renderTemplate( qrs, data.json.json, sqsCache.get( (cacheName + ".html") ), function ( tpl ) {
                    appResponse.status( 200 ).send( tpl );
                });

            } else {
                // Handle errors
                nsl.log( "error", ("Error requesting page => " + error) );

                // Could be a 404 though so serve it
                if ( data.html.status === 404 || data.json.status === 404 ) {
                    //appResponse.status( 200 ).send( data.html.html );
                    sqsTemplate.renderTemplate( qrs, pageNotFoundJson, data.html.html, function ( tpl ) {
                        appResponse.status( 404 ).send( tpl );
                    });

                    nsl.log( "warn", ("Request responded with server code 404 for => `" + url + "`") );

                    return;
                }
            }
        });
    }
}
862058
function VKOAuth2(appId, appSecret, redirectURL, fullSettings) {

    this._appId = appId;
    this._appSecret = appSecret;
    this._redirectURL = redirectURL;

    fullSettings = fullSettings || {};

    this._vkOpts = fullSettings.settings || {};
    this._apiVersion = this._vkOpts.version || '5.41';
    this._dialogOptions = this._vkOpts.dialog || {};

    this._fields = fullSettings.fieldMap ? _.values(fullSettings.fieldMap) : [];

    this._fields = _.unique(this._fields.concat(['uid', 'first_name', 'last_name', 'screen_name']));

    this._authURL = 'https://oauth.vk.com/authorize';
    this._accessTokenURI = 'https://oauth.vk.com/access_token';

    this._profileURI = 'https://api.vk.com/method/users.get';
}
312382
public void setWebApp(WebApp app)
    {
        if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)) {
            logger.logp(Level.FINE, CLASS_NAME,"setWebApp", "webapp -> "+ app +" ,this -> " + this);
        }
        
        this._webApp = app;
        if (reqContext != null)
        {
            reqContext.setCurrWebAppBoundary(app);
        }
    }
1270272
private boolean appHasWebXMLFormLogin(WebRequest webRequest) {
        return webRequest.getFormLoginConfiguration() != null &&
               webRequest.getFormLoginConfiguration().getLoginPage() != null &&
               webRequest.getFormLoginConfiguration().getErrorPage() != null;
    }
484638
public static boolean isInternalRequest(HttpServletRequest request){
		//
		if(Boolean.parseBoolean(request.getHeader(WebConstants.HEADER_INTERNAL_REQUEST))){
			return true;
		}

		boolean isInner = IpUtils.isInnerIp(request.getServerName());
		String forwardHost = request.getHeader(WebConstants.HEADER_FORWARDED_HOST);
		//来源于网关
		if(StringUtils.isNotBlank(forwardHost)){
			isInner = IpUtils.isInnerIp(StringUtils.split(forwardHost, ":")[0]);
		}else{			
			if(!isInner){
				isInner = IpUtils.isInnerIp(IpUtils.getinvokerIpAddr(request));
			}
		}
		return isInner;
	}
1135037
private void getEncryptedAppBuffer(int requested_size) throws IOException {

        final int size = Math.max(getConnLink().getPacketBufferSize(), requested_size);

        synchronized (closeSync) {
            if (closeCalled) {
                IOException up = new IOException("Operation failed due to connection close detected");
                throw up;
            }

            if (null != this.encryptedAppBuffer) {
                if (size <= this.encryptedAppBuffer.capacity()) {
                    // current buffer exists and is big enough
                    this.encryptedAppBuffer.clear();
                    return;
                }
                // exists but is too small
                this.encryptedAppBuffer.release();
                this.encryptedAppBuffer = null;
            }
            if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
                Tr.event(tc, "Allocating encryptedAppBuffer, size=" + size);
            }
            // Allocate the encrypted data buffer
            this.encryptedAppBuffer = SSLUtils.allocateByteBuffer(
                                                                  size, getConfig().getEncryptBuffersDirect());
        }
    }
1180270
public ApplicationState getApplication(final String applicationId) throws IOException {
    final String url = this.getApplicationURL(applicationId);
    final HttpGet get = prepareGet(url);
    try (final CloseableHttpResponse response = this.httpClient.execute(get, this.httpClientContext)) {
      final String message = IOUtils.toString(response.getEntity().getContent());
      final ApplicationResponse result = this.objectMapper.readValue(message, ApplicationResponse.class);
      return result.getApplicationState();
    }
  }
24795
public void handleRequest(ServletRequest request, ServletResponse response) throws Exception {
        Object token = null;
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpServletRequest httpRequest = null; //PM88028
        StringBuffer path =null;
        WebAppDispatcherContext dispatchContext =null;
        String pathInfo = null; // PK64302
        FileNotFoundException fnf = null;
        
    	
//		if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
//         	logger.entering(CLASS_NAME,"handleRequest : request--->" + req.getRequestURI()+ "<---");
//		}
		
        try {
        	//IExtendedRequest wasreq = (IExtendedRequest) ServletUtil.unwrapRequest(request);
                //PM88028 Start
                IExtendedRequest wasreq = null;
                
                if(useOriginalRequestState){

                    WebContainerRequestState reqStateSaveRequest = WebContainerRequestState.getInstance(false);
                    if(reqStateSaveRequest != null){                        
                        httpRequest = (HttpServletRequest)reqStateSaveRequest.getAttribute("unFilteredRequestObject");
                        if(httpRequest != null) {
                            wasreq = (IExtendedRequest) ServletUtil.unwrapRequest(httpRequest);  
                            if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                                logger.entering(CLASS_NAME,"handleRequest : useOriginalRequestState request--->" + httpRequest.getRequestURI()+ "<---");
                            }
                        }
                    } 
                }
                //if it is null then get it from the req
                if(httpRequest == null)
                {
                    httpRequest = (HttpServletRequest) request;
                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                        logger.entering(CLASS_NAME,"handleRequest : request--->" + httpRequest.getRequestURI()+ "<---");
                    }
                    wasreq = (IExtendedRequest) ServletUtil.unwrapRequest(request);
                }
            
		dispatchContext = (WebAppDispatcherContext)wasreq.getWebAppDispatcherContext();
			
        
            //LIBERTY: Talk to Namespace
                //webAppNameSpaceCollab.preInvoke(cmd);
			
            //remove since the preInvoke is done in WebAppFilterManager
			//The preInvoke in WebAppFilterManager calls with doAuth/enforceSecurity=true which will setup
			//the metadata for sync to thread just as well as a call with doAuth=false would.
			//securityPreInvokes.push(secCollab.preInvoke(req, resp, null, false));
        
            token = ThreadIdentityManager.runAsServer();
        
            boolean isInclude = false; // is this an include request?
            ServletContext context = _webapp;
            String fileSystemPath = null; // actual OS dependent path
            path = new StringBuffer(); // constructed path

            String servletPath = null; // PK64302
          //PM88028 change req to httpReques
            if (httpRequest.getAttribute(WebAppRequestDispatcher.REQUEST_URI_INCLUDE_ATTR) != null) {
                isInclude = true;
                servletPath = (String) httpRequest.getAttribute(WebAppRequestDispatcher.SERVLET_PATH_INCLUDE_ATTR);
                pathInfo = (String) httpRequest.getAttribute(WebAppRequestDispatcher.PATH_INFO_INCLUDE_ATTR);
            }// PM79476 (PM71901) Start
            else if(dispatchContext!= null && !handlingRequestWithOverridenPath){ //always here
                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                        logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "relative uri -->["+ dispatchContext.getRelativeUri()+"]");
                }
                servletPath = dispatchContext.getServletPath();
                if(servletPath!= null) {servletPath = WebGroup.stripURL(servletPath,false);}                    
                
                pathInfo = dispatchContext.getPathInfo();
                if(pathInfo!= null) {pathInfo = WebGroup.stripURL(pathInfo,false);}
                if(pathInfo == ""){pathInfo = null;}
                
            }// PM71901 End
            else { // never be here 
                // not get these from request as these can be overridden
                servletPath = httpRequest.getServletPath();
                pathInfo = httpRequest.getPathInfo();
            }

            if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
            	logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "servletPath [" + servletPath +"] pathInfo [" + pathInfo +"]");
            }
            
            path.append(servletPath);

            if (pathInfo != null) {
            	int semicolon = pathInfo.indexOf(';');
                if (semicolon != -1)
                    pathInfo = pathInfo.substring(0, semicolon);
               
                path.append(pathInfo);
            }

            //PK36447

            String temporaryPath = WSUtil.resolveURI(path.toString());
            String upperMatchString = temporaryPath.toUpperCase();
            boolean forbidden = false;
            if (!exposeWebInfOnDispatch && (upperMatchString.startsWith("/WEB-INF/") || upperMatchString.equals("/WEB-INF")))
                forbidden = true;

            //We check META-INF by default in the JSP codepath
            else if (upperMatchString.startsWith("/META-INF/") || upperMatchString.equals("/META-INF"))
                forbidden = true;
            
            // PK24615 change conditionals from "indexOf() != -1" to "startsWith()"
            if (forbidden) {
                int statusCode;
                //We don't want to give out more information than required.  On tWAS, this code lived in the wrapper
                //and so returning a 403 would have meant that the file was, in fact, found.  Adding this check to maintain
                //the same behavior
                //If the path was encoded and illegal, then just return a 404.
                if (temporaryPath.equals(path.toString())) {
                    statusCode = HttpServletResponse.SC_FORBIDDEN;
                } else {
                    statusCode = HttpServletResponse.SC_NOT_FOUND;
                }
                resp.sendError(
                    statusCode,
                    MessageFormat.format(nls.getString("File.not.found", "File not found: {0}"), new Object[] { path.toString()}));
                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                    logger.exiting(CLASS_NAME,"handleRequest","Forbidden-WEB-INF/META-INF");
                return;
            }
            
            if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                logger.logp(Level.FINE, CLASS_NAME,"handleRequest"," after resolving the uri: path ---> " + path);

            
            //Liberty ArchiveAPI container to be used instead of File system.
            Container webModuleContainer = _webapp.getModuleContainer();

            /*
             * In Liberty, we'll leave the file system path as just the request path so we can keep 
             * the checks for illegal characters in the same code
             */
            fileSystemPath = path.toString();

            // PQ79698 part1 starts
            if (!isValidFilePath(fileSystemPath)) {
                resp.sendError(HttpServletResponse.SC_FORBIDDEN, nls.getString("File.name.contains.illegal.character", "File path contains illegal character."));
                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                	logger.exiting(CLASS_NAME,"handleRequest","Forbidden-invalid file path");
                return;
            }
            // PQ79698 part1 ends
			// defect 220552: begin implement the deny feature for specified URI patterns
			else{
				Object matchedURI = denyPatterns.match(path.toString());
				if(matchedURI != null){	
					if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
						logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "Attempted to serve URI that matches denied URL pattern URI =[" + path.toString() + "] matched [" + matchedURI + "]");
					}
					resp.sendError(HttpServletResponse.SC_FORBIDDEN,							
							MessageFormat.format(nls.getString(
							"File.not.found", "File not found: {0}"),
							new Object[] { path.toString() }));
                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                    	logger.exiting(CLASS_NAME,"handleRequest","Forbidden-denied pattern");
						return;
				}
			}
			// defect 220552: end implement the deny feature for specified URI patterns

            boolean fileIsDirectoryInDocumentRoot = false;         // PM17845

            File file = null;
            Entry entry = null;
            boolean requestForRoot = false;
           
            //Don't call getEntry for the root container's / as there is no entry.
            if(fileSystemPath.equals("/")){      
                requestForRoot = true;
            } 
            else {
                entry = webModuleContainer.getEntry(fileSystemPath);
            }
            
            //We failed to find something at the path, either in the filesystem or via the container.
            if ((file != null && !file.exists()) || (webModuleContainer != null && entry == null && !requestForRoot)) {
            	
            	if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
    				logger.logp(Level.FINE, CLASS_NAME,"handleRequest","file does not exist --> " + path);
            	DocumentRootUtils docRoot = new DocumentRootUtils(context,extendedDocumentRoot,preFragmentExtendedDocumentRoot);
            	try {
            	    docRoot.handleDocumentRoots(path.toString());
            	} catch (FileNotFoundException fnfe) {
    				throw new FileNotFoundException(MessageFormat.format(nls.getString("File.not.found","File not found: {0}"), new Object[]{path}));
            	}
            	if (docRoot.isDirectory()) {
                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                    	logger.exiting(CLASS_NAME,"handleRequest","matchedfile is a directory");
    		    	if (!docRoot.isMatchedFromEDR() || WCCustomProperties.ALLOW_PARTIAL_URL_TO_EDR ) {
    		    		fileIsDirectoryInDocumentRoot = true;
    		    	} 
            	} else {
            		
                    if (isRequestForbidden(path))   
    	            {
                        resp.sendError(HttpServletResponse.SC_FORBIDDEN, MessageFormat.format(nls.getString("File.not.found","File not found: {0}"), new Object[]{httpRequest.getPathInfo()})); //PM88028
                        if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                        	logger.exiting(CLASS_NAME,"handleRequest","Forbidden-Extended doc root endsWith");
    		            return;
    	            }
            	
            	    ZipFileResource zipFileResource = docRoot.getMatchedZipFileResource();
            	    if (zipFileResource!=null)
            	    {            		
            		    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
            		     logger.logp(Level.FINE, CLASS_NAME,"handleRequest","zip file found: Use ZipFileServletWrapper");
            			
           		         handleZipFileWrapper(req, httpRequest, resp, path, dispatchContext,zipFileResource);
           		         return;
            	     } else {
            	        EntryResource entryResource = docRoot.getMatchedEntryResource();
            	        if(entryResource != null){
            	            if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
            	                logger.logp(Level.FINE, CLASS_NAME,"handleRequest","entry is found: Use EntryServletWrapper");
            	            EntryServletWrapper ewrapper = new EntryServletWrapper(_webapp, this, entryResource.getEntry());
            	            ewrapper.handleRequest(req, resp);
            	            
            	            if(!_webapp.isCachingEnabled()){

            	                //PM84305
            	                if(!_webapp.getConfiguration().isDisableStaticMappingCache()){
            	                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
            	                        logger.logp(Level.FINE, CLASS_NAME,"handleRequest","ewrapper addMappingTarget URI -> "+ path);

            	                    _webapp.addMappingTarget(path.toString(), ewrapper);
            	                }
            	                
            	                if (!dispatchContext.isInclude() && !dispatchContext.isForward()) {
            	                    WebContainer.addToCache(httpRequest, ewrapper, this._webapp); //PM88028
            	                }
            	            }
            	            
            	            return;
            	        }  
            	    
            	    
            		           		
            	        File matchedFile = docRoot.getMatchedFile();

            	        if (matchedFile !=null) {


            	            FileServletWrapper fwrapper = getStaticFileWrapper(_webapp, this, matchedFile);
            	            fwrapper.handleRequest(req, resp);
            	            if (!_webapp.isCachingEnabled()){
            	                try
            	                {
            	                    //PM84305
            	                    if(!_webapp.getConfiguration().isDisableStaticMappingCache()){
            	                        if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
            	                            logger.logp(Level.FINE, CLASS_NAME,"handleRequest","fwrapper addMappingTarget URI -> "+ path);

            	                        _webapp.addMappingTarget(path.toString(), fwrapper);
            	                    }

            	                    // begin 309663
            	                    // add to cache now versus wait until Webcontainer.handleRequest finds a IServletWrapper 
            	                    // (allows request.getPathInfo and request.servletPath() to stay valid)
            	                    if (!dispatchContext.isInclude() && !dispatchContext.isForward()) {
            	                        WebContainer.addToCache(httpRequest, fwrapper, this._webapp); //PM88028
            	                    }
            	                    // end 309663
            	                }
            	                catch (Exception e)
            	                {
            	                    // do nothing because its a race condition...won't happen again.
            	                }
            	            } 
            	            return;
            	        }
            	     }
            	}

               // PM17845 Add if statement
                if (!fileIsDirectoryInDocumentRoot) {
                    // Resource was not found...invoke filters                
    				throw new FileNotFoundException(MessageFormat.format(nls.getString("File.not.found","File not found: {0}"), new Object[]{path}));
                }   
            }    
            
            boolean isContainerDirectory = false;
            Container directory = null;
            // Determine if the entry is a directory
            if(webModuleContainer != null){
                if(requestForRoot){
                    directory = webModuleContainer;
                } else if (entry != null){
                    directory = entry.adapt(Container.class);
                }
                isContainerDirectory = requestForRoot || fileIsDirectoryInDocumentRoot || (entry.getSize()==0 && directory != null && directory.isRoot()==false);
            }
            
            // PM17845 Add check for ileIsDirectoryInExtendedDocumnetRoot
            if ((file != null && file.isDirectory()) || fileIsDirectoryInDocumentRoot || isContainerDirectory) 
            {
                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)) {
                    if (file != null) {
                        logger.logp(Level.FINE, CLASS_NAME, "handleRequest", "file is a directory --> " + file.getPath());
                    } else if (entry!=null) {
                        logger.logp(Level.FINE, CLASS_NAME, "handleRequest", "entry path --> " + entry.getPath());
                    } else {
                        logger.logp(Level.FINE, CLASS_NAME, "handleRequest", "file is null");
                    }
                }
                
                /*
                 * The file is a directory so first see if we should append a trailing slash to the
                 * uri and redirect.  After that try and serve a welcome file or directory browse.
                 */
                String requestString = getURLWithRequestURIEncoded(httpRequest).toString(); //PM88028
                
                //start PI31447
                if(WCCustomProperties.IGNORE_SEMICOLON_ON_REDIRECT_TO_WELCOME_PAGE){
                        String requestURI = req.getRequestURI();
                        int indexAfterContextRoot = requestURI.indexOf(context.getContextPath()) + context.getContextPath().length();
                        if(!context.getContextPath().equals("/"))
                                //if the context root is not / look for the character after next since the next is /
                                indexAfterContextRoot++;
                        if(indexAfterContextRoot < requestURI.length() && requestURI.charAt(indexAfterContextRoot) == ';'){ 
                                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE))
                                        logger.logp(Level.FINE, CLASS_NAME,"handleRequest","Removing semi-colon");
                                requestString = requestString.substring(0, requestString.indexOf(";"));
                        } 
                }
                //end PI31447
                
                String queryString = httpRequest.getQueryString(); //PM88028

                if (!requestString.endsWith("/")) {
                    if (isInclude == false) {
                        String tmpURL = requestString + "/"; // append a slash for redirect purposes.
//                        String qString;
//                        if ((qString = req.getQueryString()) != null) { // if query string exists; add it.
//                            tmpURL += "?" + qString;
//                        }
                        //PM88028
                        if (queryString != null){ // if query string exists; add it.
                            tmpURL += "?" +queryString;
                        }
                        
                        if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                        	logger.logp(Level.FINE, CLASS_NAME,"handleRequest","sendRedirect -->" + tmpURL);
                        
                        // encode redirect url to keep session info.
                        resp.sendRedirect(resp.encodeRedirectURL(tmpURL));
                        
                        if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                        	logger.exiting(CLASS_NAME,"handleRequest","redirect to context root");
                                              
                        return;
                    }
                }
                //begin PK10057
//                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
//                    logger.logp(Level.FINE, CLASS_NAME,"handleRequest","calling security check for URI --> " + path.toString() );
//                }
                
                //The preInvoke in WebAppFilterManager calls with doAuth/enforceSecurity=true
                //securityPreInvokes.push(secCollab.preInvoke ( req, resp, path.toString(), dispatchContext.isEnforceSecurity()));
             
//                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
//                    logger.logp(Level.FINE, CLASS_NAME,"handleRequest","returned from security check for URI --> " + path.toString() );
//                }
                //end PK10057
                
                String welcomeFileRedirectUri = null;
                String welcomeFileForwardUri = null;
                
                if ((welcomeFileList != null) && (welcomeFileList.size() != 0)) {
                	if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                    	logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "Check welcome file list");
                	}
                    /*
                     * Check the welcome files to see if we should be serving
                     * one of them up here.
                     */
                    Iterator e = welcomeFileList.iterator();
                    String page = null;

                    while (e.hasNext()) {
                        page = (String) e.next();

                        if ((page.charAt(0) == '/'))
                            page = page.substring(1);

                        // begin 254491    [proxies BOTP] mis-handling of non-existent welcome-file's    WAS.webcontainer -- rewritten
                        RequestProcessor rp = _webapp.getRequestMapper().map(path.toString() + page);
                        if(rp == null){
                        	if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                            	logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "No request processor found for welcome file:" + path.toString() + page);
                        	}
                        	continue;
                        }
                        else if (rp instanceof WebExtensionProcessor){
                        	boolean available = ((WebExtensionProcessor)rp).isAvailable(path.toString() + page);
                        	if(available == false){
                        		if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                                	logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "No web extension processor found for welcome file:" + path.toString() + page);
                            	}
                        		continue;
                        	}
                        }
                        else if (rp instanceof IServletWrapper){
                        	boolean available = ((IServletWrapper)rp).isAvailable();
                        	if(available == false){
                        		if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                                	logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "No servlet wrapper found for welcome file:" + path.toString() + page);
                            	}  
                        		continue;
                        	}
                        }

                        if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                        	logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "Process welcome file: path: " + path.toString() + ", page: "+page);
                    	} 
                        // end 254491    [proxies BOTP] mis-handling of non-existent welcome-file's    WAS.webcontainer -- rewritten
                        if (redirectToWelcomeFile) {
                            String qString = "";
//                            if ((req.getQueryString()) != null) { // if query string exists; add it.
//                                qString = "?" + req.getQueryString();
//                            }
                            if(queryString != null) { // if query string exists; add it.
                                qString = "?" + queryString; //PM88028
                            }
                            String rPath = removeLeadingSlashes(path.toString());
                            if (rPath == null)
                                rPath = "";
                            //	BEGIN:PK15276
                            String redirectURI;
                            if(com.ibm.ws.webcontainer.osgi.WebContainer.getServletContainerSpecLevel() >= 31 || WCCustomProperties.REDIRECT_WITH_PATH_INFO){
                                redirectURI= page + qString;
                                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE)){
                                    logger.logp(Level.FINE, CLASS_NAME,"handleRequest", "Process welcome file: redirecting with pathInfo: " + redirectURI);
                                }
                            }
                            else{
                                redirectURI = rPath + page + qString;
                            }
                            
                            
                            
                            req.setAttribute("com.ibm.ws.webcontainer.welcomefile.redirecturl", redirectURI);
                            welcomeFileRedirectUri = redirectURI;

                        }
                        else {
                            //begin 267395    SVT: can not get Admin Console on Win2000 -- m0514.18 build    WAS.webcontainer    
                            String uri = path.toString() + page;
                            //PK78371 - start
                            if (WCCustomProperties.PROVIDE_QSTRING_TO_WELCOME_FILE){
//                                if ((req.getQueryString()) != null)
//                                    uri = uri + "?" + req.getQueryString();
                                if (queryString != null)
                                    uri = uri + "?" + queryString; //PM88028
                            }
                            //PK78371 - end 
                            req.setAttribute("com.ibm.ws.webcontainer.welcomefile.url", uri);
                            welcomeFileForwardUri = uri;
                        }
                        //end 267395    SVT: can not get Admin Console on Win2000 -- m0514.18 build    WAS.webcontainer    
                    	break; // Break out of the loop with the first match
                    }
                }
                
                if (welcomeFileRedirectUri!=null){
                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                        logger.logp(Level.FINE,CLASS_NAME,"handleRequest", "sendRedirect to Welcome File:" + welcomeFileRedirectUri);

                    resp.sendRedirect(resp.encodeRedirectURL(welcomeFileRedirectUri));

                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                        logger.exiting(CLASS_NAME,"handleRequest");
                    return;

                } else if (welcomeFileForwardUri!=null){
                    RequestDispatcher rd = context.getRequestDispatcher(welcomeFileForwardUri);

                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                        logger.logp(Level.FINE,CLASS_NAME,"handleRequest", "forward :" + welcomeFileForwardUri);

                    rd.forward(req, resp);

                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                        logger.exiting(CLASS_NAME,"handleRequest");
                    return;
                }
                //End PK64097

                if (_webapp.getConfiguration().isDirectoryBrowsingEnabled()){
					RequestDispatcher dirBrowse = context.getRequestDispatcher(WebApp.DIR_BROWSING_MAPPING);

					if (dirBrowse != null) {
						
						/*
						 * invoke the directory browsing servlet
						 */
						req.setAttribute("com.ibm.servlet.engine.webapp.dir.browsing.path", fileSystemPath);
						req.setAttribute("com.ibm.servlet.engine.webapp.dir.browsing.uri", req.getRequestURI());

						  
						if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
							logger.logp(Level.FINE, CLASS_NAME,"handleRequest","Directory Browse" + fileSystemPath);           		
						dirBrowse.forward(req, resp);
						if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
							logger.exiting(CLASS_NAME,"handleRequest");
						return;
					}
                }

                /*
				 * could not find a welcome file and dir browsing not on
				 */    
                // PK31377 - added if/else
                if (!resp.isCommitted()){  
                    resp.sendError(404, MessageFormat.format(nls.getString("File.not.found", "File not found: {0}"), new Object[] {pathInfo}));
       	   	  		if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                	logger.exiting(CLASS_NAME,"handleRequest","handleRequest ---> File not found");
                }else{		    	   
                    logger.exiting("handleRequest", "handleRequest");               	
            	}
                //PK31377 - end
                return;
            }

		// PK23475 code to check for invalid charcters in the request moved to new private method isRequestForbidden

            // String matchString = path.toString();

            // defect 220552: removed checks for URI resources ending with "/" for JSP resources: handled above.

            /**
            * Do not allow ".." to appear in a path as it allows one to serve files from anywhere within
            * the file system.
            * Also check to see if the path or URI ends with '/', '\', or '.' .
            * PQ44346 - Allow files on DFS to be served.
            */
            //if ((matchString.lastIndexOf("..") != -1 && (!matchString.startsWith("/...")))
            //    || matchString.endsWith("\\")
            //    || req.getRequestURI().endsWith(".")
            //    // PK22928
            //    || req.getRequestURI().endsWith("/")){
            //    //PK22928
		
		    // PK23475 call isRequestForbidden to check if request includes ".." etc.
            if (isRequestForbidden(path))   
            {
                resp.sendError(
                    HttpServletResponse.SC_FORBIDDEN,
                    MessageFormat.format(nls.getString("File.not.found", "File not found: {0}"), new Object[] { pathInfo}));
                if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                	logger.exiting(CLASS_NAME,"handleRequest","handleRequest --> Forbidden-endsWith");
                return;
            }

            // 94578, "Case Sensitive Security Matching bug":  On Windows and Netware only, filename of
            //         requested file must exactly match case or we will throw FNF exception.
            if (webModuleContainer == null && com.ibm.ws.util.FileSystem.isCaseInsensitive) {
                File caseFile = new Java2SecurityFile(fileSystemPath);

                if (!com.ibm.ws.util.FileSystem.uriCaseCheck(caseFile, path.toString())) {
                    if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                    	logger.logp(Level.FINE, CLASS_NAME,"handleRequest","handleRequest --> Case sensitivity check - throw FileNotFoundException");               	
                    throw new FileNotFoundException(path.toString());
                }
            }
            // end 94578

            IServletWrapper fwrapper = null;
            
            if(file != null){
            // Create the FileServletWrapper to serve the file up.
              fwrapper = getStaticFileWrapper(_webapp, this, file);
			// 224858, must set pathElements for files mapped to staticFileServlet so getServletPath
			// is the same on the first request as on subsequent requests
        	//  begin 309663: should not be resetting path elements here (sitemesh issue since corrected).
			//dispatchContext.setPathElements(path.toString(),null);
        	//          end 309663
			// end 224858
            } else {
              fwrapper = getEntryWrapper(_webapp, this, entry);
            }
            
            if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
            	logger.logp(Level.FINE, CLASS_NAME,"handleRequest","Use FileServletWrapper");
            
			fwrapper.handleRequest(req, resp);

			if (!_webapp.isCachingEnabled()){
			    try
			    {
			        //PM84305
			        if(!_webapp.getConfiguration().isDisableStaticMappingCache()){
			            if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
			                logger.logp(Level.FINE, CLASS_NAME,"handleRequest","FileServletWrapper addMappingTarget URI -> "+ path);

			            _webapp.addMappingTarget(path.toString(), fwrapper);
			        }

			        // begin 309663
			        // add to cache now versus wait until Webcontainer.handleRequest finds a IServletWrapper 
			        // (allows request.getPathInfo and request.servletPath() to stay valid)
			        if (!dispatchContext.isInclude() && !dispatchContext.isForward()) {
			            WebContainer.addToCache(httpRequest, fwrapper, this._webapp); //PM88028
			        }
			        // end 309663			
			    }
			    catch (Exception e)
			    {
			        // do nothing because its a race condition...won't happen again.
			    }
			}
			
        }
        catch (FileNotFoundException e) 
		{
            // Give any registered FileNotFoundProcessors a chance to process the request
            if (!RegisterRequestInterceptor.notifyRequestInterceptors(RequestInterceptor.INTERCEPT_POINT_FNF,req, resp)) {
                 // PK64302 Start
                 if (!WCCustomProperties.THROW_404_IN_PREFERENCE_TO_403 && isDirectoryTraverse(path))   
                 {
                     resp.sendError(
                         HttpServletResponse.SC_FORBIDDEN,
                             MessageFormat.format(nls.getString("File.not.found", "File not found: {0}"), new Object[] { pathInfo}));
                     if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable (Level.FINE))
                         logger.exiting(CLASS_NAME, "handleRequest", "Forbidden-file does not exist");
                     return;
                 }
                 // PK64302 End
        	 // Begin PK27620
        	
        	WebAppErrorReport errorReport = new WebAppErrorReport(MessageFormat.format(nls.getString("File.not.found", "File not found: {0}"), new Object[] { e.getMessage()}), e);
    		logger.logp(Level.WARNING,CLASS_NAME,"handleRequest", e.getMessage());
            
        	errorReport.setErrorCode(HttpServletResponse.SC_NOT_FOUND);
        	errorReport.setTargetServletName ("DefaultExtensionProcessor");
        	
       		// Note: In V8 by default WCCustomProperties.MODIFIED_FNF_BEHAVIOR is true.
                if(!WCCustomProperties.MODIFIED_FNF_BEHAVIOR) { //PK65408
							
                com.ibm.wsspi.webcontainer.util.FFDCWrapper.processException(e, "com.ibm.ws.webcontainer.extension.DefaultExtensionProcessor.handleRequest", "573", this);
							try
							{
								_webapp.sendError(req, resp, errorReport);
							}
							catch (Exception ex)
							{
								// ignore
							
							}
							//PK65408 Start
					 }
					else {
						if (!WCCustomProperties.SERVLET_30_FNF_BEHAVIOR||request.getDispatcherType()!=DispatcherType.INCLUDE){
							if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                				logger.logp(Level.FINE, CLASS_NAME,"handleRequest","dispatch type is not include, throw normal FNF");
                    
							fnf = e;
							resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
						}
						else {
//							Max: Must throw our own type of FNF to differentiate so we can support the following spec requirement
//							and not break backwards compatibility when the servlet itself throws FileNotFound or we're not in an include
//							Spec: If the default servlet is the target of a RequestDispatch.include() and the requested
//							resource does not exist, then the default servlet MUST throw
//							FileNotFoundException. If the exception isn't caught and handled, and the
//							response has not been committed, the status code MUST be set to 500.

							if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
                				logger.logp(Level.FINE, CLASS_NAME,"handleRequest","throwing IncludeFileNotFoundException");
                    
							fnf = new IncludeFileNotFoundException(e.getMessage());
						}
						
					}
				
				
				// End PK27620
            }    
        }
	    catch (SecurityViolationException e){
	    	String strPath=null;
	    	if (path!=null){
	    		strPath=path.toString();
	    		collabHelper.processSecurityPreInvokeException (e, this, httpRequest, resp, dispatchContext, _webapp, strPath); //PM88028
	    	}
	    	return;
	    }
        finally {
            //begin PK10057
        	ThreadIdentityManager.reset(token);
        	
        	//The preInvoke in WebAppFilterManager calls with doAuth/enforceSecurity=true which will setup
//        	while (securityPreInvokes.size() != 0){ // may have null objects in list.
//        		secCollab.postInvoke(securityPreInvokes.pop());
//        	}
        	
        	//webAppNameSpaceCollab.postInvoke();
           //end PK10057
            if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))
            	logger.logp(Level.FINE, CLASS_NAME,"handleRequest","handleRequest");
          //PK65408 Start
    	    if(fnf!=null){
    	    	throw fnf;
    	    }
    	    //PK65408 End
        }
        return;
    }
1183108
public static boolean isGooglebot(HttpServletRequest request) {
		@SuppressWarnings("unchecked")
		Enumeration<String> headers = request.getHeaders("User-Agent");
		while(headers.hasMoreElements()) {
			String userAgent = headers.nextElement();
			if(userAgent.contains("Googlebot")) {
				// Verify through reverse then forward DNS lookups
				String remoteAddr = request.getRemoteAddr();
				String remoteHost = request.getRemoteHost();
				try {
					InetAddress remoteIp = InetAddress.getByName(remoteAddr);
					// Do reverse lookup if container didn't do so
					if(remoteAddr.equals(remoteHost)) remoteHost = remoteIp.getCanonicalHostName();
					// Reverse DNS result must be in the googlebot.com domain
					if(remoteHost.endsWith(".googlebot.com") || remoteHost.endsWith(".googlebot.com.")) {
						// Forward DNS must resolve back to the original IP
						for(InetAddress actualIp : InetAddress.getAllByName(remoteHost)) {
							System.out.println("DEBUG: ServletUtil: Googlebot verified: userAgent=\""+userAgent+"\", remoteAddr=\""+remoteAddr+"\", remoteHost=\""+remoteHost+"\"");
							if(actualIp.equals(remoteIp)) return true;
						}
						System.out.println("DEBUG: ServletUtil: Googlebot agent with valid reverse DNS failed forward lookup: userAgent=\""+userAgent+"\", remoteAddr=\""+remoteAddr+"\", remoteHost=\""+remoteHost+"\"");
					}
					System.out.println("DEBUG: ServletUtil: Googlebot agent failed valid reverse DNS lookup: userAgent=\""+userAgent+"\", remoteAddr=\""+remoteAddr+"\", remoteHost=\""+remoteHost+"\"");
				} catch(UnknownHostException exception) {
					// Ignored
					System.out.println("DEBUG: ServletUtil: Googlebot agent verification failed due to exception: userAgent=\""+userAgent+"\", remoteAddr=\""+remoteAddr+"\", remoteHost=\""+remoteHost+"\", exception=\""+exception+"\"");
				}
				break; // Only check the first Googlebot User-Agent header (there should normally only be one anyway)
			}
		}
		return false;
	}
1082478
@Override
    public boolean isWsocRequest(ServletRequest request) throws ServletException {
        ServletContext context = request.getServletContext();
        Object wsocContainer = null;
        if (context != null) {
            wsocContainer = context.getAttribute(WebSocketContainerManager.SERVER_CONTAINER_ATTRIBUTE);
        }

        if (wsocContainer != null) {
            //check if this is a IBM's implementation of WebSocketContainer. If this is a tomcat or some other server's WebSocket
            //implementation of WebSocketContainer then, this is not a valid WebSocket request for us and Web Container should not call
            //WsocHandler.handleRequest() subsequently.
            if (!isValidContainer(wsocContainer)) {
                return false;
            }
        } else { //not a WebSocket request if ServerContainer attribute is missing.
            return false;
        }

        //call setNoMoreAddEndPoints only once per webapp
        if (!noMoreAddsCalled) {
            ((ServerContainerExt) wsocContainer).setNoMoreAddEndpointsAllowed();
            noMoreAddsCalled = true;
        }

        return checkWebSocketRequest(request, wsocContainer);
    }
528875
public boolean handshake(RequestBaratine request)
    throws Exception
  {
    Objects.requireNonNull(request);

    _request = request;

    RequestBaratineImpl req = (RequestBaratineImpl) request;
    //ResponseBaratineImpl res = (ResponseBaratineImpl) response;

    if (log.isLoggable(Level.FINE)) {
      log.fine(this + " upgrade HTTP to WebSocket");
    }

    String method = req.method();
    // String uri = req.uri();

    if (! "GET".equals(method)) {
      req.halt(METHOD_NOT_ALLOWED);

      throw new IllegalStateException(L.l("HTTP Method must be 'GET', because the WebSocket protocol requires 'GET'.\n  remote-IP: {0}",
                                          req.ip()));
    }

    String connection = req.header("Connection");
    String upgrade = req.header("Upgrade");

    if (! "websocket".equalsIgnoreCase(upgrade)) {
      req.halt(HttpStatus.BAD_REQUEST);

      throw new IllegalStateException(L.l("HTTP Upgrade header '{0}' must be 'WebSocket', because the WebSocket protocol requires an Upgrade: WebSocket header.\n  remote-IP: {1}",
                                          upgrade,
                                          req.ip()));
    }

    if (connection == null
        || connection.toLowerCase().indexOf("upgrade") < 0) {
      req.halt(HttpStatus.BAD_REQUEST);

      throw new IllegalStateException(L.l("HTTP Connection header '{0}' must be 'Upgrade', because the WebSocket protocol requires a Connection: Upgrade header.\n  remote-IP: {1}",
                                          connection,
                                          req.ip()));
    }

    String key = req.header("Sec-WebSocket-Key");

    if (key == null) {
      req.halt(HttpStatus.BAD_REQUEST);

      throw new IllegalStateException(L.l("HTTP Sec-WebSocket-Key header is required, because the WebSocket protocol requires an Origin header.\n  remote-IP: {0}",
                                          req.ip()));
    }
    else if (key.length() != 24) {
      req.halt(HttpStatus.BAD_REQUEST);

      throw new IllegalStateException(L.l("HTTP Sec-WebSocket-Key header is invalid '{0}' because it's not a 16-byte value.\n  remote-IP: {1}",
                                          key,
                                          req.ip()));
    }

    String version = req.header("Sec-WebSocket-Version");

    String requiredVersion = WebSocketConstants.VERSION;
    if (! requiredVersion.equals(version)) {
      req.halt(HttpStatus.BAD_REQUEST);

      throw new IllegalStateException(L.l("HTTP Sec-WebSocket-Version header with value '{0}' is required, because the WebSocket protocol requires an Sec-WebSocket-Version header.\n  remote-IP: {1}",
                                          requiredVersion,
                                          req.ip()));
    }

    String extensions = req.header("Sec-WebSocket-Extensions");
    boolean isMasked = true;

    if (extensions != null && extensions.indexOf("x-unmasked") >= 0) {
      isMasked = false;
    }

    ArrayList<String> serverExtensionList = new ArrayList<String>();

    if (! isMasked) {
      serverExtensionList.add("x-unmasked");
    }

    req.status(HttpStatus.SWITCHING_PROTOCOLS);//, "Switching Protocols");
    req.header("Upgrade", "websocket");
    req.header("Connection", "Upgrade");

    String accept = calculateWebSocketAccept(key);

    req.header("Sec-WebSocket-Accept", accept);

    if (serverExtensionList.size() > 0) {
      StringBuilder sb = new StringBuilder();

      for (int i = 0; i < serverExtensionList.size(); i++) {
        if (i > 0)
          sb.append(", ");

        sb.append(serverExtensionList.get(i));
      }

      req.header("Sec-WebSocket-Extensions", sb.toString());
    }

    req.length(0);

    FrameIn fIs;

    fIs = new FrameIn();

    // _fIs = fIs;

    fIs.init(null, req.requestHttp().connTcp().readStream());

    frameInput(fIs);

    // Endpoint endpoint = _endpointSkeleton.newEndpoint(_factory, paths);
    // Endpoint endpoint = wsCxt.getFactory().get();

    //WebSocketBaratine wsConn = null;;

    ConnectionWebSocketBaratine connWs
      = new ConnectionWebSocketBaratine(this,
                                     req.requestHttp());

    // order for duplex
    req.upgrade(connWs);

    req.flush();

    _outProxy = req.connHttp().outProxy();

    _outWriter = new OutWebSocketWriter();
    _service.open(this);

    ServiceRef.flushOutbox();

    return true;
  }
359833
public Response api(Request request) throws IOException {
    Request req = new Request();
    req.setMethod(request.getMethod());
    req.setBaseUri(this.host);
    req.setEndpoint("/" + version + "/" + request.getEndpoint());
    req.setBody(request.getBody());
    for (Map.Entry<String, String> header : this.requestHeaders.entrySet()) {
      req.addHeader(header.getKey(), header.getValue());
    }
    for (Map.Entry<String, String> queryParam : request.getQueryParams().entrySet()) {
      req.addQueryParam(queryParam.getKey(), queryParam.getValue());
    }

    return makeCall(req);
  }