00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <cstdlib>
00027 #include <fstream>
00028 #include <sstream>
00029 #include <mpcl/net/cgi/config_processor.hh>
00030 #include <mpcl/net/cgi/exceptions.hh>
00031 #include <mpcl/net/url_decoder.hh>
00032 #include <mpcl/text/regex/matcher.hh>
00033
00034
00035
00036
00037
00038
00039 mpcl::net::cgi::TConfigProcessor::
00040 TConfigProcessor ( int iPARAMETER_COUNT ,
00041 const char** ppkcPARAMETERS ) :
00042 util::prefs::TConfigProcessor (iPARAMETER_COUNT, ppkcPARAMETERS) ,
00043 gHasInput (false)
00044 {
00045
00046 addEnvironmentVariable ("AUTH_TYPE");
00047 addEnvironmentVariable ("CONTENT_LENGTH");
00048 addEnvironmentVariable ("CONTENT_TYPE");
00049 addEnvironmentVariable ("GATEWAY_INTERFACE");
00050 addEnvironmentVariable ("HTTP_COOKIE");
00051 addEnvironmentVariable ("HTTP_USER_AGENT");
00052 addEnvironmentVariable ("PATH_INFO");
00053 addEnvironmentVariable ("PATH_TRANSLATED");
00054 addEnvironmentVariable ("QUERY_STRING");
00055 addEnvironmentVariable ("REMOTE_ADDR");
00056 addEnvironmentVariable ("REMOTE_HOST");
00057 addEnvironmentVariable ("REMOTE_IDENT");
00058 addEnvironmentVariable ("REMOTE_USER");
00059 addEnvironmentVariable ("REQUEST_METHOD");
00060 addEnvironmentVariable ("SCRIPT_NAME");
00061 addEnvironmentVariable ("SERVER_NAME");
00062 addEnvironmentVariable ("SERVER_PORT");
00063 addEnvironmentVariable ("SERVER_PROTOCOL");
00064 addEnvironmentVariable ("SERVER_SOFTWARE");
00065
00066 }
00067
00068
00069 void mpcl::net::cgi::TConfigProcessor::processOptions (void)
00070 {
00071
00072 using std::cin;
00073 using std::strtoul;
00074
00075 if ( !gOptionsProcessed )
00076 {
00077
00078
00079
00080
00081
00082 TString yQuery;
00083
00084
00085
00086
00087 processConfigFile();
00088
00089
00090
00091
00092
00093 if ( ( environmentValue ("REQUEST_METHOD") == "GET" ) ||
00094 ( environmentValue ("REQUEST_METHOD") == "HEAD" ) )
00095 {
00096
00097
00098
00099 yQuery = environmentValue ("QUERY_STRING");
00100 }
00101 else if ( environmentValue ("REQUEST_METHOD") == "POST" )
00102 {
00103
00104
00105
00106
00107
00108
00109 long unsigned int luiContentLength;
00110 char* pcBuffer;
00111
00112 luiContentLength = strtoul (environmentValue ("CONTENT_LENGTH").c_str(), NULL, 10);
00113 pcBuffer = new char [luiContentLength + 1];
00114 cin.read (pcBuffer, luiContentLength);
00115 pcBuffer [luiContentLength] = '\0';
00116 yQuery = pcBuffer;
00117 delete [] pcBuffer;
00118 }
00119 else
00120 {
00121 throw TBadFormException ("not supported REQUEST_METHOD", __FILE__, __LINE__);
00122 }
00123
00124
00125
00126
00127
00128 {
00129 std::basic_istringstream<char> tQueryIstringstream (yQuery);
00130
00131 readFormData (tQueryIstringstream);
00132 gOptionsProcessed = true;
00133 }
00134 }
00135
00136 }
00137
00138
00139 void mpcl::net::cgi::TConfigProcessor::processCommandLine (void)
00140 {
00141
00142 for (register int J = 1; ( J < iParametersCount ) ;++J)
00143 {
00144 updateOptionWithName (ppkcParametersList [J], "");
00145 }
00146
00147 }
00148
00149
00150 void mpcl::net::cgi::TConfigProcessor::
00151 readFormData (std::basic_istream<char_type, traits_type>& rtSOURCE_ISTREAM)
00152 {
00153
00154 using text::html::kcIdentifierValueSeparator;
00155 using text::regex::TMatcher;
00156
00157 TString yName;
00158 TString yValue;
00159 TMatcher tMatcher (rtSOURCE_ISTREAM);
00160 bool gSuccess = true;
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 while ( gSuccess )
00173 {
00174 gSuccess = ( tMatcher.scan ("%t=%t&", &yName, &yValue, NULL) > 0 );
00175 if ( !gSuccess )
00176 {
00177 gSuccess = ( tMatcher.scan ("%t=%t", &yName, &yValue, NULL) > 0 );
00178 }
00179 if ( gSuccess )
00180 {
00181 TString::size_type zSeparatorOffset = 0;
00182 TString::size_type zPointOffset = 0;
00183
00184 yName = TUrlDecoder::_decode (yName.c_str());
00185 yValue = TUrlDecoder::_decode (yValue.c_str());
00186 if ( TString::npos != (zSeparatorOffset = yName.find (kcIdentifierValueSeparator)) )
00187 {
00188 if ( TString::npos != (zPointOffset = yName.find ('.', zSeparatorOffset)) )
00189 {
00190
00191
00192
00193
00194 yValue = yName.substr (zSeparatorOffset + 1, zPointOffset - zSeparatorOffset - 1);
00195 yName = yName.substr (0, zSeparatorOffset);
00196 }
00197 else
00198 {
00199
00200
00201
00202 yName = yName.substr (0, zSeparatorOffset);
00203 }
00204 }
00205 updateFormOption (yName, yValue);
00206 gHasInput = true;
00207 }
00208 }
00209
00210 }
00211
00212
00213 mpcl::util::prefs::TOption& mpcl::net::cgi::TConfigProcessor::
00214 updateFormOption (const TString& rkyNAME, const TString& rkyVALUE)
00215 {
00216
00217 bool gFound = false;
00218 TOptionVector::const_iterator ktEnd = tFormOptionVector.end();
00219 TOptionVector::iterator I = tFormOptionVector.begin();
00220
00221 if ( !rkyNAME.empty() )
00222 {
00223 for (; ( I != ktEnd ) ;++I)
00224 {
00225 if ( I->name() == rkyNAME )
00226 {
00227 if ( !I->hasValue (rkyVALUE) )
00228 {
00229 I->addValue (rkyVALUE);
00230 }
00231 gFound = true;
00232 break;
00233 }
00234 }
00235 }
00236 if ( !gFound )
00237 {
00238 TOption tNewOption (rkyNAME, "", "");
00239
00240
00241
00242
00243
00244 tNewOption.addValue (rkyVALUE);
00245 tFormOptionVector.push_back (tNewOption);
00246 I = tFormOptionVector.end() - 1;
00247 }
00248 return *I;
00249
00250 }
00251
00252
00253 mpcl::util::prefs::TOption& mpcl::net::cgi::TConfigProcessor::
00254 updateOptionWithName ( const TString& rkyNAME ,
00255 const TString& rkyVALUE )
00256 {
00257
00258 bool gFound = false;
00259 TOptionVector::const_iterator ktEnd = tOptionVector.end();
00260 TOptionVector::iterator I = tOptionVector.begin();
00261
00262 if ( !rkyNAME.empty() )
00263 {
00264 for (; ( I != ktEnd ) ;++I)
00265 {
00266 if ( I->name() == rkyNAME )
00267 {
00268 if ( !I->hasValue (rkyVALUE) )
00269 {
00270 I->addValue (rkyVALUE);
00271 }
00272 gFound = true;
00273 break;
00274 }
00275 }
00276 }
00277 if ( !gFound )
00278 {
00279 TOption tNewOption (rkyNAME, "", "");
00280
00281
00282
00283
00284
00285 tNewOption.addValue (rkyVALUE);
00286 tOptionVector.push_back (tNewOption);
00287 I = tOptionVector.end() - 1;
00288 }
00289 return *I;
00290
00291 }
00292
00293
00294
00295
00296
00297
00298 const mpcl::text::TString& mpcl::net::cgi::TConfigProcessor::
00299 getFormValue (const char* pkcNAME) const
00300 {
00301
00302 using mpcl::text::Format;
00303 using mpcl::text::TString;
00304 using std::vector;
00305
00306 TOptionVector::iterator I = tFormOptionVector.begin();
00307 TOptionVector::const_iterator ktEnd = tFormOptionVector.end();
00308
00309 for (; ( I != ktEnd ) ;++I)
00310 {
00311 if ( I->name() == pkcNAME )
00312 {
00313 break;
00314 }
00315 }
00316 if ( I == ktEnd )
00317 {
00318 TString yMessage;
00319
00320 yMessage = Format ("form option '%s' not found", pkcNAME);
00321 throw TVariableNotFoundException (yMessage, __FILE__, __LINE__);
00322 }
00323 return I->getValue();
00324
00325 }
00326
00327
00328 bool mpcl::net::cgi::TConfigProcessor::
00329 hasFormOption (const TString& rkyNAME) const
00330 {
00331
00332 bool gSuccess = false;
00333 TOptionVector::const_iterator ktEnd = tFormOptionVector.end();
00334 TOptionVector::iterator I = tFormOptionVector.begin();
00335
00336 for (; ( I != ktEnd ) ;++I)
00337 {
00338 if ( I->name() == rkyNAME )
00339 {
00340 gSuccess = true;
00341 break;
00342 }
00343 }
00344 return gSuccess;
00345
00346 }
00347
00348
00349 bool mpcl::net::cgi::TConfigProcessor::
00350 hasOption (const TString& rkyNAME) const
00351 {
00352
00353 bool gSuccess = false;
00354 TOptionVector::const_iterator ktEnd = tOptionVector.end();
00355 TOptionVector::iterator I = tOptionVector.begin();
00356
00357 for (; ( I != ktEnd ) ;++I)
00358 {
00359 if ( I->name() == rkyNAME )
00360 {
00361 gSuccess = true;
00362 break;
00363 }
00364 }
00365 return gSuccess;
00366
00367 }
00368
00369
00370 void mpcl::net::cgi::TConfigProcessor::
00371 updateForm (text::html::TForm& rtTARGET_FORM) const
00372 {
00373
00374 TOptionVector::const_iterator ktEnd = tFormOptionVector.end();
00375 TOptionVector::iterator I = tFormOptionVector.begin();
00376
00377 rtTARGET_FORM.reset();
00378 for (; ( I != ktEnd ) ;++I)
00379 {
00380 rtTARGET_FORM.setValues (I->name(), I->getValues());
00381 }
00382
00383 }