@ -12,6 +12,7 @@ WebServerClient::WebServerClient () {
ssl = NULL ;
ssl = NULL ;
ssl_key = " " ;
ssl_key = " " ;
ssl_cert = " " ;
ssl_cert = " " ;
callback_request = NULL ;
} ;
} ;
@ -62,9 +63,9 @@ int WebServerClient::Accept (TCP *socket) {
/// @brief Read data from the network and check if the request is complete
/// @brief Read data from the network fill in the buffer. The Request must be handled from the server
/// @return -1 on error, 0 no data , 1 request complete
/// @return 0 no data , 1 request complete
int WebServerClient : : Loop ( ) {
WebRequestBuffer * WebServerClient : : Loop ( ) {
int len ;
int len ;
if ( ssl ) {
if ( ssl ) {
@ -73,28 +74,10 @@ int WebServerClient::Loop () {
else {
else {
len = tcp - > ReadTimeout ( buffer , WEB_READ_BUFFER_SIZE , 20 ) ;
len = tcp - > ReadTimeout ( buffer , WEB_READ_BUFFER_SIZE , 20 ) ;
}
}
if ( len < 0 ) return - 1 ;
if ( len < 0 ) return NULL ;
if ( len = = 0 ) return 0 ;
if ( len = = 0 ) return & ReqBuffer ;
ReqBuffer . AddBuffer ( buffer , len ) ;
ReqBuffer . AddBuffer ( buffer , len ) ;
if ( ReqBuffer . RequestComplete ( ) ) {
return & ReqBuffer ;
HandleRequest ( ) ;
return 1 ;
}
return 0 ;
} ;
int WebServerClient : : HandleRequest ( ) {
std : : string request = ReqBuffer . GetRequest ( ) ;
printf ( " WebServerClient::HandleRequest() Request:%s \n " , request . c_str ( ) ) ;
if ( request . compare ( " / " ) = = 0 ) request = " /index.html " ;
SendResponseFile ( & ReqBuffer , request , " " ) ;
ReqBuffer . Clear ( ) ;
return 1 ;
} ;
} ;
@ -203,8 +186,53 @@ std::string WebServerClient::GetFileType (std::string fname) {
if ( suffix . compare ( " .jpeg " ) = = 0 ) return " image/jpeg " ;
if ( suffix . compare ( " .jpeg " ) = = 0 ) return " image/jpeg " ;
return res ;
return res ;
} ;
int WebServerClient : : SendResponseFileFromMemory ( WebRequestBuffer * request , std : : string fname , std : : string addheader ,
void * memptr , int memsize ) {
char * outbuffer = NULL ;
int outbufferpos = 0 ;
int error = 200 ;
long int l ;
std : : string filetype = " text/html;charset=utf-8 " ;
std : : string header ;
struct stat filestat ;
int filefd ;
ssize_t bytestosend ;
//
// determine file type and size
filetype = GetFileType ( fname ) ;
//
// send header and file
header = CreateHeader ( request , error , filetype , memsize , addheader ) ;
outbufferpos = header . length ( ) ;
outbuffer = ( char * ) malloc ( outbufferpos + memsize + 1 ) ;
memcpy ( outbuffer , header . c_str ( ) , outbufferpos ) ;
//
// append data to send
memcpy ( outbuffer + outbufferpos , memptr , memsize ) ;
bytestosend = outbufferpos + memsize ;
if ( ssl ) l = ssl - > Write ( outbuffer , bytestosend ) ;
else l = tcp - > Write ( outbuffer , bytestosend ) ;
// debug ("send file %s with %ld bytes\n", fname.c_str(), filereadbytes);
if ( l ! = bytestosend ) {
debug ( " could not send all data. Error:%s \n " , strerror ( errno ) ) ;
free ( outbuffer ) ;
return 0 ;
}
}
free ( outbuffer ) ;
return 1 ;
} ;
/// @brief send a file as response
/// @brief send a file as response
@ -283,7 +311,7 @@ int WebServerClient::SendResponseFile (WebRequestBuffer *request, std::string fn
free ( outbuffer ) ;
free ( outbuffer ) ;
return 1 ;
return 1 ;
}
} ;
std : : string WebServerClient : : Get_WebFile_FullPath ( std : : string file ) {
std : : string WebServerClient : : Get_WebFile_FullPath ( std : : string file ) {
@ -302,3 +330,183 @@ std::string WebServerClient::Get_WebFile_FullPath(std::string file) {
return ret ;
return ret ;
} ;
} ;
WebServer : : WebServer ( ) {
running = 0 ;
conf_maxclients = 10 ;
conf_httpport = 8080 ;
conf_httpsport = 8081 ;
conf_docroot = " ./www " ;
conf_sslcert = " ./cert.pem " ;
conf_sslkey = " ./privkey.pem " ;
} ;
WebServer : : ~ WebServer ( ) {
Stop ( ) ;
} ;
/// @brief Setup new ports. Restart needed.
/// @param httpport
/// @param httpsport
/// @return
int WebServer : : SetupPorts ( int httpport , int httpsport ) {
int wasrunning = running ;
if ( wasrunning ) Stop ( ) ;
conf_httpport = httpport ;
conf_httpsport = httpsport ;
if ( wasrunning ) Start ( ) ;
return 1 ;
} ;
/// @brief Setup document root. Restart needed.
/// @param httpport
/// @param httpsport
/// @return
int WebServer : : SetupDocumentRoot ( std : : string docroot ) {
int wasrunning = running ;
if ( wasrunning ) Stop ( ) ;
conf_docroot = docroot ;
if ( wasrunning ) Start ( ) ;
return 1 ;
} ;
/// @brief Setup SSL key and SSL certificate. Reconnect needed
/// @param sslkeyfile
/// @param sslcertfile
/// @return
int WebServer : : SetupSSL ( std : : string sslkeyfile , std : : string sslcertfile ) {
conf_sslkey = sslkeyfile ;
conf_sslcert = sslcertfile ;
return 1 ;
} ;
int WebServer : : Start ( ) {
if ( http . Listen ( conf_httpport ) ! = 1 ) {
printf ( " error on listen \n " ) ;
return 0 ;
}
printf ( " test server is running on port: %d \n " , conf_httpport ) ;
if ( https . Listen ( conf_httpsport ) ! = 1 ) {
printf ( " error on listen \n " ) ;
return 0 ;
}
printf ( " test server is running on port: %d \n " , conf_httpsport ) ;
running = 1 ;
return 1 ;
} ;
int WebServer : : Stop ( ) {
http . Close ( ) ;
https . Close ( ) ;
list < WebServerClient * > : : iterator wci ;
for ( wci = webclients . begin ( ) ; wci ! = webclients . end ( ) ; wci + + ) {
delete ( WebServerClient * ) * wci ;
webclients . remove ( * wci ) ;
wci = webclients . begin ( ) ;
if ( wci = = webclients . end ( ) ) continue ;
}
return 1 ;
} ;
/// @brief Checks for new connections and for data on any connected webclient
/// @return -2 client could not connect, -1 on max connections, 0 on error, 1 no error
int WebServer : : Loop ( ) {
list < WebServerClient * > : : iterator wci ;
WebServerClient * webclient ;
TCP * tcpclient = NULL ;
int ssl_enabled = 1 ;
int res ;
//
// any new connection?
if ( ( tcpclient = https . Accept ( ) ) = = NULL ) {
ssl_enabled = 0 ;
tcpclient = http . Accept ( ) ;
}
if ( tcpclient ) {
printf ( " new %s connection from %s \n " , ssl_enabled ? " HTTPS " : " HTTP " , tcpclient - > GetRemoteAddr ( ) . c_str ( ) ) ;
if ( webclients . size ( ) > conf_maxclients ) {
printf ( " max connections reached. closing connection. \n " ) ;
tcpclient - > Close ( ) ;
delete tcpclient ;
return - 1 ;
}
webclient = new WebServerClient ( ) ;
if ( ssl_enabled ) res = webclient - > Accept ( tcpclient , conf_sslkey , conf_sslcert ) ;
else res = webclient - > Accept ( tcpclient ) ;
if ( res = = 0 ) {
printf ( " webclient could not connect. closing connection \n " ) ;
delete webclient ;
delete tcpclient ;
return - 2 ;
}
webclient - > SetDecoumentRoot ( " ./www " ) ;
webclients . push_back ( webclient ) ;
printf ( " add new connection to client list \n " ) ;
}
//
// go through all the clients and check for new requests
for ( wci = webclients . begin ( ) ; wci ! = webclients . end ( ) ; wci + + ) {
WebRequestBuffer * reqbuffer = NULL ;
webclient = * wci ;
reqbuffer = webclient - > Loop ( ) ;
if ( reqbuffer = = NULL ) {
// error on loop, remove and delete webclient.
printf ( " remove connection \n " ) ;
webclients . remove ( webclient ) ;
delete webclient ;
wci = webclients . begin ( ) ;
if ( wci = = webclients . end ( ) ) continue ;
}
else if ( reqbuffer - > RequestComplete ( ) ) {
if ( HandleRequest ( reqbuffer , * wci ) = = 1 ) continue ;
// error handling request, remove and delete webclient.
printf ( " remove connection \n " ) ;
webclients . remove ( webclient ) ;
delete webclient ;
wci = webclients . begin ( ) ;
if ( wci = = webclients . end ( ) ) continue ;
}
}
return 1 ;
} ;
int WebServer : : HandleRequest ( WebRequestBuffer * requestbuffer , WebServerClient * webclient ) {
if ( requestbuffer = = NULL | | webclient = = NULL ) return 0 ;
std : : string request = requestbuffer - > GetRequest ( ) ;
printf ( " WebServerClient::HandleRequest() Request:%s \n " , request . c_str ( ) ) ;
if ( request . compare ( " / " ) = = 0 ) request = " /index.html " ;
if ( webclient - > SendResponseFile ( requestbuffer , request , " " ) ! = 1 ) return 0 ;
requestbuffer - > Clear ( ) ;
return 1 ;
} ;