/Server.cc
C++ | 278 lines | 201 code | 77 blank | 0 comment | 38 complexity | a2b970d1b55a47e52239daed9702b4bc MD5 | raw file
- #include "Server.h"
- Server::Server(char* rootPath, int Port)
- {
- rootDir = rootPath;
- port = Port;
- }
- int Server::Start()
- {
- struct sockaddr_in serv_addr;
- listenSocket = socket(AF_INET, SOCK_STREAM, 0);
- if (listenSocket < 0)
- {
- std::cout << "Failed to create socket!!\n";
- return -1;
- }
- memset(&serv_addr, 0x00, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(port);
- if (bind(listenSocket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
- {
- std::cout << "could not bind socket!\n";
- return -1;
- }
- listen(listenSocket, 5);
- isAlive = true;
- pthread_create(&serverThreadHandle, NULL, ServerThread, this);
- return 0;
- }
- void* Server::ServerThread(void* classPtr)
- {
- Server* s = reinterpret_cast<Server*>(classPtr);
- while(s->isAlive)
- {
- s->clientSocket = accept(s->listenSocket, NULL, NULL);
- if (s->clientSocket < 0)
- {
- close(s->listenSocket);
- close(s->clientSocket);
- s->SetError(-1);
- s->Kill();
- }
- }
- return NULL;
- }
- void* ConnectionThread(void* socketptr)
- {
- int socket = *(int*)socketptr;
- char headerBuffer[1024];
- int bytesReceived = read(socket, headerBuffer, 1024);
- std::string headerString(headerBuffer, bytesReceived);
- std::string fileRequest = Server::ParseHeader(headerBuffer, bytesReceived);
- if (fileRequest.compare("/") == 0)
- fileRequest.append("index.html");
- std::string typeResponse = Server::GenerateHeader(fileRequest);
- int responseBytesSent = Server::SendData(socket, (char*)typeResponse.data(), typeResponse.size());
- fileData file = Server::GetFile((char*)fileRequest.data());
- int dataBytesSent = Server::SendData(socket, file.data, file.size);
- delete(file.data);
- close(socket);
- }
- void Server::Kill()
- {
- isAlive = false;
- usleep(500);
- close(clientSocket);
- close(listenSocket);
- pthread_cancel(serverThreadHandle);
- }
- void Server::SetCallback(void* callbackptr)
- {
- if (callbackptr)
- cb = reinterpret_cast<recCallback*>(callbackptr);
- }
- std::string Server::ParseHeader(char* headerbuf, int headerlen)
- {
- if (headerlen > 10)
- {
- std::string header(headerbuf, headerlen);
- int requeststart = 0;
- int requestend = 0;
- requeststart = header.find('/');
- if (header.find('?') != -1)
- requestend = header.find('?', requeststart);
- else
- requestend = header.find(' ', requeststart);
- return header.substr(requeststart, (requestend - requeststart));
- }
- std::string header;
- header.append("404");
- return header;
- }
- fileData Server::GetFile(char* filename)
- {
- fileData returnfile = { NULL, 0 };
- std::string filepath;
- filepath.append(Server::ExposeDir());
- filepath.append(filename);
- int fileHandle = open(filepath.data(), O_RDONLY);
- if (fileHandle != -1)
- {
- int bytesRead = 0;
- struct stat fileStat;
- fstat(fileHandle, &fileStat);
- returnfile.size = fileStat.st_size;
- returnfile.data = (char*)malloc(returnfile.size);
- bytesRead = read(fileHandle, returnfile.data, returnfile.size);
- close(fileHandle);
- return returnfile;
- }
- else
- {
- std::cout << "Could not open file!\n";
- }
- return returnfile;
- }
- int Server::SendData(int sock, char* buff, int size)
- {
- int len = size;
- while (len > 0)
- {
- int bytesSent = send(sock, buff, len, 0);
- if (bytesSent < 0)
- return -1;
- else {
- len -= bytesSent;
- buff += bytesSent;
- }
- }
- return 0;
- }
- std::string Server::GenerateHeader(std::string filereq)
- {
- const char* headerstart = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: ";
- const char* headererr = "HTTP/1.1 404 Not Found\r\nConnection: close";
- const char* headerend = "\r\n\r\n";
- std::string headerString(headerstart);
- if (filereq.find("404") != -1)
- {
- std::string errstring(headererr);
- errstring.append(headerend);
- return errstring;
- }
- if (filereq.find(".htm") != -1 || filereq.find(".html") != -1)
- {
- headerString.append("text/html");
- headerString.append(headerend);
- return headerString;
- }
- if (filereq.find(".css") != -1)
- {
- headerString.append("text/css");
- headerString.append(headerend);
- return headerString;
- }
- if (filereq.find(".js") != -1)
- {
- headerString.append("application/javascript");
- headerString.append(headerend);
- return headerString;
- }
- if (filereq.find(".jpg") != -1)
- {
- headerString.append("image/jpeg");
- headerString.append(headerend);
- return headerString;
- }
- if (filereq.find(".ico") != -1)
- {
- headerString.append("image/x-icon");
- headerString.append(headerend);
- return headerString;
- }
- if (filereq.find(".png") != -1)
- {
- headerString.append("image/jpeg");
- headerString.append(headerend);
- return headerString;
- }
- if (filereq.find(".gif") != -1)
- {
- headerString.append("image/jpeg");
- headerString.append(headerend);
- return headerString;
- }
- if (filereq.find(".scss") != -1)
- {
- headerString.append("text/css");
- headerString.append(headerend);
- return headerString;
- }
- if (filereq.find(".woff") != -1 || filereq.find(".woff2") != -1)
- {
- headerString.append("application/font-woff");
- headerString.append(headerend);
- return headerString;
- }
- headerString.append("application/octet-stream");
- headerString.append(headerend);
- return headerString;
- }