Skip to content

Commit 4d8f68a

Browse files
committed
Add comments to improve code readability
1 parent a789cee commit 4d8f68a

File tree

6 files changed

+70
-1
lines changed

6 files changed

+70
-1
lines changed

src/conversion.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "conversion.h"
22

3+
// Shall I need to convert that image? This function gives us a clue.
34
int is_image(char *tok) {
45
if (!strncmp(&tok[0], "image/jpeg", strlen("image/jpeg"))) {
56
return 1;
@@ -22,21 +23,26 @@ int is_image(char *tok) {
2223
return 0;
2324
}
2425

26+
// Checker for headers: does this header have quality inside?
2527
int has_quality(char *tok) {
2628
if (strstr(tok, ";q=") != NULL) {
2729
return 1;
2830
}
2931
return 0;
3032
}
3133

34+
// Here we take an header and give back the conversion quality as an int.
3235
int conversion_quality(char *header) {
3336
char *tok, *str, *dbuf;
3437
double quality;
3538
int retval;
3639

3740
dbuf = str = strdup(header);
41+
// Iteration upon tokens returned by strsep
3842
while ((tok = strsep(&str, ",")) != NULL) {
3943
if (is_image(tok) && has_quality(tok)) {
44+
// strsep again upon a different token
45+
// to get our quality
4046
strsep(&tok, ";q=");
4147
tok += 2;
4248
quality = atof(tok)*100;
@@ -49,6 +55,7 @@ int conversion_quality(char *header) {
4955
return 0;
5056
}
5157

58+
// Compute a cached filename from a basic filename buffer
5259
char * cached_filename(char *buf, int quality) {
5360
char *str;
5461
char *retval = malloc(sizeof(buf)+4);
@@ -64,11 +71,14 @@ char * cached_filename(char *buf, int quality) {
6471
return retval;
6572
}
6673

74+
// Cache hit helper function.
6775
int cachehit(char *buf, hcontainer *headers) {
6876
char *cachedfn, *toaccess;
6977
int q;
7078
if (!strcmp(headers[0].val, "")) { return 0; }
7179

80+
// Checking if we have a conversion quality > 0
81+
// Then computing the correct filename
7282
if ((q = conversion_quality(headers[0].val)) == 0) { return 0; }
7383
cachedfn = cached_filename(buf, q);
7484

@@ -78,17 +88,25 @@ int cachehit(char *buf, hcontainer *headers) {
7888

7989
printf("%s\n", toaccess);
8090

91+
// If the cached copy doesn't exist, we convert
92+
// the file on-the-fly with an helper
8193
if (access(toaccess, F_OK | R_OK) == 0) {
8294
logger(LOG, "Cache hit!", "serving the cached file");
8395
} else {
8496
logger(LOG, "Cache didn't hit", "still need to convert the file");
8597
convert_img(buf, cachedfn, q);
8698
}
8799

100+
// Here we violate the single responsibility principle
101+
// editing the buffer and pointing it to another file.
102+
// The cached one.
88103
strcpy(buf, cachedfn);
89104
return 1;
90105
}
91106

107+
// We use an sprintf-powered builder to build up a string
108+
// then we issue a system command. We use this function as
109+
// an abstraction layer upon `convert`.
92110
int convert_img(char *source, char *dest, int quality) {
93111
char cmd[sizeof(source)+sizeof(dest)+211];
94112

src/error_handler.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "error_handler.h"
22

3+
// Error handler shorthand function.
4+
// We have a switch case and various writes to the buffer,
5+
// each one with a static response.
36
void handle_error(int type, int socket_fd) {
47
switch(type) {
58
case ERROR:

src/grocery.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
#include "grocery.h"
22

3+
// Prints an help string if needed.
34
void print_help() {
45
printf("Usage: ./grocery 8080");
56
}
67

8+
// Preliminary checks for execution.
9+
// We create the cache directory, and we check for proper arguments.
10+
// In case we don't meet the requirements, we exit(0).
711
void preliminary_checks(int argc, char **argv) {
812
if (argc != 2 || !strcmp(argv[1], "-h")) {
913
print_help();
@@ -23,14 +27,15 @@ void preliminary_checks(int argc, char **argv) {
2327
}
2428
}
2529

30+
// Spawning the server
2631
void spawn_server(char **argv) {
2732
int pid, lfd, sock_fd, optv;
2833
static struct sockaddr_in cli;
2934
static struct sockaddr_in server;
3035

3136
socklen_t l;
3237

33-
/* Just ignore SIGCHLD and SIGHUP, we don't care. */
38+
// Just ignore SIGCHLD and SIGHUP, we don't care.
3439
signal(SIGHUP, SIG_IGN);
3540
signal(SIGCHLD, SIG_IGN);
3641

@@ -47,16 +52,23 @@ void spawn_server(char **argv) {
4752

4853
printf("grocery listening on port %s\n", argv[1]);
4954

55+
// Endless loop to accept requests and
56+
// dispatch new child processes
5057
for (;;) {
5158
l = sizeof(cli);
5259

60+
// Accept incoming connections, fork and handle requests
5361
if ((sock_fd = accept(lfd, (struct sockaddr *)&cli, &l)) < 0) { logger(ERROR, "Error during a syscall", "accept"); }
5462

5563
if ((pid = fork()) < 0) {
5664
logger(ERROR, "Error during a syscall", "fork()");
5765
}
5866
else {
5967
if (pid == 0) {
68+
// Properly handle requests passing the socket file descriptor
69+
// as an argument. The second argument is the keepalive one.
70+
// Basing a logic upon this lets us discriminate about requests
71+
// coming from keepalive connections or not.
6072
request_handler(sock_fd, 0);
6173
} else {
6274
close(sock_fd);
@@ -65,6 +77,9 @@ void spawn_server(char **argv) {
6577
}
6678
}
6779

80+
// Main function.
81+
// We run our preliminary checks, then we spawn the server
82+
// passing the argv arguments array to bind properly
6883
int main(int argc, char **argv) {
6984
preliminary_checks(argc, argv);
7085
spawn_server(argv);

src/headers.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "headers.h"
22

3+
// Determine an header's length
4+
// iterating on the buffer.
35
int headers_l(char *buf) {
46
int i, res = 0;
57
for (i = 0; i < BUFSIZE; i++) {
@@ -11,6 +13,9 @@ int headers_l(char *buf) {
1113
return res;
1214
}
1315

16+
// Look for a particular header in the buffer.
17+
// Takin' a label, the buffer, and iterate on the
18+
// buffer until we find the Ring.
1419
char * hlook(char *label, char *buf) {
1520
char *tk, *str, *dbuf;
1621
dbuf = str = strdup(buf);

src/logger.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "logger.h"
22

3+
// Constants-powered logger shorthand function.
4+
// We print all of our informations to the STDOUT,
5+
// then to a `grocery.log` plain text file.
36
void logger(int type, char *s1, char *s2) {
47
int fd;
58
char logbuffer[BUFSIZE*2];

src/request_handler.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#include "request_handler.h"
22

3+
// Request identifier.
34
char * whichreq(char *buf) {
45
if (!strncmp(&buf[0],"GET", 3) || !strncmp(&buf[0],"get", 3)) { return "get"; }
56
if (!strncmp(&buf[0],"HEAD", 4) || !strncmp(&buf[0],"head", 4)) { return "head"; }
67
return "other";
78
}
89

10+
// Unsupported method handler. Here we print out to the response buffer a 405 Unsupported Method.
911
void handle_unsupported_method(int sock_fd, char *buf) {
1012
sprintf(
1113
buf,
@@ -17,18 +19,24 @@ void handle_unsupported_method(int sock_fd, char *buf) {
1719
exit(0);
1820
}
1921

22+
// Handler for GETs.
2023
void handle_get(int sock_fd, char *buf, char *ext, hcontainer *headers) {
2124
int fle;
2225
long ln, rt;
2326
char fn[sizeof(buf) + 11];
2427

28+
// Here we check for cache-hit and set an eventual cache directory prefix
29+
// otherwise we use `./www`
2530
if (is_image(ext) && cachehit(&buf[5], headers)) {
2631
strcpy(fn, "./cache/");
2732
strcat(fn, &buf[5]);
2833
} else {
2934
strcpy(fn, "./www/");
3035
strcat(fn, &buf[5]);
3136
}
37+
38+
// ... then we try to open the file.
39+
// If we can't open it, we fire a 404 Not Found.
3240
if ((fle = open(fn, O_RDONLY)) == -1) {
3341
logger(NOTFOUND, "not found", &buf[5]);
3442
handle_error(NOTFOUND, sock_fd);
@@ -37,6 +45,8 @@ void handle_get(int sock_fd, char *buf, char *ext, hcontainer *headers) {
3745
logger(LOG, "GET", &buf[5]);
3846
ln = (long)lseek(fle, (off_t)0, SEEK_END);
3947
lseek(fle, (off_t)0, SEEK_SET);
48+
49+
// Print the response' header to the response buffer
4050
sprintf(
4151
buf,
4252
"HTTP/1.1 200 OK\nServer: grocery/%d.0\nContent-Length: %ld\nConnection: %s\nContent-Type: %s\n\n",
@@ -47,13 +57,15 @@ void handle_get(int sock_fd, char *buf, char *ext, hcontainer *headers) {
4757
);
4858
write(sock_fd, buf, strlen(buf));
4959

60+
// Then write the actual file to the buffer.
5061
while ((rt = read(fle, buf, BUFSIZE)) > 0) {
5162
write(sock_fd, buf, rt);
5263
}
5364

5465
close(fle);
5566
sleep(1);
5667

68+
// Check for a keepalive header, then dispatch another handler or close everything and die
5769
if (strlen(headers[1].val) != 0 && !strncmp(&headers[1].val[1], "close", 5)) {
5870
close(sock_fd);
5971
free(headers);
@@ -66,6 +78,8 @@ void handle_get(int sock_fd, char *buf, char *ext, hcontainer *headers) {
6678
}
6779
}
6880

81+
// HEAD handler.
82+
// Very similar to the one above, but without the file body.
6983
void handle_head(int sock_fd, char *buf, char *ext) {
7084
int fle;
7185
long ln;
@@ -93,13 +107,15 @@ void handle_head(int sock_fd, char *buf, char *ext) {
93107
exit(0);
94108
}
95109

110+
// Generic request handler.
96111
void request_handler(int sock_fd, int keepalive) {
97112
long rt, ln, i;
98113
static char buf[BUFSIZE+1];
99114
char *method, *ext;
100115

101116
hcontainer headers[3];
102117

118+
// We declare a struct of supported extensions/filetypes
103119
struct {
104120
char *ext;
105121
char *filetype;
@@ -118,6 +134,7 @@ void request_handler(int sock_fd, int keepalive) {
118134
{0, 0}
119135
};
120136

137+
// Read the request then check for errors
121138
rt = read(sock_fd, buf, BUFSIZE);
122139
if (rt == -1) {
123140
logger(ERROR, "Error reading request", "read()");
@@ -129,6 +146,8 @@ void request_handler(int sock_fd, int keepalive) {
129146

130147
(rt > 0 && rt < BUFSIZE) ? (buf[rt] = 0) : (buf[0] = 0);
131148

149+
// Check for headers through `hlook`, then
150+
// populate the `headers` struct
132151
if (keepalive == 0) {
133152
headers[0].key = "Accept";
134153
headers[0].val = hlook("Accept: ", buf);
@@ -151,13 +170,16 @@ void request_handler(int sock_fd, int keepalive) {
151170
break;
152171
}
153172
}
173+
// index.html standard support!
154174
if (!strncmp(&buf[0],"GET /\0", 6) || !strncmp(&buf[0],"get /\0", 6)) {
155175
strcpy(buf, "GET /index.html");
156176
}
157177
if (!strncmp(&buf[0],"HEAD /\0", 7) || !strncmp(&buf[0],"head /\0", 7)) {
158178
strcpy(buf, "HEAD /index.html");
159179
}
160180

181+
// Check if the file extension is supported, then
182+
// fire a 403 Forbidden if this is not the case
161183
ext = "";
162184
for (i = 0; extensions[i].ext != 0; i++) {
163185
ln = strlen(extensions[i].ext);
@@ -170,6 +192,9 @@ void request_handler(int sock_fd, int keepalive) {
170192
handle_error(FORBIDDEN, sock_fd);
171193
}
172194

195+
// Discriminate incoming requests.
196+
// Should I use GET' handler? HEAD's one?
197+
// Should I stay or should I go?
173198
method = whichreq(buf);
174199
if (!strncmp(&method[0], "get", 3)) {
175200
handle_get(sock_fd, buf, ext, headers);

0 commit comments

Comments
 (0)