static Response *staticHandler(Request *req) { ROUTE(req, "/static/"); // EXIT ON SHENANIGANS if (strstr(req->uri, "../")) return NULL; char *filename = req->uri + 1; // EXIT ON DIRS struct stat sbuff; if (stat(filename, &sbuff) < 0 || S_ISDIR(sbuff.st_mode)) return NULL; // EXIT ON NOT FOUND FILE *file = fopen(filename, "r"); if (!file) return NULL; // GET LENGTH char *buff; char lens[25]; size_t len; fseek(file, 0, SEEK_END); len = ftell(file); sprintf(lens, "%ld", (long int) len); rewind(file); // SET BODY Response *response = responseNew(); buff = malloc(sizeof(char) * len); fread(buff, sizeof(char), len, file); responseSetBody(response, bsNewLen(buff, len)); fclose(file); free(buff); // MIME TYPE char *mimeType = "text/plain"; len = bsGetLen(req->uri); if (!strncmp(req->uri + len - 4, "html", 4)) mimeType = "text/html"; else if (!strncmp(req->uri + len - 4, "json", 4)) mimeType = "application/json"; else if (!strncmp(req->uri + len - 4, "jpeg", 4)) mimeType = "image/jpeg"; else if (!strncmp(req->uri + len - 3, "jpg", 3)) mimeType = "image/jpeg"; else if (!strncmp(req->uri + len - 3, "gif", 3)) mimeType = "image/gif"; else if (!strncmp(req->uri + len - 3, "png", 3)) mimeType = "image/png"; else if (!strncmp(req->uri + len - 3, "css", 3)) mimeType = "text/css"; else if (!strncmp(req->uri + len - 2, "js", 2)) mimeType = "application/javascript"; // RESPOND responseSetStatus(response, OK); responseAddHeader(response, "Content-Type", mimeType); responseAddHeader(response, "Content-Length", lens); responseAddHeader(response, "Cache-Control", "max-age=2592000"); return response; }
char *bsCat(char *bs1, char *bs2) { size_t len1 = bsGetLen(bs1); size_t len2 = bsGetLen(bs2); size_t len = len1 + len2; char *bs = BS_HEADER_LEN + malloc(sizeof(char) * BS_HEADER_LEN + sizeof(char) * (len + 1)); strcpy(bs, bs1); strcpy(bs + len1, bs2); bsSetLen(bs, len); return bs; }
void bsLCat(char **orig, char *s) { size_t lenO = bsGetLen(*orig); size_t lenS = strlen(s); size_t len = lenO + lenS; *orig = BS_HEADER_LEN + (char *) realloc(*orig - BS_HEADER_LEN, sizeof(char) * BS_HEADER_LEN + sizeof(char) * (len + 1)); strcpy(*orig + lenO, s); bsSetLen(*orig, len); }
char *bsSubstr(char *orig, uint32_t beginning, int32_t end) { size_t len = bsGetLen(orig); size_t newLen = (end <= 0) ? len - beginning + end : end - beginning; assert(newLen > 0); assert(newLen <= len); char *bs = BS_HEADER_LEN + malloc(sizeof(char) * BS_HEADER_LEN + sizeof(char) * (newLen + 1)); memcpy(bs, orig + beginning, newLen); bsSetLen(bs, newLen); return bs; }
void responseWrite(Response *response, int fd) { ListCell *buffer = NULL; ListCell *header; char sbuffer[2048]; // HEADERS header = response->headers; while (header) { sprintf(sbuffer, "%s: %s\r\n", ((KV *)header->value)->key, ((KV *)header->value)->value); buffer = listCons(sbuffer, sizeof(char) * (strlen(sbuffer) + 1), buffer); header = header->next; } // STATUS sprintf(sbuffer, "HTTP/1.0 %d %s\r\n", response->status, STATUSES[response->status / 100 - 1][response->status % 100]); buffer = listCons(sbuffer, sizeof(char) * (strlen(sbuffer) + 1), buffer); // OUTPUT while (buffer) { write(fd, buffer->value, strlen(buffer->value)); buffer = buffer->next; } write(fd, "\r\n", 2); if (response->body) write(fd, response->body, bsGetLen(response->body)); }