Modified the Web Interface and finished documentation ins all files

This commit is contained in:
Bazsalanszky 2019-11-24 23:23:48 +01:00
parent 6a2c64a759
commit dc0d7544aa
Signed by: Bazsalanszky
GPG key ID: 3A1E008A6F682DA0
7 changed files with 189 additions and 89 deletions

2
main.c
View file

@ -67,7 +67,7 @@ int main(void) {
WebIO webIo;
res = webio_create(config,mynode, &webIo);
res = webio_create(config,&peerList1, &webIo);
if (res != 0) {
return EXIT_FAILURE;
}

View file

@ -9,12 +9,15 @@
#include "../utility.h"
#include "../lib/map.h"
#include "../lib/debugmalloc/debugmalloc.h"
//! Az alapértelmezett hallgató portszám
#ifdef RANDOM_PORT
#define DEFAULT_PORT "0"
#else
#define DEFAULT_PORT "6327"
#endif
//! Az alapértelmezett hallgató portszám a felhasználói felület számára
#define DEFAULT_INTERFACE_PORT "5081"
//! Az alapértelmezett mappa, ami felhasználói felület számára szükséges fájlokat tárolja
#define DEFAULT_WWW_FOLDER "htdocs/"
/*!
* @brief Betölti a `config.ini` fájlt és létrehoz egy Map struktúrát abból.

View file

@ -1,7 +1,7 @@
/*!
* @author Toldi Balázs Ádám
* @date 2019. 10. 09.
*/
//
// Készítette: Toldi Balázs Ádám
// Dátum 2019. 10. 09.
//
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include "../utility.h"
@ -22,7 +22,7 @@ typedef struct peer{ //! A peer általános adatait tartalmazó struktúr
SOCKET socket; //! A socket-et főbb adatait tartalmazó struktúra
struct sockaddr_in sockaddr;
} Peer;
//! A peereket tartó lista
//! @brief A peereket tartó lista
//! @note Ez egy dinaamikusan méretezett tömb. Használat után fel kell szabadítani a lefoglalt memoriaterületet.
typedef struct PeerList{
//! A lista által lefoglalt hely

View file

@ -48,7 +48,7 @@ void serverThread(SOCKET listening, fd_set *master, WebIO webIo, PeerList list,N
if (peer_HandleConnection(listening, &list, mynode, master) != 0)
logger_log("Error while receiving connection...");
} else if (FD_ISSET(webIo.socket, &copy)) {
int res = webio_handleRequest(webIo, &list);
int res = webio_handleRequest(webIo);
if (res == -2) {
run = false;
}

View file

@ -7,29 +7,32 @@
#include "webio.h"
#include "../lib/debugmalloc/debugmalloc.h"
/*!
*
* @param list
* @param mynode
* @param master
* @brief Betölti és csatlakozik a `peer.txt` fájlban megadott peerekhez
* @param[in,out] list A peerek listájának mutatója
* @param[in] mynode Az az adatstruktúra amiben a saját adatainkat tároljuk
* @param[in,out] master Ebben tároljuk a peer sokcet-ét. select() függvényhez szükséges
*/
void peer_loadPeerList(PeerList *list,Node_data mynode,fd_set * master);
/*!
*
* @param[out] output
* @brief Generál vagy betölt egy azonosítót.
* Ha nem létezik a `seed.txt` fájl akkor generál egy 16 karakterből álló sztringet és elmenti az az újonnan létrehozott `seed.txt` fájéba.
* Ha létezik,akkor onnan betölti azt.
* @param[out] output Az azonosító
*/
void getSeed(char*output);
/*!
*
* @param[in] cfg
* @return
* @brief Létrehozza azt az adatstruktúra amiben a saját adatainkat tároljuk.
* @param[in] cfg A program konfigurációja
* @return A létrehozott Node_data struktúra
*/
Node_data construct_Mynodedata(Config cfg);
/*!
*
* @param listening
* @param master
* @param webIo
* @param list
* @param mynode
* @brief Ez a függvény a program "lelke".Ezt a program inicializálása után hívja meg.
* Ez kezeli a bejövő csomagokat,kapcsolatokat.
* @param[in] listening A socket amin a program fut.
* @param[in,out] master Ebben tároljuk a peer sokcet-ét. select() függvényhez szükséges
* @param[in] webIo A felhasználói felület adatstruktúrája
* @param[in] list A peerek listája
* @param[in] mynode Az az adatstruktúra amiben a saját adatainkat tároljuk
*/
void serverThread(SOCKET listening, fd_set* master, WebIO webIo, PeerList list,Node_data mynode);

View file

@ -4,7 +4,7 @@
//
#include "webio.h"
int webio_create(Config config, struct Node_data myData, WebIO *webIo) {
int webio_create(Config config, struct PeerList *list, WebIO *webIo) {
char *port = map_getValue(config, "interface-port");
if (port == NULL)
port = DEFAULT_INTERFACE_PORT;
@ -20,23 +20,22 @@ int webio_create(Config config, struct Node_data myData, WebIO *webIo) {
SOCKET listening;
result = tcp_createIPv4Socket(&listening, atoi(port), !local_mode);
if (result == NULL) {
return 1;
return 3;
}
int res = tcp_bindnlisten(listening, result, SOMAXCONN);
if (res != 0) {
return 2;
return res;
}
WebIO wio;
wio.sockaddr = tcp_getAddr_in(listening);
wio.socket = listening;
wio.nodeData = myData;
wio.list = list;
strcpy(wio.folder, folder);
*webIo = wio;
return 0;
}
int webio_handleRequest(WebIO wio, const PeerList *list) {
int webio_handleRequest(WebIO wio) {
SOCKET client = accept(wio.socket, NULL, NULL);
char buf[8192];
memset(buf, 0, 8192);
@ -46,13 +45,24 @@ int webio_handleRequest(WebIO wio, const PeerList *list) {
closesocket(client);
return -1;
}
char method[5],v_major[2],v_minor[3],file[50];
sscanf(buf, "%s %s %*[^/]/%[^.].%s",method,file,v_major,v_minor);
if(strcmp(v_major,"1") != 0){
char *response = "HTTP/1.0 505 HTTP Version Not Supportedd"
"Content-Encoding: gzip\r\n"
"Content-Language: en\r\n"
"Content-Type: text/html\r\n\r\n"
"<h1>Error 505: HTTP version not supportedd!</h1>";
res = send(client, response, (int) strlen(response), 0);
if (res == SOCKET_ERROR) {
logger_log("Error sending 505 page!");
}
return -1;
}
if (strcmp(method, "GET") == 0) {
res = webio_handleGETrequest(client, wio, file);
if (strncmp(buf, "GET", 3) == 0) {
char file[50];
sscanf(buf, "%*s %s", file);
res = webio_handleGETrequest(client, wio, file, list);
} else if (strncmp(buf, "POST", 4) == 0) {
} else if (strcmp(method, "POST") == 0) {
int i = (int) strlen(buf) - 1;
while (buf[i] != '\n') {
i--;
@ -62,10 +72,20 @@ int webio_handleRequest(WebIO wio, const PeerList *list) {
strcpy(tmp, buf + i);
Map post = getPacketData(tmp);
res = webio_handlePOSTrequest(client, wio, list, post);
res = webio_handlePOSTrequest(client, wio, post);
free(post.pairs);
} else
res = -1;
} else{
char *response = "HTTP/1.0 501 Not Implemented"
"Content-Encoding: gzip\r\n"
"Content-Language: en\r\n"
"Content-Type: text/html\r\n\r\n"
"<h1>Error 501: Method not implemented!</h1>";
res = send(client, response, (int) strlen(response), 0);
if (res == SOCKET_ERROR) {
logger_log("Error sending 501 page!");
}
}
return res;
}
@ -102,6 +122,7 @@ char *webio_getMIMEtype(char *filename) {
char *webio_getFiletype(char *filename) {
char *ext = (char *) malloc(sizeof(char) * 10);
strcpy(ext,"");
char *tmp = strtok(filename, ".");
while (tmp != NULL) {
strncpy(ext, tmp, 10);
@ -110,7 +131,7 @@ char *webio_getFiletype(char *filename) {
return ext;
}
static int webio_handleGETrequest(SOCKET client, WebIO wio, char *file, const PeerList *list) {
static int webio_handleGETrequest(SOCKET client, WebIO wio, char *file) {
char path[129];
@ -121,11 +142,11 @@ static int webio_handleGETrequest(SOCKET client, WebIO wio, char *file, const Pe
memmove(file, file + 1, strlen(file));
if (strcmp(file, "") == 0) {
char index[8192] = "";
webio_getIndex(wio.folder, list, index);
webio_getIndex(wio, index);
webio_sendPage(client, index);
} else if (peer_ID_isFound(*list, file) || webio_isPeerFound(wio.folder, file)) {
} else if (peer_ID_isFound(*(wio.list), file) || webio_isPeerFound(wio.folder, file)) {
char cnt[8192] = "";
webio_getPeerPage(wio.folder, file, (peer_ID_getPeer(*list, file) != -1), cnt);
webio_getPeerPage(wio, file, cnt);
webio_sendPage(client, cnt);
} else if (strcmp(file, "kill") == 0) {
webio_sendPage(client, "<h1>Server Killed!</h1>");
@ -173,9 +194,9 @@ static int webio_handleGETrequest(SOCKET client, WebIO wio, char *file, const Pe
return 0;
}
static int webio_handlePOSTrequest(SOCKET client, WebIO wio, const PeerList *list, Map post) {
static int webio_handlePOSTrequest(SOCKET client, WebIO wio, Map post) {
shutdown(client, SD_RECEIVE);
char *response = "HTTP/1.1 304 Not Modified ";
char *response = "HTTP/1.0 304 Not Modified ";
int res = send(client, response, (int) strlen(response), 0);
if (res == SOCKET_ERROR) {
@ -192,7 +213,7 @@ static int webio_handlePOSTrequest(SOCKET client, WebIO wio, const PeerList *lis
#if defined(_WIN32)
mkdir(folder);
#else
mkdir(folder, 0777); // notice that 777 is different than 0777
mkdir(folder, 0777);
#endif
sprintf(file, "%s%s.txt", folder, map_getValue(post, "id"));
FILE *f;
@ -200,20 +221,20 @@ static int webio_handlePOSTrequest(SOCKET client, WebIO wio, const PeerList *lis
fprintf(f, "Me: %s\n", map_getValue(post, "message"));
fclose(f);
char buf[DEFAULT_BUFLEN];
int i = peer_ID_getPeer(*list, map_getValue(post, "id"));
int i = peer_ID_getPeer(*(wio.list), map_getValue(post, "id"));
if (i < 0) {
logger_log("Error sending message! Error: Peer offline!");
return 1;
}
sprintf(buf, "@message=%s", map_getValue(post, "message"));
res = send(list->array[i].socket, buf, DEFAULT_BUFLEN, 0);
res = send(wio.list->array[i].socket, buf, DEFAULT_BUFLEN, 0);
if (res == SOCKET_ERROR) {
logger_log("Error sending message.Error: %d", errno);
return 2;
}
logger_log("Message sent to %s", map_getValue(post, "id"));
} else map_dump(post);
}
return 0;
}
@ -236,24 +257,24 @@ static void webio_getHeader(char *folder, char result[]) {
result = "<html>";
}
static void webio_getIndex(char *folder, const PeerList *list, char *outputBuffer) {
static void webio_getIndex(WebIO wio, char *outputBuffer) {
char content[8192] = "";
char header[4096] = "";
webio_getHeader(folder, header);
webio_getHeader(wio.folder, header);
strcpy(content, header);
strcat(content, "<h1>Peers:</h1>\n");
if (list->length > 0) {
if (wio.list->length > 0) {
strcat(content, "<ul>\n");
for (int i = 0; i < list->length; ++i) {
for (int i = 0; i < wio.list->length; ++i) {
sprintf(content, "%s<li>"
"<a href=\"%s\">",
content, list->array[i].peerData.id);
if (strcmp(list->array[i].peerData.nick, "") != 0) {
sprintf(content, "%s%s - ", content, list->array[i].peerData.nick);
content, wio.list->array[i].peerData.id);
if (strcmp(wio.list->array[i].peerData.nick, "") != 0) {
sprintf(content, "%s%s - ", content, wio.list->array[i].peerData.nick);
}
sprintf(content, "%s%s</a></li>\n", content, list->array[i].peerData.id);
sprintf(content, "%s%s</a></li>\n", content, wio.list->array[i].peerData.id);
}
strcat(content, "</ul>\n");
} else
@ -262,7 +283,7 @@ static void webio_getIndex(char *folder, const PeerList *list, char *outputBuffe
"</div>\n", content);
strcat(content, "<h1>Offline messages:</h1>\n");
char path[65];
sprintf(path, "%s/peers/", folder);
sprintf(path, "%s/peers/", wio.folder);
#ifdef _MSC_VER
HANDLE dir;
WIN32_FIND_DATA file_data;
@ -313,13 +334,13 @@ static void webio_getIndex(char *folder, const PeerList *list, char *outputBuffe
strcpy(outputBuffer, content);
}
static void webio_getPeerPage(char *folder, char *id, bool online, char *outputBuffer) {
static void webio_getPeerPage(WebIO wio, char *id, char *outputBuffer) {
char content[8192] = "";
char header[4096] = "";
webio_getHeader(folder, header);
webio_getHeader(wio.folder, header);
strcpy(content, header);
bool online = peer_ID_isFound(*wio.list,id);
char *img = (online) ? "<img width=\"30\" height=\"30\" src=\"assets\\img\\on.svg\">"
: "<img width=\"30\" height=\"30\" src=\"assets\\img\\off.svg\">";
char *disabled = (online) ? "" : "disabled";
@ -352,7 +373,7 @@ static bool webio_isPeerFound(char *folder, char *id) {
void webio_sendOKHeader(SOCKET socket, char *file) {
char response[8192];
sprintf(response, "HTTP/1.1 200 OK "
sprintf(response, "HTTP/1.0 200 OK "
"Content-Encoding: gzip\r\n"
"Content-Language: en\r\n"
"Content-Type: %s\r\n\r\n", webio_getMIMEtype(file));
@ -364,7 +385,7 @@ void webio_sendOKHeader(SOCKET socket, char *file) {
void webio_sendOKHeader_wSize(SOCKET socket, char *file, int size) {
char response[8192];
sprintf(response, "HTTP/1.1 200 OK "
sprintf(response, "HTTP/1.0 200 OK "
"Content-Encoding: gzip\r\n"
"Content-Language: en\r\n"
"Content-Length: %d\r\n"
@ -377,7 +398,7 @@ void webio_sendOKHeader_wSize(SOCKET socket, char *file, int size) {
void webio_send404Page(SOCKET socket) {
char *response = "HTTP/1.1 404 Not Found "
char *response = "HTTP/1.0 404 Not Found "
"Content-Encoding: gzip\r\n"
"Content-Language: en\r\n"
"Content-Type: text/html\r\n\r\n"

View file

@ -12,39 +12,112 @@
#include "../lib/debugmalloc/debugmalloc.h"
typedef struct webio{
SOCKET socket;
struct sockaddr_in sockaddr;
char folder[65];
struct Node_data nodeData;
/*!
* @brief A felhasználói felület számára szükséges adatokat tárolja
*/
typedef struct WebIO{ //!A felhasználói felület socket-e
SOCKET socket; //! A mappa amiben a felhasználói felület fájljai vannak
char folder[65]; //! A peerek listájának mutatója
struct PeerList * list;
} WebIO;
int webio_create(Config config, struct Node_data myData, WebIO *webIo);
int webio_handleRequest(WebIO wio, const PeerList *list);
static int webio_handleGETrequest(SOCKET client, WebIO wio, char * file, const PeerList *list);
static int webio_handlePOSTrequest(SOCKET client, WebIO wio, const PeerList *list, Map post);
/*!
* @brief A kapott adatok alapján létrehozza a felhasználói felületet
* @param[in] config A program konfigurációja lásd config.h
* @param[in] list A peerek listájának mutatója
* @param[out] webIo Mutató arra struktúrára ahová az adatokat írni szeretnénk
* @return A művelet sikerességét jelző szám
* <table>
* <tr><th>Kód</th><th>Jelentése</th></tr>
* <tr><td>0</td><td>A művelet sikeres volt</td></tr>
* <tr><td>1</td><td>A bind() függvény futása közben hiba lépett fel</td></tr>
* <tr><td>2</td><td>A listen() függvény futása közben hiba lépett fel</td></tr>
* <tr><td>3</td><td>A tcp_createIPv4Socket() függvény futása közben hiba lépett fel</td></tr>
* </table>
*/
int webio_create(Config config, struct PeerList *list, WebIO *webIo);
/*!
* @brief Fogadja a socket-re érkező csatlakozásokat és a HTTP request-ek alapján elküldi a HTTP response-okat
* @param[in] wio A felhasználói felület struktúrája
* @return A művelet sikerességét jelző szám.(Ha 0, akkor a sikeres volt,egyébként sikertelen)
*/
int webio_handleRequest(WebIO wio);
/*!
* @brief Ez a függvény kezeli a HTTP GET request-eket. Elküldi a kért filokat.
* @param[in] client A socket amire az adatokat kell küldeni
* @param[in] wio A felhasználói felület struktúrája
* @param[in] file A kért file neve
* @return A művelet sikerességét jelző szám.(Ha 0, akkor a sikeres volt,egyébként sikertelen)
*/
static int webio_handleGETrequest(SOCKET client, WebIO wio, char *file);
/*!
* @brief Ez a függvény kezeli a HTTP POST request-eket.
* @param[in] client A socket amire az adatokat kell küldeni
* @param[in] wio A felhasználói felület struktúrája
* @param[in] post A kapott adatokat tároló Map
* @return A művelet sikerességét jelző szám.(Ha 0, akkor a sikeres volt,egyébként sikertelen)
*/
static int webio_handlePOSTrequest(SOCKET client, WebIO wio, Map post);
/*!
* @brief a file neve alapján visszaadja a típusához tartozó <a href="https://en.wikipedia.org/wiki/MIME">MIME típust</a>
* @param[in] filename A file neve
* @return A file típusához tartozó <a href="https://en.wikipedia.org/wiki/MIME">MIME típus</a>
*/
static char* webio_getMIMEtype(char* filename);
/*!
* Visszaadja a paraméterként kapott fájl kiterjesztését
* @param[in] filename A fájl neve
* @return A fájl kiterjesztése
* @note A visszatérési érték címét a malloc() függvénnyel foglalja le,így később fel kell azt szabadítani
*/
static char* webio_getFiletype(char* filename);
/*!
* @brief Betölti a fejlécet a főbb oldalakhoz
* @param[in] folder A mappa amiben a fejléc fájl(header.html) található
* @param[out] result A fejléc tartalma
*/
static void webio_getHeader(char* folder, char result[]);
static void webio_getIndex(char* folder, const PeerList *list, char *outputBuffer);
static void webio_getPeerPage(char* folder, char *id, bool online, char *outputBuffer);
/*!
* @brief Betölti a főoldal tartalmát
* @param[in] wio A felhasználói felület struktúrája
* @param outputBuffer Ebbe a buffer-be fogja a főoldalt betölteni
*/
static void webio_getIndex(WebIO wio, char *outputBuffer);
/*!
* @brief Betölti egy megadott peerhez tartozó oldal tartalmát
* @param[in] wio A felhasználói felület struktúrája
* @param[in] id A peer,aminek az oldalát szeretnénk betölteni
* @param[out] outputBuffer Ebbe a buffer-be fogja az oldalt betölteni
*/
static void webio_getPeerPage(WebIO wio, char *id, char *outputBuffer);
/*!
* @brief Megnézi hogy egy adott azonosítójú peer létezik.e
* @param[in] folder A felhasználói felület mappája
* @param[in] id A peer azonosítója amit keresünk
* @return Igaz vagy hamis érték az alapján hogy a peer létezik-e( vagy létezett)
*/
static bool webio_isPeerFound(char* folder,char* id);
/*!
* @brief Elküldi a HTTP header-t,ami azt jelzi fogy a kért file létezik
* @param[in] socket A socket amire a header-t szeretnénk küldeni
* @param[in] file A kért file neve
* @note Ha ismerjük a file(vagyis az oldal) méretét, érdemesebb a webio_sendOKHeader_wSize() függvényt használni
*/
static void webio_sendOKHeader(SOCKET socket,char* file);
/*!
* @copybrief webio_sendOKHeader
* @param[in] socket A socket amire a header-t szeretnénk küldeni
* @param[in] file A kért file neve
* @param[in] size A kért file mérete
*/
static void webio_sendOKHeader_wSize(SOCKET socket,char* file,int size);
/*!
* @brief Elküld a egy oldalt
* @param[in] socket A socket amire az oldalt küldeni szeretnénk
* @param[in] content Az oldal tartalma
*/
static void webio_sendPage(SOCKET socket, char* content);
/*!
* @brief Elküldi a HTTP header-t,ami azt jelzi fogy a kért file nem létezik
* @param[in] socket A socket amire a header-t szeretnénk küldeni
*/
static void webio_send404Page(SOCKET socket);