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 47 of file HttpdSocket.h.


Constructor & Destructor Documentation

HttpdSocket::HttpdSocket ( ISocketHandler h  ) 

Definition at line 51 of file HttpdSocket.cpp.

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

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

HttpdSocket::~HttpdSocket (  ) 

Definition at line 66 of file HttpdSocket.cpp.

References m_cookies, m_file, and m_form.

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

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

Definition at line 73 of file HttpdSocket.h.

00073 : 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 79 of file HttpdSocket.cpp.

00080 {
00081 }

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 84 of file HttpdSocket.cpp.

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

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

void HttpdSocket::OnHeaderComplete (  )  [virtual]

Callback fires when all http headers have been received.

Implements HTTPSocket.

Definition at line 109 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().

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

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

Chunk of http body data recevied.

Implements HTTPSocket.

Definition at line 151 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().

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

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 293 of file HttpdSocket.cpp.

References m_http_date.

Referenced by OnHeaderComplete().

00294 {
00295         return m_http_date; 
00296 }

HttpdCookies * HttpdSocket::GetCookies (  ) 

Get pointer to cookie class.

Definition at line 299 of file HttpdSocket.cpp.

References m_cookies.

00300 {
00301         return m_cookies; 
00302 }

const HttpdForm * HttpdSocket::GetForm (  )  const

Get pointer to query string/form data class.

Definition at line 305 of file HttpdSocket.cpp.

References m_form.

00306 {
00307         return m_form; 
00308 }

size_t HttpdSocket::ContentLength (  )  const [inline]

Definition at line 68 of file HttpdSocket.h.

00068 { return m_content_length; }

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

Definition at line 69 of file HttpdSocket.h.

00069 { return m_file; }

int HttpdSocket::RequestId (  )  const [inline]

Definition at line 70 of file HttpdSocket.h.

00070 { 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 179 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().

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

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

Definition at line 209 of file HttpdSocket.cpp.

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

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

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

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

Definition at line 254 of file HttpdSocket.cpp.

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

00255 {
00256         time_t t = time(NULL);
00257         struct tm tp;
00258 #ifdef _WIN32
00259         memcpy(&tp, localtime(&t), sizeof(tp));
00260 #else
00261         localtime_r(&t, &tp);
00262 #endif
00263         char slask[40]; // yyyy-mm-dd hh:mm:ss
00264         sprintf(slask,"%d-%02d-%02d %02d:%02d:%02d",
00265                 tp.tm_year + 1900,
00266                 tp.tm_mon + 1,
00267                 tp.tm_mday,
00268                 tp.tm_hour,tp.tm_min,tp.tm_sec);
00269         return slask;
00270 }

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

Reset state of socket to sucessfully implement keep-alive.

Reimplemented from HTTPSocket.

Definition at line 273 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().

00274 {
00275         HTTPSocket::Reset();
00276         m_content_length = 0;
00277         if (m_file)
00278         {
00279                 delete m_file;
00280                 m_file = NULL;
00281         }
00282         m_received = 0;
00283         m_request_id = ++m_request_count;
00284         if (m_cookies)
00285                 delete m_cookies;
00286         m_cookies = NULL;
00287         if (m_form)
00288                 delete m_form;
00289         m_form = NULL;
00290 }

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

Definition at line 88 of file HttpdSocket.h.

00088 { return *this; }


Member Data Documentation

std::string HttpdSocket::m_http_cookie [protected]

Definition at line 82 of file HttpdSocket.h.

Referenced by OnHeader(), and OnHeaderComplete().

std::string HttpdSocket::m_content_type [protected]

Definition at line 83 of file HttpdSocket.h.

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

std::string HttpdSocket::m_content_length_str [protected]

Definition at line 84 of file HttpdSocket.h.

Referenced by OnHeader(), and OnHeaderComplete().

std::string HttpdSocket::m_if_modified_since [protected]

Definition at line 85 of file HttpdSocket.h.

Referenced by OnHeader(), and Send64().

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

Definition at line 89 of file HttpdSocket.h.

Referenced by Reset().

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

Definition at line 90 of file HttpdSocket.h.

Referenced by HttpdSocket(), and Send64().

Definition at line 91 of file HttpdSocket.h.

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

Definition at line 92 of file HttpdSocket.h.

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

size_t HttpdSocket::m_received [private]

Definition at line 93 of file HttpdSocket.h.

Referenced by OnData(), and Reset().

Definition at line 94 of file HttpdSocket.h.

Referenced by Reset().

std::string HttpdSocket::m_http_date [private]

Definition at line 95 of file HttpdSocket.h.

Referenced by GetHttpDate(), and HttpdSocket().

Definition at line 96 of file HttpdSocket.h.

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

Definition at line 97 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