Package er.extensions.appserver

Source Code of er.extensions.appserver.ERXComponentRequestHandler

package er.extensions.appserver;


import com.webobjects.appserver.WOActionResults;
import com.webobjects.appserver.WOApplication;
import com.webobjects.appserver.WOComponent;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WORequest;
import com.webobjects.appserver.WORequestHandler;
import com.webobjects.appserver.WOResponse;
import com.webobjects.appserver.WOSession;
import com.webobjects.appserver.WOStatisticsStore;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSLog;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.foundation.NSNotificationCenter;

import er.extensions.foundation.ERXProperties;

/**
* Patch to prevent direct access to components via /wo/pagename.wo URLs
* @property ERXDirectComponentAccessAllowed set to true to restore the original behavior. Default is false.
*/
public class ERXComponentRequestHandler extends WORequestHandler
{
  private boolean _directComponentAccessAllowed;

  public ERXComponentRequestHandler() {
    super();
    setDirectComponentAccessAllowed(ERXProperties.booleanForKeyWithDefault("ERXDirectComponentAccessAllowed", false));
  }

  public static NSDictionary requestHandlerValuesForRequest(WORequest aRequest)
  {
    NSMutableDictionary aDictionary = new NSMutableDictionary();
    NSArray pathArray = aRequest.requestHandlerPathArray();
    String lastObject = null;
    String penultElement = null;
    String aSessionID = null;
    String aContextID = null;
    String aSenderID = null;
    int p = 0;
    int count = 0;
    int length = 0;
    int pageNameLength = 0;
    boolean _lookForIDsInCookiesFirst = WORequest._lookForIDsInCookiesFirst();

    if (_lookForIDsInCookiesFirst) {
      aSessionID = aRequest.cookieValueForKey(WOApplication.application().sessionIdKey());
    }
    if (pathArray != null) {
      count = pathArray.count();
    }
    if ((pathArray != null) && (count != 0))
    {
      lastObject = (String)pathArray.lastObject();
      if (count > 1) {
        penultElement = (String)pathArray.objectAtIndex(count - 2);
      }

      length = lastObject.length();

      while ((p < length) && (Character.isDigit(lastObject.charAt(p)))) {
        p++;
      }
      if ((p < length) && (lastObject.charAt(p) == '.'))
      {
        aContextID = lastObject.substring(0, p);

        p++;
        aSenderID = lastObject.substring(p);

        if ((penultElement != null) && (penultElement.endsWith(".wo")))
        {
          pageNameLength = count - 2;
        } else if (penultElement != null)
        {
          if ((!_lookForIDsInCookiesFirst) || (aSessionID == null)) {
            aSessionID = penultElement;
          }

          pageNameLength = count - 2;
        }
        else {
          pageNameLength = 0;
        }

        if (aContextID != null) {
          aDictionary.setObjectForKey(aContextID, "wocid");
          aDictionary.setObjectForKey(aSenderID, "woeid");
        }

      }
      else {
        if (lastObject.endsWith(".wo")) {
          pageNameLength = count;
        }
        else
        {
          aSessionID = lastObject;

          pageNameLength = count - 1;
        }
      }
     
      if ((aSessionID == null) && (!_lookForIDsInCookiesFirst))
      {
        aSessionID = aRequest.stringFormValueForKey(WOApplication.application().sessionIdKey());
        if (aSessionID == null) {
          aSessionID = aRequest.cookieValueForKey(WOApplication.application().sessionIdKey());
        }
      }

    }
    else if (WOApplication.application().shouldRestoreSessionOnCleanEntry(aRequest))
    {
      aSessionID = aRequest.cookieValueForKey(WOApplication.application().sessionIdKey());
    }

    if ((aSessionID != null) && (aSessionID.length() != 0)) {
      aDictionary.setObjectForKey(aSessionID, WOApplication.application().sessionIdKey());
    }
    return aDictionary;
  }

  private WOComponent _restorePageForContextID(String oldContextID, WOSession aSession)
  {
    return aSession.restorePageForContextID(oldContextID);
  }

