/*************************************************************/ /* */ /* Name: cgiForm.cpp */ /* */ /* Description: Program to process fields submitted from */ /* a HTML form. */ /* */ /*************************************************************/ #include #include #include #include using namespace std; /* Create header of HTML page */ void header(string); /* Create footer of HTML page */ void footer(); /* Makes sure this request is a form submission */ int VerifyForm(); /* Read the data sent from the form */ void readData(int method, string &buf, int &len); /* Parses the submitted form data, filling the names[] and values[] arrays with useful information */ void ParseForm(string buffer, int length); /* Copies src to dst, unescaping any special characters in the process. dst must be at least as large as src in order to ensure that there is enough space. */ void UnescapeString(string &dst, const string &src); const int MAX_FIELDS = 100; // Max number of fields on form int numFields = 0; // Number of fields on form submitted string name[MAX_FIELDS]; // Array of field names string values[MAX_FIELDS]; // Array of fields values int main() { ofstream output; string myTitle = "Form Results"; int method; // method used to submit form values // 0 = post, 1 = get, -1 = not post or get string data; // data submitted from the form int len; // length of input data string temp; header(myTitle); method = VerifyForm(); if (method == -1) { // get or post not used cout << "

Error

" << endl; cout << "You must submit a form using the GET or POST method!
" << endl; footer(); cout.flush(); return 0; } // end if VerifyForm // Read the data submitted from the form readData(method, data, len); // Parse the form values ParseForm(data, len); for (int i = 0; i < numFields; i++) cout << name[i] << " = " << values[i] << "
" << endl; output.open("ipaddress.txt"); output << values[0]; footer(); return 0; } // end function main void header(string title) { cout << "Content-Type: text/html" << endl << endl; cout << "" << endl; cout << "" << endl; cout << "" << title << "" << endl; cout << "" << endl; cout << "" << endl; return; } // end function header void footer() { cout << "" << endl; cout << "" << endl; cout.flush(); return; } // end function footer // Will make sure the submission is a form and uses POST method int VerifyForm() { char *form = "application/x-www-form-urlencoded"; // form submission char *pst = "POST"; // POST method char *gt = "GET"; char *method = getenv("REQUEST_METHOD"); // is it post method? if (strncmp(method, pst, 4) == 0) if (strcmp(getenv("CONTENT_TYPE"), form) != 0) // not a form submission return -1; else return 0; // is it get method? if (strncmp(method, gt, 3) == 0) return 1; return -1; } // end function VerifyForm void readData(int meth, string &buf, int &len) { char *contentLength; // CONTENT_LENGTH environment variable char *buffer; // Find length of data sent by form contentLength = getenv("CONTENT_LENGTH"); if (contentLength == NULL) len = 0; else len = atoi(contentLength); // Allocate space for buffer buffer = new char[len + 1]; if (!buffer) return; // unable to allocate memory if (meth == 0) { // post method cin.read(buffer, len); if (cin.gcount() < len) return; // read less than the desired number of characters } // end if meth == 0 else // get method buffer = getenv("QUERY_STRING"); buf = (string)buffer; return; } // end function readData void ParseForm(string buffer, int length) { string pos; // Current position in data int place = 0; // Current position int oldPlace = 0; // Previous position pos = buffer; cout << "Forms from field:
" << endl; cout << pos << "
" << endl; place = pos.find("=", oldPlace); // find first = while (place != -1) { UnescapeString(name[numFields], pos.substr(oldPlace, place - oldPlace)); oldPlace = place + 1; place = pos.find("&", oldPlace); // Find & if (place == -1) break; UnescapeString(values[numFields], pos.substr(oldPlace, place - oldPlace)); numFields++; oldPlace = place + 1; if (place == length) break; place = pos.find("=", oldPlace); } // end while place != -1 UnescapeString(values[numFields], pos.substr(oldPlace, place - oldPlace)); numFields++; return; } // end function parseForm void UnescapeString(string &dst, const string &src) { /* Loop over the characters in the string until we encounter the null character at the end, which tests false. */ for (int i = 0; i < src.length(); i++) { char c; c = src[i]; /* Handle spaces escaped as + signs */ if (c == '+') { c = ' '; } else if (c == '%') { /* Handle % escapes */ char hexdigits[3]; int ascii; i++; if (!src[i]) break; // Digits missing! Ignore escape hexdigits[0] = src[i]; i++; if (!src[i]) break; // Digits missing! Ignore escape hexdigits[1] = src[i]; hexdigits[2] = '\0'; // Add a terminating null... /* Now use the C standard library function sscanf() to read the hex value */ sscanf(hexdigits, "%x", &ascii); c = ascii; // And convert it back to a character } dst = dst + c; } } // end function UnescapeString void DieWithError(char *errorMessage) { perror(errorMessage); exit(1); }