Commit Diff


commit - 3b486b32233bf7e55e12e568e2c799990abf9e37
commit + c83e450a02fd06d73c5cbc444a1ccd6fc0bf0fa6
blob - 4122004350c48f4836092646efbd80ac564d455d
blob + 62fe18352621f0158077483ff1740b4cf7c4ab32
--- web/http.c
+++ web/http.c
@@ -112,8 +112,11 @@ http_parse(struct request *req, int fd)
 				if (*t != '\0')
 					*t++ = '\0';
 				req->path = xstrdup(s);
-				if (strcmp("HTTP/1.0", t) != 0 &&
-				    strcmp("HTTP/1.1", t) != 0) {
+				if (!strcmp("HTTP/1.0", t))
+					req->version = HTTP_1_0;
+				else if (!strcmp("HTTP/1.1", t))
+					req->version = HTTP_1_1;
+				else {
 					log_warnx("unknown http version: %s",
 					    t);
 					return -1;
@@ -194,10 +197,11 @@ http_read(struct request *req, int fd)
 }
 
 void
-http_response_init(struct reswriter *res, int fd)
+http_response_init(struct reswriter *res, struct request *req, int fd)
 {
 	memset(res, 0, sizeof(*res));
 	res->fd = fd;
+	res->chunked = req->version == HTTP_1_1;
 }
 
 int
@@ -208,13 +212,12 @@ http_reply(struct reswriter *res, int code, const char
 	int		 r;
 
 	res->len = 0;	/* discard any leftover from reading */
-	res->chunked = ctype != NULL;
 
 	log_debug("> %d %s", code, reason);
 
 	if (code >= 300 && code < 400) {
 		location = ctype;
-		ctype = NULL;
+		ctype = "text/html;charset=UTF-8";
 	}
 
 	r = snprintf(res->buf, sizeof(res->buf), "HTTP/1.1 %d %s\r\n"
@@ -231,11 +234,23 @@ http_reply(struct reswriter *res, int code, const char
 	    location == NULL ? "" : "Location: ",
 	    location == NULL ? "" : location,
 	    location == NULL ? "" : "\r\n",
-	    ctype == NULL ? "" : "Transfer-Encoding: chunked\r\n");
+	    res->chunked ? "Transfer-Encoding: chunked\r\n" : "");
 	if (r < 0 || (size_t)r >= sizeof(res->buf))
 		return -1;
 
-	return writeall(res, res->buf, r);
+	if (writeall(res, res->buf, r) == -1)
+		return -1;
+
+	if (location) {
+		if (http_writes(res, "<a href='") == -1 ||
+		    http_htmlescape(res, location) == -1 ||
+		    http_writes(res, "'>") == -1 ||
+		    http_htmlescape(res, reason) == -1 ||
+		    http_writes(res, "</a>") == -1)
+			return -1;
+	}
+
+	return 0;
 }
 
 int
@@ -253,6 +268,13 @@ http_flush(struct reswriter *res)
 	if (res->len == 0)
 		return 0;
 
+	if (!res->chunked) {
+		if (writeall(res, res->buf, res->len) == -1)
+			return -1;
+		res->len = 0;
+		return 0;
+	}
+
 	r = snprintf(buf, sizeof(buf), "%zx\r\n", res->len);
 	if (r < 0 || (size_t)r >= sizeof(buf)) {
 		log_warn("snprintf failed");
blob - c457f7765fa8d07caa8b0cb7f255800debb1787f
blob + 51cbdb77bac5f32482d1db3184660b2a6e2cac12
--- web/http.h
+++ web/http.h
@@ -20,12 +20,18 @@ enum http_method {
 	METHOD_POST,
 };
 
+enum http_version {
+	HTTP_1_0,
+	HTTP_1_1,
+};
+
 struct request {
 	char	buf[BUFSIZ];
 	size_t	len;
 
 	char	*path;
 	int	 method;
+	int	 version;
 	char	*ctype;
 	size_t	 clen;
 };
@@ -40,7 +46,7 @@ struct reswriter {
 
 int	http_parse(struct request *, int);
 int	http_read(struct request *, int);
-void	http_response_init(struct reswriter *, int);
+void	http_response_init(struct reswriter *, struct request *, int);
 int	http_reply(struct reswriter *, int, const char *, const char *);
 int	http_flush(struct reswriter *);
 int	http_write(struct reswriter *, const char *, size_t);
blob - 3904a24bfcba03acd812a6e6f3be7564415b3978
blob + 9e64528d62a13660ef647ef40120c6a03dc0efa6
--- web/web.c
+++ web/web.c
@@ -645,7 +645,7 @@ handle_client(int psock)
 		close(sock);
 		return;
 	}
-	http_response_init(&res, sock);
+	http_response_init(&res, &req, sock);
 	route_dispatch(&res, &req);
 	http_flush(&res);
 	http_close(&res);