// // Készítette: Toldi Balázs Ádám // Dátum: 2019. 10. 14.. // #include "webio.h" int webio_create(Config config, struct Node_data myData, WebIO *webIo) { char *port = map_getValue(config, "interface-port"); if (port == NULL) port = DEFAULT_INTERFACE_PORT; char *folder = map_getValue(config, "interface-folder"); if (folder == NULL) folder = DEFAULT_WWW_FOLDER; char *local_mode_str = map_getValue(config, "interface-local"); bool local_mode = false; if (local_mode_str != NULL && strcmp(local_mode_str, "true") == 0) local_mode = true; struct addrinfo *result = NULL; SOCKET listening; result = tcp_createIPv4Socket(&listening, atoi(port), !local_mode); if (result == NULL) { return 1; } int res = tcp_bindnlisten(listening, result, SOMAXCONN); if (res != 0) { return 2; } WebIO wio; wio.sockaddr = tcp_getAddr_in(listening); wio.socket = listening; wio.nodeData = myData; strcpy(wio.folder, folder); *webIo = wio; return 0; } int webio_handleRequest(WebIO wio, const PeerList *list) { SOCKET client = accept(wio.socket, NULL, NULL); char buf[8192]; memset(buf, 0, 8192); int res = recv(client, buf, 8192, 0); if (res <= 0) { logger_log("Error with web interface!"); closesocket(client); return -1; } 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) { int i = (int) strlen(buf) - 1; while (buf[i] != '\n') { i--; } i++; char tmp[8196]; strcpy(tmp, buf + i); Map post = getPacketData(tmp); res = webio_handlePOSTrequest(client, wio, list, post); free(post.pairs); } else res = -1; return res; } char *webio_getMIMEtype(char *filename) { char type[10]; char *ext = webio_getFiletype(filename); strcpy(type, ext); free(ext); if (strcmp(type, "html") == 0) return "text/html"; else if (strcmp(type, "json") == 0) return "application/json"; else if (strcmp(type, "svg") == 0) return "image/svg+xml"; else if (strcmp(type, "js") == 0) return "application/javascript"; else if (strcmp(type, "css") == 0) return "text/css"; else if (strcmp(type, "jpg") == 0) return "image/jpeg"; else if (strcmp(type, "png") == 0) return "image/png"; else if (strcmp(type, "bmp") == 0) return "image/bmp"; else if (strcmp(type, "ico") == 0) return "image/x-icon"; else if (strcmp(type, "xml") == 0) return "text/xml"; else if (strcmp(type, "zip") == 0) return "application/zip"; else return "text/plain"; } char *webio_getFiletype(char *filename) { char *ext = (char *) malloc(sizeof(char) * 10); char *tmp = strtok(filename, "."); while (tmp != NULL) { strncpy(ext, tmp, 10); tmp = strtok(NULL, "."); } return ext; } static int webio_handleGETrequest(SOCKET client, WebIO wio, char *file, const PeerList *list) { char path[129]; memset(path, 0, sizeof(path)); strcat(path, wio.folder); int len = 0; if (file[0] == '/') memmove(file, file + 1, strlen(file)); if (strcmp(file, "") == 0) { char index[8192] = ""; webio_getIndex(wio.folder, list, index); webio_sendPage(client, index); } else if (peer_ID_isFound(*list, file) || webio_isPeerFound(wio.folder, file)) { char cnt[8192] = ""; webio_getPeerPage(wio.folder, file, (peer_ID_getPeer(*list, file) != -1), cnt); webio_sendPage(client, cnt); } else if (strcmp(file, "kill") == 0) { webio_sendPage(client, "

Server Killed!

"); logger_log("Exit sign received.Exiting..."); return -2; } else { strcat(path, file); //File küldés windows-on #ifdef _WIN32 HANDLE file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); DWORD size = GetFileSize(file, NULL); if (file == INVALID_HANDLE_VALUE || size < 0) webio_send404Page(client); else { webio_sendOKHeader_wSize(client, path, size); TransmitFile(client, file, 0, 0, NULL, NULL, 0); CloseHandle(file); } #else int fd = open(path, O_RDONLY); if (fd == -1) webio_send404Page(client); else { struct stat stat_struct; fstat(fd, &stat_struct); int length = stat_struct.st_size; webio_sendOKHeader(client, path); size_t total_bytes_sent = 0; ssize_t bytes_sent; char puf[len]; while (total_bytes_sent < length) { bytes_sent = sendfile(client,fd,0,length); if(bytes_sent == -1) logger_log("Error: %s",strerror(errno)); total_bytes_sent += bytes_sent; } } #endif shutdown(client, SD_BOTH); } closesocket(client); return 0; } static int webio_handlePOSTrequest(SOCKET client, WebIO wio, const PeerList *list, Map post) { shutdown(client, SD_RECEIVE); char *response = "HTTP/1.1 304 Not Modified "; int res = send(client, response, (int) strlen(response), 0); if (res == SOCKET_ERROR) { logger_log("Error with io"); return -1; } shutdown(client, SD_BOTH); if (map_isFound(post, "id") && map_isFound(post, "message") && strcmp(map_getValue(post, "message"), "%0D%0A") != 0) { char file[64]; char folder[72]; sprintf(folder, "%s/peers/", wio.folder); #if defined(_WIN32) mkdir(folder); #else mkdir(folder, 0777); // notice that 777 is different than 0777 #endif sprintf(file, "%s%s.txt", folder, map_getValue(post, "id")); FILE *f; f = fopen(file, "a"); 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")); 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); 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; } static void webio_getHeader(char *folder, char result[]) { char path[65]; strcpy(path, folder); strcat(path, "/header.html"); FILE *fp; fp = fopen(path, "r"); if (fp != NULL) { char buf[1024]; while (fgets(buf, 1024, fp) != NULL) { strcat(result, buf); } fclose(fp); } else result = ""; } static void webio_getIndex(char *folder, const PeerList *list, char *outputBuffer) { char content[8192] = ""; char header[4096] = ""; webio_getHeader(folder, header); strcpy(content, header); strcat(content, "

Peers:

\n"); if (list->length > 0) { strcat(content, "\n"); } else sprintf(content, "%s
\n" " No peers connected!\n" "
\n", content); strcat(content, "

Offline messages:

\n"); char path[65]; sprintf(path, "%s/peers/", folder); #ifdef _DIRENT_H_ DIR *d; d = opendir(path); if (d != NULL){ strcat(content, "\n"); }else{ sprintf(content, "%s
\n" " No offline messages!\n" "
\n", content); } #else HANDLE dir; WIN32_FIND_DATA file_data; strcat(path,"/*"); if ((dir = FindFirstFile(path, &file_data)) == INVALID_HANDLE_VALUE) sprintf(content, "%s
\n" " No offline messages!\n" "
\n", content); else{ strcat(content, "