From 3ad4d2422e2890ceb5779d164979f2887f7adca6 Mon Sep 17 00:00:00 2001 From: reyk Date: Thu, 1 Jan 2015 14:54:06 +0000 Subject: [PATCH] Merge error page changes from httpd: send Content-Length:, change Date: from asctime to the preferred HTTP/1.1 format, and use the popular "Comic Sans" style (can be changed in the configuration). --- usr.sbin/relayd/relay_http.c | 64 +++++++++++++++++++++++------------- usr.sbin/relayd/relayd.h | 3 +- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/usr.sbin/relayd/relay_http.c b/usr.sbin/relayd/relay_http.c index e462034e457..a6a62196abd 100644 --- a/usr.sbin/relayd/relay_http.c +++ b/usr.sbin/relayd/relay_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay_http.c,v 1.38 2015/01/01 14:21:06 reyk Exp $ */ +/* $OpenBSD: relay_http.c,v 1.39 2015/01/01 14:54:06 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -871,6 +871,17 @@ relay_lookup_query(struct ctl_relay_event *cre, struct kv *kv) return (ret); } +ssize_t +relay_http_time(time_t t, char *tmbuf, size_t len) +{ + struct tm tm; + + /* New HTTP/1.1 RFC 7231 prefers IMF-fixdate from RFC 5322 */ + if (t == -1 || gmtime_r(&t, &tm) == NULL) + return (-1); + else + return (strftime(tmbuf, len, "%a, %d %h %Y %T %Z", &tm)); +} void relay_abort_http(struct rsession *con, u_int code, const char *msg, @@ -879,11 +890,10 @@ relay_abort_http(struct rsession *con, u_int code, const char *msg, struct relay *rlay = con->se_relay; struct bufferevent *bev = con->se_in.bev; const char *httperr = NULL, *text = ""; - char *httpmsg; - time_t t; - struct tm *lt; + char *httpmsg, *body = NULL; char tmbuf[32], hbuf[128]; const char *style, *label = NULL; + int bodylen; if ((httperr = relay_httperror_byid(code)) == NULL) httperr = "Unknown Error"; @@ -905,29 +915,26 @@ relay_abort_http(struct rsession *con, u_int code, const char *msg, if (print_host(&rlay->rl_conf.ss, hbuf, sizeof(hbuf)) == NULL) goto done; - /* RFC 2616 "tolerates" asctime() */ - time(&t); - lt = localtime(&t); - tmbuf[0] = '\0'; - if (asctime_r(lt, tmbuf) != NULL) - tmbuf[strlen(tmbuf) - 1] = '\0'; /* skip final '\n' */ + if (relay_http_time(time(NULL), tmbuf, sizeof(tmbuf)) <= 0) + goto done; /* Do not send details of the Internal Server Error */ - if (code != 500) + switch (code) { + case 500: + break; + default: text = msg; + break; + } /* A CSS stylesheet allows minimal customization by the user */ - if ((style = rlay->rl_proto->style) == NULL) - style = "body { background-color: #a00000; color: white; }"; + style = (rlay->rl_proto->style != NULL) ? rlay->rl_proto->style : + "body { background-color: #a00000; color: white; font-family: " + "'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }\n" + "hr { border: 0; border-bottom: 1px dashed; }\n"; /* Generate simple HTTP+HTML error document */ - if (asprintf(&httpmsg, - "HTTP/1.0 %03d %s\r\n" - "Date: %s\r\n" - "Server: %s\r\n" - "Connection: close\r\n" - "Content-Type: text/html\r\n" - "\r\n" + if ((bodylen = asprintf(&body, "\n" "\n" "\n" @@ -941,10 +948,22 @@ relay_abort_http(struct rsession *con, u_int code, const char *msg, "
%s at %s port %d
\n" "\n" "\n", - code, httperr, tmbuf, RELAYD_SERVERNAME, code, httperr, style, httperr, text, label == NULL ? "" : label, - RELAYD_SERVERNAME, hbuf, ntohs(rlay->rl_conf.port)) == -1) + RELAYD_SERVERNAME, hbuf, ntohs(rlay->rl_conf.port))) == -1) + goto done; + + /* Generate simple HTTP+HTML error document */ + if (asprintf(&httpmsg, + "HTTP/1.0 %03d %s\r\n" + "Date: %s\r\n" + "Server: %s\r\n" + "Connection: close\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %d\r\n" + "\r\n" + "%s", + code, httperr, tmbuf, RELAYD_SERVERNAME, bodylen, body) == -1) goto done; /* Dump the message without checking for success */ @@ -952,6 +971,7 @@ relay_abort_http(struct rsession *con, u_int code, const char *msg, free(httpmsg); done: + free(body); if (asprintf(&httpmsg, "%s (%03d %s)", msg, code, httperr) == -1) relay_close(con, msg); else { diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index ab2b534fab4..e319645c707 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.201 2014/12/21 00:54:49 guenther Exp $ */ +/* $OpenBSD: relayd.h,v 1.202 2015/01/01 14:54:06 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -1187,6 +1187,7 @@ const char const char *relay_httperror_byid(u_int); int relay_httpdesc_init(struct ctl_relay_event *); +ssize_t relay_http_time(time_t, char *, size_t); /* relay_udp.c */ void relay_udp_privinit(struct relayd *, struct relay *); -- 2.20.1