PageRenderTime 21ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Server.cc

https://gitlab.com/br0k3n_/SockWebServer
C++ | 278 lines | 201 code | 77 blank | 0 comment | 38 complexity | a2b970d1b55a47e52239daed9702b4bc MD5 | raw file
  1. #include "Server.h"
  2. Server::Server(char* rootPath, int Port)
  3. {
  4. rootDir = rootPath;
  5. port = Port;
  6. }
  7. int Server::Start()
  8. {
  9. struct sockaddr_in serv_addr;
  10. listenSocket = socket(AF_INET, SOCK_STREAM, 0);
  11. if (listenSocket < 0)
  12. {
  13. std::cout << "Failed to create socket!!\n";
  14. return -1;
  15. }
  16. memset(&serv_addr, 0x00, sizeof(serv_addr));
  17. serv_addr.sin_family = AF_INET;
  18. serv_addr.sin_addr.s_addr = INADDR_ANY;
  19. serv_addr.sin_port = htons(port);
  20. if (bind(listenSocket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
  21. {
  22. std::cout << "could not bind socket!\n";
  23. return -1;
  24. }
  25. listen(listenSocket, 5);
  26. isAlive = true;
  27. pthread_create(&serverThreadHandle, NULL, ServerThread, this);
  28. return 0;
  29. }
  30. void* Server::ServerThread(void* classPtr)
  31. {
  32. Server* s = reinterpret_cast<Server*>(classPtr);
  33. while(s->isAlive)
  34. {
  35. s->clientSocket = accept(s->listenSocket, NULL, NULL);
  36. if (s->clientSocket < 0)
  37. {
  38. close(s->listenSocket);
  39. close(s->clientSocket);
  40. s->SetError(-1);
  41. s->Kill();
  42. }
  43. }
  44. return NULL;
  45. }
  46. void* ConnectionThread(void* socketptr)
  47. {
  48. int socket = *(int*)socketptr;
  49. char headerBuffer[1024];
  50. int bytesReceived = read(socket, headerBuffer, 1024);
  51. std::string headerString(headerBuffer, bytesReceived);
  52. std::string fileRequest = Server::ParseHeader(headerBuffer, bytesReceived);
  53. if (fileRequest.compare("/") == 0)
  54. fileRequest.append("index.html");
  55. std::string typeResponse = Server::GenerateHeader(fileRequest);
  56. int responseBytesSent = Server::SendData(socket, (char*)typeResponse.data(), typeResponse.size());
  57. fileData file = Server::GetFile((char*)fileRequest.data());
  58. int dataBytesSent = Server::SendData(socket, file.data, file.size);
  59. delete(file.data);
  60. close(socket);
  61. }
  62. void Server::Kill()
  63. {
  64. isAlive = false;
  65. usleep(500);
  66. close(clientSocket);
  67. close(listenSocket);
  68. pthread_cancel(serverThreadHandle);
  69. }
  70. void Server::SetCallback(void* callbackptr)
  71. {
  72. if (callbackptr)
  73. cb = reinterpret_cast<recCallback*>(callbackptr);
  74. }
  75. std::string Server::ParseHeader(char* headerbuf, int headerlen)
  76. {
  77. if (headerlen > 10)
  78. {
  79. std::string header(headerbuf, headerlen);
  80. int requeststart = 0;
  81. int requestend = 0;
  82. requeststart = header.find('/');
  83. if (header.find('?') != -1)
  84. requestend = header.find('?', requeststart);
  85. else
  86. requestend = header.find(' ', requeststart);
  87. return header.substr(requeststart, (requestend - requeststart));
  88. }
  89. std::string header;
  90. header.append("404");
  91. return header;
  92. }
  93. fileData Server::GetFile(char* filename)
  94. {
  95. fileData returnfile = { NULL, 0 };
  96. std::string filepath;
  97. filepath.append(Server::ExposeDir());
  98. filepath.append(filename);
  99. int fileHandle = open(filepath.data(), O_RDONLY);
  100. if (fileHandle != -1)
  101. {
  102. int bytesRead = 0;
  103. struct stat fileStat;
  104. fstat(fileHandle, &fileStat);
  105. returnfile.size = fileStat.st_size;
  106. returnfile.data = (char*)malloc(returnfile.size);
  107. bytesRead = read(fileHandle, returnfile.data, returnfile.size);
  108. close(fileHandle);
  109. return returnfile;
  110. }
  111. else
  112. {
  113. std::cout << "Could not open file!\n";
  114. }
  115. return returnfile;
  116. }
  117. int Server::SendData(int sock, char* buff, int size)
  118. {
  119. int len = size;
  120. while (len > 0)
  121. {
  122. int bytesSent = send(sock, buff, len, 0);
  123. if (bytesSent < 0)
  124. return -1;
  125. else {
  126. len -= bytesSent;
  127. buff += bytesSent;
  128. }
  129. }
  130. return 0;
  131. }
  132. std::string Server::GenerateHeader(std::string filereq)
  133. {
  134. const char* headerstart = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: ";
  135. const char* headererr = "HTTP/1.1 404 Not Found\r\nConnection: close";
  136. const char* headerend = "\r\n\r\n";
  137. std::string headerString(headerstart);
  138. if (filereq.find("404") != -1)
  139. {
  140. std::string errstring(headererr);
  141. errstring.append(headerend);
  142. return errstring;
  143. }
  144. if (filereq.find(".htm") != -1 || filereq.find(".html") != -1)
  145. {
  146. headerString.append("text/html");
  147. headerString.append(headerend);
  148. return headerString;
  149. }
  150. if (filereq.find(".css") != -1)
  151. {
  152. headerString.append("text/css");
  153. headerString.append(headerend);
  154. return headerString;
  155. }
  156. if (filereq.find(".js") != -1)
  157. {
  158. headerString.append("application/javascript");
  159. headerString.append(headerend);
  160. return headerString;
  161. }
  162. if (filereq.find(".jpg") != -1)
  163. {
  164. headerString.append("image/jpeg");
  165. headerString.append(headerend);
  166. return headerString;
  167. }
  168. if (filereq.find(".ico") != -1)
  169. {
  170. headerString.append("image/x-icon");
  171. headerString.append(headerend);
  172. return headerString;
  173. }
  174. if (filereq.find(".png") != -1)
  175. {
  176. headerString.append("image/jpeg");
  177. headerString.append(headerend);
  178. return headerString;
  179. }
  180. if (filereq.find(".gif") != -1)
  181. {
  182. headerString.append("image/jpeg");
  183. headerString.append(headerend);
  184. return headerString;
  185. }
  186. if (filereq.find(".scss") != -1)
  187. {
  188. headerString.append("text/css");
  189. headerString.append(headerend);
  190. return headerString;
  191. }
  192. if (filereq.find(".woff") != -1 || filereq.find(".woff2") != -1)
  193. {
  194. headerString.append("application/font-woff");
  195. headerString.append(headerend);
  196. return headerString;
  197. }
  198. headerString.append("application/octet-stream");
  199. headerString.append(headerend);
  200. return headerString;
  201. }