00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef _WIN32
00021 #pragma warning(disable:4786)
00022 #endif
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <time.h>
00027 #ifdef WIN32
00028 #include <winsock2.h>
00029 #else
00030 #include <sys/time.h>
00031 #include <unistd.h>
00032 #endif
00033
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036
00037 #include "Form.h"
00038 #include "Cookies.h"
00039
00040
00041
00042 #include "WebForm.h"
00043 #include "Web.h"
00044 #include "Parse.h"
00045 #include "Base64.h"
00046
00047 #ifdef WIN32
00048 #define strcasecmp stricmp
00049 #endif
00050
00051
00052 namespace Cgi {
00053
00054 Web::Web()
00055 :m_pclForm(NULL)
00056 ,m_pclCookies(NULL)
00057 ,m_strCookieDomain("")
00058 ,m_strCookiePath("")
00059 ,m_lastmodified("")
00060 ,m_bValid(false)
00061 ,m_contentType("text/html; charset=ISO-8859-1")
00062 {
00063 time_t t = time(NULL);
00064 struct tm * tp = localtime(&t);
00065 char date[40];
00066
00067 sprintf(date,"%d-%02d-%02d %02d:%02d:%02d",
00068 tp -> tm_year + 1900,
00069 tp -> tm_mon + 1,
00070 tp -> tm_mday,
00071 tp -> tm_hour,
00072 tp -> tm_min,
00073 tp -> tm_sec);
00074 m_date = date;
00075
00076
00077 }
00078
00079
00080 Web::Web(const std::string &strd,const std::string &strp,const std::string& id)
00081 :m_pclForm(NULL)
00082 ,m_pclCookies(NULL)
00083 ,m_strCookieDomain(strd)
00084 ,m_strCookiePath(strp)
00085 ,m_lastmodified("")
00086 ,m_bValid(false)
00087 ,m_contentType("text/html; charset=ISO-8859-1")
00088 {
00089 time_t t = time(NULL);
00090 struct tm * tp = localtime(&t);
00091 char date[40];
00092
00093 sprintf(date,"%d-%02d-%02d %02d:%02d:%02d",
00094 tp -> tm_year + 1900,
00095 tp -> tm_mon + 1,
00096 tp -> tm_mday,
00097 tp -> tm_hour,
00098 tp -> tm_min,
00099 tp -> tm_sec);
00100 m_date = date;
00101
00102 Init(id);
00103 }
00104
00105
00106 Web::Web(int ,char *argv[],const std::string &strd,const std::string &strp,const std::string& id)
00107 :m_pclForm(NULL)
00108 ,m_pclCookies(NULL)
00109 ,m_strCookieDomain(strd)
00110 ,m_strCookiePath(strp)
00111 ,m_lastmodified("")
00112 ,m_bValid(false)
00113 ,m_contentType("text/html; charset=ISO-8859-1")
00114 {
00115 time_t t = time(NULL);
00116 struct tm * tp = localtime(&t);
00117 char date[40];
00118
00119 sprintf(date,"%d-%02d-%02d %02d:%02d:%02d",
00120 tp -> tm_year + 1900,
00121 tp -> tm_mon + 1,
00122 tp -> tm_mday,
00123 tp -> tm_hour,
00124 tp -> tm_min,
00125 tp -> tm_sec);
00126 m_date = date;
00127
00128 Init(id);
00129
00130 struct stat st;
00131 if (stat(argv[0], &st) != -1)
00132 {
00133 time_t t = st.st_mtime;
00134 struct tm *tp = localtime(&t);
00135 sprintf(date,"%d-%02d-%02d %02d:%02d:%02d",
00136 tp -> tm_year + 1900,
00137 tp -> tm_mon + 1,
00138 tp -> tm_mday,
00139 tp -> tm_hour,
00140 tp -> tm_min,
00141 tp -> tm_sec);
00142 m_lastmodified = date;
00143 }
00144 }
00145
00146
00147 void Web::RegWebForm(WebForm *pclForm)
00148 {
00149 m_forms.insert(m_forms.end(), pclForm);
00150 }
00151
00152
00153 void Web::Init(const std::string& id)
00154 {
00155 char *r_m = getenv("REQUEST_METHOD");
00156
00157 char *q_s = getenv("QUERY_STRING");
00158
00159 char *h_c = getenv("HTTP_COOKIE");
00160
00161 if (q_s)
00162 m_query_string = q_s;
00163
00164 #ifdef WIN32
00165 #else
00166 struct timeval tv;
00167
00168 gettimeofday(&tv,NULL);
00169 srandom( (tv.tv_sec % 1000000) * 1000 + tv.tv_usec);
00170 #endif
00171
00172 if (!r_m)
00173 {
00174 fprintf(stderr,"This is a cgi program\n");
00175 exit(-1);
00176 }
00177 m_method = r_m;
00178 if (!strcasecmp(r_m,"get"))
00179 {
00180 if (q_s)
00181 {
00182 m_pclForm = new Form(q_s,strlen(q_s));
00183 }
00184 else
00185 {
00186 #ifdef WIN32
00187
00188 m_pclForm = new Form("",0);
00189 #else
00190 fprintf(stderr,"QUERY_STRING undefined\n");
00191 exit(-1);
00192 #endif
00193 }
00194 }
00195 else
00196 if (id.size())
00197 {
00198 FILE *fil = fopen(id.c_str(),"rb");
00199 m_pclForm = new Form(fil);
00200 fclose(fil);
00201 }
00202 else
00203 if (!strcasecmp(r_m,"post"))
00204 {
00205 m_pclForm = new Form;
00206 }
00207 else
00208 {
00209 fprintf(stderr,"Unknown request method: '%s'\n",r_m);
00210 exit(-1);
00211 }
00212
00213 m_pclCookies = new Cookies(h_c ? h_c : (char *)"");
00214 }
00215
00216
00217 Web::~Web()
00218 {
00219 if (m_pclForm)
00220 {
00221 delete m_pclForm;
00222 }
00223 if (m_pclCookies)
00224 {
00225 delete m_pclCookies;
00226 }
00227 }
00228
00229
00230 void Web::Execute()
00231 {
00232 GetEnvironment();
00233 ReadCookies();
00234 FormInput();
00235 ValidateAuth();
00236 CreateHeader();
00237 GenerateDocument();
00238 }
00239
00240
00241 void Web::GetEnvironment()
00242 {
00243 }
00244
00245
00246 void Web::ReadCookies()
00247 {
00248 }
00249
00250
00251 void Web::FormInput()
00252 {
00253 std::list<WebForm *>::iterator it;
00254
00255 for (it = m_forms.begin(); it != m_forms.end(); it++)
00256 {
00257 WebForm *pclForm = static_cast<WebForm *>(*it);
00258 pclForm -> Process();
00259 }
00260 }
00261
00262
00263 void Web::ValidateAuth()
00264 {
00265 if (m_realm.size())
00266 {
00267 char *auth = getenv("HTTP_AUTHORIZATION");
00268 if (auth)
00269 {
00270 Parse pa(auth);
00271 pa.getword();
00272 char slask[1000];
00273 pa.getword(slask);
00274 Base64 b;
00275 std::string tmp = slask;
00276 b.decode_to_buffer(tmp, slask, 1000);
00277 Parse pa2(slask, ":");
00278 pa2.getword(slask);
00279 m_user = slask;
00280 pa2.getword(slask);
00281 if (ValidateUser(m_user, slask))
00282 {
00283 m_bValid = true;
00284 }
00285 }
00286 }
00287 }
00288
00289
00290 void Web::CreateHeader()
00291 {
00292
00293 printf("Content-type: %s\n", m_contentType.c_str());
00294 if (m_contentDisposition.size())
00295 {
00296 printf("Content-disposition: %s\n", m_contentDisposition.c_str());
00297 }
00298 if (m_realm.size())
00299 {
00300 printf("WWW-Authenticate: Basic realm=\"%s\"\n", m_realm.c_str());
00301 if (!m_bValid)
00302 {
00303 printf("Status: 401 Forbidden\n");
00304 }
00305 }
00306 if (m_location.size())
00307 {
00308 printf("Location: %s\n", m_location.c_str());
00309 }
00310 printf("\n");
00311 fflush(stdout);
00312
00313
00314
00315
00316
00317 fflush(stdout);
00318 }
00319
00320
00321 void Web::GenerateDocument()
00322 {
00323 }
00324
00325
00326 void Web::SetCookieDomain(const std::string &str)
00327 {
00328 m_strCookieDomain = str;
00329 }
00330
00331
00332 void Web::SetCookiePath(const std::string &str)
00333 {
00334 m_strCookiePath = str;
00335 }
00336
00337
00338 void Web::SetCookie(const std::string &name,const std::string &value)
00339 {
00340 m_pclCookies -> setcookie( (char *)m_strCookieDomain.c_str(),
00341 (char *)m_strCookiePath.c_str(),
00342 (char *)name.c_str(),
00343 (char *)value.c_str());
00344 }
00345
00346
00347 void Web::SetCookie(const std::string &name,long value)
00348 {
00349 m_pclCookies -> setcookie( (char *)m_strCookieDomain.c_str(),
00350 (char *)m_strCookiePath.c_str(),
00351 (char *)name.c_str(),
00352 value);
00353 }
00354
00355
00356 void Web::SetCookie(const std::string &name,int value)
00357 {
00358 m_pclCookies -> setcookie( (char *)m_strCookieDomain.c_str(),
00359 (char *)m_strCookiePath.c_str(),
00360 (char *)name.c_str(),
00361 value);
00362 }
00363
00364
00365 void Web::SetCgiName(const std::string &name)
00366 {
00367 m_strCgiName = name;
00368 }
00369
00370
00371 std::string Web::GetCgiName()
00372 {
00373 return m_strCgiName;
00374 }
00375
00376
00377 Form *Web::GetForm()
00378 {
00379 return m_pclForm;
00380 }
00381
00382
00383 Cookies *Web::GetCookies()
00384 {
00385 return m_pclCookies;
00386 }
00387
00388
00389 std::string Web::GetDate()
00390 {
00391 return m_date;
00392 }
00393
00394
00395 std::string Web::GetRequestMethod()
00396 {
00397 return m_method;
00398 }
00399
00400
00401 void Web::UpdateModified(const std::string& str)
00402 {
00403 if (!m_lastmodified.size() || strcmp(str.c_str(),m_lastmodified.c_str()) > 0)
00404 {
00405 if (str.size())
00406 m_lastmodified = str;
00407 }
00408 }
00409
00410
00411 std::string Web::datetime2httpdate(const std::string& dt)
00412 {
00413
00414 char slask[8];
00415 struct tm tp;
00416 time_t t;
00417 char *days[] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
00418
00419
00420
00421
00422 char *months[] = { "Jan","Feb","Mar","Apr","May","Jun",
00423 "Jul","Aug","Sep","Oct","Nov","Dec" };
00424 int i;
00425 char s[40];
00426
00427
00428
00429 if (dt.size() == 19)
00430 {
00431 slask[4] = 0;
00432 tp.tm_year = atoi(strncpy(slask,dt.c_str(),4)) - 1900;
00433 slask[2] = 0;
00434 i = atoi(strncpy(slask,dt.c_str() + 5,2)) - 1;
00435 tp.tm_mon = i >= 0 ? i : 0;
00436 tp.tm_mday = atoi(strncpy(slask,dt.c_str() + 8,2));
00437 tp.tm_hour = atoi(strncpy(slask,dt.c_str() + 11,2));
00438 tp.tm_min = atoi(strncpy(slask,dt.c_str() + 14,2));
00439 tp.tm_sec = atoi(strncpy(slask,dt.c_str() + 17,2));
00440 tp.tm_wday = 0;
00441 tp.tm_yday = 0;
00442 tp.tm_isdst = 0;
00443 t = mktime(&tp);
00444 if (t == -1)
00445 {
00446 printf("datetime2httpdate() failed\n");
00447 }
00448
00449 sprintf(s,"%s, %02d %s %d %02d:%02d:%02d GMT",
00450 days[tp.tm_wday],
00451 tp.tm_mday,
00452 months[tp.tm_mon],
00453 tp.tm_year + 1900,
00454 tp.tm_hour,tp.tm_min,tp.tm_sec);
00455 }
00456 else
00457 {
00458 *s = 0;
00459 }
00460 return s;
00461 }
00462
00463
00464 void Web::SetRealm(const std::string& session_id)
00465 {
00466 m_realm = session_id;
00467 }
00468
00469
00470 bool Web::ValidateUser(const std::string& ,const std::string& )
00471 {
00472 return false;
00473 }
00474
00475
00476 const std::string& Web::GetUser()
00477 {
00478 return m_user;
00479 }
00480
00481
00482 bool Web::Valid()
00483 {
00484 return m_bValid;
00485 }
00486
00487
00488 }