The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download | Blog | Stats
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

HttpServerSocket Class Reference

A socket used for HTTP transport. More...

Inheritance diagram for HttpServerSocket:

Inheritance graph
[legend]
Collaboration diagram for HttpServerSocket:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 HttpServerSocket (InspIRCd *SI, std::string host, int port, bool listening, unsigned long maxtime, FileReader *index_page)
 HttpServerSocket (InspIRCd *SI, int newfd, char *ip, FileReader *ind)
FileReaderGetIndex ()
 ~HttpServerSocket ()
virtual int OnIncomingConnection (int newsock, char *ip)
 If your socket is a listening socket, when a new connection comes in on the socket this method will be called.
virtual void OnClose ()
 Whenever close() is called, OnClose() will be called first.
std::string Response (int response)
void SendHeaders (unsigned long size, int response, const std::string &extraheaders)
virtual bool OnDataReady ()
 When there is data waiting to be read on a socket, the OnDataReady() method is called.
void ServeData ()
void Page (std::stringstream *n, int response, std::string &extraheaders)
void SetWrite ()
bool OnWriteReady ()
 When it is ok to write to the socket, and a write event was requested, this method is triggered.

Private Attributes

FileReaderindex
HttpState InternalState
std::stringstream headers
std::string postdata
std::string request_type
std::string uri
std::string http_version
unsigned int postsize

Detailed Description

A socket used for HTTP transport.

Definition at line 38 of file m_httpd.cpp.


Constructor & Destructor Documentation

HttpServerSocket::HttpServerSocket InspIRCd SI,
std::string  host,
int  port,
bool  listening,
unsigned long  maxtime,
FileReader index_page
[inline]
 

Definition at line 51 of file m_httpd.cpp.

References HTTP_LISTEN, and InternalState.

Referenced by OnIncomingConnection().

00051                                                                                                                                 : InspSocket(SI, host, port, listening, maxtime), index(index_page), postsize(0)
00052         {
00053                 InternalState = HTTP_LISTEN;
00054         }

HttpServerSocket::HttpServerSocket InspIRCd SI,
int  newfd,
char *  ip,
FileReader ind
[inline]
 

Definition at line 56 of file m_httpd.cpp.

References HTTP_SERVE_WAIT_REQUEST, and InternalState.

00056                                                                              : InspSocket(SI, newfd, ip), index(ind), postsize(0)
00057         {
00058                 InternalState = HTTP_SERVE_WAIT_REQUEST;
00059         }

HttpServerSocket::~HttpServerSocket  )  [inline]
 

Definition at line 66 of file m_httpd.cpp.

00067         {
00068         }


Member Function Documentation

FileReader* HttpServerSocket::GetIndex  )  [inline]
 

Definition at line 61 of file m_httpd.cpp.

References index.

00062         {
00063                 return index;
00064         }

virtual void HttpServerSocket::OnClose  )  [inline, virtual]
 

Whenever close() is called, OnClose() will be called first.

Please note that this means OnClose will be called alongside OnError(), OnTimeout(), and Close(), and also when cancelling a listening socket by calling the destructor indirectly.

Reimplemented from InspSocket.

Definition at line 79 of file m_httpd.cpp.

00080         {
00081         }

virtual bool HttpServerSocket::OnDataReady  )  [inline, virtual]
 

When there is data waiting to be read on a socket, the OnDataReady() method is called.

Within this method, you *MUST* call the Read() method to read any pending data. At its lowest level, this event is signalled by the core via the socket engine. If you return false from this function, the core removes your socket from its list and erases it from the socket engine, then calls InspSocket::Close() and deletes it.

Returns:
false to close the socket

Reimplemented from InspSocket.

Definition at line 193 of file m_httpd.cpp.

References headers, HTTP_SERVE_RECV_POSTDATA, HTTP_SERVE_SEND_DATA, HTTP_SERVE_WAIT_REQUEST, http_version, InternalState, postdata, postsize, InspSocket::Read(), request_type, SendHeaders(), ServeData(), SetWrite(), and uri.

00194         {
00195                 char* data = this->Read();
00196 
00197                 /* Check that the data read is a valid pointer and it has some content */
00198                 if (data && *data)
00199                 {
00200                         headers << data;
00201 
00202                         if (headers.str().find("\r\n\r\n") != std::string::npos)
00203                         {
00204                                 if (request_type.empty())
00205                                 {
00206                                         headers >> request_type;
00207                                         headers >> uri;
00208                                         headers >> http_version;
00209 
00210                                         std::transform(request_type.begin(), request_type.end(), request_type.begin(), ::toupper);
00211                                         std::transform(http_version.begin(), http_version.end(), http_version.begin(), ::toupper);
00212                                 }
00213 
00214                                 if ((InternalState == HTTP_SERVE_WAIT_REQUEST) && (request_type == "POST"))
00215                                 {
00216                                         /* Do we need to fetch postdata? */
00217                                         postdata.clear();
00218                                         InternalState = HTTP_SERVE_RECV_POSTDATA;
00219                                         std::string header_item;
00220                                         while (headers >> header_item)
00221                                         {
00222                                                 if (header_item == "Content-Length:")
00223                                                 {
00224                                                         headers >> header_item;
00225                                                         postsize = atoi(header_item.c_str());
00226                                                 }
00227                                         }
00228                                         if (!postsize)
00229                                         {
00230                                                 InternalState = HTTP_SERVE_SEND_DATA;
00231                                                 SendHeaders(0, 400, "");
00232                                                 SetWrite();
00233                                         }
00234                                         else
00235                                         {
00236                                                 std::string::size_type x = headers.str().find("\r\n\r\n");
00237                                                 postdata = headers.str().substr(x+4, headers.str().length());
00238                                                 /* Get content length and store */
00239                                                 if (postdata.length() >= postsize)
00240                                                         ServeData();
00241                                         }
00242                                 }
00243                                 else if (InternalState == HTTP_SERVE_RECV_POSTDATA)
00244                                 {
00245                                         /* Add postdata, once we have it all, send the event */
00246                                         postdata.append(data);
00247                                         if (postdata.length() >= postsize)
00248                                                 ServeData();
00249                                 }
00250                                 else
00251                                 {
00252                                         ServeData();
00253                                 }
00254                                 return true;
00255                         }
00256                         return true;
00257                 }
00258                 else
00259                 {
00260                         return false;
00261                 }
00262         }

virtual int HttpServerSocket::OnIncomingConnection int  newsock,
char *  ip
[inline, virtual]
 

If your socket is a listening socket, when a new connection comes in on the socket this method will be called.

Given the new file descriptor in the parameters, and the IP, it is recommended you copy them to a new instance of your socket class, e.g.:

MySocket* newsocket = new MySocket(newfd,ip);

Once you have done this, you can then associate the new socket with the core using Server::AddSocket().

Reimplemented from InspSocket.

Definition at line 70 of file m_httpd.cpp.

References HTTP_LISTEN, HttpServerSocket(), index, and InternalState.

00071         {
00072                 if (InternalState == HTTP_LISTEN)
00073                 {
00074                         new HttpServerSocket(this->Instance, newsock, ip, index);
00075                 }
00076                 return true;
00077         }

bool HttpServerSocket::OnWriteReady  )  [inline, virtual]
 

When it is ok to write to the socket, and a write event was requested, this method is triggered.

Within this method you should call write() or send() etc, to send data to the other end of the socket. Further write events will not be triggered unless you call WantWrite().

Returns:
false to close the socket

Reimplemented from InspSocket.

Definition at line 312 of file m_httpd.cpp.

00313         {
00314                 return false;
00315         }

void HttpServerSocket::Page std::stringstream *  n,
int  response,
std::string extraheaders
[inline]
 

Definition at line 298 of file m_httpd.cpp.

References InspSocket::FlushWriteBuffer(), SendHeaders(), SetWrite(), and InspSocket::Write().

Referenced by ModuleHttpServer::OnRequest().

