Пример #1
0
  @SuppressWarnings("unchecked")
  @Override
  public WOResponse handleRequest(WORequest request) {
    WOApplication application = WOApplication.application();
    application.awake();
    try {
      WOContext context = application.createContextForRequest(request);
      WOResponse response = application.createResponseInContext(context);

      Object output;
      try {
        String inputString = request.contentString();
        JSONObject input = new JSONObject(inputString);
        String wosid = request.cookieValueForKey("wosid");
        if (wosid == null) {
          ERXMutableURL url = new ERXMutableURL();
          url.setQueryParameters(request.queryString());
          wosid = url.queryParameter("wosid");
          if (wosid == null && input.has("wosid")) {
            wosid = input.getString("wosid");
          }
        }
        context._setRequestSessionID(wosid);
        WOSession session = null;
        if (context._requestSessionID() != null) {
          session = WOApplication.application().restoreSessionWithID(wosid, context);
        }
        if (session != null) {
          session.awake();
        }
        try {
          JSONComponentCallback componentCallback = null;

          ERXDynamicURL url = new ERXDynamicURL(request._uriDecomposed());
          String requestHandlerPath = url.requestHandlerPath();
          JSONRPCBridge jsonBridge;
          if (requestHandlerPath != null && requestHandlerPath.length() > 0) {
            String componentNameAndInstance = requestHandlerPath;
            String componentInstance;
            String componentName;
            int slashIndex = componentNameAndInstance.indexOf('/');
            if (slashIndex == -1) {
              componentName = componentNameAndInstance;
              componentInstance = null;
            } else {
              componentName = componentNameAndInstance.substring(0, slashIndex);
              componentInstance = componentNameAndInstance.substring(slashIndex + 1);
            }

            if (session == null) {
              session = context.session();
            }

            String bridgesKey =
                (componentInstance == null) ? "_JSONGlobalBridges" : "_JSONInstanceBridges";
            Map<String, JSONRPCBridge> componentBridges =
                (Map<String, JSONRPCBridge>) session.objectForKey(bridgesKey);
            if (componentBridges == null) {
              int limit =
                  ERXProperties.intForKeyWithDefault(
                      (componentInstance == null)
                          ? "er.ajax.json.globalBacktrackCacheSize"
                          : "er.ajax.json.backtrackCacheSize",
                      WOApplication.application().pageCacheSize());
              componentBridges = new LRUMap<String, JSONRPCBridge>(limit);
              session.setObjectForKey(componentBridges, bridgesKey);
            }
            jsonBridge = componentBridges.get(componentNameAndInstance);
            if (jsonBridge == null) {
              Class componentClass = _NSUtilities.classWithName(componentName);
              JSONComponent component;
              if (JSONComponent.class.isAssignableFrom(componentClass)) {
                component =
                    (JSONComponent)
                        _NSUtilities.instantiateObject(
                            componentClass,
                            new Class[] {WOContext.class},
                            new Object[] {context},
                            true,
                            false);
              } else {
                throw new SecurityException(
                    "There is no JSON component named '" + componentName + "'.");
              }
              jsonBridge =
                  createBridgeForComponent(
                      component, componentName, componentInstance, componentBridges);
            }

            componentCallback = new JSONComponentCallback(context);
            jsonBridge.registerCallback(componentCallback, WOContext.class);
          } else {
            jsonBridge = _sharedBridge;
          }

          try {
            output = jsonBridge.call(new Object[] {request, response, context}, input);
          } finally {
            if (componentCallback != null) {
              jsonBridge.unregisterCallback(componentCallback, WOContext.class);
            }
          }

          if (context._session() != null) {
            WOSession contextSession = context._session();
            // If this is a new session, then we have to force it to be a cookie session
            if (wosid == null) {
              boolean storesIDsInCookies = contextSession.storesIDsInCookies();
              try {
                contextSession.setStoresIDsInCookies(true);
                contextSession._appendCookieToResponse(response);
              } finally {
                contextSession.setStoresIDsInCookies(storesIDsInCookies);
              }
            } else {
              contextSession._appendCookieToResponse(response);
            }
          }
          if (output != null) {
            response.appendContentString(output.toString());
          }

          if (response != null) {
            response._finalizeInContext(context);
            response.disableClientCaching();
          }
        } finally {
          try {
            if (session != null) {
              session.sleep();
            }
          } finally {
            if (context._session() != null) {
              WOApplication.application().saveSessionForContext(context);
            }
          }
        }
      } catch (NoSuchElementException e) {
        e.printStackTrace();
        output =
            new JSONRPCResult(
                JSONRPCResult.CODE_ERR_NOMETHOD, null, JSONRPCResult.MSG_ERR_NOMETHOD);
      } catch (JSONException e) {
        e.printStackTrace();
        output = new JSONRPCResult(JSONRPCResult.CODE_ERR_PARSE, null, JSONRPCResult.MSG_ERR_PARSE);
      } catch (Throwable t) {
        t.printStackTrace();
        output = new JSONRPCResult(JSONRPCResult.CODE_ERR_PARSE, null, t.getMessage());
      }

      return response;
    } finally {
      application.sleep();
    }
  }
  public WOResponse _handleRequest(WORequest request) {
    // Retrieve the application object. We need to inform it of awake/sleep
    // and use some of its helper methods.
    WOApplication application = Application.app();

    WOResponse response;
    WOContext context;

    application.awake();
    try {
      // Instantiate the action object for this request.
      // The WOAction sets up the context and restores the session and so
      // on.
      WOAction action = new ContentAction(request);

      // Retrieve the context object from the action.
      context = action.context();

      // Retrieve the content path. e.g. blog or blog/2009/10/10/foobar or
      // whatever.
      String contentPath = request.requestHandlerPath();

      // TODO: We probably could use some exception handling here.
      // 1. performActionNamed throws generating the WOActionResults
      // 2. performActionNamed returns null
      // 3. generateResponse throws
      // 4. generateResponse returns null (although we do kind of handle
      // this already).

      // Ask the action object to handle the request. Unlike normal action
      // objects the
      // ContentAction object takes a path instead of the first part of a
      // method name.
      WOActionResults actionResults = action.performActionNamed(contentPath);

      // Generate the response object.
      if (actionResults != null) response = actionResults.generateResponse();
      else response = null;

      // FIXME: When we do add error handling, do we or don't we save the
      // session in the
      // event of an error?
      if (context != null) {
        // Check the session in to the session store. Particularly
        // important if the
        // session store is out of process.
        application.saveSessionForContext(context);
      }
    } finally {
      // End of request.
      application.sleep();
    }

    // Ah, the joys of calling private APIs. For some reason both
    // WOActionRequestHandler
    // and WOComponentRequestHandler know about and call this method as
    // virtually the
    // last thing before returning the response. I am somewhat unclear as to
    // why this
    // method is private and why it isn't called by our caller instead of
    // within the
    // request handler.
    // It is imperative that this method be called because it generates HTTP
    // Set-Cookie
    // headers from the NSArray<WOCookie>. Without this no cookies will ever
    // function.
    if (response != null) response._finalizeInContext(context);

    return response;
  }
Пример #3
0
  @Override
  public WOResponse handleRequest(WORequest request) {
    int bufferSize = 16384;

    WOApplication application = WOApplication.application();
    application.awake();
    try {
      WOContext context = application.createContextForRequest(request);
      WOResponse response = application.createResponseInContext(context);

      String sessionIdKey = application.sessionIdKey();
      String sessionId = (String) request.formValueForKey(sessionIdKey);
      if (sessionId == null) {
        sessionId = request.cookieValueForKey(sessionIdKey);
      }
      context._setRequestSessionID(sessionId);
      if (context._requestSessionID() != null) {
        application.restoreSessionWithID(sessionId, context);
      }

      try {
        final WODynamicURL url = request._uriDecomposed();
        final String requestPath = url.requestHandlerPath();
        final Matcher idMatcher = Pattern.compile("^id/(\\d+)/").matcher(requestPath);

        final Integer requestedAttachmentID;
        String requestedWebPath;

        final boolean requestedPathContainsAnAttachmentID = idMatcher.find();
        if (requestedPathContainsAnAttachmentID) {
          requestedAttachmentID = Integer.valueOf(idMatcher.group(1));
          requestedWebPath = idMatcher.replaceFirst("/");
        } else {
          // MS: This is kind of goofy because we lookup by path, your web path needs to
          // have a leading slash on it.
          requestedWebPath = "/" + requestPath;
          requestedAttachmentID = null;
        }

        try {
          InputStream attachmentInputStream;
          String mimeType;
          String fileName;
          long length;
          String queryString = url.queryString();
          boolean proxyAsAttachment =
              (queryString != null && queryString.contains("attachment=true"));

          EOEditingContext editingContext = ERXEC.newEditingContext();
          editingContext.lock();

          try {
            ERAttachment attachment =
                fetchAttachmentFor(editingContext, requestedAttachmentID, requestedWebPath);

            if (_delegate != null && !_delegate.attachmentVisible(attachment, request, context)) {
              throw new SecurityException("You are not allowed to view the requested attachment.");
            }
            mimeType = attachment.mimeType();
            length = attachment.size().longValue();
            fileName = attachment.originalFileName();
            ERAttachmentProcessor<ERAttachment> attachmentProcessor =
                ERAttachmentProcessor.processorForType(attachment);
            if (!proxyAsAttachment) {
              proxyAsAttachment = attachmentProcessor.proxyAsAttachment(attachment);
            }
            InputStream rawAttachmentInputStream =
                attachmentProcessor.attachmentInputStream(attachment);
            attachmentInputStream = new BufferedInputStream(rawAttachmentInputStream, bufferSize);
          } finally {
            editingContext.unlock();
          }

          response.setHeader(mimeType, "Content-Type");
          response.setHeader(String.valueOf(length), "Content-Length");

          if (proxyAsAttachment) {
            response.setHeader("attachment; filename=\"" + fileName + "\"", "Content-Disposition");
          }

          response.setStatus(200);
          response.setContentStream(attachmentInputStream, bufferSize, length);
        } catch (SecurityException e) {
          NSLog.out.appendln(e);
          response.setContent(e.getMessage());
          response.setStatus(403);
        } catch (NoSuchElementException e) {
          NSLog.out.appendln(e);
          response.setContent(e.getMessage());
          response.setStatus(404);
        } catch (FileNotFoundException e) {
          NSLog.out.appendln(e);
          response.setContent(e.getMessage());
          response.setStatus(404);
        } catch (IOException e) {
          NSLog.out.appendln(e);
          response.setContent(e.getMessage());
          response.setStatus(500);
        }

        return response;
      } finally {
        if (context._requestSessionID() != null) {
          WOApplication.application().saveSessionForContext(context);
        }
      }
    } finally {
      application.sleep();
    }
  }