#include #include #include #include #include #include #include #include #include #include "websvc.h" using namespace std; const unsigned short PORT = 6021; const char GET[] = "GET"; const char OKAY[] = "200 OKAY\r\nServer: \r\nContent-type: text/plain\r\n\r\n"; const char NOT_FOUND[] = "404 NOT FOUND\r\nServer: \r\nContent-type: text/html\r\n\r\n"; const char INTERNAL[] = "500 INTERNAL SERVER ERROR\r\nServer: \r\nContent-type: text/plain\r\n\r\n"; const char NOT_SUPPORTED[] = "501 NOT IMPLEMENTED\r\nServer: \r\nContent-type: text/plain\r\n\r\n"; int main() { int service, session; struct sockaddr_in clientAddress; socklen_t clientAddressLength = sizeof( clientAddress ); unsigned int clientIpAddress; unsigned short clientPort; struct sockaddr_in serverAddress; char buffer[512]; int filled; stringstream messageBuffer; // create socket listener if( (service = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) { perror( "listener creation fail" ); exit(1); } // setup the listen socket (specific port) serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(PORT); serverAddress.sin_addr.s_addr = 0; // try to bind the socket to the listener so it can listen for connections if( bind(service, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0 ) { perror( "bind error" ); exit(1); } // start listening if( listen( service, 1 ) < 0 ) { perror( "couldnt listen" ); exit(1); } printf( "Listening....\n" ); while(true) { session = accept( service, (struct sockaddr *)&clientAddress, &clientAddressLength ); if( session < 0 ) { perror( "couldnt accept the connection" ); exit(1); } // obtain client's ip address (converted to proper byte order) clientIpAddress = ntohl( clientAddress.sin_addr.s_addr ); clientPort = ntohs( clientAddress.sin_port ); printf( "Connection request from %x:%d\n", clientIpAddress, clientPort); filled = read( session, buffer, sizeof( buffer ) - 1 ); // still stuff to read while( filled > 0 ) { buffer[filled] = '\0'; messageBuffer << buffer; filled = read( session, buffer, sizeof( buffer) - 1 ); } string message = messageBuffer.str(); string command = message.substr(0, message.find(" ")); if( command != string(GET) ) { // got some other command, write a 501 // continue listening write( session, NOT_SUPPORTED, sizeof(NOT_SUPPORTED) - 1 ); close( session ); continue; } string filepath = message.substr(message.find("/") + 1, message.rfind(" ")); // clean up the filepath clean(filepath); // attempt to open the file and send it string data; ifstream in; in.open(filepath, ios::in); if(!in) { // file couldnt be opened, send back an internal error // continue listening write(session, INTERNAL, sizeof(INTERNAL) - 1); close(session); continue; } string line; write(session, OKAY, sizeof(OKAY) - 1); while( in.getline(line), in.good() != 0 ) { // respond with an okay message and write the data write(session, line.c_str(), sizeof(line) - 1); } close(session); } } void clean(string &path) { string temp = ""; for(int i = 0; i < path.length(); i++) { if(path[i] == '%') { char hex1 = path[i+1]; char hex2 = path[i+2]; char convert[] = {'0','x',hex1,hex2,'\0'}; temp += (char)(strtol(convert, (char **)0, 16)); i+=2; } else { temp += path[i]; } } path = temp; }