Пример #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
void ATemplateNodeHandler_RESOURCE::Node::process(ATemplateContext& ctx, AOutputBuffer& output)
{
  AAutoPtr<AEventVisitor::ScopedEvent> scoped;
  if (ctx.useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
  {
    scoped.reset(new AEventVisitor::ScopedEvent(ctx.useEventVisitor(), ASW("ATemplateNodeHandler_RESOURCE",28), m_BlockData, AEventVisitor::EL_DEBUG));
  }

  if (m_BlockData.isEmpty())
    return;

  // Get resource
  AOSContext *pContext = ctx.useObjects().useAsPtr<AOSContext>(AOSContext::OBJECTNAME);
  if (!pContext)
  {
    ARope rope("Must have AOSContext object named: ",35);
    rope.append(AOSContext::OBJECTNAME);
    ATHROW_EX(this, AException::NotFound, rope);
  }

  LIST_AString languages;
  pContext->useRequestHeader().getAcceptLanguageList(languages);
  const AXmlDocument *pDoc = pContext->useServices().useResourceManager().getResources(languages);
  if (!pDoc)
  {
    if (pContext->useEventVisitor().isLogging(AEventVisitor::EL_WARN))
    {
      pContext->useEventVisitor().startEvent(ASW("Unable to find resource container for locales in Accept-Languages",65), AEventVisitor::EL_WARN);
    }
    return;
  }
  
  const AXmlElement *pElement = pDoc->getRoot().findElement(m_BlockData);
  if (pElement)
  {
    //a_Found object
    pElement->emitContent(output);
  }
  else
  {
    if (pContext->useEventVisitor().isLogging(AEventVisitor::EL_WARN))
    {
      ARope rope("Unable to find resource element: ",33);
      rope.append(m_BlockData);
      pContext->useEventVisitor().startEvent(rope, AEventVisitor::EL_WARN);
    }
  }
}
Пример #3
0
AOSContext *AOSContextManager::_newContext(AFile_Socket *pSocket)
{
  AOSContext *pContext = (AOSContext *)m_FreeStore.popFront();
  
  if (!pContext)
    return new AOSContext(pSocket, m_Services);
  else
  {
    pContext->reset(pSocket);
    if (pContext->useEventVisitor().isLoggingEvent())
    {
      ARope rope;
      rope.append(" - ",3);
      rope.append(pSocket->getSocketInfo().m_address);
      rope.append(':');
      rope.append(AString::fromInt(pSocket->getSocketInfo().m_port));
      pContext->useEventVisitor().useName().append(rope);
    }
    return pContext;
  }
}
Пример #4
0
AOSContext *AOSContextManager::allocate(AFile_Socket *pSocket)
{
  AASSERT(this, pSocket);
  AOSContext *p = _newContext(pSocket);
  
  //a_Set logging level
  switch(m_DefaultEventLogLevel)
  {
    case AEventVisitor::EL_DEBUG: p->useEventVisitor().setEventThresholdLevel(AEventVisitor::EL_DEBUG); break;
    case AEventVisitor::EL_INFO: p->useEventVisitor().setEventThresholdLevel(AEventVisitor::EL_INFO); break;
    case AEventVisitor::EL_WARN: p->useEventVisitor().setEventThresholdLevel(AEventVisitor::EL_WARN); break;
    case AEventVisitor::EL_ERROR: p->useEventVisitor().setEventThresholdLevel(AEventVisitor::EL_ERROR); break;
    case AEventVisitor::EL_NONE: p->useEventVisitor().setEventThresholdLevel(AEventVisitor::EL_NONE); break;
    default: 
      p->useEventVisitor().setEventThresholdLevel(AEventVisitor::EL_EVENT);

  }

  ARope rope("AOSContextManager::allocate[",28);
  rope.append(AString::fromPointer(p));
  rope.append(", pFile=",8);
  rope.append(AString::fromPointer(pSocket));
  rope.append("] new create",12);
  p->useEventVisitor().startEvent(rope);

  {
    ALock lock(m_InUseSync);
    AASSERT(this, p && m_InUse.end() == m_InUse.find(p));
    m_InUse.insert(p);
  }

  AASSERT(this, &p->useSocket());
  return p;
}
Пример #5
0
u4 AOSContextQueue_IsAvailable::_threadprocWorker(AThread& thread)
{
  AOSContextQueue_IsAvailable::QueueWithThread *pThis = dynamic_cast<AOSContextQueue_IsAvailable::QueueWithThread *>(thread.getThis());
  AOSContextQueue_IsAvailable *pOwner = dynamic_cast<AOSContextQueue_IsAvailable *>(thread.getParameter());
  AASSERT(&thread, pThis);
  AASSERT(&thread, pOwner);

  timeval timeout;
  timeout.tv_sec  = 0;
  timeout.tv_usec = 0;

  thread.setRunning(true);
  fd_set sockSet;
  while (thread.isRun())
  {
    try
    {
      if (pThis->queue.size() > 0)
      {
        FD_ZERO(&sockSet);
        
        int count = 0;
        // Convert to ABasePtrQueue
        ABase *p = pThis->queue.useHead();
        while (count < FD_SETSIZE && p)
        {
          AOSContext *pContext = (AOSContext *)p;
          FD_SET((SOCKET)pContext->useSocket().getSocketInfo().m_handle, &sockSet);
          ++count;
          p = p->useNext();
        }
        
        if (count > 0)
        {
          int availCount = ::select(count, &sockSet, NULL, NULL, &timeout);
          if (availCount > 0)
          {
            int count2 = 0;
            p = pThis->queue.useHead();

            while (availCount > 0 && count2 <= count && p)
            {
              AOSContext *pContext = (AOSContext *)p;
              p = p->useNext();
              if (FD_ISSET(pContext->useSocket().getSocketInfo().m_handle, &sockSet))
              {
                pContext->useConnectionFlags().setBit(AOSContext::CONFLAG_ISAVAILABLE_SELECT_SET);

                //a_Attempt to read some data to check if it actually has data, if not then connection is closed
                size_t bytesRead = AConstant::npos;
                try
                {
                  bytesRead = pContext->useSocket().readBlockIntoLookahead();

                  if (!bytesRead || AConstant::npos == bytesRead)
                  {
                    //a_No data to read, socket is closed
                    pContext->useConnectionFlags().setBit(AOSContext::CONFLAG_IS_SOCKET_CLOSED);
                    pContext->useEventVisitor().startEvent(ASW("AOSContextQueue_IsAvailable: Detected closed remote socket",58), AEventVisitor::EL_WARN);
                    pContext->useSocket().close();

                    {
                      ALock lock(pThis->sync);
                      pThis->queue.remove(pContext);
                    }
                    pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
                  }
                  else if (AConstant::unavail == bytesRead)
                  {
                    // Would block, keep waiting
                    if (pContext->useTimeoutTimer().getInterval() > pOwner->m_NoDataTimeout)
                    {
                      AString str;
                      str.append("AOSContextQueue_IsAvailable: No data (non-blocking) after timeout: ",67);
                      pContext->useTimeoutTimer().emit(str);

                      //a_We are done with this request, still no data
                      pContext->useEventVisitor().startEvent(
                        str, 
                        (pContext->useConnectionFlags().isSet(AOSContext::CONFLAG_IS_HTTP11_PIPELINING) ? AEventVisitor::EL_EVENT : AEventVisitor::EL_ERROR)
                      );
                      {
                        ALock lock(pThis->sync);
                        pThis->queue.remove(pContext);
                      }
                      pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
                    }
                  }
                  else
                  {
                    //a_Add to next queue
                    pContext->useConnectionFlags().setBit(AOSContext::CONFLAG_ISAVAILABLE_PENDING);
                    if (pContext->useEventVisitor().isLogging(AEventVisitor::EL_DEBUG))
                      pContext->useEventVisitor().startEvent(ASW("AOSContextQueue_IsAvailable: HTTP header has more data",54), AEventVisitor::EL_DEBUG);

                    {
                      ALock lock(pThis->sync);
                      pThis->queue.remove(pContext);
                    }
                    pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_PRE_EXECUTE, &pContext);
                  }
                }
                catch(AException e)
                {
                  bytesRead = AConstant::npos;  //a_Following switch will handle this
                  ARope rope("AOSContextQueue_IsAvailable: Exception reading from socket",58);
                  rope.append(e);
                  pContext->useEventVisitor().addEvent(rope, AEventVisitor::EL_ERROR);
                }

                --availCount;
              }
              else
              {
                //a_Select called on this AOSContext and no data available
                if (pContext->useTimeoutTimer().getInterval() > pOwner->m_NoDataTimeout)
                {
                  AString str;
                  str.append("AOSContextQueue_IsAvailable: No data after timeout: ",52);
                  pContext->useTimeoutTimer().emit(str);

                  //a_We are done with this request, still no data
                  pContext->useEventVisitor().startEvent(
                    str, 
                    (pContext->useConnectionFlags().isSet(AOSContext::CONFLAG_IS_HTTP11_PIPELINING) ? AEventVisitor::EL_EVENT : AEventVisitor::EL_ERROR)
                  );
                  {
                    ALock lock(pThis->sync);
                    pThis->queue.remove(pContext);
                  }
                  pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
                }
              }
              ++count2;
            }
            AASSERT(pOwner, !availCount);
          }
          else
          {
            //a_Nothing has data, flag them all
            p = pThis->queue.useHead();
            while (p)
            {
              AOSContext *pContext = (AOSContext *)p;
              p = p->useNext();
              if (pContext->useTimeoutTimer().getInterval() > pOwner->m_NoDataTimeout)
              {
                AString str("AOSContextQueue_IsAvailable: No data after timeout: ",52);
                pContext->useTimeoutTimer().emit(str);

                //a_We are done with this request, still no data
                ALock lock(pThis->sync);
                pContext->useEventVisitor().startEvent(
                  str, 
                  (pContext->useConnectionFlags().isSet(AOSContext::CONFLAG_IS_HTTP11_PIPELINING) ? AEventVisitor::EL_EVENT : AEventVisitor::EL_ERROR)
                );
                pThis->queue.remove(pContext);
                pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext);
              }
            }
          }
        }
        
        //a_Sleep between selects, requests in this queue are already slow
        AThread::sleep(pOwner->m_LoopDelay);
      }
      else
        AThread::sleep(pOwner->m_EmptyQueueDelay);    //a_Nothing in queue, deep sleep
    }
    catch(AException& e)
    {
      pOwner->m_Services.useLog().addException(e);
    }
    catch(std::exception& e)
    {
      pOwner->m_Services.useLog().addException(e);
    }
    catch(...)
    {
      pOwner->m_Services.useLog().add(ASWNL("Unknown exception caught in AOSContextQueue_IsAvailable::threadproc"), ALog::EVENT_EXCEPTION);
    }
  }

  thread.setRunning(false);
  return 0;
}
Пример #6
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;
}
Пример #7
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");
  }
}
Пример #8
0
void AOSContextManager::adminEmitXml(AXmlElement& eBase, const AHTTPRequestHeader& request)
{
  AOSAdminInterface::adminEmitXml(eBase, request);

  //a_Check if specific context is required
  AString contextId;
  if (request.getUrl().getParameterPairs().get(ASW("contextId",9), contextId))
  {
    //a_Find the specific context
    {
      ALock lock(m_InUseSync);
      for (CONTEXT_INUSE::const_iterator cit = m_InUse.begin(); cit != m_InUse.end(); ++cit)
      {
        if (contextId == AString::fromPointer(*cit))
        {
          adminAddProperty(eBase, ASW("contextDetail",7), *(*cit), AXmlElement::ENC_CDATADIRECT);
          return;
        }
      }
    }
    
    {
      ALock lock(m_ErrorHistory.useSync());
      for (ABase *p = m_ErrorHistory.useTail(); p; p = p->usePrev())
      {
        AOSContext *pContext = dynamic_cast<AOSContext *>(p);
        if (contextId == AString::fromPointer(pContext))
        {
          adminAddProperty(eBase, ASW("contextDetail",7), *pContext, AXmlElement::ENC_CDATADIRECT);
          return;
        }
      }
    }

    {
      ALock lock(m_History.useSync());
      for (ABase *p = m_History.useTail(); p; p = p->usePrev())
      {
        AOSContext *pContext = dynamic_cast<AOSContext *>(p);
        if (contextId == AString::fromPointer(pContext))
        {
          adminAddProperty(eBase, ASW("contextDetail",7), *pContext, AXmlElement::ENC_CDATADIRECT);
          return;
        }
      }
    }

	  //a_Context no longer available
    adminAddError(eBase, ASWNL("AOSContext no longer available"));
  }
  else
  {
    //a_Display context summary
    for (size_t i=0; i < m_Queues.size(); ++i)
    {
      AOSContextQueueInterface *pQueue = m_Queues.at(i);
      if (pQueue)
        adminAddProperty(eBase, AString::fromSize_t(i), pQueue->getClass());
      else
        adminAddProperty(eBase, AString::fromSize_t(i), AConstant::ASTRING_NULL);
    }

    adminAddPropertyWithAction(
      eBase,
      ASW("log_level",9), 
      AString::fromInt(m_DefaultEventLogLevel),
      ASW("Update",6), 
      ASWNL("Maximum event to log 0:Disabled 1:Error, 2:Event, 3:Warning, 4:Info, 5:Debug"),
      ASW("Set",3)
    );

    {
      AString str;
      str.assign('[');
      str.append(AString::fromSize_t(m_History.size()));
      str.append('/');
      str.append(AString::fromSize_t(m_HistoryMaxSize));
      str.append(']');

      AXmlElement& eHistory = eBase.addElement("object").addAttribute("name", "history");
      adminAddPropertyWithAction(eHistory, ASWNL("max_size"), str, ASW("Set",3), ASWNL("Set maximum AOSContext history size (objects not immediately deleted)"), ASW("Set",3));
    }
    
    adminAddPropertyWithAction(
      eBase,
      ASW("clear_history",13), 
      AConstant::ASTRING_EMPTY,
      ASW("Clear",5), 
      ASWNL("Clear context history: 0:all  1:history  2:error history"),
      ASW("Clear",5) 
    );
      
    {
      AString str;
      str.assign('[');
      str.append(AString::fromSize_t(m_ErrorHistory.size()));
      str.append('/');
      str.append(AString::fromSize_t(m_ErrorHistoryMaxSize));
      str.append(']');

      AXmlElement& eErrorHistory = eBase.addElement("object").addAttribute("name", "error_history");
      adminAddPropertyWithAction(eErrorHistory, ASWNL("max_size"), str, ASW("Set",3), ASWNL("Set maximum AOSContext error history size (objects not immediately deleted)"), ASW("Set",3));
    }

    {
      AString str;
      str.assign('[');
      str.append(AString::fromSize_t(m_FreeStore.size()));
      str.append('/');
      str.append(AString::fromSize_t(m_FreeStoreMaxSize));
      str.append(']');

      AXmlElement& eFreestore = eBase.addElement("object").addAttribute("name", "freestore");
      adminAddPropertyWithAction(eFreestore, ASWNL("max_size"), str, ASW("Set",3), ASWNL("Set maximum AOSContext freestore size (objects not immediately deleted)"), ASW("Set",3));
    }

    AXmlElement& eInUse = eBase.addElement("object");
    eInUse.addAttribute("name", "InUse");
    eInUse.addAttribute("size", AString::fromSize_t(m_InUse.size()));
    CONTEXT_INUSE::const_iterator citU = m_InUse.begin();
    if (citU != m_InUse.end())
    {
      ALock lock(m_InUseSync);
      while(citU != m_InUse.end())
      {
        AXmlElement& eProp = adminAddProperty(eInUse, ASW("context",7), (*citU)->useEventVisitor(), AXmlElement::ENC_CDATADIRECT);
        eProp.addAttribute(ASW("errors",6), AString::fromSize_t((*citU)->useEventVisitor().getErrorCount()));
        eProp.addElement(ASW("url",3)).addData((*citU)->useEventVisitor().useName(), AXmlElement::ENC_CDATADIRECT);
        eProp.addElement(ASW("contextId",9)).addData(AString::fromPointer(*citU), AXmlElement::ENC_CDATADIRECT);
        ++citU;
      }
    }

    {
      AXmlElement& eHistory = eBase.addElement("object").addAttribute("name", "history");
      ALock lock(m_History.useSync());
      for (ABase *p = m_History.useTail(); p; p = p->usePrev())
      {
        AOSContext *pContext = dynamic_cast<AOSContext *>(p);
        if (pContext)
        {
          AXmlElement& eProp = adminAddProperty(eHistory, ASW("context",7), pContext->useEventVisitor(), AXmlElement::ENC_CDATADIRECT);
          eProp.addAttribute(ASW("errors",6), AString::fromSize_t(pContext->useEventVisitor().getErrorCount()));
          eProp.addElement(ASW("url",3), pContext->useEventVisitor().useName(), AXmlElement::ENC_CDATADIRECT);
          eProp.addElement(ASW("contextId",3)).addData(AString::fromPointer(pContext), AXmlElement::ENC_CDATADIRECT);
        }
        else
          ATHROW(this, AException::InvalidObject);
      }
    }

    {
      AXmlElement& eErrorHistory = eBase.addElement("object").addAttribute("name", "error_history");
      ALock lock(m_ErrorHistory.useSync());
      for (ABase *p = m_ErrorHistory.useTail(); p; p = p->usePrev())
      {
        AOSContext *pContext = dynamic_cast<AOSContext *>(p);
        if (pContext)
        {
          AXmlElement& eProp = adminAddProperty(eErrorHistory, ASW("context",7), pContext->useEventVisitor(), AXmlElement::ENC_CDATADIRECT);
          eProp.addAttribute(ASW("errors",6), AString::fromSize_t(pContext->useEventVisitor().getErrorCount()));
          eProp.addElement(ASW("url",3), pContext->useEventVisitor().useName(), AXmlElement::ENC_CDATADIRECT);
          eProp.addElement(ASW("contextId",3)).addData(AString::fromPointer(pContext), AXmlElement::ENC_CDATADIRECT);
        }
        else
          ATHROW(this, AException::InvalidObject);
      }
    }
  }
}
Пример #9
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;
}
Пример #10
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;
}