Massive update!
[link.git] / Source / HTTP / ServerThread.cpp
blobec146036b31c7fdcc888ac33812066e3d7ee9d2a
1 #include <iostream>
2 #include <string.h>
3 #include <regex>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <string.h>
9 #include <arpa/inet.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <thread>
13 #include <fstream>
14 #include "ServerThread.hpp"
15 #include "../Headers/Headers.hpp"
18 * Manages HTTP connections.
20 void* ConnectionHandler(void* arg) {
21 HTTP::ClientData* Data = (HTTP::ClientData*)arg;
22 char msg[1000];
23 Headers* req = new Headers(Data->getSocket());
24 Headers* res = new Headers(Data->getSocket());
25 recv(Data->getSocket(), msg, 1000, 0);
26 req->SetRequest(msg);
27 res->SetStatus("200 OK");
28 std::string msgString(msg);
29 std::string path = msgString.substr(0, msgString.find("\n")-10);
30 if (path.substr(0,1) == "G") path = path.substr(5, path.length());
31 if (path == "") path = "index.html";
32 res->SendFile("www/" + path);
33 close(Data->getSocket());
34 pthread_exit(NULL);
35 return NULL;
39 * Manages HTTP connections.
41 * Initialized via HTTP::ServerThread
43 void run(void* arg) {
44 HTTP::ServerThread* ServerThread = (HTTP::ServerThread*)arg;
45 int ServerSocket = socket(PF_INET, SOCK_STREAM, 0), ClientSocket;
46 struct sockaddr_in ServerAddress;
47 struct sockaddr_storage ServerStorage;
48 socklen_t AddressSize;
49 ServerAddress.sin_family = AF_INET;
50 ServerAddress.sin_port = htons(ServerThread->getPort());
51 ServerAddress.sin_addr.s_addr = INADDR_ANY;
52 bzero(&(ServerAddress.sin_zero), 8);
53 if (bind(ServerSocket, (struct sockaddr*)&ServerAddress, sizeof(ServerAddress)) != 0) {
54 fprintf(stderr, "[HTTP][!] Could not bind to port %d\n", ServerThread->getPort());
55 exit(0);
57 listen(ServerSocket, ServerThread->getMaxConnections());
58 fprintf(stdout, "[HTTP][#] Listening on port %d\n", ServerThread->getPort());
59 pthread_t ThreadID[ServerThread->getMaxConnections()+ServerThread->getMaxQueuedConnections()];
60 int CurrentThread = 0;
61 while (ServerThread->isRunning()) {
62 AddressSize = sizeof(ServerStorage);
63 ClientSocket = accept(ServerSocket, (struct sockaddr*)&ServerStorage, &AddressSize);
64 HTTP::ClientData ClientData(ServerThread, ClientSocket);
65 pthread_create(&ThreadID[CurrentThread++], NULL, ConnectionHandler, &ClientData);
66 if (CurrentThread >= ServerThread->getMaxQueuedConnections()) {
67 CurrentThread = 0;
68 while (CurrentThread < ServerThread->getMaxQueuedConnections()) pthread_join(ThreadID[CurrentThread++], NULL);
71 shutdown(ServerSocket, SHUT_RDWR);
72 pthread_exit(NULL);
75 namespace HTTP {
77 * Manages the server connections.
79 * @param port The port to listen on.
80 * @param maxConnections The maximum number of connections to accept.
82 ServerThread::ServerThread(int port, int maxConnections, int maxQueuedConnections, bool* Running) {
83 this->port = port;
84 this->maxConnections = maxConnections;
85 this->maxQueuedConnections = maxQueuedConnections;
86 this->Running = Running;
87 std::thread Thread = std::thread(run, (void*)this);
88 Thread.join();
92 * Gets the port.
94 * @return The port number.
96 int ServerThread::getPort() {
97 return this->port;
101 * Gets the maximum number of connections.
103 * @return The maximum number of connections.
105 int ServerThread::getMaxConnections() {
106 return this->maxConnections;
110 * Gets the maximum number of queued connections.
112 * @return The maximum number of queued connections.
114 int ServerThread::getMaxQueuedConnections() {
115 return this->maxQueuedConnections;
119 * Gets if the main thread is still running.
121 * @return True if the main thread is still running.
123 bool ServerThread::isRunning() {
124 return this->Running;
128 * Holds all the client's needed data.
130 * @param serverThread The server thread.
131 * @param socket The socket.
132 * @param address The address.
134 ClientData::ClientData(ServerThread* serverThread, int socket) {
135 this->serverThread = serverThread;
136 this->socket = socket;
140 * Gets the server thread.
142 * @return The server thread.
145 ServerThread* ClientData::getServerThread() {
146 return this->serverThread;
150 * Gets the socket.
152 * @return The socket.
154 int ClientData::getSocket() {
155 return this->socket;