00299         {
00300                 SendHeaders(n->str().length(), response, extraheaders);
00301                 this->Write(n->str());
00302                 this->FlushWriteBuffer();
00303                 SetWrite();
00304         }

std::string HttpServerSocket::Response int  response  )  [inline]
 

Definition at line 83 of file m_httpd.cpp.

Referenced by SendHeaders().

00084         {
00085                 switch (response)
00086                 {
00087                         case 100:
00088                                 return "CONTINUE";
00089                         case 101:
00090                                 return "SWITCHING PROTOCOLS";
00091                         case 200:
00092                                 return "OK";
00093                         case 201:
00094                                 return "CREATED";
00095                         case 202:
00096                                 return "ACCEPTED";
00097                         case 203:
00098                                 return "NON-AUTHORITATIVE INFORMATION";
00099                         case 204:
00100                                 return "NO CONTENT";
00101                         case 205:
00102                                 return "RESET CONTENT";
00103                         case 206:
00104                                 return "PARTIAL CONTENT";
00105                         case 300:
00106                                 return "MULTIPLE CHOICES";
00107                         case 301:
00108                                 return "MOVED PERMENANTLY";
00109                         case 302:
00110                                 return "FOUND";
00111                         case 303:
00112                                 return "SEE OTHER";
00113                         case 304:
00114                                 return "NOT MODIFIED";
00115                         case 305:
00116                                 return "USE PROXY";
00117                         case 307:
00118                                 return "TEMPORARY REDIRECT";
00119                         case 400:
00120                                 return "BAD REQUEST";
00121                         case 401:
00122                                 return "UNAUTHORIZED";
00123                         case 402:
00124                                 return "PAYMENT REQUIRED";
00125                         case 403:
00126                                 return "FORBIDDEN";
00127                         case 404:
00128                                 return "NOT FOUND";
00129                         case 405:
00130                                 return "METHOD NOT ALLOWED";
00131                         case 406:
00132                                 return "NOT ACCEPTABLE";
00133                         case 407:
00134                                 return "PROXY AUTHENTICATION REQUIRED";
00135                         case 408:
00136                                 return "REQUEST TIMEOUT";
00137                         case 409:
00138                                 return "CONFLICT";
00139                         case 410:
00140                                 return "GONE";
00141                         case 411:
00142                                 return "LENGTH REQUIRED";
00143                         case 412:
00144                                 return "PRECONDITION FAILED";
00145                         case 413:
00146                                 return "REQUEST ENTITY TOO LARGE";
00147                         case 414:
00148                                 return "REQUEST-URI TOO LONG";
00149                         case 415:
00150                                 return "UNSUPPORTED MEDIA TYPE";
00151                         case 416:
00152                                 return "REQUESTED RANGE NOT SATISFIABLE";
00153                         case 417:
00154                                 return "EXPECTATION FAILED";
00155                         case 500:
00156                                 return "INTERNAL SERVER ERROR";
00157                         case 501:
00158                                 return "NOT IMPLEMENTED";
00159                         case 502:
00160                                 return "BAD GATEWAY";
00161                         case 503:
00162                                 return "SERVICE UNAVAILABLE";
00163                         case 504:
00164                                 return "GATEWAY TIMEOUT";
00165                         case 505:
00166                                 return "HTTP VERSION NOT SUPPORTED";
00167                         default:
00168                                 return "WTF";
00169                         break;
00170                                 
00171                 }
00172         }

void HttpServerSocket::SendHeaders unsigned long  size,
int  response,
const std::string extraheaders
[inline]
 

Definition at line 174 of file m_httpd.cpp.

References ConvToStr(), InspSocket::FlushWriteBuffer(), InspSocket::Instance, Response(), InspIRCd::Time(), and InspSocket::Write().

Referenced by OnDataReady(), Page(), and ServeData().

