예제 #1
0
AOSContext::ReturnCode AOSOutput_JSON::execute(AOSContext& context)
{
  AXmlElement::CONST_CONTAINER paths;
  AXmlElement::CONST_CONTAINER nodes;
  if (context.getOutputParams().find(AOS_BaseModules_Constants::PATH, paths))
  {
    // Get the path fragments and convert into nodes
    for (AXmlElement::CONST_CONTAINER::const_iterator cit = paths.begin(); cit != paths.end(); ++cit)
    {
      // Get path and find associated nodes
      AString path;
      (*cit)->emitContent(path);
      context.useModel().find(path, nodes);
    }
  }

  if (nodes.size() > 0)
  {
    if (nodes.size() > 1)
    {
      // Array
      context.useOutputBuffer().append("[\r\n",3);
      AXmlElement::CONST_CONTAINER::const_iterator cit = nodes.begin();
      while(cit != nodes.end())
      {
        (*cit)->emitJson(context.useOutputBuffer(),1); 
        ++cit;
        if (cit != nodes.end())
          context.useOutputBuffer().append("\r\n,\r\n",5);
      }
      context.useOutputBuffer().append("\r\n]",3);
    }
    else
    {
      // Single object
      nodes.front()->emitJson(context.useOutputBuffer(),0);
    }
  }
  else
  {
    // Entire context model to JSON
    if (context.useEventVisitor().isLoggingDebug())
    {
      context.useEventVisitor().addEvent(ASWNL("Emitting the entire model as JSON object"), AEventVisitor::EL_DEBUG);
    }
    context.useModel().emitJson(context.useOutputBuffer(),0);
  }
  
  // Set the correct content type for XML extension
  m_Services.useConfiguration().setMimeTypeFromExt(ASW("json",4), context);

  return AOSContext::RETURN_OK;
}
예제 #2
0
AOSContext::ReturnCode AOSModule_TestFail::execute(AOSContext& context, const AXmlElement& params)
{
  context.useModel().addElement("test").addData("This is a fail test!");

  //a_Module returns a false
  return AOSContext::RETURN_ERROR;
}
예제 #3
0
AOSContext::ReturnCode AOSModule_Template::execute(AOSContext& context, const AXmlElement& params)
{
  const AXmlElement *pNode = params.findElement(ASW("template",8));
  AAutoPtr<ATemplate> pTemplate(NULL, false);
  AAutoPtr<AFile> pFile(NULL, false);
  if (pNode)
  {
    //a_Element contains script
    pTemplate.reset(m_Services.createTemplate(), true);
    
    //a_Parse template
    AFile_AString strfile;
    pNode->emitContent(strfile);
    pTemplate->fromAFile(strfile);
  }
  else
  {
    //a_Filename provided, use the cache
    pNode = params.findElement(AOS_BaseModules_Constants::FILENAME);
    if (pNode)
    {
      AString relativePath;
      pNode->emitContent(relativePath);

      //a_File to be used (may need caching for it, but for now keep it dynamic)
      AFilename filename(m_Services.useConfiguration().getAosBaseDataDirectory(), true);
      filename.join(relativePath, false);
      if (ACacheInterface::NOT_FOUND == m_Services.useCacheManager().getTemplate(context, filename, pTemplate))
      {
        //a_Not found, return error
        ARope rope;
        rope.append(getClass());
        rope.append(": Unable to find a template file: ",34);
        rope.append(filename);
        context.useEventVisitor().startEvent(rope, AEventVisitor::EL_ERROR);
        return AOSContext::RETURN_ERROR;
      }
    }
    else
    {
      context.addError(getClass(), ASWNL("Unable to find module/template nor module/filename, Template module did not execute, params"));
      return AOSContext::RETURN_ERROR;  //a_Did not find either module/template or module/filename
    }
  }  

  //a_Process and save output
  ARope ropeOutput;
  pTemplate->process(context.useLuaTemplateContext(), ropeOutput);
  
  //a_Add template to debug
  if (context.getDumpContextLevel() > 0)
  {
    AString str("debug/",6);
    str.append(getClass());
    str.append("/template",9);
    AXmlElement& base = context.useModel().addElement(str);
    pTemplate->emitXml(base);
  }

  //a_Insert output into outpath (if any)
  pNode = params.findElement(AOS_BaseModules_Constants::PATH);
  if (pNode)
  {
    AString xmlpath;
    pNode->emitContent(xmlpath);
    if (!xmlpath.isEmpty())
    {
      //a_Add output as CDATA
      context.useModel().addElement(xmlpath).addData(ropeOutput, AXmlElement::ENC_CDATADIRECT);
    }
  }
  else
  {
    context.useEventVisitor().addEvent(ASWNL("Unable to find module/path, output from template discarded"), AEventVisitor::EL_WARN);
  }
  return AOSContext::RETURN_OK;
}
예제 #4
0
void AOSOutputExecutor::execute(AOSContext& context)
{
  AString command;
  if (
    context.useRequestParameterPairs().exists(OVERRIDE_OUTPUT)
    && m_Services.useConfiguration().isOutputOverrideAllowed()
  )
  {
    //a_Override requested and allowed
    context.useRequestParameterPairs().get(OVERRIDE_OUTPUT, command);
  }
  else
  {
    command = context.getOutputCommand();
    if (context.useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
    {
      ARope rope("Default output generator overridden to: ",40);
      rope.append(command);
      context.useEventVisitor().startEvent(rope, AEventVisitor::EL_DEBUG);
    }
  }

  if (command.equals("NOP"))
  {
    //a_If NOP was used force XML
    m_Services.useConfiguration().setMimeTypeFromExt(ASW("xml",3), context);
    if (context.useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
      context.useEventVisitor().startEvent(ASWNL("NOP detected, defaulting to XML output"), AEventVisitor::EL_DEBUG);
  }

  if (command.isEmpty())
  {
    if (!m_Services.useConfiguration().getAosDefaultOutputGenerator().isEmpty())
    {
      command.assign(m_Services.useConfiguration().getAosDefaultOutputGenerator());
      if (context.useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
      {
        ARope rope("No output generator specified, defaulting to: ",46);
        rope.append(command);
        context.useEventVisitor().startEvent(rope, AEventVisitor::EL_DEBUG);
      }
    }
    else
    {
      if (context.useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
        context.useEventVisitor().startEvent(ASW("No output generator, defaulting to XML",38), AEventVisitor::EL_DEBUG);
      return;
    }
  }

  try
  {
    //a_Find input command, if not found execute the default
    OutputGeneratorContainer::iterator it = m_OutputGenerators.find(command);
    if (it == m_OutputGenerators.end())
    {
      if (context.useEventVisitor().isLogging(AEventVisitor::EL_WARN))
      {
        ARope rope("Skipping unknown output generator: ",35);
        rope.append(command);
        context.useEventVisitor().startEvent(rope, AEventVisitor::EL_WARN);
      }
    }
    else
    {
      ATimer timer(true);

      //a_Generate output
      if (context.useEventVisitor().isLogging(AEventVisitor::EL_INFO))
      {
        ARope rope("Generating output: ",19);
        rope.append((*it).first);
        context.useEventVisitor().startEvent(rope, AEventVisitor::EL_INFO);
      }

      if (context.useContextFlags().isClear(AOSContext::CTXFLAG_IS_AJAX))
      {
        context.useModel().overwriteElement(ASW("execute/output", 14)).addData(command);

        //a_Publish timers
        context.getRequestTimer().emitXml(context.useModel().overwriteElement(ASW("request_time",12)));
        context.getContextTimer().emitXml(context.useModel().overwriteElement(ASW("context_time",12)));
      }

      //a_Generate output
      AOSContext::ReturnCode ret = (*it).second->execute(context);
      switch (ret)
      {
        case AOSContext::RETURN_OK:
        break;

        case AOSContext::RETURN_REDIRECT:
          if (context.useEventVisitor().isLogging(AEventVisitor::EL_INFO))
          {
            context.useEventVisitor().startEvent(ASWNL("Output generator has done a redirect"), AEventVisitor::EL_DEBUG);
          }
        break;
      
        default:
          context.addError((*it).second->getClass(), ASWNL("Output generator returned neither OK nor REDIRECT"));
        return;
      }

      //a_Event over
      context.useEventVisitor().endEvent();

      //a_Add execution time
      (*it).second->addExecutionTimeSample(timer.getInterval());
    }
  }
  catch(AException& ex)
  {
    AString strWhere("AOSOutputExecutor::execute(", 27);
    strWhere.append(command);
    strWhere.append(')');
    context.addError(strWhere, ex.what());

    AXmlElement& element = context.useModel().addElement("output_error");
    element.addElement("where", strWhere);
    element.addElement("exception", ex);
  }
  catch(...)
  {
    AString strWhere("AOSOutputExecutor::execute(", 27);
    strWhere.append(command);
    strWhere.append(')');
    context.addError(strWhere, ASWNL("Unknown Exception"));

    context.useModel().addElement("output_error").addData("Unknown Exception");
  }
}
예제 #5
0
AOSContext::ReturnCode AOSOutput_Template::execute(AOSContext& context)
{
  //a_See if extension for mime type set for the template(s)
  AString ext;
  if (context.getOutputParams().emitContentFromPath(AOS_BaseModules_Constants::MIME_EXTENSION, ext))
  {
    m_Services.useConfiguration().setMimeTypeFromExt(ext, context);
  }
  else
  {
    //a_Set content type based on request URL extension
    m_Services.useConfiguration().setMimeTypeFromExt(context.useRequestUrl().getExtension(), context);
  }
  
  // Iterate parameters and build the template
  const AXmlElement::CONTAINER& container = context.getOutputParams().getContentContainer();
  for (AXmlElement::CONTAINER::const_iterator cit = container.begin(); cit != container.end(); ++cit)
  {
    //a_Check "if" condition
    AString ifElement;
    if ((*cit)->getAttributes().get(ASW("if",2), ifElement))
    {
      if (ifElement.getSize() > 0)
      {
        //a_Check condition, if not met continue with next template
        if (!context.useModel().exists(ifElement))
        {
          if (context.useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
            context.useEventVisitor().startEvent(ARope("Skipping conditional file template IF ")+ifElement, AEventVisitor::EL_DEBUG);
          continue;
        }
      }
    }
    //a_Check "ifnot" condition
    ifElement.clear();
    if ((*cit)->getAttributes().get(ASW("ifnot",5), ifElement))
    {
      if (ifElement.getSize() > 0)
      {
        //a_Check condition, if not met continue with next template
        if (context.useModel().exists(ifElement))
        {
          if (context.useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
            context.useEventVisitor().startEvent(ARope("Skipping conditional file template IFNOT ")+ifElement, AEventVisitor::EL_DEBUG);
          continue;
        }
      }
    }

    //
    // Now we check if this is inlined or filename
    //
    AString str(1024, 512);
    if ((*cit)->getName().equals(AOS_BaseModules_Constants::TEMPLATE))
    {
      if (context.useEventVisitor().isLoggingDebug())
      {
        context.useEventVisitor().startEvent(getClass() + ": Creating new inline template", AEventVisitor::EL_DEBUG);
      }
      // Create a new template
      AAutoPtr<ATemplate> pTemplate(m_Services.createTemplate(), true);

      // Add inline template
      str.clear();
      (*cit)->emitContent(str);
      AFile_AString strfile(str);
      pTemplate->clear();
      pTemplate->fromAFile(strfile);
      pTemplate->process(context.useLuaTemplateContext(), context.useOutputBuffer());
    }
    else if ((*cit)->getName().equals(AOS_BaseModules_Constants::FILENAME))
    {
      // Add filename based template
      AFilename filename(m_Services.useConfiguration().getAosBaseDataDirectory());
      str.clear();
      (*cit)->emitContent(str);
      filename.join(str, false);

      if (context.useEventVisitor().isLoggingDebug())
      {
        context.useEventVisitor().startEvent(getClass()+": Fetching/parsing template for: "+filename, AEventVisitor::EL_DEBUG);
      }
      AAutoPtr<ATemplate> pT(NULL, false);
      if (ACacheInterface::NOT_FOUND == m_Services.useCacheManager().getTemplate(context, filename, pT))
      {
        //a_Not found add error and continue
        if (context.useEventVisitor().isLogging(AEventVisitor::EL_WARN))
          context.useEventVisitor().startEvent(ARope(getClass())+ASWNL(": Unable to find a template file: ")+filename+ASWNL(", ignoring and continuing"), AEventVisitor::EL_WARN);
        continue;
      }

      //a_Parse template
      if (context.useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
      {
        context.useEventVisitor().startEvent(getClass()+"Processing template file: "+filename, AEventVisitor::EL_DEBUG);
      }
      AASSERT(this, pT.isNotNull());
      pT->process(context.useLuaTemplateContext(), context.useOutputBuffer());
    }
  }

  return AOSContext::RETURN_OK;
}
예제 #6
0
u4 AOSContextQueue_ErrorExecutor::_threadproc(AThread& thread)
{
  AOSContextQueue_ErrorExecutor *pThis = dynamic_cast<AOSContextQueue_ErrorExecutor *>(thread.getThis());
  AASSERT(&thread, pThis);
  AOSContext *pContext = NULL;

  thread.setRunning(true);
  while(thread.isRun())
  {
    try
    {
      while (pContext = pThis->_nextContext()) 
      {
#ifndef NDEBUG
        if (!ADebugDumpable::isPointerValid(pContext))
        {
          AString error("AOSContext pointer is invalid: ");
          error.append(AString::fromPointer(pContext));
          AASSERT_EX(NULL, false, error);
          continue;
        }
#endif
        pContext->useEventVisitor().startEvent(ASW("AOSContextQueue_ErrorExecutor: Processing error condition", 57));

        //a_Should only be here if an error occured, if status not set >200, then assume 500
        if (pContext->useResponseHeader().getStatusCode() == AHTTPResponseHeader::SC_200_Ok)
          pContext->useResponseHeader().setStatusCode(AHTTPResponseHeader::SC_500_Internal_Server_Error);

        //a_Check is socket was closed, if so do nothing else, we are done
        if (pContext->useConnectionFlags().isSet(AOSContext::CONFLAG_IS_SOCKET_ERROR))
        {
          //a_Proceed
          m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
          continue;
        }

        if (
             pContext->useContextFlags().isSet(AOSContext::CTXFLAG_IS_RESPONSE_HEADER_SENT)
          || pContext->useContextFlags().isSet(AOSContext::CTXFLAG_IS_OUTPUT_SENT)
        )
        {
          //a_Log to file, output is done already
          m_Services.useLog().add(pContext->useEventVisitor(), ALog::EVENT_FAILURE);
        }
        else
        {          

          //a_Add XSLT stylesheet for the error XML
          //if (m_Services.useConfiguration().exists(ASW("/config/server/error-stylesheet",31)))
          //{
          //  AString errorStylesheet;
          //  m_Services.useConfiguration().emitString(ASW("/config/server/error-stylesheet",31), errorStylesheet);
          //  pContext->useModelXmlDocument().addInstruction(AXmlInstruction::XML_STYLESHEET)
          //    .addAttribute(ASW("type",4), ASW("text/xsl",8))
          //    .addAttribute(ASW("href",4), errorStylesheet);
          //}

          //a_Add request header to result XML
          if (!pContext->useModel().exists(ASW("REQUEST",7)))
            pContext->useRequestHeader().emitXml(pContext->useModel().overwriteElement(ASW("REQUEST",7)));
          pContext->useResponseHeader().emitXml(pContext->useModel().overwriteElement(ASW("RESPONSE",8)));

          //a_Check if dumpContext is specified to override and emit XML
          int dumpContextLevel = pContext->getDumpContextLevel();
          pContext->dumpContext(dumpContextLevel);
          if (dumpContextLevel > 0)
          {
            //a_Write contents of the output XML instead of output buffer
            m_Services.useConfiguration().setMimeTypeFromExt(ASW("xml",3), *pContext);
            pContext->useResponseHeader().setStatusCode(AHTTPResponseHeader::SC_200_Ok);
            pContext->writeOutputBuffer(true);
          }
          else
          {
            //a_Set the current content type as text/html
            pContext->useResponseHeader().set(AHTTPHeader::HT_ENT_Content_Type, ASW("text/html; charset=utf-8",24));

            int statusCode = pContext->useResponseHeader().getStatusCode();
            
            AAutoPtr<ATemplate> pTemplate(NULL, false);  //a_Call to cache manager will set a template
            pContext->clearOutputBuffer();
            if (m_Services.useCacheManager().getStatusTemplate(statusCode, pTemplate))
            {
              //a_Template for this status code is found, so process and emit into output buffer
              pTemplate->process(pContext->useLuaTemplateContext(), pContext->useOutputBuffer());
              if (pContext->useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
              {
                ARope rope("Using error template for status ");
                rope.append(AString::fromInt(statusCode));
                pContext->useEventVisitor().startEvent(rope, AEventVisitor::EL_DEBUG);
              }
            }
            else
            {
              if (pContext->useEventVisitor().isLogging(AEventVisitor::EL_WARN))
              {
                ARope rope("Did not find error template for status ");
                rope.append(AString::fromInt(statusCode));
                pContext->useEventVisitor().startEvent(rope, AEventVisitor::EL_WARN);
              }
            }

            if (pContext->isOutputBufferEmpty())
            {
              AString strError(1024, 256);
              strError.assign("Error ",6);
              strError.append(AString::fromInt(pContext->useResponseHeader().getStatusCode()));
              strError.append(": ", 2);
              strError.append(pContext->useResponseHeader().getStatusCodeReasonPhrase(pContext->useResponseHeader().getStatusCode()));

              //a_Put some generic stuff since there is no error template
              pContext->useOutputBuffer().append("<html><head><title>",19);
              pContext->useOutputBuffer().append(strError);
              pContext->useOutputBuffer().append("</title></head>",15);
              pContext->useOutputBuffer().append("<body>",6);
              pContext->useOutputBuffer().append(strError);
              pContext->useOutputBuffer().append("</body></html>",14);
            }

            try
            {
              pContext->writeOutputBuffer();
            }
            catch(ASocketException& ex)
            {
              pContext->useEventVisitor().addEvent(ex, AEventVisitor::EL_ERROR);
              pContext->useConnectionFlags().setBit(AOSContext::CONFLAG_IS_SOCKET_ERROR);
              m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
              continue;
            }
          }
        }

        //a_Close connection
        pContext->useSocket().close();

        //a_Proceed
        m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
        continue;
      }
      AThread::sleep(pThis->m_SleepDelay);  //a_Empty queue, avoid thrashing
    }
    catch(AException& e)
    {
      pContext->useEventVisitor().addEvent(e, AEventVisitor::EL_ERROR);
      m_Services.useLog().add(pContext->useEventVisitor(), ALog::EVENT_FAILURE);
      m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
    }
    catch(std::exception& e)
    {
      pContext->useEventVisitor().addEvent(ASWNL(e.what()), AEventVisitor::EL_ERROR);
      m_Services.useLog().add(pContext->useEventVisitor(), ALog::EVENT_FAILURE);
      m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
    }
    catch(...)
    {
      m_Services.useLog().add(pContext->useEventVisitor(), ALog::EVENT_FAILURE);
      pContext->useEventVisitor().addEvent(ASWNL("Unknown exception caught in AOSContextQueue_ErrorExecutor::_threadproc"), AEventVisitor::EL_ERROR);
      m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
      break;
    }
  }

  thread.setRunning(false);
  return 0;
}
예제 #7
0
AOSContext::ReturnCode AOSModule_Wiki_ViewFromFileSystem::execute(AOSContext& context, const AXmlElement& moduleParams)
{
    //a_Get base path
    AString basePath;
    if (!moduleParams.emitString(AOS_Wiki_Constants::PARAM_BASE_PATH, basePath))
    {
        context.addError(getClass(), ASWNL("Unable to find module/base-path parameter"));
        return AOSContext::RETURN_ERROR;
    }
    AFilename wikifile(m_Services.useConfiguration().getAosBaseDataDirectory());
    wikifile.join(basePath, true);

    //a_Get relative wiki path
    AString str;
    context.useRequestParameterPairs().get(ASW("wikipath",8), str);
    wikifile.join(str, false);

    u4 type = AFileSystem::getType(wikifile);
    //a_Directory only will get default index.html
    if (type & AFileSystem::Directory)
    {
        //a_Directory name specified
        wikifile.useFilename().assign(ASW("index.html",10));
    }
    else
        wikifile.setExtension(ASW(".html",5));

    AString strData;
    if (context.useRequestParameterPairs().get(ASW("wiki.newdata",12), strData))
    {
        //a_Check if authentication passed
        if (
            moduleParams.exists(AOS_Wiki_Constants::PARAM_SECURE)
            && !context.useModel().exists(ASW("wiki/Authenticated",18))
        )
        {
            context.useModel().overwriteElement(ASW("wiki/AuthFailed",15));
            return AOSContext::RETURN_OK;
        }

        //a_New data submitted
        u4 type = AFileSystem::getType(wikifile);
        if (AFileSystem::DoesNotExist != type)
        {
            //a_New data submitted, old file exists
            AFilename newwikifile(wikifile);

            //a_Temporary filename to use during the swap
            AFilename tempwikifile(newwikifile);
            tempwikifile.setExtension(ASW("_temporary_rename_",19));

            //a_Generate temporary filename
            AFileSystem::generateTemporaryFilename(newwikifile);

            //a_Save new data to temp filename
            AFile_Physical file(newwikifile, "wb");
            file.open();
            file.write(strData);
            file.close();

            //a_Add to context so it can ve viewed after save
            context.useModel().overwriteElement(AOS_Wiki_Constants::ELEMENT_DATA).addData(strData, AXmlElement::ENC_CDATADIRECT);

            //a_Rename temp to current
            AFileSystem::rename(wikifile, tempwikifile);
            AFileSystem::rename(newwikifile, wikifile);
            AFileSystem::remove(tempwikifile);
        }
        else
        {
            //a_Does not exist yet
            //a_Make sure directories exist
            AFileSystem::createDirectories(wikifile);

            //a_Save new data
            AFile_Physical file(wikifile, "wb");
            file.open();
            file.write(strData);
            file.close();

            //a_Add to context so it can ve viewed after save
            context.useModel().overwriteElement(AOS_Wiki_Constants::ELEMENT_DATA).addData(strData, AXmlElement::ENC_CDATADIRECT);
        }
    }
    else
    {
        u4 type = AFileSystem::getType(wikifile);
        if (AFileSystem::DoesNotExist != type)
        {
            AFile_Physical file(wikifile);
            file.open();
            context.useModel().overwriteElement(AOS_Wiki_Constants::ELEMENT_DATA).addData(file, AXmlElement::ENC_CDATADIRECT);
        }
        else
        {
            //a_Signal that the wiki file does not exist
            context.useModel().overwriteElement(AOS_Wiki_Constants::ELEMENT_DOES_NOT_EXIST);
        }

        if (moduleParams.exists(AOS_Wiki_Constants::PARAM_SECURE))
        {
            context.useModel().overwriteElement(AOS_Wiki_Constants::ELEMENT_SECURE_EDIT);
        }

    }

    return AOSContext::RETURN_OK;
}