Written by Udhaya Kumar.V
20 - April - 2001
http://www.udhaya.com
Conduct Id : [email protected]
Web Server Source Code( SCO Unix )
makefile
WebServer : WebServer.o
CC -g WebServer.o -lsocket -o WebServer
strip WebServer
mcs -d WebServer
WebServer.o : WebServer.cpp WebServer.hpp WebServer.dpp
cp WebServer.cpp WebServer.C
CC -g -c WebServer.C
rm WebServer.C
WebServer.hpp
class TCPServer
{
private:
struct sockaddr_in ServerAddress;
struct sockaddr_in ClientAddress;
int Server;
int Client;
int ServerHandle;
int ServerPort;
char Data[ SIZE ],buff[ 25 ];
char FileName[30];
char FilePath[100];
char FileType[6];
int IsDirectory;
int IsExist;
int FileSize;
char Method[10];
char ContentType[50];
public:
TCPServer( int PortNo );
~TCPServer () {}
int CreateServer( void );
int ServerListen ( int BackLog );
int ServerAccept ( void );
void DataSend ( void );
void DataRecieve ( void );
private :
void GetPath ( void );
void GenerateHomePage ( void );
void SendFile ( void );
void GetFileType ( void );
void GetContentType ( void );
};
WebServer.dpp
#define DEFAULT_PATH "/usr/udhaya/WWWroot"
#define DEFAULT_FILE "Default.html"
#define HTML "html"
#define HTM "htm"
#define TEXT "txt"
#define JPG "jpg"
#define JPEG "jpeg"
#define PJPEG "pjpeg"
#define GIF "gif"
#define XBITMAP "x-xbitmap"
#define PNG "png"
#define BMP "bmp"
#define CDIR "."
#define PDIR ".."
#define SIZE 1024
WebServer.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <dirent.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "WebServer.dpp"
#include "WebServer.hpp"
TCPServer :: TCPServer( int PortNo )
{
ServerAddress.sin_family = AF_INET;
ServerAddress.sin_port = htons ( PortNo );
ServerAddress.sin_addr.s_addr = INADDR_ANY;
bzero ( &ServerAddress.sin_zero, 8 );
strcpy ( FilePath, DEFAULT_PATH );
IsDirectory = 0;
IsExist = 0;
FileSize = 0;
}
int TCPServer :: CreateServer( void )
{
if ( ( Server = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
printf ( "\nSocket Error." );
else
{
if ( bind ( Server, (struct sockaddr * ) &ServerAddress,16 )<0 )
printf ( "\nBind Error." );
}
return ( Server );
}
int TCPServer :: ServerListen ( int BackLog )
{
int Ret;
if ( ( Ret = listen ( Server, BackLog ) ) < 0 )
perror ( "Listen Error:" );
return ( Ret );
}
int TCPServer :: ServerAccept ( void )
{
if ( ( ServerHandle = accept ( Server , (struct sockaddr *) &ClientAddress, &Client ) ) < 0 )
perror ( "Accept Error :" );
return ( ServerHandle );
}
void TCPServer :: DataSend ( void )
{
char Str[ SIZE ];
char s[ SIZE ];
if ( IsExist == 1 ) /* File Is Exist */
SendFile();
else /* File Not Found */
{
char Error[ SIZE ]="<html< <body bgcolor=lightgreen><h1< Given File Not Found <p< Please Enter proper path </p< </h1< </body< </html<";
sprintf ( s, "HTTP/1.0 302 Found\nServer: NCSA/1.3\nMIME-version: 1.0\nContent-type: text/html\nContent-length: %d\nLocation: http://udhaya%s\n\n", strlen ( Error ), FileName );
write ( ServerHandle, s, strlen ( s ) );
write ( ServerHandle, Error, strlen(Error) );
write ( ServerHandle, "\n\n", strlen("\n\n") );
}
}
void TCPServer :: DataRecieve ( void )
{
memset ( Data, 0, sizeof(Data) );
if ( read ( ServerHandle, Data, sizeof ( Data ) ) <= 0 )
{
close ( Client );
exit ( 1 ) ;
}
else
GetPath();
}
void TCPServer :: GetPath ( void )
{
int i=0,j=0,Tag=0;
char Word[ SIZE ];
int Cnt=1;
struct stat FileStat;
memset ( FileName, '\0', 30 );
for ( i=0; Data[i]!='\0'; i++ )
{
Word[j]=Data[i];
j++;
if ( Data[i] == ' ' && Tag == 0 )
{
Tag=1; j=0;
Word[j]='\0';
strcpy ( Method, Word );
memset ( Word, '\0', SIZE );
}
else if ( Data[i] == ' ' && Tag == 1 )
{
Word[j]='\0';
strcpy ( FileName, Word );
for ( j=0; j<=30; j++)
{
if ( FileName[j] == ' ' )
FileName[j]='\0';
}
break;
}
}
strcpy ( FilePath, DEFAULT_PATH );
strcat ( FilePath, FileName );
/* Find File Type */
lstat( (const char * ) FilePath, &FileStat );
if ( S_ISDIR ( FileStat.st_mode ) )
{
IsDirectory = 1;
if ( strcmp ( FileName , "/" ) == 0)
strcat ( FilePath, DEFAULT_FILE );
else
{
strcat ( FilePath, "/" );
strcat ( FilePath, DEFAULT_FILE );
}
}
else
IsDirectory = 0;
/* Find File */
if ( ( access ( FilePath, F_OK ) ) < 0 )
IsExist = 0;
else
IsExist = 1;
/* Find File Size */
FileSize = ( int ) FileStat.st_size;
/* Get File type ... Only extension */
GetFileType ();
if ( IsDirectory == 1 )
IsExist = 1;
/*Generate Default.html for Directory */
if ( IsExist == 1 && IsDirectory == 1 )
{
strcpy ( FileType, HTML );
GenerateHomePage ();
}
}
void TCPServer :: GenerateHomePage ( void )
{
FILE *Fp;
char File[30];
char Fpath[100];
char Dpath[100];
DIR *dirp;
int Cnt=1;
struct dirent *dp;
struct stat FileStat;
if ( IsDirectory == 1 )
{
if ( FilePath[ strlen(FilePath) - 1 ] == '/' )
FilePath[ strlen(FilePath) - 1 ] = '\0';
strcpy ( File, FilePath );
Fp = fopen ( File, "w" );
if ( strcmp ( FileName, "/" ) == 0 )
{
fputs( "<html> <body bgcolor=lightgreen> <center> <h1> Hai Welcome to Document World... </h1> <h2> TCP/IP, UDP, Socket, RPC .....</h2> </center>", Fp );
}
else
{
fputs( "<html> <body bgcolor=lightgreen> <center> <h1> Document List .</h1> <h2> You can select any document...</h2> </center>", Fp );
}
strcpy ( Dpath, FilePath );
Dpath[ strlen ( FilePath ) - 12 ] ='\0';
dirp = opendir ( Dpath );
fputs ( "\n<table border = 1 width=100%> <tr> <TD width=75%> Document Name </TD> <TD width=25%> Document Size </TD>", Fp );
while ( ( dp = readdir ( dirp ) ) != NULL )
{
if ( ( strcmp ( dp->d_name, CDIR ) != 0 ) && ( strcmp ( dp->d_name, PDIR ) != 0 ) && ( strcmp ( dp->d_name, DEFAULT_FILE ) != 0 ) )
{
sprintf ( Fpath, "%s/%s", Dpath, dp->d_name );
lstat( (const char * ) Fpath, &FileStat );
fprintf ( Fp, "\n<TR> <TD> <a href=http://udhaya/%s> %d %s </a> </TD> <TD>%d </TD> </TR>", dp->d_name, Cnt, dp->d_name, FileStat.st_size );
Cnt++;
}
}
fputs ( "\n</table> </body> </html>", Fp );
fclose ( Fp );
lstat( (const char * ) FilePath, &FileStat );
FileSize = (int) FileStat.st_size;
}
}
void TCPServer :: SendFile ( void )
{
FILE *Fp;
int bfp;
char Str[ SIZE ];
char s[ SIZE ];
int i;
for ( i=0; i<=30; i++)
if ( FilePath[i] == ' ' )
FilePath[i]='\0';
GetContentType (); /* Gent The content type value */
if ( strcmp ( FileType, GIF ) == 0 || strcmp ( FileType, XBITMAP ) == 0 || strcmp ( FileType, JPEG ) == 0 || strcmp ( FileType, PJPEG ) == 0 || strcmp ( FileType, PNG ) == 0 || strcmp ( FileType, BMP ) == 0 || strcmp ( FileType, JPG ) == 0 )
{
long Dat;
bfp = open ( FilePath, O_RDONLY );
sprintf ( s, "HTTP/1.0 302 Found\nServer: NCSA/1.3\nMIME-version: 1.0\nContent-type: %s\nContent-length: %Ld\nLocation: http://udhaya%s\n\n", ContentType, FileSize, FileName );
write ( ServerHandle, s, strlen ( s ) );
while ( read ( bfp, &Dat, SIZE) )
{
if ( write ( ServerHandle, &Dat, SIZE ) < 0 )
perror ( "Error Write :" );
}
close ( bfp );
write ( ServerHandle, "\n\n", strlen("\n\n") );
}
else
{
Fp = fopen ( FilePath, "r" );
sprintf ( s, "HTTP/1.0 302 Found\nServer: NCSA/1.3\nMIME-version: 1.0\nContent-type: %s\nContent-length: %Ld\nLocation: http://udhaya%s\n\n", ContentType, FileSize, FileName );
write ( ServerHandle, s, strlen ( s ) );
while ( !feof(Fp) )
{
fgets ( Str, SIZE, Fp );
if ( write ( ServerHandle, Str, strlen(Str) ) < 0 )
perror ( "Error Write :" );
}
write ( ServerHandle, "\n\n", strlen("\n\n") );
fclose ( Fp );
}
}
void TCPServer :: GetFileType ( void )
{
int i,j=0,Tag=0;
memset ( FileType, '\0', 8 );
if ( strlen ( FileName ) > 1 )
{
for ( i=0; FileName[i]!='\0'; i++ )
{
if ( Tag == 1 )
{
FileType[j]=FileName[i];
j++;
}
if ( FileName[i] == '.' )
Tag=1;
}
FileType[j]='\0';
if ( strlen ( FileType ) == 0 )
strcpy ( FileType, HTML );
for ( i=0; FileType[i] != '\0'; i++ )
FileType[i] = tolower ( FileType[i] );
if ( strcmp ( FileType, HTM ) == 0 )
strcpy ( FileType, HTML );
}
}
void TCPServer :: GetContentType ( void )
{
if ( strcmp ( FileType, HTML ) == 0 || strcmp ( FileType, HTM ) == 0 )
strcpy ( ContentType, "text/html" );
else if ( strcmp ( FileType, TEXT ) == 0 )
strcpy ( ContentType, "text/plain" );
else if ( strcmp ( FileType, JPG ) == 0 )
strcpy ( ContentType, "image/jpeg" );
else if ( strcmp ( FileType, GIF ) == 0 || strcmp ( FileType, XBITMAP ) == 0 || strcmp ( FileType, JPEG ) == 0 || strcmp ( FileType, PJPEG ) == 0 || strcmp ( FileType, PNG ) == 0 || strcmp ( FileType, BMP ) == 0 )
{
strcpy ( ContentType, "image/" );
strcat ( ContentType, FileType );
}
else
strcpy ( ContentType, "text/plain" );
}
main ()
{
char *Str;
int SHandle;
int Cid;
TCPServer *Server = new TCPServer ( 80 );
Server->CreateServer ();
Server->ServerListen( 5 );
while ( 1 )
{
Str = ( char * ) malloc ( SIZE );
SHandle = Server->ServerAccept ();
Cid = fork ();
if ( Cid == 0 )
{
Server->DataRecieve ();
Server->DataSend ();
close ( SHandle );
_exit ( 0 );
}
}
}