-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.c
100 lines (83 loc) · 2.84 KB
/
server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
void error(char *msg){
perror(msg);
exit(1);
}
void send_response(int sockfd, const char *status, const char *content_type, const char *body) {
char response[1024];
sprintf(response, "HTTP/1.1 %s\r\nContent-Type: %s\r\nContent-Length: %ld\r\n\r\n%s",
status, content_type, strlen(body), body);
write(sockfd, response, strlen(response));
}
struct http_request {
char method[10];
char path[256];
char version[10];
};
void parse_request(char *buffer, struct http_request *req) {
sscanf(buffer, "%s %s %s", req->method, req->path, req->version);
}
void handle_route(int sockfd, struct http_request *req) {
if (strcmp(req->path, "/") == 0) {
send_response(sockfd, "200 OK", "text/html",
"<html><body>"
"<h1>Related resources I used:</h1>"
"<a href='https://www.linuxhowtos.org/C_C++/socket.htm'>LinuxHowTos</a><br>"
"<a href='https://youtu.be/gnvDPCXktWQ?si=HiO1_CJPYCXq6gAV'>YT</a><br>"
"<a href='https://github.com/stktyagi/Socket-Programming-in-C/blob/main/README.md'>README</a>"
"</body></html>");
} else if (strcmp(req->path, "/about") == 0) {
send_response(sockfd, "200 OK", "text/html", "<html><body><h1>About Page</h1></body></html>");
} else {
send_response(sockfd, "404 Not Found", "text/html", "<html><body><h1>404 Not Found</h1></body></html>");
}
}
int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno, clilen;
char buffer[1024];
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2) {
fprintf(stderr, "Port number not provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
error("Error opening socket");
}
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
error("Error on binding");
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) {
error("Error on accept");
}
bzero(buffer, 1024);
read(newsockfd, buffer, 1023);
struct http_request req;
parse_request(buffer, &req);
if (strcmp(req.method, "GET") == 0) {
handle_route(newsockfd, &req);
}
else {
send_response(newsockfd, "405 Method Not Allowed", "text/html", "<html><body><h1>405 Method Not Allowed</h1></body></html>");
}
close(newsockfd);
}
close(sockfd);
return 0;
}