Google
Web alhem.net

Web.cpp

Go to the documentation of this file.
00001 // Web.cpp
00002 /*
00003 Copyright (C) 2003  Anders Hedstrom
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 //#include <string>
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036 
00037 #include "Form.h"
00038 #include "Cookies.h"
00039 //#include "WebForm.h"
00040 
00041 //#include <vector>
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 //      Init();
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; // st_atime, st_mtime, st_ctime
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 //      char *c_l = getenv("CONTENT_LENGTH");
00157         char *q_s = getenv("QUERY_STRING");
00158 //      char *r_a = getenv("REMOTE_ADDR");
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                         // IIS won't set QUERY_STRING if it's empty
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         // Retrieve cookies
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(); // 'basic'
00272                         char slask[1000];
00273                         pa.getword(slask); // base64(user:pw)
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         // character set
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         // 4.01 strict
00314 //      printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
00315         // 4.01 transitional
00316 //      printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\n");
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 /* time_t mktime(struct tm *) */
00414         char slask[8];
00415         struct tm tp;
00416         time_t t;
00417         char *days[] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
00418 /*
00419         char *months[] = { "Jan","Feb","Mar","Apr","May","Jun",
00420                            "Jul","Aug","Sep","Oct","Nov","Dec" };
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 /* 1997-12-16 09:50:40 */
00428 
00429         if (dt.size() == 19) // && (int)strlen(dt) == 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 } // namespace

Generated for cgi++ by doxygen 1.3.7

Page, code, and content Copyright (C) 2004 by Anders Hedström