Logo
~Sockets~
~Examples~
~Contact~


HttpdSocket Class Reference
[Webserver framework]

Web server socket framework. More...

#include <HttpdSocket.h>

Inheritance diagram for HttpdSocket:
Collaboration diagram for HttpdSocket:

List of all members.


Public Member Functions

 HttpdSocket (ISocketHandler &)
 ~HttpdSocket ()
void OnFirst ()
 Callback executes when first line has been received.
void OnHeader (const std::string &key, const std::string &value)
 For each header line this callback is executed.
void OnHeaderComplete ()
 Callback fires when all http headers have been received.
void OnData (const char *, size_t)
 Chunk of http body data recevied.
virtual void Exec ()=0
 This method needs to be implemented with logic to produce a response to an incoming request.
const std::string & GetHttpDate () const
 Get current date in http rfc format.
HttpdCookiesGetCookies ()
 Get pointer to cookie class.
const HttpdFormGetForm () const
 Get pointer to query string/form data class.
size_t ContentLength () const
const IFileBody () const
int RequestId () const

Protected Member Functions

 HttpdSocket (const HttpdSocket &s)
void Send64 (const std::string &str64, const std::string &type)
 Decode and send a base64-encoded string.
std::string datetime2httpdate (const std::string &dt)
std::string GetDate ()
void Reset ()
 Reset state of socket to sucessfully implement keep-alive.

Protected Attributes

std::string m_http_cookie
std::string m_content_type
std::string m_content_length_str
std::string m_if_modified_since

Private Member Functions

HttpdSocketoperator= (const HttpdSocket &s)

Private Attributes

size_t m_content_length
IFilem_file
size_t m_received
int m_request_id
std::string m_http_date
HttpdCookiesm_cookies
HttpdFormm_form

Static Private Attributes

static int m_request_count = 0
static std::string m_start = ""

Detailed Description

Web server socket framework.

Definition at line 49 of file HttpdSocket.h.


Constructor & Destructor Documentation

HttpdSocket::HttpdSocket ( ISocketHandler h  ) 

Definition at line 52 of file HttpdSocket.cpp.

References datetime2httpdate(), GetDate(), m_http_date, and m_start.

00053 :HTTPSocket(h)
00054 ,m_content_length(0)
00055 ,m_file(NULL)
00056 ,m_received(0)
00057 ,m_request_id(++m_request_count)
00058 ,m_cookies(NULL)
00059 ,m_form(NULL)
00060 {
00061         m_http_date = datetime2httpdate(GetDate());
00062         if (!m_start.size())
00063                 m_start = m_http_date;
00064 }

HttpdSocket::~HttpdSocket (  ) 

Definition at line 67 of file HttpdSocket.cpp.

References m_cookies, m_file, and m_form.

00068 {
00069         if (m_file)
00070         {
00071                 delete m_file;
00072         }
00073         if (m_cookies)
00074                 delete m_cookies;
00075         if (m_form)
00076                 delete m_form;
00077 }

HttpdSocket::HttpdSocket ( const HttpdSocket s  )  [inline, protected]

Definition at line 75 of file HttpdSocket.h.

00075 : HTTPSocket(s) {}


Member Function Documentation

void HttpdSocket::OnFirst (  )  [virtual]

Callback executes when first line has been received.

GetMethod, GetUrl/GetUri, and GetHttpVersion are valid when this callback is executed.

Implements HTTPSocket.

Definition at line 80 of file HttpdSocket.cpp.

00081 {
00082 }

void HttpdSocket::OnHeader ( const std::string &  key,
const std::string &  value 
) [virtual]

For each header line this callback is executed.

Parameters:
key Http header name
value Http header value

Implements HTTPSocket.

Definition at line 85 of file HttpdSocket.cpp.

References m_content_length, m_content_length_str, m_content_type, m_http_cookie, and m_if_modified_since.

00086 {
00087         if (!strcasecmp(key.c_str(),"content-length"))
00088         {
00089                 m_content_length = atoi(value.c_str());
00090                 m_content_length_str = value;
00091         }
00092         else
00093         if (!strcasecmp(key.c_str(),"cookie"))
00094         {
00095                 m_http_cookie = value;
00096         }
00097         else
00098         if (!strcasecmp(key.c_str(),"content-type"))
00099         {
00100                 m_content_type = value;
00101         }
00102         else
00103         if (!strcasecmp(key.c_str(),"if-modified-since"))
00104         {
00105                 m_if_modified_since = value;
00106         }
00107 }

