Commit Diff


commit - 0792225237dc78b7edaf36ab8a3e7c1199874c1b
commit + 5163fbe9321a5cb71b9c71ee25f2d6691fa92ee5
blob - afe0005e65e130c9d747fdc7ffa3527c49acd8a3
blob + 7aa8029c8fc0b3e874cb757e725c4670f09ed977
--- proxy.c
+++ proxy.c
@@ -58,6 +58,7 @@ int	proxy_dispatch_parent(int, struct privsep_proc *, 
 void	proxy_translate_gemtext(struct client *);
 void	proxy_resolved(struct asr_result *, void *);
 void	proxy_connect(int, short, void *);
+int	proxy_start_reply(struct client *, int, const char *);
 void	proxy_read(struct bufferevent *, void *);
 void	proxy_write(struct bufferevent *, void *);
 void	proxy_error(struct bufferevent *, short, void *);
@@ -357,7 +358,7 @@ proxy_start_request(struct galileo *env, struct client
 	char			 port[32];
 
 	if ((clt->clt_pc = proxy_server_match(env, clt)) == NULL) {
-		if (clt_printf(clt, "Status: 501\r\n\r\n") == -1)
+		if (proxy_start_reply(clt, 501, NULL) == -1)
 			return;
 		fcgi_end_request(clt, 1);
 		return;
@@ -397,9 +398,7 @@ proxy_resolved(struct asr_result *res, void *d)
 		log_warnx("failed to resolve %s:%d: %s",
 		    pc->proxy_addr, pc->proxy_port,
 		    gai_strerror(res->ar_gai_errno));
-		if (clt_printf(clt, "Status: 501\r\n") == -1)
-			return;
-		if (clt_printf(clt, "Content-Type: text/plain\r\n") == -1)
+		if (proxy_start_reply(clt, 501, "text/plain") == -1)
 			return;
 		if (clt_printf(clt, "Proxy error; connection failed") == -1)
 			return;
@@ -515,10 +514,8 @@ done:
 err:
 	log_warn("failed to connect to %s:%d",
 	    clt->clt_pc->proxy_addr, clt->clt_pc->proxy_port);
-	if (clt_printf(clt, "Status: 501\r\n") == -1)
+	if (proxy_start_reply(clt, 501, "text/plain") == -1)
 		return;
-	if (clt_printf(clt, "Content-Type: text/plain\r\n") == -1)
-		return;
 	if (clt_printf(clt, "Proxy error; connection failed") == -1)
 		return;
 	fcgi_end_request(clt, 1);
@@ -592,7 +589,35 @@ proxy_tp_putc(struct template *tp, int c)
 	}
 	return (0);
 }
+
+int
+proxy_start_reply(struct client *clt, int status, const char *ctype)
+{
+	const char	*csp;
 
+	csp = "Content-Security-Policy: default-src 'self'; "
+	    "script-src 'none'; object-src 'none';\r\n";
+
+	if (ctype != NULL && !strcmp(ctype, "text/html"))
+		ctype = "text/html;charset=utf-8";
+
+	if (status != 200 &&
+	    ctl_printf(ctl, "Status: %d\r\n", status) == -1)
+		return (-1);
+
+	if (ctype != NULL &&
+	    clt_printf(clt, "Content-Type: %s\r\n", ctype) == -1)
+		return (-1);
+
+	if (clt_puts(clt, cps) == -1)
+		return (-1);
+
+	if (clt_puts(clt, "\r\n") == -1)
+		return (-1);
+
+	return (0);
+}
+
 void
 proxy_read(struct bufferevent *bev, void *d)
 {
@@ -633,13 +658,8 @@ proxy_read(struct bufferevent *bev, void *d)
 		/* handled below */
 		break;
 	default:
-		if (clt_puts(clt, "Status: 501\r\n") == -1)
-			goto err;
-		if (clt_puts(clt,
-		    "Content-Type: text/plain;charset=utf-8\r\n") == -1)
+		if (proxy_start_reply(clt, 501, "text/plain") == -1)
 			goto err;
-		if (clt_puts(clt, "\r\n") == -1)
-			goto err;
 		if (clt_printf(clt, "Request failed with code %c%c\n\n",
 		    hdr[0], hdr[1]) == -1)
 			goto err;
@@ -651,13 +671,8 @@ proxy_read(struct bufferevent *bev, void *d)
 
 	mime = hdr + 2 + strspn(hdr + 2, " \t");
 	if (parse_mime(clt, mime, lang, sizeof(lang)) == -1) {
-		if (clt_puts(clt, "Status: 501\r\n") == -1)
+		if (proxy_start_reply(clt, 501, "text/plain") == -1)
 			goto err;
-		if (clt_puts(clt,
-		    "Content-Type: text/plain;charset=utf-8\r\n") == -1)
-			goto err;
-		if (clt_puts(clt, "\r\n") == -1)
-			goto err;
 		if (clt_printf(clt, "Failed to parse the Gemini response\n")
 		    == -1)
 		fcgi_end_request(clt, 1);
@@ -708,10 +723,8 @@ proxy_error(struct bufferevent *bev, short err, void *
 	    err);
 
 	if (!clt->clt_headersdone) {
-		if (clt_printf(clt, "Status: 501\r\n") == -1)
+		if (proxy_start_reply(clt, 501, "text/plain") == -1)
 			return;
-		if (clt_printf(clt, "Content-Type: text/plain\r\n") == -1)
-			return;
 		if (clt_printf(clt, "Proxy error\n") == -1)
 			return;
 	} else if (status == 0) {