#include "Global.h" #include "Exception.h" #include "__mysql.h" #include #include namespace jet { Global::Global(char **envp) : envp(envp) { } Global::~Global() { } void Global::dump() { for (auto i = variables.begin(); i != variables.end(); i++) std::cout << i->first << "=[" << i->second << "]" << std::endl; } bool Global::sessionExists(coreutils::MString sessionId) { return sessions.find(sessionId) != sessions.end(); } void Global::addSession(coreutils::MString sessionId, __mysql *mysql) { if(sessionExists(sessionId)) coreutils::Exception("sessionid already exists."); sessions[sessionId] = mysql; } void Global::removeSession(coreutils::MString sessionId) { sessions.erase(sessionId); } coreutils::MString& Global::processModifier(coreutils::MString &value, coreutils::MString &modifier) { if(modifier.getLength() == 0) return value; if(modifier == "tobinary") modifiers.processToBinaryModifier(value, lastConverted); if(modifier == "frombinary") modifiers.processFromBinaryModifier(value, lastConverted); if(modifier == "tohex") modifiers.processToHexModifier(value, lastConverted); if(modifier == "fromhex") modifiers.processFromHexModifier(value, lastConverted); if(modifier == "tobase64") modifiers.processToBase64Modifier(value, lastConverted); if(modifier == "frombase64") modifiers.processFromBase64Modifier(value, lastConverted); if(modifier == "toupper") modifiers.processToUpperModifier(value, lastConverted); if(modifier == "tolower") modifiers.processToLowerModifier(value, lastConverted); if(modifier == "tocgi") modifiers.processToCGIModifier(value, lastConverted); if(modifier == "fromcgi") modifiers.processFromCGIModifier(value, lastConverted); return lastConverted; } coreutils::ZString Global::getVariable(coreutils::ZString &variable, std::map &lvariables) { if(variable.ifNext("$[")) { coreutils::MString name; coreutils::MString modifier; if(variable.ifNext("!")) { renderVariableName(variable, name, modifier, lvariables); return variables[name]; } if(variable.ifNext(":")) { renderVariableName(variable, name, modifier, lvariables); if(name.find(":") == -1) { name << ":0"; } return processModifier(cgiVariables[name], modifier); } if(variable.ifNext("@")) { // TODO: should only allow session variables. Allow substitution. } if(variable.ifNext("%")) { renderVariableName(variable, name, modifier, lvariables); return getenv(name.c_str()); } else { renderVariableName(variable, name, modifier, lvariables); name.split("."); if(name.getList().size() == 1) { return processModifier(variables[name[0]], modifier); } return getSessionVariable(name); } throw coreutils::Exception("expected variable name or type designator."); } if(variable.ifNext("#[")) { coreutils::MString name; coreutils::MString modifier; renderVariableName(variable, name, modifier, lvariables); return lvariables[name]; } throw coreutils::Exception("Expecting a variable initializer ('$[' or '#[')."); } void Global::renderVariableName(coreutils::ZString &variable, coreutils::MString &name, coreutils::MString &modifier, std::map &lvariables) { while(!variable.ifNext("]")) { name << variable.getTokenInclude("#?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"); if(variable.ifNext(";")) { renderVariableName(variable, modifier, modifier, lvariables); return; } else if(variable.ifNext(":")) { name << ":"; } else if(variable.startsWith("$[") || variable.startsWith("#[")) name << getVariable(variable, lvariables); else if(variable.ifNext("]")) return; else if(!variable.ifNextInclude("#?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-")) throw coreutils::Exception("invalid variable name."); } return; } __mysql * Global::getSession(coreutils::MString sessionId) { if(sessions.find(sessionId) == sessions.end()) throw coreutils::Exception("requested session is not available."); return sessions[sessionId]; } coreutils::ZString Global::getSessionVariable(coreutils::MString &splitName) { if(sessions.find(splitName[0]) == sessions.end()) throw coreutils::Exception("requested session is not available in variable."); return sessions[splitName[0]]->getColumnValue(splitName[1]); } void Global::outputHeaders() { if(headers.size() > 0) { for(auto header = headers.begin(); header != headers.end(); ++header) { std::cout << header->first << ": " << header->second << std::endl; } std::cout << std::endl; } } void Global::setupFormData(coreutils::ZString &formdata) { coreutils::ZString boundary = formdata.goeol(); while(!formdata.eod()) { if(formdata.ifNext("Content-Disposition: form-data;")) { formdata.skipWhitespace(); if(formdata.ifNext("name=\"")) { coreutils::ZString name = formdata.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"); if(formdata.ifNext("\"")) { formdata.goeol(); formdata.goeol(); coreutils::ZString data = formdata.getTokenExclude("-"); // TODO: Fix this parsing. Need a string exclusion method to check for 'boundary'. data.trimCRLF(); formdata.ifNext(boundary); int index = 0; coreutils::MString namex; do { namex = ""; namex << name << ":" << index++; } while(cgiVariables.count(namex) != 0); cgiVariables[namex] = data; if(formdata.ifNext("--")) break; formdata.goeol(); } else throw coreutils::Exception("expecting closing double quote on variable name in received CGI data."); } else throw coreutils::Exception("expecting name subfield in received CGI data."); } else throw coreutils::Exception("expecting Content-Disposition header in received CGI data."); } } void Global::setupFormURLEncoded(coreutils::ZString &formdata) { while(!formdata.eod()) { coreutils::ZString name = formdata.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"); if(formdata.ifNext("=")) { coreutils::MString data = formdata.getTokenExclude("&"); formdata.ifNext("&"); int index = 0; coreutils::MString namex; do { namex = ""; namex << name << ":" << index++; } while(cgiVariables.count(namex) != 0); modifiers.processFromCGIModifier(data, lastConverted); cgiVariables[namex] = lastConverted; } else throw coreutils::Exception("expecting = after name in received CGI data."); } } }