void HttpdSocket::OnHeaderComplete (  )  [virtual]

Callback fires when all http headers have been received.

Implements HTTPSocket.

Definition at line 110 of file HttpdSocket.cpp.

References HTTPSocket::AddResponseHeader(), datetime2httpdate(), Exec(), GetDate(), GetHttpDate(), HTTPSocket::GetMethod(), HTTPSocket::GetQueryString(), HTTPSocket::GetUri(), Utility::Logo, m_content_length_str, m_content_type, m_cookies, m_file, m_form, m_http_cookie, Reset(), Send64(), HTTPSocket::SendResponse(), Utility::SetEnv(), HTTPSocket::SetStatus(), and HTTPSocket::SetStatusText().

00111 {
00112         m_cookies = new HttpdCookies(m_http_cookie);
00113 
00114         if (GetMethod() == "GET")
00115         {
00116                 Utility::SetEnv("QUERY_STRING", GetQueryString());
00117         }
00118         Utility::SetEnv("REQUEST_METHOD", GetMethod());
00119         Utility::SetEnv("HTTP_COOKIE", m_http_cookie);
00120         Utility::SetEnv("CONTENT_TYPE", m_content_type);
00121         Utility::SetEnv("CONTENT_LENGTH", m_content_length_str);
00122         if (GetMethod() == "POST")
00123         {
00124                 m_file = new MemFile;
00125         }
00126         else
00127         if (GetMethod() == "GET")
00128         {
00129                 m_form = new HttpdForm(GetQueryString(), GetQueryString().size() );
00130                 AddResponseHeader("Date", datetime2httpdate(GetDate()) );
00131                 if (GetUri() == "/image")
00132                 {
00133                         Send64(Utility::Logo, "image/png");
00134                 }
00135                 else
00136                 {
00137                         Exec();
00138                 }
00139                 Reset(); // prepare for next request
00140         }
00141         else
00142         {
00143                 AddResponseHeader("Date", GetHttpDate());
00144                 AddResponseHeader("Connection", "close");
00145                 SetStatus("405");
00146                 SetStatusText("Method not allowed");
00147                 SendResponse();
00148         }
00149 }

void HttpdSocket::OnData ( const char *  ,
size_t   
) [virtual]

Chunk of http body data recevied.

Implements HTTPSocket.

Definition at line 152 of file HttpdSocket.cpp.

References HTTPSocket::AddResponseHeader(), datetime2httpdate(), Exec(), GetDate(), HTTPSocket::GetUri(), Utility::Logo, m_content_length, m_content_type, m_file, m_form, m_received, Reset(), and Send64().

00153 {
00154         if (m_file)
00155         {
00156                 m_file -> fwrite(p,1,l);
00157         }
00158         m_received += l;
00159         if (m_received >= m_content_length && m_content_length)
00160         {
00161                 // all done
00162                 if (m_file && !m_form)
00163                 {
00164                         m_form = new HttpdForm(m_file, m_content_type, m_content_length);
00165                         AddResponseHeader("Date", datetime2httpdate(GetDate()) );
00166                         if (GetUri() == "/image")
00167                         {
00168                                 Send64(Utility::Logo, "image/png");
00169                         }
00170                         else
00171                         {
00172                                 Exec();
00173                         }
00174                         Reset(); // prepare for next request
00175                 }
00176         }
00177 }

virtual void HttpdSocket::Exec (  )  [pure virtual]

This method needs to be implemented with logic to produce a response to an incoming request.

Referenced by OnData(), and OnHeaderComplete().

const std::string & HttpdSocket::GetHttpDate (  )  const

Get current date in http rfc format.

Definition at line 303 of file HttpdSocket.cpp.

References m_http_date.

Referenced by OnHeaderComplete().

00304 {
00305         return m_http_date; 
00306 }

HttpdCookies * HttpdSocket::GetCookies (  ) 

Get pointer to cookie class.

Definition at line 309 of file HttpdSocket.cpp.

References m_cookies.

00310 {
00311         return m_cookies; 
00312 }

const HttpdForm * HttpdSocket::GetForm (  )  const

