simplefiles

A lightweight C CGI web application for managing files.
git clone https://scm.kuandu.systems/git-raw/simplefiles.git
Log | Files | Refs | README | LICENSE

http.c (2042B)


      1 #include <stdio.h>
      2 
      3 #include "html.h"
      4 #include "http.h"
      5 
      6 void
      7 html_headers(const char *status)
      8 {
      9 	printf("Status: %s\r\n", status);
     10 	printf("Content-Type: text/html; charset=utf-8\r\n");
     11 	printf("X-Content-Type-Options: nosniff\r\n");
     12 	printf("X-Frame-Options: DENY\r\n");
     13         printf("\r\n");
     14 }
     15 
     16 int
     17 download_headers(const char *filename, off_t size)
     18 {
     19 	const unsigned char *p;
     20 
     21 	if (filename == NULL)
     22 		return -1;
     23 
     24 	for (p = (const unsigned char *) filename; *p != '\0'; p++) {
     25 		if (*p == '\r' || *p == '\n')
     26 			return -1;
     27 	}
     28 
     29 	printf("Status: 200 OK\r\n");
     30 	printf("Content-Type: application/octet-stream\r\n");
     31 	printf("Content-Disposition: attachment; filename=\"%s\"\r\n",
     32 	    filename);
     33 	printf("Content-Length: %lld\r\n", (long long) size);
     34 	printf("X-Content-Type-Options: nosniff\r\n");
     35 	printf("X-Frame-Options: DENY\r\n");
     36 	printf("\r\n");
     37 
     38 	return 0;
     39 }
     40 
     41 void
     42 reply(const char *status, const char *msg)
     43 {
     44 	html_headers(status);
     45 
     46         printf("<!doctype html>\n");
     47         printf("<html>\n");
     48         printf("<body>\n");
     49         printf("<h1>");
     50         html_escape(stdout, msg);
     51         printf("</h1>\n");
     52         printf("</body>\n");
     53         printf("</html>\n");
     54 }
     55 
     56 void
     57 redirect(const char *uri)
     58 {
     59         printf("Status: 303 See Other\r\n");
     60         printf("Location: %s\r\n", uri);
     61         printf("\r\n");
     62 }
     63 
     64 int
     65 render_template_response(const char *template,
     66     const struct html_var *vars, size_t nvars,
     67     const struct html_block *blocks, size_t nblocks)
     68 {
     69 	FILE *tmp;
     70 	char buffer[8192];
     71 	size_t n;
     72 
     73 	tmp = tmpfile();
     74 	if (tmp == NULL)
     75 		return -1;
     76 
     77 	if (render_template(tmp,
     78 	    template,
     79 	    vars, nvars,
     80 	    blocks, nblocks) == -1) {
     81 		fclose(tmp);
     82 		return -1;
     83 	}
     84 
     85 	if (fflush(tmp) == EOF ||
     86 	    fseek(tmp, 0, SEEK_SET) == -1) {
     87 		fclose(tmp);
     88 		return -1;
     89 	}
     90 
     91 	html_headers("200 OK");
     92 
     93 	while ((n = fread(buffer, 1, sizeof(buffer), tmp)) > 0) {
     94 		if (fwrite(buffer, 1, n, stdout) != n) {
     95 			fclose(tmp);
     96 			return -1;
     97 		}
     98 	}
     99 
    100 	if (ferror(tmp)) {
    101 		fclose(tmp);
    102 		return -1;
    103 	}
    104 
    105 	fclose(tmp);
    106 	return 0;
    107 }