00175         {
00176                 time_t local = this->Instance->Time();
00177                 struct tm *timeinfo = gmtime(&local);
00178                 this->Write("HTTP/1.1 "+ConvToStr(response)+" "+Response(response)+"\r\nDate: ");
00179                 this->Write(asctime(timeinfo));
00180                 if (extraheaders.empty())
00181                 {
00182                         this->Write("Content-Type: text/html\r\n");
00183                 }
00184                 else
00185                 {
00186                         this->Write(extraheaders);
00187                 }
00188                 this->Write("Server: InspIRCd/m_httpd.so/1.1\r\nContent-Length: "+ConvToStr(size)+
00189                                 "\r\nConnection: close\r\n\r\n");
00190                 this->FlushWriteBuffer();
00191         }

void HttpServerSocket::ServeData  )  [inline]
 

Definition at line 264 of file m_httpd.cpp.

References claimed, FileReader::Contents(), FileReader::ContentSize(), InspSocket::FlushWriteBuffer(), headers, HTTP_SERVE_SEND_DATA, http_version, index, InternalState, postdata, request_type, Event::Send(), SendHeaders(), SetWrite(), uri, and InspSocket::Write().

Referenced by OnDataReady().

00265         {
00266                 /* Headers are complete */
00267                 InternalState = HTTP_SERVE_SEND_DATA;
00268         
00269                 if ((http_version != "HTTP/1.1") && (http_version != "HTTP/1.0"))
00270                 {
00271                         SendHeaders(0, 505, "");
00272                         SetWrite();
00273                 }
00274                 else
00275                 {
00276                         if ((request_type == "GET") && (uri == "/"))
00277                         {
00278                                 SendHeaders(index->ContentSize(), 200, "");
00279                                 this->Write(index->Contents());
00280                                 this->FlushWriteBuffer();
00281                                 SetWrite();
00282                         }
00283                         else
00284                         {
00285                                 claimed = false;
00286                                 HTTPRequest httpr(request_type,uri,&headers,this,this->GetIP(),postdata);
00287                                 Event e((char*)&httpr, (Module*)HttpModule, "httpd_url");
00288                                 e.Send(this->Instance);
00289                                 if (!claimed)
00290                                 {
00291                                         SendHeaders(0, 404, "");
00292                                         SetWrite();
00293                                 }
00294                         }
00295                 }
00296         }

void HttpServerSocket::SetWrite  )  [inline]
 

Definition at line 306 of file m_httpd.cpp.

References InspSocket::Instance, InspIRCd::SE, InspSocket::WaitingForWriteEvent, and SocketEngine::WantWrite().

Referenced by OnDataReady(), Page(), and ServeData().

00307         {
00308                 this->WaitingForWriteEvent = true;
00309                 Instance->SE->WantWrite(this);
00310         }


Member Data Documentation

std::stringstream HttpServerSocket::headers [private]
 

Definition at line 42 of file m_httpd.cpp.

Referenced by OnDataReady(), and ServeData().

std::string HttpServerSocket::http_version [private]
 

Definition at line 46 of file m_httpd.cpp.

Referenced by OnDataReady(), and ServeData().

FileReader* HttpServerSocket::index [private]
 

Definition at line 40 of file m_httpd.cpp.

Referenced by GetIndex(), OnIncomingConnection(), and ServeData().

HttpState HttpServerSocket::InternalState [private]
 

Definition at line 41 of file m_httpd.cpp.

Referenced by HttpServerSocket(), OnDataReady(), OnIncomingConnection(), and ServeData().

std::string HttpServerSocket::postdata [private]
 

Definition at line 43 of file m_httpd.cpp.

Referenced by OnDataReady(), and ServeData().

unsigned int HttpServerSocket::postsize [private]
 

Definition at line 47 of file m_httpd.cpp.

Referenced by OnDataReady().

std::string HttpServerSocket::request_type [private]
 

Definition at line 44 of file m_httpd.cpp.

Referenced by OnDataReady(), and ServeData().

std::string HttpServerSocket::uri [private]
 

Definition at line 45 of file m_httpd.cpp.

Referenced by OnDataReady(), and ServeData().


The documentation for this class was generated from the following file: