// // Készítette: Toldi Balázs Ádám // Dátum: 2019. 10. 14.. // #include "webio.h" #ifdef RANDOM_PORT #define DEFAULT_INTERFACE_PORT "0" #else #define DEFAULT_INTERFACE_PORT "5081" #endif int webio_create(int port,char* folder,struct Node_data myData,WebIO *webIo){ struct addrinfo hint; ZeroMemory(&hint, sizeof(hint)); struct addrinfo *result = NULL; WebIO wio; memset(&hint, 0, sizeof(struct addrinfo)); hint.ai_protocol = IPPROTO_TCP; hint.ai_socktype = SOCK_STREAM; hint.ai_family = AF_INET; //TODO: Disable this in local modeó hint.ai_canonname = NULL; hint.ai_addr = NULL; hint.ai_next = NULL; //TODO: Use config to determine port int res = getaddrinfo(NULL, DEFAULT_INTERFACE_PORT, &hint, &result); if (res != 0) { char error[129]; sprintf(error,"Error creating address information!Error code: %d", WSAGetLastError()); logger_log(error); WSACleanup(); return -1; } //Creating listening socket SOCKET listening = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (listening == INVALID_SOCKET) { char error[129]; sprintf(error,"Error creating socket!Error code: %d", WSAGetLastError()); logger_log(error); WSACleanup(); return -1; } //Binding the socket res = bind(listening, result->ai_addr, result->ai_addrlen); if (res == SOCKET_ERROR) { char error[129]; sprintf(error,"Error at binding!Error code: %d", WSAGetLastError()); logger_log(error); freeaddrinfo(result); WSACleanup(); return -1; } freeaddrinfo(result); //TODO: Set max connection count in config res = listen(listening, SOMAXCONN); if (res == -1) { char error[129]; sprintf(error,"Error at starting listening!Error code: %d", WSAGetLastError()); logger_log(error); WSACleanup(); return -1; } //Ez alapvetően akkor hasznos amikor a port 0-ra van állítva, azaz akkor amikor a rendszer random választ egyet. struct sockaddr_in sin; socklen_t len = sizeof(sin); if (getsockname(listening, (struct sockaddr *) &sin, &len) == -1) { char error[129]; sprintf(error,"Error at getsockname!Error code: %d", WSAGetLastError()); logger_log(error); return -1; } wio.sockaddr = sin; wio.socket= listening; wio.nodeData = myData; strcpy(wio.folder,folder); *webIo = wio; return 0; } int webio_handleRequest(WebIO wio,peerList list){ SOCKET client = accept(wio.socket,NULL,NULL); char buf[8192]; ZeroMemory(buf,8192); int res = recv(client,buf,8192,0); if(res <=0){ logger_log("Error with web interface!"); closesocket(client); return -1; } char req[10]; sscanf(buf,"%s",req); if(strcmp(req,"GET") == 0) { char file[50]; sscanf(buf, "%*s %s", file); res = webio_handleGETrequest(client,wio,file, list); }else if(strcmp(req,"POST") == 0) { int i = strlen(buf)-1; while(buf[i] != '\n'){ i--; } i++; char tmp[8196]; strcpy(tmp,buf+i); map post = getHandshakeData(tmp); res = webio_handlePOSTrequest(client, wio,list,post); }else res = -1; return res; } char* webio_getMIMEtype(char* filename){ char* ext = webio_getFiletype(filename); if (strcmp(ext,"html") == 0) return "text/html"; else if (strcmp(ext, "json") == 0) return "application/json"; else if (strcmp(ext, "js")== 0) return "application/javascript"; else if (strcmp(ext, "css")== 0) return "text/css"; else if (strcmp(ext, "jpg")== 0) return "image/jpeg"; else if (strcmp(ext, "png")== 0) return "image/png"; else if (strcmp(ext, "ico")== 0) return "image/x-icon"; else if (strcmp(ext, "xml")== 0) return "text/xml"; else if (strcmp(ext, "zip")== 0) return "application/zip"; else return "text/plain"; } char* webio_getFiletype(char* filename){ char *type = (char*) malloc(10); char* tmp = strtok(filename,"."); while(tmp != NULL){ type =tmp; tmp = strtok(NULL,"."); } return type; } int webio_handleGETrequest(SOCKET client,WebIO wio,char* file,peerList list){ char buf[8192]; sscanf(buf,"%*s %s",file); char path[129]; ZeroMemory(path,sizeof(path)); strcat(path,wio.folder); char *response = (char *) malloc(sizeof(char) * 8192); if (file[0] == '/') memmove(file, file+1, strlen(file)); if(strlen(file) == 0) { char index[8192]; getIndex(wio.folder, list, index); sprintf(response, "HTTP/1.1 200 OK " "Content-Encoding: gzip\r\n" "Content-Language: en\r\n" "Content-Type: text/html\r\n\r\n%s",index); }else if(peer_isFoundInList(list,file)){ sprintf(response, "HTTP/1.1 200 OK " "Content-Encoding: gzip\r\n" "Content-Language: en\r\n" "Content-Type: text/html\r\n\r\n%s" ,getPeerPage(wio.folder,peer_getPeerByID(list,file) ) ); }else if(strcmp(file,"kill") == 0){ logger_log("Exit sign received.Exiting..."); return -2; } else{ strcat(path, file); FILE *fp; fp = fopen(path, "r"); if (fp != NULL) { char *content = (char *) calloc(sizeof(char) * 16384, sizeof(char)); char buf[4096]; int counter = 0; while (fgets(buf, 4096, fp) != NULL) { int len = strlen(content); strcat(content, buf); counter += 4096; if (counter >= len) { content = realloc(content, counter + 16384); } } fclose(fp); int len = counter + 1024; response = (char *) realloc(response,sizeof(char) * len); sprintf(response, "HTTP/1.1 200 OK " "Content-Encoding: gzip\r\n" "Content-Language: en\r\n" "Content-Type: %s\r\n\r\n%s" ,webio_getMIMEtype(file), content); free(content); } else { sprintf(response, "HTTP/1.1 404 Not Found " "Content-Encoding: gzip\r\n" "Content-Language: en\r\n" "Content-Type: text/html\r\n\r\n" "