Last active
July 14, 2022 13:08
-
-
Save epshteinmatthew/186e2ccd433bb2d722a45ec6a8b2972b to your computer and use it in GitHub Desktop.
Another small web server in c. Support multiple routes and(?) multiple users. IDK if post requests work/how to handle file uploads, will figure that later. oh and also a working(?) parser for my shitty json clone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <sys/types.h> | |
| #include <sys/socket.h> | |
| #include <netdb.h> | |
| #include <stdio.h> | |
| #include <poll.h> | |
| #include <string.h> | |
| #define BACKLOG 10 | |
| #define BUFFER 1024 | |
| // request and reader | |
| struct request | |
| { | |
| char team[5]; // max is 4 chars in a team name(lets hope) | |
| char body[257]; // unbounded cuz who cares | |
| }; | |
| // one mon | |
| struct request monParse(char *token) | |
| { | |
| struct request x; | |
| char broken[BUFFER]; | |
| strcpy(broken, token); | |
| char *other_token = strtok(broken, ":"); | |
| strcpy(x.team, other_token); | |
| while (other_token != NULL) | |
| { | |
| strcpy(x.body, other_token); | |
| other_token = strtok(NULL, ":"); | |
| } | |
| return x; | |
| } | |
| // two mon | |
| int monRead(struct request reqsArr[20]) | |
| { | |
| // i think i need to use pointers for this and monappend | |
| FILE *fp; | |
| char ch[BUFFER]; | |
| char* context = NULL; | |
| char *token; | |
| // allocate memory | |
| fp = fopen("requests.mon", "r"); | |
| fgets(ch, BUFFER, (FILE *)fp); | |
| puts(ch); | |
| token = strtok_r(ch, ";", &context); | |
| int lastentry = 0; | |
| while (token != NULL) | |
| { | |
| puts(token); | |
| reqsArr[lastentry] = monParse(token); | |
| lastentry++; | |
| token = strtok_r(NULL, ";", &context); | |
| } | |
| fclose(fp); | |
| return 0; | |
| } | |
| // redmonbluemon | |
| int monAppend(struct request req) | |
| { | |
| char toadd[BUFFER]; | |
| strcat(toadd, req.team); | |
| strcat(toadd, ":"); | |
| strcat(toadd, req.body); | |
| strcat(toadd, ";"); | |
| // how to do this in one line? | |
| FILE *fp; | |
| fp = fopen("requests.mon", "a"); | |
| fprintf(fp, toadd); | |
| fclose(fp); | |
| return 0; | |
| } | |
| int monDelete(struct request req){ | |
| struct request allReqs[20]; | |
| monRead(allReqs); | |
| fclose(fopen("requests.mon", "w")); | |
| for (int i = 0; allReqs[i].team != NULL; i++) | |
| { | |
| if (strcmp(allReqs[i].team, req.team) != 0 || strcmp(allReqs[i].body, req.body) != 0) | |
| { | |
| monAppend(allReqs[i]); | |
| } | |
| } | |
| //delete the one you want from the list | |
| //for loop thru the rest and monAppend | |
| return 0; | |
| } | |
| // glorified event loop | |
| int main() | |
| { | |
| struct request a[20]; | |
| monRead(a); | |
| int sockfd, new_fd, status; | |
| struct addrinfo hints; | |
| struct addrinfo *servinfo; | |
| struct sockaddr_storage their_addr; | |
| socklen_t addr_size; | |
| char resp[] = "HTTP/1.0 200 OK\r\n" | |
| "Server: webserver-c\r\n" | |
| "Content-type: text/html\r\n\r\n" | |
| "<html>hello, world</html>\r\n"; | |
| char *msgb = "So, we are gamers!"; | |
| char recvb[BUFFER], method[BUFFER], uri[BUFFER], version[BUFFER]; | |
| int lenm, bytes_sent, recieved; | |
| memset(&hints, 0, sizeof hints); | |
| hints.ai_family = AF_UNSPEC; | |
| hints.ai_socktype = SOCK_STREAM; | |
| hints.ai_flags = AI_PASSIVE; | |
| if ((status = getaddrinfo(NULL, "3268", &hints, &servinfo) != 0)) | |
| { | |
| perror(gai_strerror(status)); | |
| } | |
| if ((sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1) | |
| { | |
| perror("problem creating socket"); | |
| } | |
| // sorry joe, adress isnt already in use | |
| int yes = 1; | |
| if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) | |
| { | |
| perror("error fixing other error"); | |
| } | |
| if (bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen) != 0) | |
| { | |
| perror("Problem binding socket"); | |
| } | |
| // servinfo is not needed anymore | |
| freeaddrinfo(servinfo); | |
| if (listen(sockfd, BACKLOG) != 0) | |
| { | |
| perror("Problem listening"); | |
| } | |
| while (1) | |
| { | |
| addr_size = sizeof their_addr; | |
| // this needs to be changed to accept multiple connections | |
| new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size); | |
| lenm = strlen(msgb); | |
| recieved = recv(new_fd, recvb, sizeof recvb, 0); | |
| sscanf(recvb, "%s %s %s", method, uri, version); | |
| if (strcmp(uri, "/") == 0) | |
| { | |
| bytes_sent = send(new_fd, msgb, lenm, 0); | |
| } | |
| else if (strcmp(uri, "/vader") == 0) | |
| { | |
| char *msgd = "James earl Jones sent for me"; | |
| lenm = strlen(msgd); | |
| bytes_sent = send(new_fd, msgd, lenm, 0); | |
| } | |
| else if (strcmp(uri, "/http") == 0) | |
| { | |
| bytes_sent = send(new_fd, resp, strlen(resp), 0); | |
| } | |
| else | |
| { | |
| bytes_sent = send(new_fd, "404", strlen("404"), 0); | |
| } | |
| printf(recvb); | |
| close(new_fd); | |
| } | |
| // of the above shoudl be error checked, returns 0/1 if no problem | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment