203 lines
7.1 KiB
C++
203 lines
7.1 KiB
C++
#include "Global.h"
|
|
#include "Exception.h"
|
|
#include "__mysql.h"
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
|
|
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 == "")
|
|
return value;
|
|
if(modifier == "tobinary")
|
|
return value.toBinary();
|
|
else if(modifier == "frombinary")
|
|
return value.fromBinary();
|
|
else if(modifier == "tohex")
|
|
return value.toHex();
|
|
else if(modifier == "fromhex")
|
|
return value.fromHex();
|
|
else if(modifier == "tobase64")
|
|
return value.toBase64();
|
|
else if(modifier == "frombase64")
|
|
return value.fromBase64();
|
|
else if(modifier == "toupper")
|
|
return value.toUpper();
|
|
else if(modifier == "tolower")
|
|
return value.toLower();
|
|
else if(modifier == "tocgi")
|
|
return value.toCGI();
|
|
else if(modifier == "fromcgi")
|
|
return value.fromCGI();
|
|
throw coreutils::Exception("modifier not valid.");
|
|
}
|
|
|
|
coreutils::MString Global::getVariable(coreutils::ZString &variable,
|
|
std::map<coreutils::MString, coreutils::MString> &lvariables,
|
|
std::map<coreutils::MString, coreutils::MString> &keywords) {
|
|
if(variable.ifNext("$[")) {
|
|
coreutils::MString name;
|
|
coreutils::MString modifier;
|
|
if(variable.ifNext("!")) {
|
|
renderVariableName(variable, name, modifier, lvariables, keywords);
|
|
return variables[name];
|
|
} else if(variable.ifNext("%")) {
|
|
renderVariableName(variable, name, modifier, lvariables, keywords);
|
|
return keywords[name];
|
|
} else if(variable.ifNext(":")) {
|
|
renderVariableName(variable, name, modifier, lvariables, keywords);
|
|
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, keywords);
|
|
return getenv(name.c_str());
|
|
} else {
|
|
renderVariableName(variable, name, modifier, lvariables, keywords);
|
|
name.split(".");
|
|
if(name.getList().size() == 1) {
|
|
if(variables.find(name[0]) == variables.end())
|
|
throw coreutils::Exception("global variable is not initialized.");
|
|
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, keywords);
|
|
if(lvariables.find(name) == lvariables.end())
|
|
throw coreutils::Exception("local variable is not initialized.");
|
|
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<coreutils::MString, coreutils::MString> &lvariables,
|
|
std::map<coreutils::MString, coreutils::MString> &keywords) {
|
|
while(!variable.ifNext("]")) {
|
|
name << variable.getTokenInclude("?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-");
|
|
if(variable.ifNext(";")) {
|
|
renderVariableName(variable, modifier, modifier, lvariables, keywords);
|
|
return;
|
|
} else if(variable.ifNext(":")) {
|
|
name << ":";
|
|
} else if(variable.startsWith("$[") || variable.startsWith("#[")) {
|
|
name << getVariable(variable, lvariables, keywords);
|
|
} 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);
|
|
cgiVariables[namex] = data.fromCGI();
|
|
} else
|
|
throw coreutils::Exception("expecting = after name in received CGI data.");
|
|
}
|
|
}
|
|
|
|
}
|