Get pointer to query string/form data class.

Definition at line 315 of file HttpdSocket.cpp.

References m_form.

00316 {
00317         return m_form; 
00318 }

size_t HttpdSocket::ContentLength (  )  const [inline]

Definition at line 70 of file HttpdSocket.h.

00070 { return m_content_length; }

const IFile* HttpdSocket::Body (  )  const [inline]

Definition at line 71 of file HttpdSocket.h.

00071 { return m_file; }

int HttpdSocket::RequestId (  )  const [inline]

Definition at line 72 of file HttpdSocket.h.

00072 { return m_request_id; }

void HttpdSocket::Send64 ( const std::string &  str64,
const std::string &  type 
) [protected]

Decode and send a base64-encoded string.

Parameters:
str64 Base64-encoded string
type Mime type of content (content-type header)

Definition at line 180 of file HttpdSocket.cpp.

References HTTPSocket::AddResponseHeader(), Base64::decode(), Base64::decode_length(), Utility::l2string(), m_if_modified_since, m_start, TcpSocket::SendBuf(), HTTPSocket::SendResponse(), HTTPSocket::SetStatus(), and HTTPSocket::SetStatusText().

Referenced by OnData(), and OnHeaderComplete().

00181 {
00182         Base64 bb;
00183 
00184         if (!strcasecmp(m_start.c_str(), m_if_modified_since.c_str()))
00185         {
00186                 SetStatus("304");
00187                 SetStatusText("Not Modified");
00188                 SendResponse();
00189         }
00190         else
00191         {
00192                 size_t len = bb.decode_length(str64);
00193                 unsigned char *buf = new unsigned char[len];
00194 
00195                 SetStatus("200");
00196                 SetStatusText("OK");
00197 
00198                 AddResponseHeader("Content-length", Utility::l2string( (long)len) );
00199                 AddResponseHeader("Content-type", type );
00200                 AddResponseHeader("Last-modified", m_start);
00201                 SendResponse();
00202 
00203                 bb.decode(str64, buf, len);
00204                 SendBuf( (char *)buf, len);
00205                 delete[] buf;
00206         }
00207 }

std::string HttpdSocket::datetime2httpdate ( const std::string &  dt  )  [protected]

Definition at line 210 of file HttpdSocket.cpp.

References Socket::Handler(), and ISocketHandler::LogError().

Referenced by HttpdSocket(), OnData(), and OnHeaderComplete().

00211 {
00212         struct tm tp;
00213         time_t t;
00214         const char *days[] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
00215         const char *months[] = { "Jan","Feb","Mar","Apr","May","Jun",
00216                            "Jul","Aug","Sep","Oct","Nov","Dec" };
00217         int i;
00218         char s[40];
00219 
00220 /* 1997-12-16 09:50:40 */
00221 
00222         if (dt.size() == 19) 
00223         {
00224                 tp.tm_year = atoi(dt.substr(0,4).c_str()) - 1900;
00225                 i = atoi(dt.substr(5,2).c_str()) - 1;
00226                 tp.tm_mon = i >= 0 ? i : 0;
00227                 tp.tm_mday = atoi(dt.substr(8,2).c_str());
00228                 tp.tm_hour = atoi(dt.substr(11,2).c_str());
00229                 tp.tm_min = atoi(dt.substr(14,2).c_str());
00230                 tp.tm_sec = atoi(dt.substr(17,2).c_str());
00231                 tp.tm_wday = 0;
00232                 tp.tm_yday = 0;
00233                 tp.tm_isdst = 0;
00234                 t = mktime(&tp);
00235                 if (t == -1)
00236                 {
00237                         Handler().LogError(this, "datetime2httpdate", 0, "mktime() failed");
00238                 }
00239 
00240                 snprintf(s,sizeof(s),"%s, %02d %s %d %02d:%02d:%02d GMT",
00241                  days[tp.tm_wday],
00242                  tp.tm_mday,
00243                  months[tp.tm_mon],
00244                  tp.tm_year + 1900,
00245                  tp.tm_hour,tp.tm_min,tp.tm_sec);
00246         } 
00247         else
00248         {
00249                 *s = 0;
00250         }
00251         return s;
00252 }

std::string HttpdSocket::GetDate (  )  [protected]

