Skip to content

Instantly share code, notes, and snippets.

@tvlooy
Last active November 30, 2018 19:47
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tvlooy/8f5c9253f9e283eaee9a77e9721daa52 to your computer and use it in GitHub Desktop.
Save tvlooy/8f5c9253f9e283eaee9a77e9721daa52 to your computer and use it in GitHub Desktop.
OpenBSD httpd errordocs patch
Index: httpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.76
diff -u -p -u -r1.76 httpd.conf.5
--- httpd.conf.5 14 Nov 2016 10:28:31 -0000 1.76
+++ httpd.conf.5 21 Nov 2016 19:12:34 -0000
@@ -128,6 +128,9 @@ If not specified, it defaults to
within the
.Xr chroot 2
directory.
+.It Ic errordocs Ar directory
+Specifies the full path in the chroot of the directory where custom error
+documents are held. The filenames are named like 404.html, ...
.It Ic prefork Ar number
Run the specified number of server processes.
This increases the performance and prevents delays when connecting
Index: httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.123
diff -u -p -u -r1.123 httpd.h
--- httpd.h 6 Nov 2016 10:49:38 -0000 1.123
+++ httpd.h 21 Nov 2016 19:12:34 -0000
@@ -514,6 +514,7 @@ struct httpd {
int sc_paused;
char *sc_chroot;
char *sc_logdir;
+ char *sc_errordocs;
struct serverlist *sc_servers;
struct mediatypes *sc_mediatypes;
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.84
diff -u -p -u -r1.84 parse.y
--- parse.y 6 Nov 2016 15:50:47 -0000 1.84
+++ parse.y 21 Nov 2016 19:12:34 -0000
@@ -134,7 +134,7 @@ typedef struct {
%token LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK
%token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TIMEOUT
%token TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
-%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS
+%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS ERRORDOCS
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.port> port
@@ -206,6 +206,9 @@ main : PREFORK NUMBER {
| LOGDIR STRING {
conf->sc_logdir = $2;
}
+ | ERRORDOCS STRING {
+ conf->sc_errordocs = $2;
+ }
| DEFAULT TYPE mediastring {
memcpy(&conf->sc_default_type, &media,
sizeof(struct media_type));
@@ -1198,6 +1201,7 @@ lookup(char *s)
{ "drop", DROP },
{ "ecdhe", ECDHE },
{ "error", ERR },
+ { "errordocs", ERRORDOCS },
{ "fastcgi", FCGI },
{ "hsts", HSTS },
{ "include", INCLUDE },
Index: server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.110
diff -u -p -u -r1.110 server_http.c
--- server_http.c 26 Aug 2016 10:46:39 -0000 1.110
+++ server_http.c 21 Nov 2016 19:12:34 -0000
@@ -734,6 +734,8 @@ server_abort_http(struct client *clt, un
char buf[IBUF_READ_SIZE];
char *escapedmsg = NULL;
int bodylen;
+ char *errordoc_name;
+ FILE *errordoc_fd;
if (code == 0) {
server_close(clt, "dropped");
@@ -803,29 +805,69 @@ server_abort_http(struct client *clt, un
free(escapedmsg);
- /* A CSS stylesheet allows minimal customization by the user */
- style = "body { background-color: white; color: black; font-family: "
- "'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }\n"
- "hr { border: 0; border-bottom: 1px dashed; }\n";
-
- /* Generate simple HTML error document */
- if ((bodylen = asprintf(&body,
- "<!DOCTYPE html>\n"
- "<html>\n"
- "<head>\n"
- "<meta http-equiv=\"Content-Type\" content=\"text/html; "
- "charset=utf-8\"/>\n"
- "<title>%03d %s</title>\n"
- "<style type=\"text/css\"><!--\n%s\n--></style>\n"
- "</head>\n"
- "<body>\n"
- "<h1>%03d %s</h1>\n"
- "<hr>\n<address>%s</address>\n"
- "</body>\n"
- "</html>\n",
- code, httperr, style, code, httperr, HTTPD_SERVERNAME)) == -1) {
- body = NULL;
- goto done;
+ if (httpd_env->sc_errordocs != NULL) {
+ errordoc_name = malloc(strlen(httpd_env->sc_errordocs + 10)); // 10 = /xxx.html\0
+ asprintf(&errordoc_name, "%s/%d.html", httpd_env->sc_errordocs, code);
+ }
+
+ if (httpd_env->sc_errordocs != NULL && access(errordoc_name, F_OK) != -1) {
+ errordoc_fd = fopen(errordoc_name, "r");
+ if (! errordoc_fd) {
+ log_debug("Error file exists but can't be read.");
+ body = NULL;
+ goto done;
+ }
+
+ fseek(errordoc_fd, 0L, SEEK_END);
+ bodylen = ftell(errordoc_fd);
+ rewind(errordoc_fd);
+
+ /* allocate memory for the entire error document */
+ body = malloc(bodylen + 1);
+ if (! body) {
+ log_debug("Can't allocate memory for error document.");
+ fclose(errordoc_fd);
+ bodylen = 0;
+ body = NULL;
+ goto done;
+ }
+
+ /* copy the error document into the buffer */
+ if (fread(body, bodylen, 1, errordoc_fd) != 1) {
+ log_debug("Cannot copy the error document into the buffer.");
+ fclose(errordoc_fd);
+ bodylen = 0;
+ body = NULL;
+ goto done;
+ }
+ body[bodylen] = 0;
+
+ fclose(errordoc_fd);
+ } else {
+ /* A CSS stylesheet allows minimal customization by the user */
+ style = "body { background-color: white; color: black; font-family: "
+ "'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }\n"
+ "hr { border: 0; border-bottom: 1px dashed; }\n";
+
+ /* Generate simple HTML error document */
+ if ((bodylen = asprintf(&body,
+ "<!DOCTYPE html>\n"
+ "<html>\n"
+ "<head>\n"
+ "<meta http-equiv=\"Content-Type\" content=\"text/html; "
+ "charset=utf-8\"/>\n"
+ "<title>%03d %s</title>\n"
+ "<style type=\"text/css\"><!--\n%s\n--></style>\n"
+ "</head>\n"
+ "<body>\n"
+ "<h1>%03d %s</h1>\n"
+ "<hr>\n<address>%s</address>\n"
+ "</body>\n"
+ "</html>\n",
+ code, httperr, style, code, httperr, HTTPD_SERVERNAME)) == -1) {
+ body = NULL;
+ goto done;
+ }
}
if (srv_conf->flags & SRVFLAG_SERVER_HSTS) {
@tvlooy
Copy link
Author

tvlooy commented Nov 21, 2016

My /etc/httpd.conf

errordocs "/error_documents"
server "default" {
    listen on egress port 80

    root "/htdocs/test"

    directory {
        index "index.php"
    }
    location "/*.php*" {
        fastcgi socket "/run/php-fpm.sock"
    }
}

Output:

# httpd -dn
configuration OK

@Ranguvar
Copy link

@Ranguvar
Copy link

Not working for me on 6.4, may be patch issue or something else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment