User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C++ section within the Software Development category of DaniWeb, a massive community of 456,575 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,582 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C++ advertiser: Programming Forums
Views: 977 | Replies: 5
Reply
Join Date: Aug 2004
Location: United States
Posts: 44
Reputation: mister-fett is an unknown quantity at this point 
Rep Power: 5
Solved Threads: 0
mister-fett's Avatar
mister-fett mister-fett is offline Offline
Light Poster

A C++ CGI Problem

  #1  
Oct 27th, 2007
I decided to revive my (many months) inactive site today using things I've learned about C++ CGI and the Document Object Model along with CSS. The site is still down, but I'm trying to get back into CGI after leaving it alone for a while (also months). I've spent the past three hours debugging this (90 minutes fixing late-night typos and a few missing semicolons, the rest spent trying to fix the problem described herein) but I can't get the function I'm basically writing it for to work. The (cgi::find) function.

This http://24.148.160.212/cgi-bin/test.cgi?cheese=cheese& is supposed to output:
cheese = cheese
I would like cheese today.

I also shouldn't need an & at the end of the query, but for some reason and hours of fiddling with my code to sort a query into variables and contents of those variables I still need the & at the end.

My server is running Apache 2.2.4 and on Windows XP and the code was compiled using Borland C++ 5.5.1 for Win32.

/*

A CGI tool allowing the use of form.find("input name") in scripts after running init()

example in main:

#include "cgi.cpp"

int main(int argc, char *argv[])
{
	cgi form = init();
	string cheese;

	form.find( "cheese", cheese );

	cout<<"<html>";
	cout<<cheese;
	cout<<"</html>";
}

would generate a page with the content of query or post input 'cheese' on it.

I don't know if my array use is secure or not, it supports a megabyte at the moment.

I'll begin optimization on return from vacation, any suggestions?

*/

//planned features:

//function 'text("filename")' outputs the file to a browser - can be used for blogs

//function 'cgi.record("name","filename")' puts the content of name at the end of file filename

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class cgi
{
	friend cgi init();

	private: string name; //post/query variable
	string content; //contents of post/query variable
	cgi *nextone; //nextone cgi. functions stop at NULL when searching for a certain name.

	public: cgi(string n=" ", string c=" ") //initialize the cgi
	{
		name = n;
		content = c;
		nextone = NULL;
	}

	void reset(string n, string c) //reset the cgi
	{
		name = n;
		content = c;
		nextone = NULL;
	}

	void add(string n, string c) //add a variable to the end
	{
		if (nextone==NULL)
		{
			nextone = new cgi(n,c);
		}
		else
			nextone->add(n,c);
	}

	bool find(string n, string &c) //find n, and if found, return true and copy n's content to c. if not, return false
	{
		if ( ! name.compare( n ) ) //if name is equal to n
		{
			c = content;
			return true;
		}
		else if (nextone==NULL) //if this is the last element of the cgi
			return false;
		else //pass the find to the nextone 
			return nextone->find(n,c); 	
	}

	private: void convert()
	{
		int length = content.length();
		int con; //content position
		int nco=0; //new content position
		string newcontent;
		
		for (con = 0; con<length; con++)
		{
			if (content[con]=='%') //URL encoded, leave normally encoded things alone, convert what is safe to use in HTML
			{
				switch (content[con+1])
				{
					case '2':
						switch (content[con+2])
						{
							case '0': newcontent[nco++]=' '; continue;
							case '4': newcontent[nco++]='$'; continue;
							case '6': newcontent[nco++]='&'; continue;
							case 'b':
							case 'B': newcontent[nco++]='+'; continue;
							case 'c':
							case 'C': newcontent[nco++]=','; continue;
							case 'f':
							case 'F': newcontent[nco++]='/'; continue;

							default: newcontent[nco++] = '%';
							newcontent[nco++] = content[con++];
							newcontent[nco++] = content[con++];
							continue;
						}
						con+=2;
						nco++;
						continue;

					case '3':
						switch (content[con+2])
						{
							case 'a':
							case 'A': newcontent[nco++]=':'; continue;
							case 'b':
							case 'B': newcontent[nco++]=';'; continue;
							case 'd':
							case 'D': newcontent[nco++]='='; continue;
							case 'f':
							case 'F': newcontent[nco++]='?'; continue;

							default: newcontent[nco++] = '%';
							newcontent[nco++] = content[con++];
							newcontent[nco++] = content[con++];
							continue;
						}
						con+=2;
						nco++;
						continue;

					case '4':
						if (content[con+2]=='0')
							newcontent[nco++]='@';
						else
						{
							newcontent[nco++] = '%';
							newcontent[nco++] = content[con++];
							newcontent[nco++] = content[con++];
							continue;
						}
						con+=2;
						nco++;
						continue;

					default: newcontent[nco++] = '%';
					newcontent[nco++] = content[con++];
					newcontent[nco++] = content[con++];
					continue;
				}
			}
			else //if already plaintext
			{
				newcontent[nco] = content[con];
				nco++;
			}
		}
		newcontent[nco]='\0';
		content = newcontent;

		if (nextone!=NULL)
			nextone->convert();

	}
};

cgi init()
{
	cgi raw; //before url unencoding
	cgi plain; //after url unencoding
	string query; //in case of query string
	int length; //content length, if existent
	int a; //integer variable
	int b; //integer variable
	string c; //string variable
	string d; //string variable
	char buffer[1024000]; //support a megabyte of form data

	cout<<"Content-type: text/html\n\n"; //give the browser a heads up

	if ( getenv( "QUERY_STRING" ) ) //if there is a query string
	{
		query = getenv( "QUERY_STRING" );
	}

	else if ( getenv( "CONTENT_LENGTH" ) )
	{
		length = atoi( getenv( "CONTENT_LENGTH") );
		cin.read( buffer, length );
		query = buffer;
	}

	else
	{
		cout<<"Content-type: text/html\n\n";
		cout<<"No form input.";
	}

	//initialize the raw cgi

		a = query.find_first_of('='); //find the end of the variable name
		c = query.substr( 0 , a ); //assign c the variable name
		b = query.find_first_of('&'); //find the end of the variable content
		if (query.find_first_of('&') == -1 ) //if & not found
			b = query.length();
		d = query.substr( a+1 , b ); //assign d the variable content
		query = query.substr( b+1, query.length() ); //shorten the query string accordingly
		raw.reset( c, d );

		cout<<c<<" = "<<d<<endl<<"<br>";

		while (query.length()>1)
		{
			a = query.find_first_of('='); //find the end of the variable name
			if (query.find_first_of('=') == -1) //there are no more variables
				break;
			c = query.substr( 0 , a ); //assign c the variable name
			b = query.find_first_of('&'); //find the end of the variable content
			if (query.find_first_of('&') == -1 ) //if & not found
				b = query.length();
			d = query.substr( a+1 , b ); //assign d the variable content
			query = query.substr( b+1, query.length() ); //shorten the query string accordingly
			raw.add( c, d ); //add to the cgi instead of resetting it

			cout<<c<<" = "<<d<<"<br>";
		}

	//herein lies the conversion of all raw cgi content's to plaintext (not a grammatical error)

	raw.convert();
	plain = raw;

	//herein lies the returning of the converted content goodness

	return plain;
}

I had a blog, comment system, and forum working before, but that code was such a terrible mess (yes, worse than this) that I decided not to use it. Also, my previous code used RudeCGI which was difficult to cross-platform. I'm trying to write (at least) a platform-portable .cpp file allowing me to write programs that read form input from a browser and access the content of the form's inputs using form.find("inputname"), or better yet form["inputname"].

I'm finding it truer and truer that coding is small% writing and majority% debugging/maintenance.

Any suggestions, assistance, or tips on my rusty C++ coding style are appreciated.
Cheese. In fact, I rather dislike cheese.
AddThis Social Bookmark Button
Reply With Quote  
Join Date: May 2006
Location: ★ ijug.net ★
Posts: 1,018
Reputation: ithelp will become famous soon enough ithelp will become famous soon enough 
Rep Power: 6
Solved Threads: 68
ithelp ithelp is offline Offline
Veteran Poster

Re: A C++ CGI Problem

  #2  
Oct 27th, 2007
That is quite messy.
Better move to perl/php
Reply With Quote  
Join Date: May 2006
Posts: 2,781
Reputation: WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold 
Rep Power: 15
Solved Threads: 229
Moderator
WaltP's Avatar
WaltP WaltP is offline Offline
Posting Maven

Re: A C++ CGI Problem

  #3  
Oct 27th, 2007
Originally Posted by ithelp View Post
That is quite messy.
Better move to perl/php

Yes, it's quite messy because you used TABs for indentation instead of 3-4 SPACEs. Outside of that the formatting seems fine.

And moving to Perl or PHP is one of the most asinine suggestions I've ever heard. Why would someone want to develop a C++ program in Perl or PHP?
Got a cough? Go home tonight and eat a whole box of Ex-Lax. Tomorrow, you'll be afraid to cough.
-- Pearl Williams
Reply With Quote  
Join Date: Dec 2005
Posts: 3,834
Reputation: Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of 
Rep Power: 23
Solved Threads: 436
Colleague
Salem's Avatar
Salem Salem is offline Offline
banned

Re: A C++ CGI Problem

  #4  
Oct 27th, 2007
Well despite their C++ skills, there's already one glaring security hole just waiting to be exploited.

Writing internet facing applications needs a lot more security awareness than this. Using languages which protect you from dumb stuff like unguarded reads into finite length char arrays for example.
Reply With Quote  
Join Date: May 2006
Location: ★ ijug.net ★
Posts: 1,018
Reputation: ithelp will become famous soon enough ithelp will become famous soon enough 
Rep Power: 6
Solved Threads: 68
ithelp ithelp is offline Offline
Veteran Poster

Re: A C++ CGI Problem

  #5  
Oct 27th, 2007
Originally Posted by WaltP View Post

And moving to Perl or PHP is one of the most asinine suggestions I've ever heard. Why would someone want to develop a C++ program in Perl or PHP?

CGI stuff can coded more quickly in perl and php
Last edited by ithelp : Oct 27th, 2007 at 7:23 am.
Reply With Quote  
Join Date: May 2006
Posts: 2,781
Reputation: WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold 
Rep Power: 15
Solved Threads: 229
Moderator
WaltP's Avatar
WaltP WaltP is offline Offline
Posting Maven

Re: A C++ CGI Problem

  #6  
Oct 27th, 2007
Originally Posted by ithelp View Post
CGI stuff can coded more quickly in perl and php

Immaterial. You develop programs in the language
1) your skillset lies
2) your boss wants it developed in
3) you decide is necessary to develop the code

I agree PHP and Perl may be better, but to suggest it to someone that is developing a system in another language is IMO a rude suggestion. It the same as suggesting a student use vectors when they are learning (or barely understand) arrays.
Got a cough? Go home tonight and eat a whole box of Ex-Lax. Tomorrow, you'll be afraid to cough.
-- Pearl Williams
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

DaniWeb C++ Marketplace
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes

Similar Threads
Other Threads in the C++ Forum

All times are GMT -4. The time now is 6:12 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC