Skip to content

Instantly share code, notes, and snippets.

@epshteinmatthew
Last active July 14, 2022 13:08
Show Gist options
  • Select an option

  • Save epshteinmatthew/186e2ccd433bb2d722a45ec6a8b2972b to your computer and use it in GitHub Desktop.

Select an option

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.
#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