  private WOResponse _dispatchWithPreparedPage(WOComponent aPage, WOSession aSession, WOContext aContext, NSDictionary someElements) {
    WORequest aRequest = aContext.request();
    WOApplication anApplication = WOApplication.application();
    WOResponse aResponse = anApplication.createResponseInContext(aContext);
    String aSenderID = aContext.senderID();

    String oldContextID = aSession._contextIDMatchingIDs(aContext);
    aResponse.setHTTPVersion(aRequest.httpVersion());

    aResponse.setHeader("text/html", "content-type");

    aContext._setResponse(aResponse);

    if (oldContextID == null)
    {
      if (aSenderID != null)
      {
        if (aRequest._hasFormValues()) {
          anApplication.takeValuesFromRequest(aRequest, aContext);
        }
      }

      aContext._setPageChanged(false);
      if (aSenderID != null)
      {
        WOActionResults anActionResults = anApplication.invokeAction(aRequest, aContext);

        if ((anActionResults == null) || ((anActionResults instanceof WOComponent)))
        {
          WOComponent aResultComponent = (WOComponent)anActionResults;
          if ((aResultComponent != null) && (aResultComponent.context() != aContext)) {
            aResultComponent._awakeInContext(aContext);
          }
          boolean didPageChange = false;
          if ((aResultComponent != null) && (aResultComponent != aContext._pageElement())) {
            didPageChange = true;
          }
          aContext._setPageChanged(didPageChange);
          if (didPageChange) {
            aContext._setPageElement(aResultComponent);
          }

        }
        else
        {
          WOResponse theResponse = anActionResults.generateResponse();

          return theResponse;
        }
      }

    }
    else
    {
      WOComponent responsePage = _restorePageForContextID(oldContextID, aSession);
      aContext._setPageElement(responsePage);
    }

    anApplication.appendToResponse(aResponse, aContext);

    return aResponse;
  }

  private WOResponse _dispatchWithPreparedSession(WOSession aSession, WOContext aContext, NSDictionary someElements) {
    WOComponent aPage = null;
    WOResponse aResponse = null;
    String aPageName = (String)someElements.objectForKey("wopage");
    String oldContextID = aContext._requestContextID();
    String oldSessionID = (String)someElements.objectForKey(WOApplication.application().sessionIdKey());
    WOApplication anApplication = WOApplication.application();
    boolean clearIDsInCookies = false;

    if ((oldSessionID == null) || (oldContextID == null))
    {
      if ((aPageName == null) && (!aSession.storesIDsInCookies()))
      {
        WORequest request = aContext.request();

        String cookieHeader = request.headerForKey("cookie");

        if ((cookieHeader != null) && (cookieHeader.length() > 0)) {
          NSDictionary cookieDict = request.cookieValues();

          if ((cookieDict.objectForKey(WOApplication.application().sessionIdKey()) != null) || (cookieDict.objectForKey(WOApplication.application().instanceIdKey()) != null)) {
            clearIDsInCookies = true;
          }
        }
      }

      aPage = anApplication.pageWithName(aPageName, aContext);
    }
    else
    {
      aPage = _restorePageForContextID(oldContextID, aSession);
      if (aPage == null) {
        if (anApplication._isPageRecreationEnabled())
          aPage = anApplication.pageWithName(aPageName, aContext);
        else {
          return anApplication.handlePageRestorationErrorInContext(aContext);
        }
      }
    }
    aContext._setPageElement(aPage);
    aResponse = _dispatchWithPreparedPage(aPage, aSession, aContext, someElements);

    if (anApplication.isPageRefreshOnBacktrackEnabled()) {
      aResponse.disableClientCaching();
    }

    aSession._saveCurrentPage();
    if ((clearIDsInCookies) && (!aSession.storesIDsInCookies())) {
      aSession._clearCookieFromResponse(aResponse);
    }
    return aResponse;
  }

  private WOResponse _dispatchWithPreparedApplication(WOApplication anApplication, WOContext aContext, NSDictionary someElements) {
    WOSession aSession = null;
    WOResponse aResponse = null;
    WOResponse errorResponse = null;
    String aSessionID = (String)someElements.objectForKey(WOApplication.application().sessionIdKey());

    if (aSessionID == null) {
      aSession = anApplication._initializeSessionInContext(aContext);
      if (aSession == null)
        errorResponse = anApplication.handleSessionCreationErrorInContext(aContext);
    }
    else {
      aSession = anApplication.restoreSessionWithID(aSessionID, aContext);
      if (aSession == null) {
        errorResponse = anApplication.handleSessionRestorationErrorInContext(aContext);
      }
    }

    if (errorResponse == null)
    {
      aResponse = _dispatchWithPreparedSession(aSession, aContext, someElements);
    }
    else aResponse = errorResponse;

    aContext._putAwakeComponentsToSleep();
    anApplication.saveSessionForContext(aContext);
    return aResponse;
  }

  WOResponse _handleRequest(WORequest aRequest)
  {
    WOContext aContext = null;
    WOResponse aResponse;

    NSDictionary requestHandlerValues = requestHandlerValuesForRequest(aRequest);

    WOApplication anApplication = WOApplication.application();
    String aSessionID = (String)requestHandlerValues.objectForKey(WOApplication.application().sessionIdKey());

    if ((!anApplication.isRefusingNewSessions()) || (aSessionID != null)) {
      String aSenderID = (String)requestHandlerValues.objectForKey("woeid");

      String oldContextID = (String)requestHandlerValues.objectForKey("wocid");

      WOStatisticsStore aStatisticsStore = anApplication.statisticsStore();
      if (aStatisticsStore != null)
        aStatisticsStore.applicationWillHandleComponentActionRequest();

      try {
        aContext = anApplication.createContextForRequest(aRequest);

        aContext._setRequestContextID(oldContextID);
        aContext._setSenderID(aSenderID);
        anApplication.awake();
        aResponse = _dispatchWithPreparedApplication(anApplication, aContext, requestHandlerValues);
        NSNotificationCenter.defaultCenter().postNotification(WORequestHandler.DidHandleRequestNotification, aContext);

        anApplication.sleep();
      }
      catch (Exception exception)
      {
        try
        {
          NSLog.err.appendln("<" + getClass().getName() + ">: Exception occurred while handling request:\n" + exception.toString());
          if (NSLog.debugLoggingAllowedForLevelAndGroups(1, 4L)) {
            NSLog.debug.appendln(exception);
          }

          if (aContext == null)
            aContext = anApplication.createContextForRequest(aRequest);
          else {
            aContext._putAwakeComponentsToSleep();
          }
          WOSession aSession = aContext._session();
          aResponse = anApplication.handleException(exception, aContext);
          if (aSession != null)
          {
            try
            {
              anApplication.saveSessionForContext(aContext);
              anApplication.sleep();
            } catch (Exception eAgain) {
              NSLog.err.appendln("<WOApplication '" + anApplication.name() + "'>: Another Exception  occurred while trying to clean the application:\n" + eAgain.toString());
              if (NSLog.debugLoggingAllowedForLevelAndGroups(1, 4L))
                NSLog.debug.appendln(eAgain);
            }
          }
        }
        finally
        {
          if ((aContext != null) && (aContext._session() != null))
            anApplication.saveSessionForContext(aContext);
        }
      }
      if (aResponse != null) {
        aResponse._finalizeInContext(aContext);
      }

      if (aStatisticsStore != null) {
        WOComponent aPage = aContext.page();
        String aName = null;
        if (aPage != null) {
          aName = aPage.name();
        }
        aStatisticsStore.applicationDidHandleComponentActionRequestWithPageNamed(aName);
      }
    }
    else {
      String newLocationURL = anApplication._newLocationForRequest(aRequest);
      String contentString = "Sorry, your request could not immediately be processed. Please try this URL: <a href=\"" + newLocationURL + "\">" + newLocationURL + "</a>";
      aResponse = anApplication.createResponseInContext(null);
      WOResponse._redirectResponse(aResponse, newLocationURL, contentString);
      aResponse._finalizeInContext(null);
    }

    return aResponse;
  }

  @Override
  public WOResponse handleRequest(WORequest aRequest)
  {
    WOApplication anApplication = WOApplication.application();
    Object globalLock = anApplication.requestHandlingLock();
    WOResponse aResponse;
    if (globalLock != null)
    {
      synchronized (globalLock) {
        aResponse = _handleRequest(aRequest);
      }
    } else {
      aResponse = _handleRequest(aRequest);
    }

    return aResponse;
  }

  public boolean isDirectComponentAccessAllowed() {
    return _directComponentAccessAllowed;
  }

  public void setDirectComponentAccessAllowed(boolean directComponentAccessAllowed) {
    _directComponentAccessAllowed = directComponentAccessAllowed;
  }
}
TOP

Related Classes of er.extensions.appserver.ERXComponentRequestHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.