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; }
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; }
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; }
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"); } }
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; }
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; }
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; }