Definition at line 255 of file HttpdSocket.cpp.

Referenced by HttpdSocket(), OnData(), and OnHeaderComplete().

00256 {
00257         time_t t = time(NULL);
00258         char slask[40]; // yyyy-mm-dd hh:mm:ss
00259 #ifdef __CYGWIN__
00260         struct tm *tp = localtime(&t);
00261         snprintf(slask,sizeof(slask),"%d-%02d-%02d %02d:%02d:%02d",
00262                 tp -> tm_year + 1900,
00263                 tp -> tm_mon + 1,
00264                 tp -> tm_mday,
00265                 tp -> tm_hour,tp -> tm_min,tp -> tm_sec);
00266 #else
00267         struct tm tp;
00268 #if defined( _WIN32) && !defined(__CYGWIN__)
00269         localtime_s(&tp, &t);
00270 #else
00271         localtime_r(&t, &tp);
00272 #endif
00273         snprintf(slask,sizeof(slask),"%d-%02d-%02d %02d:%02d:%02d",
00274                 tp.tm_year + 1900,
00275                 tp.tm_mon + 1,
00276                 tp.tm_mday,
00277                 tp.tm_hour,tp.tm_min,tp.tm_sec);
00278 #endif
00279         return slask;
00280 }

void HttpdSocket::Reset (  )  [protected, virtual]

Reset state of socket to sucessfully implement keep-alive.

Reimplemented from HTTPSocket.

Definition at line 283 of file HttpdSocket.cpp.

References m_content_length, m_cookies, m_file, m_form, m_received, m_request_count, m_request_id, and HTTPSocket::Reset().

Referenced by OnData(), and OnHeaderComplete().

00284 {
00285         HTTPSocket::Reset();
00286         m_content_length = 0;
00287         if (m_file)
00288         {
00289                 delete m_file;
00290                 m_file = NULL;
00291         }
00292         m_received = 0;
00293         m_request_id = ++m_request_count;
00294         if (m_cookies)
00295                 delete m_cookies;
00296         m_cookies = NULL;
00297         if (m_form)
00298                 delete m_form;
00299         m_form = NULL;
00300 }

HttpdSocket& HttpdSocket::operator= ( const HttpdSocket s  )  [inline, private]

Definition at line 90 of file HttpdSocket.h.

00090 { return *this; }


Member Data Documentation

std::string HttpdSocket::m_http_cookie [protected]

Definition at line 84 of file HttpdSocket.h.

Referenced by OnHeader(), and OnHeaderComplete().

std::string HttpdSocket::m_content_type [protected]

Definition at line 85 of file HttpdSocket.h.

Referenced by OnData(), OnHeader(), and OnHeaderComplete().

std::string HttpdSocket::m_content_length_str [protected]

Definition at line 86 of file HttpdSocket.h.

Referenced by OnHeader(), and OnHeaderComplete().

std::string HttpdSocket::m_if_modified_since [protected]

Definition at line 87 of file HttpdSocket.h.

Referenced by OnHeader(), and Send64().

int HttpdSocket::m_request_count = 0 [static, private]

Definition at line 91 of file HttpdSocket.h.

Referenced by Reset().

std::string HttpdSocket::m_start = "" [static, private]

Definition at line 92 of file HttpdSocket.h.

Referenced by HttpdSocket(), and Send64().

Definition at line 93 of file HttpdSocket.h.

Referenced by OnData(), OnHeader(), and Reset().

Definition at line 94 of file HttpdSocket.h.

Referenced by OnData(), OnHeaderComplete(), Reset(), and ~HttpdSocket().

size_t HttpdSocket::m_received [private]

Definition at line 95 of file HttpdSocket.h.

Referenced by OnData(), and Reset().

Definition at line 96 of file HttpdSocket.h.

Referenced by Reset().

std::string HttpdSocket::m_http_date [private]

Definition at line 97 of file HttpdSocket.h.

Referenced by GetHttpDate(), and HttpdSocket().

Definition at line 98 of file HttpdSocket.h.

Referenced by GetCookies(), OnHeaderComplete(), Reset(), and ~HttpdSocket().

Definition at line 99 of file HttpdSocket.h.

Referenced by GetForm(), OnData(), OnHeaderComplete(), Reset(), and ~HttpdSocket().


The documentation for this class was generated from the following files:
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4