diff -Naur Pound-2.0.9.orig/config.c Pound-2.0.9/config.c --- Pound-2.0.9.orig/config.c 2006-06-23 14:10:59.000000000 +0200 +++ Pound-2.0.9/config.c 2006-07-31 02:40:57.000000000 +0200 @@ -78,6 +78,7 @@ static regex_t Service, URL, HeadRequire, HeadDeny, BackEnd, Priority, HAport, HAportAddr, Redirect, TimeOut; static regex_t Session, Type, TTL, ID; static regex_t ClientCert, AddHeader, Ciphers, CAlist, VerifyList, NoHTTPS11; +static regex_t HTMLErr414, HTMLErr500, HTMLErr501, HTMLErr503; static regmatch_t matches[5]; @@ -518,6 +519,22 @@ } else if(!regexec(&Err503, lin, 4, matches, 0)) { lin[matches[1].rm_eo] = '\0'; res->err503 = file2str(lin + matches[1].rm_so); + } else if(!regexec(&HTMLErr414, lin, 4, matches, 0)) { + lin[matches[1].rm_eo] = '\0'; + res->err414 = file2str(lin + matches[1].rm_so); + htmle414 = 1; + } else if(!regexec(&HTMLErr500, lin, 4, matches, 0)) { + lin[matches[1].rm_eo] = '\0'; + res->err500 = file2str(lin + matches[1].rm_so); + htmle500 = 1; + } else if(!regexec(&HTMLErr501, lin, 4, matches, 0)) { + lin[matches[1].rm_eo] = '\0'; + res->err501 = file2str(lin + matches[1].rm_so); + htmle501 = 1; + } else if(!regexec(&HTMLErr503, lin, 4, matches, 0)) { + lin[matches[1].rm_eo] = '\0'; + res->err503 = file2str(lin + matches[1].rm_so); + htmle503 = 1; } else if(!regexec(&MaxRequest, lin, 4, matches, 0)) { res->max_req = atol(lin + matches[1].rm_so); } else if(!regexec(&HeadRemove, lin, 4, matches, 0)) { @@ -654,6 +671,22 @@ } else if(!regexec(&Err503, lin, 4, matches, 0)) { lin[matches[1].rm_eo] = '\0'; res->err503 = file2str(lin + matches[1].rm_so); + } else if(!regexec(&HTMLErr414, lin, 4, matches, 0)) { + lin[matches[1].rm_eo] = '\0'; + res->err414 = file2str(lin + matches[1].rm_so); + htmle414 = 1; + } else if(!regexec(&HTMLErr500, lin, 4, matches, 0)) { + lin[matches[1].rm_eo] = '\0'; + res->err500 = file2str(lin + matches[1].rm_so); + htmle500 = 1; + } else if(!regexec(&HTMLErr501, lin, 4, matches, 0)) { + lin[matches[1].rm_eo] = '\0'; + res->err501 = file2str(lin + matches[1].rm_so); + htmle501 = 1; + } else if(!regexec(&HTMLErr503, lin, 4, matches, 0)) { + lin[matches[1].rm_eo] = '\0'; + res->err503 = file2str(lin + matches[1].rm_so); + htmle503 = 1; } else if(!regexec(&MaxRequest, lin, 4, matches, 0)) { res->max_req = atol(lin + matches[1].rm_so); } else if(!regexec(&HeadRemove, lin, 4, matches, 0)) { @@ -925,6 +958,10 @@ || regcomp(&Err500, "^[ \t]*Err500[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) || regcomp(&Err501, "^[ \t]*Err501[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) || regcomp(&Err503, "^[ \t]*Err503[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) + || regcomp(&HTMLErr414, "^[ \t]*HTMLErr414[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) + || regcomp(&HTMLErr500, "^[ \t]*HTMLErr500[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) + || regcomp(&HTMLErr501, "^[ \t]*HTMLErr501[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) + || regcomp(&HTMLErr503, "^[ \t]*HTMLErr503[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) || regcomp(&MaxRequest, "^[ \t]*MaxRequest[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) || regcomp(&HeadRemove, "^[ \t]*HeadRemove[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) || regcomp(&RewriteLocation, "^[ \t]*RewriteLocation[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) @@ -1043,6 +1080,10 @@ regfree(&Err500); regfree(&Err501); regfree(&Err503); + regfree(&HTMLErr414); + regfree(&HTMLErr500); + regfree(&HTMLErr501); + regfree(&HTMLErr503); regfree(&MaxRequest); regfree(&HeadRemove); regfree(&RewriteLocation); diff -Naur Pound-2.0.9.orig/http.c Pound-2.0.9/http.c --- Pound-2.0.9.orig/http.c 2006-06-23 14:10:59.000000000 +0200 +++ Pound-2.0.9/http.c 2006-07-31 02:40:57.000000000 +0200 @@ -41,11 +41,17 @@ * Reply with an error */ static void -err_reply(BIO *c, char *head, char *txt) +err_reply(BIO *c, char *head, char *txt, int is_html) { char rep[MAXBUF], cont[MAXBUF]; - snprintf(cont, sizeof(cont), err_cont, head, head, txt); + /* error is from complete html file or only error message*/ + if ( is_html ) { + snprintf(cont, sizeof(cont), "%s", txt); + } else { + snprintf(cont, sizeof(cont), err_cont, head, head, txt); + } + snprintf(rep, sizeof(rep), err_head, head, strlen(cont), cont); BIO_write(c, rep, strlen(rep)); BIO_flush(c); @@ -307,13 +313,13 @@ } else if(res >= (MAXBUF - 1)) { /* check for request length limit */ logmsg(LOG_WARNING, "headers: request URI too long"); - err_reply(cl, h414, lstn->err414); + err_reply(cl, h414, lstn->err414, htmle414); return NULL; } if((headers = (char **)calloc(MAXHEADERS, sizeof(char *))) == NULL) { logmsg(LOG_WARNING, "headers: out of memory"); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); return NULL; } @@ -321,14 +327,14 @@ if((headers[n] = (char *)malloc(MAXBUF)) == NULL) { free_headers(headers); logmsg(LOG_WARNING, "header: out of memory"); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); return NULL; } strncpy(headers[n], buf, MAXBUF - 1); if((res = BIO_gets(in, buf, MAXBUF)) <= 0) { free_headers(headers); logmsg(LOG_WARNING, "can't read header"); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); return NULL; } strip_eol(buf); @@ -338,7 +344,7 @@ free_headers(headers); logmsg(LOG_WARNING, "too many headers"); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); return NULL; } @@ -495,7 +501,7 @@ if(!cl_11) { if(errno) logmsg(LOG_WARNING, "error read from %s: %s", inet_ntoa(from_host), strerror(errno)); - /* err_reply(cl, h500, lstn->err500); */ + /* err_reply(cl, h500, lstn->err500, htmle500); */ } clean_all(); pthread_exit(NULL); @@ -515,7 +521,7 @@ /* && strncasecmp(request + matches[1].rm_so, "OPTIONS", matches[1].rm_eo - matches[1].rm_so)); */ } else { logmsg(LOG_WARNING, "bad request \"%s\" from %s", request, inet_ntoa(from_host)); - err_reply(cl, h501, lstn->err501); + err_reply(cl, h501, lstn->err501, htmle501); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -525,7 +531,7 @@ url[matches[2].rm_eo - matches[2].rm_so] = '\0'; if(regexec(&lstn->url_pat, url, 0, NULL, 0)) { logmsg(LOG_WARNING, "bad URL \"%s\" from %s", url, inet_ntoa(from_host)); - err_reply(cl, h501, lstn->err501); + err_reply(cl, h501, lstn->err501, htmle501); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -610,7 +616,7 @@ /* possibly limited request size */ if(lstn->max_req > 0L && cont > 0L && cont > lstn->max_req) { logmsg(LOG_WARNING, "request too large (%ld) from %s", cont, inet_ntoa(from_host)); - err_reply(cl, h501, lstn->err501); + err_reply(cl, h501, lstn->err501, htmle501); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -628,14 +634,14 @@ /* check that the requested URL still fits the old back-end (if any) */ if((svc = get_service(lstn, url, &headers[1])) == NULL) { logmsg(LOG_WARNING, "no service \"%s\" from %s", request, inet_ntoa(from_host)); - err_reply(cl, h503, lstn->err503); + err_reply(cl, h503, lstn->err503, htmle503); free_headers(headers); clean_all(); pthread_exit(NULL); } if((backend = get_backend(svc, from_host, url, &headers[1])) == NULL) { logmsg(LOG_WARNING, "no back-end \"%s\" from %s", request, inet_ntoa(from_host)); - err_reply(cl, h503, lstn->err503); + err_reply(cl, h503, lstn->err503, htmle503); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -650,7 +656,7 @@ if(backend->domain == PF_UNIX) { if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { logmsg(LOG_WARNING, "backend %s create: %s", backend->addr.un.sun_path, strerror(errno)); - err_reply(cl, h503, lstn->err503); + err_reply(cl, h503, lstn->err503, htmle503); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -661,7 +667,7 @@ kill_be(svc, backend); if((backend = get_backend(svc, from_host, url, &headers[1])) == NULL) { logmsg(LOG_WARNING, "no back-end \"%s\" from %s", request, inet_ntoa(from_host)); - err_reply(cl, h503, lstn->err503); + err_reply(cl, h503, lstn->err503, htmle503); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -672,7 +678,7 @@ if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { logmsg(LOG_WARNING, "backend %s:%hd create: %s", inet_ntoa(backend->addr.in.sin_addr), ntohs(backend->addr.in.sin_port), strerror(errno)); - err_reply(cl, h503, lstn->err503); + err_reply(cl, h503, lstn->err503, htmle503); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -684,7 +690,7 @@ kill_be(svc, backend); if((backend = get_backend(svc, from_host, url, &headers[1])) == NULL) { logmsg(LOG_WARNING, "no back-end \"%s\" from %s", request, inet_ntoa(from_host)); - err_reply(cl, h503, lstn->err503); + err_reply(cl, h503, lstn->err503, htmle503); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -701,7 +707,7 @@ logmsg(LOG_WARNING, "BIO_new_socket server failed"); shutdown(sock, 2); close(sock); - err_reply(cl, h503, lstn->err503); + err_reply(cl, h503, lstn->err503, htmle503); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -713,7 +719,7 @@ } if((bb = BIO_new(BIO_f_buffer())) == NULL) { logmsg(LOG_WARNING, "BIO_new(buffer) server failed"); - err_reply(cl, h503, lstn->err503); + err_reply(cl, h503, lstn->err503, htmle503); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -739,7 +745,7 @@ if(BIO_printf(be, "%s\r\n", headers[n]) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); free_headers(headers); clean_all(); pthread_exit(NULL); @@ -755,7 +761,7 @@ if(BIO_printf(be, "%s\r\n", lstn->ssl_head) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write HTTPSHeader to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); clean_all(); pthread_exit(NULL); } @@ -765,7 +771,7 @@ if(BIO_printf(be, "X-SSL-Subject: %s\r\n", buf) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write X-SSL-Subject to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); BIO_free_all(bb); clean_all(); pthread_exit(NULL); @@ -776,7 +782,7 @@ if(BIO_printf(be, "X-SSL-Issuer: %s\r\n", buf) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write X-SSL-Issuer to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); BIO_free_all(bb); clean_all(); pthread_exit(NULL); @@ -787,7 +793,7 @@ if(BIO_printf(be, "X-SSL-notBefore: %s\r\n", buf) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write X-SSL-notBefore to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); BIO_free_all(bb); clean_all(); pthread_exit(NULL); @@ -798,7 +804,7 @@ if(BIO_printf(be, "X-SSL-notAfter: %s\r\n", buf) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write X-SSL-notAfter to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); BIO_free_all(bb); clean_all(); pthread_exit(NULL); @@ -806,7 +812,7 @@ if(BIO_printf(be, "X-SSL-serial: %ld\r\n", ASN1_INTEGER_get(X509_get_serialNumber(x509))) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write X-SSL-serial to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); BIO_free_all(bb); clean_all(); pthread_exit(NULL); @@ -817,7 +823,7 @@ if(BIO_printf(be, "X-SSL-certificate: %s\r\n", buf) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write X-SSL-certificate to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); BIO_free_all(bb); clean_all(); pthread_exit(NULL); @@ -827,7 +833,7 @@ if(BIO_printf(be, "\t%s\r\n", buf) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write X-SSL-certificate to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); BIO_free_all(bb); clean_all(); pthread_exit(NULL); @@ -839,7 +845,7 @@ if(BIO_printf(be, "X-SSL-cipher: %s\r\n", buf) <= 0) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error write X-SSL-cipher to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); clean_all(); pthread_exit(NULL); } @@ -858,7 +864,7 @@ if(cl_11 && chunked) { /* had Transfer-encoding: chunked so read/write all the chunks (HTTP/1.1 only) */ if(copy_chunks(cl, be, NULL, cur_backend->be_type != BACK_END, lstn->max_req)) { - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); clean_all(); pthread_exit(NULL); } @@ -866,7 +872,7 @@ /* had Content-length, so do raw reads/writes for the length */ if(copy_bin(cl, be, cont, NULL, cur_backend->be_type != BACK_END)) { logmsg(LOG_WARNING, "error copy client cont: %s", strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); clean_all(); pthread_exit(NULL); } @@ -876,7 +882,7 @@ if(cur_backend->be_type == BACK_END && BIO_flush(be) != 1) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "error flush to %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); clean_all(); pthread_exit(NULL); } @@ -932,7 +938,7 @@ if((headers = get_headers(be, cl, lstn)) == NULL) { str_be(buf, MAXBUF - 1, cur_backend); logmsg(LOG_WARNING, "response error read from %s: %s", buf, strerror(errno)); - err_reply(cl, h500, lstn->err500); + err_reply(cl, h500, lstn->err500, htmle500); clean_all(); pthread_exit(NULL); } diff -Naur Pound-2.0.9.orig/pound.c Pound-2.0.9/pound.c --- Pound-2.0.9.orig/pound.c 2006-06-23 14:10:59.000000000 +0200 +++ Pound-2.0.9/pound.c 2006-07-31 02:40:57.000000000 +0200 @@ -40,6 +40,11 @@ log_level, /* logging mode - 0, 1, 2 */ print_log; /* print log messages to stdout/stderr */ +int htmle414, /* if html error 414 is used */ + htmle500, /* if html error 500 is used */ + htmle501, /* if html error 515 is used */ + htmle503; /* if html error 503 is used */ + SERVICE *services; /* global services (if any) */ LISTENER *listeners; /* all available listeners */ diff -Naur Pound-2.0.9.orig/pound.h Pound-2.0.9/pound.h --- Pound-2.0.9.orig/pound.h 2006-06-23 14:10:59.000000000 +0200 +++ Pound-2.0.9/pound.h 2006-07-31 02:40:57.000000000 +0200 @@ -233,6 +233,11 @@ log_level, /* logging mode - 0, 1, 2 */ print_log; /* print log messages to stdout/stderr */ +extern int htmle414, /* if html error 414 is used */ + htmle500, /* if html error 500 is used */ + htmle501, /* if html error 515 is used */ + htmle503; /* if html error 503 is used */ + extern regex_t HTTP, /* normal HTTP requests: GET, POST, HEAD */ XHTTP, /* extended HTTP requests: PUT, DELETE */ WEBDAV, /* WebDAV requests: LOCK, UNLOCK, SUBSCRIBE, PROPFIND, PROPPATCH, BPROPPATCH, SEARCH, diff -Naur Pound-2.0.9.orig/pound.8 Pound-2.0.9/pound.8 --- Pound-2.0.9.orig/pound.8 2006-06-23 14:10:59.000000000 +0200 +++ Pound-2.0.9/pound.8 2006-07-31 02:40:57.000000000 +0200 @@ -220,6 +220,18 @@ A file with the text to be displayed if an Error 503 occurs. Default: "The service is not available. Please try again later.". .TP +\fBHTMLErr414\fR "filename" +A html file with the text to be displayed if an Error 414 occurs. +.TP +\fBHTMLErr500\fR "filename" +A html file with the text to be displayed if an Error 500 occurs. +.TP +\fBHTMLErr501\fR "filename" +A html file with the text to be displayed if an Error 501 occurs. +.TP +\fBHTMLErr503\fR "filename" +A html file with the text to be displayed if an Error 503 occurs. +.TP \fBMaxRequest\fR nnn Request maximal size. All requests will be limited to these many bytes. If a request contains more data than allowed an error 414 is returned. Default: