diff options
397 files changed, 4990 insertions, 20340 deletions
diff --git a/debian/changelog b/debian/changelog index ee0857b..01f68a0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +apache2 (2.4.59-1~deb10u1) buster-security; urgency=medium + + [ Yadd ] + * Team upload + * New upstream version 2.4.59 (Closes: CVE-2019-17567, CVE-2023-31122, + CVE-2023-38709, CVE-2023-45802, CVE-2024-24795, CVE-2024-27316) + * Update test framework + * Drop old patches + * Update patches + + [ Bastien Roucariès ] + * Break against fossil + + -- Bastien Roucariès <rouca@debian.org> Fri, 24 May 2024 22:36:21 +0000 + apache2 (2.4.38-3+deb10u10) buster-security; urgency=medium * Non-maintainer upload by the LTS Team. diff --git a/debian/control b/debian/control index 4d5ca9f..61bef7b 100644 --- a/debian/control +++ b/debian/control @@ -82,7 +82,8 @@ Suggests: apache2-doc, www-browser Breaks: gridsite (<< 3.0.0~20170225gitd51b2fd-1~), libapache2-mod-dacs (<= 1.4.38a-2), - libapache2-mod-proxy-uwsgi (<< 2.4.33) + libapache2-mod-proxy-uwsgi (<< 2.4.33), + fossil (<< 2.8-1+deb10u1~) Provides: ${apache2:API} Replaces: libapache2-mod-proxy-uwsgi (<< 2.4.33) Description: Apache HTTP Server (modules and other binary files) diff --git a/debian/patches/0052-CVE-2023-27522-HTTP-Response-Smuggling-mod_proxy_uws.patch b/debian/patches/0052-CVE-2023-27522-HTTP-Response-Smuggling-mod_proxy_uws.patch deleted file mode 100644 index f39fa72..0000000 --- a/debian/patches/0052-CVE-2023-27522-HTTP-Response-Smuggling-mod_proxy_uws.patch +++ /dev/null @@ -1,120 +0,0 @@ -From: Eric Covener <covener@apache.org> -Date: Sun, 5 Mar 2023 20:22:52 +0000 -Subject: CVE-2023-27522: HTTP Response Smuggling mod_proxy_uwsgi - -HTTP Response Smuggling vulnerability in Apache HTTP Server via mod_proxy_uwsgi. -This issue affects Apache HTTP Server: from 2.4.30 through 2.4.55. -Special characters in the origin response header can truncate/split the response forwarded to the client. - -mod_proxy_uwsgi: Stricter backend HTTP response parsing/validation - -Reviewed By: ylavic, covener, gbechis, rpluem - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1908094 13f79535-47bb-0310-9956-ffa450edef68 -origin: https://github.com/apache/httpd/commit/d753ea76b5972a85349b68c31b59d04c60014f2d.patch -bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1032476 -bug-debian-security: https://security-tracker.debian.org/tracker/CVE-2023-27522 -bug-cve: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-27522 ---- - .../proxy_uwsgi_response_validation.txt | 2 + - modules/proxy/mod_proxy_uwsgi.c | 49 +++++++++++++++------- - 2 files changed, 37 insertions(+), 14 deletions(-) - create mode 100644 changes-entries/proxy_uwsgi_response_validation.txt - -diff --git a/changes-entries/proxy_uwsgi_response_validation.txt b/changes-entries/proxy_uwsgi_response_validation.txt -new file mode 100644 -index 0000000..2cdb6c6 ---- /dev/null -+++ b/changes-entries/proxy_uwsgi_response_validation.txt -@@ -0,0 +1,2 @@ -+ *) mod_proxy_uwsgi: Stricter backend HTTP response parsing/validation. -+ [Yann Ylavic] -diff --git a/modules/proxy/mod_proxy_uwsgi.c b/modules/proxy/mod_proxy_uwsgi.c -index ebe16e8..9ba10b9 100644 ---- a/modules/proxy/mod_proxy_uwsgi.c -+++ b/modules/proxy/mod_proxy_uwsgi.c -@@ -303,18 +303,16 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend, - pass_bb = apr_brigade_create(r->pool, c->bucket_alloc); - - len = ap_getline(buffer, sizeof(buffer), rp, 1); -- - if (len <= 0) { -- /* oops */ -+ /* invalid or empty */ - return HTTP_INTERNAL_SERVER_ERROR; - } -- - backend->worker->s->read += len; -- -- if (len >= sizeof(buffer) - 1) { -- /* oops */ -+ if ((apr_size_t)len >= sizeof(buffer)) { -+ /* too long */ - return HTTP_INTERNAL_SERVER_ERROR; - } -+ - /* Position of http status code */ - if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) { - status_start = 9; -@@ -323,8 +321,8 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend, - status_start = 7; - } - else { -- /* oops */ -- return HTTP_INTERNAL_SERVER_ERROR; -+ /* not HTTP */ -+ return HTTP_BAD_GATEWAY; - } - status_end = status_start + 3; - -@@ -344,21 +342,44 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend, - } - r->status_line = apr_pstrdup(r->pool, &buffer[status_start]); - -- /* start parsing headers */ -+ /* parse headers */ - while ((len = ap_getline(buffer, sizeof(buffer), rp, 1)) > 0) { -+ if ((apr_size_t)len >= sizeof(buffer)) { -+ /* too long */ -+ len = -1; -+ break; -+ } - value = strchr(buffer, ':'); -- /* invalid header skip */ -- if (!value) -- continue; -- *value = '\0'; -- ++value; -+ if (!value) { -+ /* invalid header */ -+ len = -1; -+ break; -+ } -+ *value++ = '\0'; -+ if (*ap_scan_http_token(buffer)) { -+ /* invalid name */ -+ len = -1; -+ break; -+ } - while (apr_isspace(*value)) - ++value; - for (end = &value[strlen(value) - 1]; - end > value && apr_isspace(*end); --end) - *end = '\0'; -+ if (*ap_scan_http_field_content(value)) { -+ /* invalid value */ -+ len = -1; -+ break; -+ } - apr_table_add(r->headers_out, buffer, value); - } -+ if (len < 0) { -+ /* Reset headers, but not to NULL because things below the chain expect -+ * this to be non NULL e.g. the ap_content_length_filter. -+ */ -+ r->headers_out = apr_table_make(r->pool, 1); -+ return HTTP_BAD_GATEWAY; -+ } - - if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { - ap_set_content_type(r, apr_pstrdup(r->pool, buf)); diff --git a/debian/patches/0053-CVE-2023-25690-1.patch b/debian/patches/0053-CVE-2023-25690-1.patch deleted file mode 100644 index a7370c7..0000000 --- a/debian/patches/0053-CVE-2023-25690-1.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 8789f6bb926fa4c33b4231a8444340515c82bdff Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Sun, 5 Mar 2023 20:28:43 +0000 -Subject: [PATCH] [1/2] Fix CVE-2023-25690: HTTP Request Smuggling in mod_proxy* - - don't forward invalid query strings - - Submitted by: rpluem - -Reviewed By: covener, fielding, rpluem, gbechis -bug: https://httpd.apache.org/security/vulnerabilities_24.html#CVE-2023-25690 -bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1032476 -bug-debian-security: https://security-tracker.debian.org/tracker/CVE-2023-25690 -origin: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1908096 13f79535-47bb-0310-9956-ffa450edef68 -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1908096 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/http2/mod_proxy_http2.c | 10 ++++++++++ - modules/mappers/mod_rewrite.c | 22 ++++++++++++++++++++++ - modules/proxy/mod_proxy_ajp.c | 10 ++++++++++ - modules/proxy/mod_proxy_balancer.c | 10 ++++++++++ - modules/proxy/mod_proxy_http.c | 10 ++++++++++ - modules/proxy/mod_proxy_wstunnel.c | 10 ++++++++++ - 6 files changed, 72 insertions(+) - -diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c -index 3faf03472bb..aa299b937a5 100644 ---- a/modules/http2/mod_proxy_http2.c -+++ b/modules/http2/mod_proxy_http2.c -@@ -158,6 +158,16 @@ static int proxy_http2_canon(request_rec *r, char *url) - path = ap_proxy_canonenc(r->pool, url, (int)strlen(url), - enc_path, 0, r->proxyreq); - search = r->args; -+ if (search && *(ap_scan_vchar_obstext(search))) { -+ /* -+ * We have a raw control character or a ' ' in r->args. -+ * Correct encoding was missed. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() -+ "To be forwarded query string contains control " -+ "characters or spaces"); -+ return HTTP_FORBIDDEN; -+ } - } - break; - case PROXYREQ_PROXY: -diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c -index 943996560e5..f6398f19386 100644 ---- a/modules/mappers/mod_rewrite.c -+++ b/modules/mappers/mod_rewrite.c -@@ -4729,6 +4729,17 @@ static int hook_uri2file(request_rec *r) - unsigned skip; - apr_size_t flen; - -+ if (r->args && *(ap_scan_vchar_obstext(r->args))) { -+ /* -+ * We have a raw control character or a ' ' in r->args. -+ * Correct encoding was missed. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410) -+ "Rewritten query string contains control " -+ "characters or spaces"); -+ return HTTP_FORBIDDEN; -+ } -+ - if (ACTION_STATUS == rulestatus) { - int n = r->status; - -@@ -5013,6 +5024,17 @@ static int hook_fixup(request_rec *r) - if (rulestatus) { - unsigned skip; - -+ if (r->args && *(ap_scan_vchar_obstext(r->args))) { -+ /* -+ * We have a raw control character or a ' ' in r->args. -+ * Correct encoding was missed. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10411) -+ "Rewritten query string contains control " -+ "characters or spaces"); -+ return HTTP_FORBIDDEN; -+ } -+ - if (ACTION_STATUS == rulestatus) { - int n = r->status; - -diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c -index 1449acad733..e46bd903a36 100644 ---- a/modules/proxy/mod_proxy_ajp.c -+++ b/modules/proxy/mod_proxy_ajp.c -@@ -69,6 +69,16 @@ static int proxy_ajp_canon(request_rec *r, char *url) - path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, - r->proxyreq); - search = r->args; -+ if (search && *(ap_scan_vchar_obstext(search))) { -+ /* -+ * We have a raw control character or a ' ' in r->args. -+ * Correct encoding was missed. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10406) -+ "To be forwarded query string contains control " -+ "characters or spaces"); -+ return HTTP_FORBIDDEN; -+ } - } - if (path == NULL) - return HTTP_BAD_REQUEST; -diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c -index f6fb6345ae3..7f990084336 100644 ---- a/modules/proxy/mod_proxy_balancer.c -+++ b/modules/proxy/mod_proxy_balancer.c -@@ -106,6 +106,16 @@ static int proxy_balancer_canon(request_rec *r, char *url) - path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, - r->proxyreq); - search = r->args; -+ if (search && *(ap_scan_vchar_obstext(search))) { -+ /* -+ * We have a raw control character or a ' ' in r->args. -+ * Correct encoding was missed. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10407) -+ "To be forwarded query string contains control " -+ "characters or spaces"); -+ return HTTP_FORBIDDEN; -+ } - } - if (path == NULL) - return HTTP_BAD_REQUEST; -diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c -index ec4e7fb06b5..51d19a0a21b 100644 ---- a/modules/proxy/mod_proxy_http.c -+++ b/modules/proxy/mod_proxy_http.c -@@ -125,6 +125,16 @@ static int proxy_http_canon(request_rec *r, char *url) - path = ap_proxy_canonenc(r->pool, url, strlen(url), - enc_path, 0, r->proxyreq); - search = r->args; -+ if (search && *(ap_scan_vchar_obstext(search))) { -+ /* -+ * We have a raw control character or a ' ' in r->args. -+ * Correct encoding was missed. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10408) -+ "To be forwarded query string contains control " -+ "characters or spaces"); -+ return HTTP_FORBIDDEN; -+ } - } - break; - case PROXYREQ_PROXY: -diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c -index bcbba42f9a4..88f86a49dbb 100644 ---- a/modules/proxy/mod_proxy_wstunnel.c -+++ b/modules/proxy/mod_proxy_wstunnel.c -@@ -114,6 +114,16 @@ static int proxy_wstunnel_canon(request_rec *r, char *url) - path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, - r->proxyreq); - search = r->args; -+ if (search && *(ap_scan_vchar_obstext(search))) { -+ /* -+ * We have a raw control character or a ' ' in r->args. -+ * Correct encoding was missed. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10409) -+ "To be forwarded query string contains control " -+ "characters or spaces"); -+ return HTTP_FORBIDDEN; -+ } - } - if (path == NULL) - return HTTP_BAD_REQUEST; - diff --git a/debian/patches/0054-CVE-2023-25690-2.patch b/debian/patches/0054-CVE-2023-25690-2.patch deleted file mode 100644 index 978be78..0000000 --- a/debian/patches/0054-CVE-2023-25690-2.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8b93a6512f14f5f68887ddfe677e91233ed79fb0 Mon Sep 17 00:00:00 2001 -From: Ruediger Pluem <rpluem@apache.org> -Date: Mon, 6 Mar 2023 10:00:09 +0000 -Subject: [PATCH] [2/2] Fix CVE-2023-25690: HTTP Request Smuggling in mod_proxy* - -* modules/http2/mod_proxy_http2.c: Fix missing APLOGNO. - -Submitted by: jorton -Reviewed by: rpluem - -Note: mod_proxy_http2 is CTR on 2.4.x. - -bug: https://httpd.apache.org/security/vulnerabilities_24.html#CVE-2023-25690 -bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1032476 -bug-debian-security: https://security-tracker.debian.org/tracker/CVE-2023-25690 -origin: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1908118 13f79535-47bb-0310-9956-ffa450edef68 -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1908118 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/http2/mod_proxy_http2.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c -index aa299b937a5..2a9967e5d57 100644 ---- a/modules/http2/mod_proxy_http2.c -+++ b/modules/http2/mod_proxy_http2.c -@@ -163,7 +163,7 @@ static int proxy_http2_canon(request_rec *r, char *url) - * We have a raw control character or a ' ' in r->args. - * Correct encoding was missed. - */ -- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10412) - "To be forwarded query string contains control " - "characters or spaces"); - return HTTP_FORBIDDEN; - diff --git a/debian/patches/0055-CVE-2023-25690-Regression-1.patch b/debian/patches/0055-CVE-2023-25690-Regression-1.patch deleted file mode 100644 index d57a71c..0000000 --- a/debian/patches/0055-CVE-2023-25690-Regression-1.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 815cf05bb2d506f44a35b65e93de393d5410c779 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic <ylavic@apache.org> -Date: Tue, 1 Mar 2022 13:26:03 +0000 -Subject: [PATCH] mod_rewrite: URI-to-filename rewrites to transparently handle - proxy mappings. - -Since mod_rewrite works on r->filename and mod_proxy's mapping=servlet|decoded -sets its "proxy:" URL there at pre_translate_name stage (i.e. before -mod_rewrite's translate_name hook), users have to match the full proxy URL in -their RewriteRules to handle proxy mappings, which is not very friendly nor -consistent with how proxy non-mapping requests have to be matched. - -Let's use r->filename = r->uri in hook_uri2file() for pre_trans'ed reverse -proxy requests, and restore r->filename to its original value if the request -was finally DECLINED (like in hook_fixup). - -But if a proxy mapping gets rewritten to a non-proxy request, clear any -proxy specific r->proxyreq or r->handler so that processing continues -accordingly. - - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1898509 13f79535-47bb-0310-9956-ffa450edef68 ---- - changes-entries/rewrite_vs_proxy_mapping.txt | 2 ++ - modules/mappers/mod_rewrite.c | 38 +++++++++++++++----- - 2 files changed, 32 insertions(+), 8 deletions(-) - create mode 100644 changes-entries/rewrite_vs_proxy_mapping.txt - -Index: apache2/changes-entries/rewrite_vs_proxy_mapping.txt -=================================================================== ---- /dev/null -+++ apache2/changes-entries/rewrite_vs_proxy_mapping.txt -@@ -0,0 +1,2 @@ -+ *) mod_rewrite: Make URI-to-filename rewrites work transparently with -+ proxy early mappings (mapping=servlet/decoded). [Yann Ylavic] -\ No newline at end of file -Index: apache2/modules/mappers/mod_rewrite.c -=================================================================== ---- apache2.orig/modules/mappers/mod_rewrite.c -+++ apache2/modules/mappers/mod_rewrite.c -@@ -4575,6 +4575,7 @@ static int hook_uri2file(request_rec *r) - unsigned int port; - int rulestatus; - void *skipdata; -+ char *ofilename; - const char *oargs; - - /* -@@ -4628,7 +4629,10 @@ static int hook_uri2file(request_rec *r) - /* - * remember the original query string for later check, since we don't - * want to apply URL-escaping when no substitution has changed it. -+ * also, we'll restore original r->filename if we decline this -+ * request. - */ -+ ofilename = r->filename; - oargs = r->args; - - /* -@@ -4671,13 +4675,15 @@ static int hook_uri2file(request_rec *r) - apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URI, var); - - if (!(saved_rulestatus = apr_table_get(r->notes,"mod_rewrite_rewritten"))) { -- /* if filename was not initially set, -- * we start with the requested URI -+ /* If r->filename was not initially set or if it's a pre_trans reverse -+ * "proxy:" scheme, we start with the requested URI. - */ -- if (r->filename == NULL) { -+ if (r->filename == NULL || (r->proxyreq == PROXYREQ_REVERSE && -+ strncmp(r->filename, "proxy:", 6) == 0)) { - r->filename = apr_pstrdup(r->pool, r->uri); -- rewritelog((r, 2, NULL, "init rewrite engine with requested uri %s", -- r->filename)); -+ rewritelog((r, 2, NULL, "init rewrite engine with requested uri " -+ "%s. Original filename = %s", r->filename, -+ ((ofilename) ? ofilename : "n/a"))); - } - else { - rewritelog((r, 2, NULL, "init rewrite engine with passed filename " -@@ -4701,6 +4707,7 @@ static int hook_uri2file(request_rec *r) - if (rulestatus) { - unsigned skip; - apr_size_t flen; -+ int to_proxyreq; - - if (r->args && *(ap_scan_vchar_obstext(r->args))) { - /* -@@ -4721,7 +4728,19 @@ static int hook_uri2file(request_rec *r) - } - - flen = r->filename ? strlen(r->filename) : 0; -- if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) { -+ to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); -+ -+ /* If a pre_trans reverse "proxy:" filename gets rewritten to -+ * a non-proxy one this is not a proxy request anymore. -+ */ -+ if (r->proxyreq == PROXYREQ_REVERSE && !to_proxyreq) { -+ if (r->handler && strcmp(r->handler, "proxy-server") == 0) { -+ r->handler = NULL; -+ } -+ r->proxyreq = PROXYREQ_NONE; -+ } -+ -+ if (to_proxyreq) { - /* it should be go on as an internal proxy request */ - - /* check if the proxy module is enabled, so -@@ -4888,7 +4907,9 @@ static int hook_uri2file(request_rec *r) - } - } - else { -- rewritelog((r, 1, NULL, "pass through %s", r->filename)); -+ rewritelog((r, 1, NULL, "pass through %s, filename %s", -+ r->filename, ((ofilename) ? ofilename : "n/a"))); -+ r->filename = ofilename; - return DECLINED; - } - } -@@ -5234,7 +5255,8 @@ static int hook_fixup(request_rec *r) - } - } - else { -- rewritelog((r, 1, dconf->directory, "pass through %s", r->filename)); -+ rewritelog((r, 1, dconf->directory, "pass through %s, filename %s", -+ r->filename, ((ofilename) ? ofilename : "n/a"))); - r->filename = ofilename; - return DECLINED; - } diff --git a/debian/patches/0056-CVE-2023-25690-Regression-2.patch b/debian/patches/0056-CVE-2023-25690-Regression-2.patch deleted file mode 100644 index 55eaa6b..0000000 --- a/debian/patches/0056-CVE-2023-25690-Regression-2.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 07b802c934b841d376733a3e2ecfa55f6b0ee994 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Sat, 11 Mar 2023 20:57:52 +0000 -Subject: [PATCH] allow decoded chars when they will be escaped - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908296 13f79535-47bb-0310-9956-ffa450edef68 ---- - changes-entries/rewrite-escape.diff | 3 ++ - modules/mappers/mod_rewrite.c | 45 +++++++++++++++++------------ - 2 files changed, 30 insertions(+), 18 deletions(-) - create mode 100644 changes-entries/rewrite-escape.diff - -Index: apache2/changes-entries/rewrite-escape.diff -=================================================================== ---- /dev/null -+++ apache2/changes-entries/rewrite-escape.diff -@@ -0,0 +1,3 @@ -+ *) mod_rewrite: Re-allow some proxy and redirect substitutions flagged as -+ 403 errors in 2.4.56. [Eric Covener] -+ -Index: apache2/modules/mappers/mod_rewrite.c -=================================================================== ---- apache2.orig/modules/mappers/mod_rewrite.c -+++ apache2/modules/mappers/mod_rewrite.c -@@ -4705,14 +4705,19 @@ static int hook_uri2file(request_rec *r) - } - - if (rulestatus) { -- unsigned skip; -- apr_size_t flen; -- int to_proxyreq; -- -- if (r->args && *(ap_scan_vchar_obstext(r->args))) { -+ unsigned skip_absolute = is_absolute_uri(r->filename, NULL); -+ apr_size_t flen = r->filename ? strlen(r->filename) : 0; -+ int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); -+ int will_escape = (to_proxyreq || skip_absolute) -+ && (rulestatus != ACTION_NOESCAPE); -+ -+ if (r->args -+ && !will_escape -+ && *(ap_scan_vchar_obstext(r->args))) { - /* - * We have a raw control character or a ' ' in r->args. -- * Correct encoding was missed. -+ * Correct encoding was missed and we're not going to escape -+ * it before returning. - */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410) - "Rewritten query string contains control " -@@ -4727,9 +4732,6 @@ static int hook_uri2file(request_rec *r) - return n; - } - -- flen = r->filename ? strlen(r->filename) : 0; -- to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); -- - /* If a pre_trans reverse "proxy:" filename gets rewritten to - * a non-proxy one this is not a proxy request anymore. - */ -@@ -4782,15 +4784,15 @@ static int hook_uri2file(request_rec *r) - r->filename)); - return OK; - } -- else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) { -+ else if (skip_absolute > 0) { - int n; - - /* it was finally rewritten to a remote URL */ - - if (rulestatus != ACTION_NOESCAPE) { - rewritelog((r, 1, NULL, "escaping %s for redirect", -- r->filename)); -- r->filename = escape_absolute_uri(r->pool, r->filename, skip); -+ r->filename)); -+ r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute); - } - - /* append the QUERY_STRING part */ -@@ -5016,9 +5018,17 @@ static int hook_fixup(request_rec *r) - */ - rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory); - if (rulestatus) { -- unsigned skip; -+ unsigned skip_absolute = is_absolute_uri(r->filename, NULL); -+ int to_proxyreq = 0; -+ int will_escape = 0; - -- if (r->args && *(ap_scan_vchar_obstext(r->args))) { -+ l = strlen(r->filename); -+ to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0; -+ will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE); -+ -+ if (r->args -+ && !will_escape -+ && *(ap_scan_vchar_obstext(r->args))) { - /* - * We have a raw control character or a ' ' in r->args. - * Correct encoding was missed. -@@ -5036,8 +5046,7 @@ static int hook_fixup(request_rec *r) - return n; - } - -- l = strlen(r->filename); -- if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) { -+ if (to_proxyreq) { - /* it should go on as an internal proxy request */ - - /* make sure the QUERY_STRING and -@@ -5061,7 +5070,7 @@ static int hook_fixup(request_rec *r) - "%s [OK]", r->filename)); - return OK; - } -- else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) { -+ else if (skip_absolute > 0) { - /* it was finally rewritten to a remote URL */ - - /* because we are in a per-dir context -@@ -5070,7 +5079,7 @@ static int hook_fixup(request_rec *r) - */ - if (dconf->baseurl != NULL) { - /* skip 'scheme://' */ -- cp = r->filename + skip; -+ cp = r->filename + skip_absolute; - - if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) { - rewritelog((r, 2, dconf->directory, -@@ -5114,8 +5123,8 @@ static int hook_fixup(request_rec *r) - /* now prepare the redirect... */ - if (rulestatus != ACTION_NOESCAPE) { - rewritelog((r, 1, dconf->directory, "escaping %s for redirect", -- r->filename)); -- r->filename = escape_absolute_uri(r->pool, r->filename, skip); -+ r->filename)); -+ r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute); - } - - /* append the QUERY_STRING part */ diff --git a/debian/patches/0057-CVE-2023-25690-Regression-3.patch b/debian/patches/0057-CVE-2023-25690-Regression-3.patch deleted file mode 100644 index 431f145..0000000 --- a/debian/patches/0057-CVE-2023-25690-Regression-3.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 1a4aac3d209f4314bcb511d73cf12f8c25c8c984 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Sat, 11 Mar 2023 21:29:11 +0000 -Subject: [PATCH] followup to r1908296: only for redirects - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908299 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/mappers/mod_rewrite.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -Index: apache2/modules/mappers/mod_rewrite.c -=================================================================== ---- apache2.orig/modules/mappers/mod_rewrite.c -+++ apache2/modules/mappers/mod_rewrite.c -@@ -4708,8 +4708,7 @@ static int hook_uri2file(request_rec *r) - unsigned skip_absolute = is_absolute_uri(r->filename, NULL); - apr_size_t flen = r->filename ? strlen(r->filename) : 0; - int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); -- int will_escape = (to_proxyreq || skip_absolute) -- && (rulestatus != ACTION_NOESCAPE); -+ int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE); - - if (r->args - && !will_escape diff --git a/debian/patches/CVE-2006-20001.patch b/debian/patches/CVE-2006-20001.patch deleted file mode 100644 index 0ba150b..0000000 --- a/debian/patches/CVE-2006-20001.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 7469547c3f617717ca545d0f7c56d01134703813 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Tue, 10 Jan 2023 13:21:48 +0000 -Subject: [PATCH] Merge r1906487 from trunk: - -* modules/dav/main/util.c (dav_process_if_header): Fix error - path for "Not" prefix parsing. - - -Submitted By: jorton -Reviewed By: jorton, covener, rpluem - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1906543 13f79535-47bb-0310-9956-ffa450edef68 ---- - STATUS | 8 -------- - modules/dav/main/util.c | 8 +++++++- - 2 files changed, 7 insertions(+), 9 deletions(-) - ---- a/modules/dav/main/util.c -+++ b/modules/dav/main/util.c -@@ -746,8 +746,14 @@ - "for the same state."); - } - condition = DAV_IF_COND_NOT; -+ list += 2; -+ } -+ else { -+ return dav_new_error(r->pool, HTTP_BAD_REQUEST, -+ DAV_ERR_IF_UNK_CHAR, 0, -+ "Invalid \"If:\" header: " -+ "Unexpected character in List"); - } -- list += 2; - break; - - case ' ': diff --git a/debian/patches/CVE-2019-0196.patch b/debian/patches/CVE-2019-0196.patch deleted file mode 100644 index eaec989..0000000 --- a/debian/patches/CVE-2019-0196.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 8de3c6f2a0df79d1476c89ec480a96f9282cea28 Mon Sep 17 00:00:00 2001 -From: Stefan Eissing <icing@apache.org> -Date: Tue, 5 Feb 2019 11:52:28 +0000 -Subject: [PATCH] Merge of r1852986 from trunk: - -mod_http2: disentangelment of stream and request method. - - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1852989 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/http2/h2_request.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c -index 8899c4feb75..5ee88e9679f 100644 ---- a/modules/http2/h2_request.c -+++ b/modules/http2/h2_request.c -@@ -266,7 +266,7 @@ request_rec *h2_request_create_rec(const h2_request *req, conn_rec *c) - - /* Time to populate r with the data we have. */ - r->request_time = req->request_time; -- r->method = req->method; -+ r->method = apr_pstrdup(r->pool, req->method); - /* Provide quick information about the request method as soon as known */ - r->method_number = ap_method_number_of(r->method); - if (r->method_number == M_GET && r->method[0] == 'H') { diff --git a/debian/patches/CVE-2019-0197.patch b/debian/patches/CVE-2019-0197.patch deleted file mode 100644 index 92d2943..0000000 --- a/debian/patches/CVE-2019-0197.patch +++ /dev/null @@ -1,93 +0,0 @@ -# https://svn.apache.org/r1855406 ---- apache2.orig/modules/http2/h2_conn.c -+++ apache2/modules/http2/h2_conn.c -@@ -305,6 +305,10 @@ conn_rec *h2_slave_create(conn_rec *mast - c->notes = apr_table_make(pool, 5); - c->input_filters = NULL; - c->output_filters = NULL; -+ c->keepalives = 0; -+#if AP_MODULE_MAGIC_AT_LEAST(20180903, 1) -+ c->filter_conn_ctx = NULL; -+#endif - c->bucket_alloc = apr_bucket_alloc_create(pool); - c->data_in_input_filters = 0; - c->data_in_output_filters = 0; -@@ -332,16 +336,15 @@ conn_rec *h2_slave_create(conn_rec *mast - ap_set_module_config(c->conn_config, mpm, cfg); - } - -- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, -- "h2_stream(%ld-%d): created slave", master->id, slave_id); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c, -+ "h2_slave(%s): created", c->log_id); - return c; - } - - void h2_slave_destroy(conn_rec *slave) - { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, slave, -- "h2_stream(%s): destroy slave", -- apr_table_get(slave->notes, H2_TASK_ID_NOTE)); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, slave, -+ "h2_slave(%s): destroy", slave->log_id); - slave->sbh = NULL; - apr_pool_destroy(slave->pool); - } -@@ -365,6 +368,7 @@ apr_status_t h2_slave_run_pre_connection - slave->keepalive = AP_CONN_CLOSE; - return ap_run_pre_connection(slave, csd); - } -+ ap_assert(slave->output_filters); - return APR_SUCCESS; - } - ---- apache2.orig/modules/http2/h2_mplx.c -+++ apache2/modules/http2/h2_mplx.c -@@ -327,7 +327,8 @@ static int stream_destroy_iter(void *ctx - && !task->rst_error); - } - -- if (reuse_slave && slave->keepalive == AP_CONN_KEEPALIVE) { -+ task->c = NULL; -+ if (reuse_slave) { - h2_beam_log(task->output.beam, m->c, APLOG_DEBUG, - APLOGNO(03385) "h2_task_destroy, reuse slave"); - h2_task_destroy(task); -@@ -437,6 +438,8 @@ void h2_mplx_release_and_join(h2_mplx *m - apr_status_t status; - int i, wait_secs = 60; - -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, -+ "h2_mplx(%ld): start release", m->id); - /* How to shut down a h2 connection: - * 0. abort and tell the workers that no more tasks will come from us */ - m->aborted = 1; -@@ -977,6 +980,9 @@ static apr_status_t unschedule_slow_task - */ - n = (m->tasks_active - m->limit_active - (int)h2_ihash_count(m->sredo)); - while (n > 0 && (stream = get_latest_repeatable_unsubmitted_stream(m))) { -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, -+ "h2_mplx(%s): unschedule, resetting task for redo later", -+ stream->task->id); - h2_task_rst(stream->task, H2_ERR_CANCEL); - h2_ihash_add(m->sredo, stream); - --n; ---- apache2.orig/modules/http2/h2_task.c -+++ apache2/modules/http2/h2_task.c -@@ -504,7 +504,7 @@ static int h2_task_pre_conn(conn_rec* c, - (void)arg; - if (h2_ctx_is_task(ctx)) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, -- "h2_h2, pre_connection, found stream task"); -+ "h2_slave(%s), pre_connection, adding filters", c->log_id); - ap_add_input_filter("H2_SLAVE_IN", NULL, NULL, c); - ap_add_output_filter("H2_PARSE_H1", NULL, NULL, c); - ap_add_output_filter("H2_SLAVE_OUT", NULL, NULL, c); -@@ -545,7 +545,6 @@ h2_task *h2_task_create(conn_rec *slave, - void h2_task_destroy(h2_task *task) - { - if (task->output.beam) { -- h2_beam_log(task->output.beam, task->c, APLOG_TRACE2, "task_destroy"); - h2_beam_destroy(task->output.beam); - task->output.beam = NULL; - } diff --git a/debian/patches/CVE-2019-0211.patch b/debian/patches/CVE-2019-0211.patch deleted file mode 100644 index 1b69f45..0000000 --- a/debian/patches/CVE-2019-0211.patch +++ /dev/null @@ -1,249 +0,0 @@ -From df7edb5ddae609ea1fd4285f7439f0d590d97b37 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic <ylavic@apache.org> -Date: Wed, 13 Mar 2019 08:59:54 +0000 -Subject: [PATCH] Merge r1855306 from trunk: - -MPMs unix: bind the bucket number of each child to its slot number - -We need not remember each child's bucket number in SHM for restarts, for the -lifetime of the httpd main process the bucket number can be bound to the slot -number such that: bucket = slot % num_buckets. - -This both simplifies the logic and helps children maintenance per bucket in -threaded MPMs, where previously perform_idle_server_maintenance() could create -or kill children processes for the buckets it was not in charge of. - -Submitted by: ylavic -Reviewed by: ylavic, rpluem, jorton - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855378 13f79535-47bb-0310-9956-ffa450edef68 ---- - CHANGES | 3 +++ - include/scoreboard.h | 4 +++- - server/mpm/event/event.c | 13 ++++++++----- - server/mpm/prefork/prefork.c | 19 +++++++------------ - server/mpm/worker/worker.c | 10 ++++++---- - 5 files changed, 27 insertions(+), 22 deletions(-) - -#diff --git a/CHANGES b/CHANGES -#index e79251389d5..6b560802119 100644 -#--- a/CHANGES -#+++ b/CHANGES -#@@ -1,6 +1,9 @@ -# -*- coding: utf-8 -*- -# Changes with Apache 2.4.39 -# -#+ *) MPMs unix: bind the bucket number of each child to its slot number, for a -#+ more efficient per bucket maintenance. [Yann Ylavic] -#+ -# *) mod_auth_digest: Fix a race condition. Authentication with valid -# credentials could be refused in case of concurrent accesses from -# different users. PR 63124. [Simon Kappel <simon.kappel axis.com>] -diff --git a/include/scoreboard.h b/include/scoreboard.h -index 9376da246b0..92d198d6de1 100644 ---- a/include/scoreboard.h -+++ b/include/scoreboard.h -@@ -148,7 +148,9 @@ struct process_score { - apr_uint32_t lingering_close; /* async connections in lingering close */ - apr_uint32_t keep_alive; /* async connections in keep alive */ - apr_uint32_t suspended; /* connections suspended by some module */ -- int bucket; /* Listener bucket used by this child */ -+ int bucket; /* Listener bucket used by this child; this field is DEPRECATED -+ * and no longer updated by the MPMs (i.e. always zero). -+ */ - }; - - /* Scoreboard is now in 'local' memory, since it isn't updated once created, -diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c -index 4cfb09c5b28..5e5af339adc 100644 ---- a/server/mpm/event/event.c -+++ b/server/mpm/event/event.c -@@ -2696,7 +2696,6 @@ static int make_child(server_rec * s, int slot, int bucket) - - ap_scoreboard_image->parent[slot].quiescing = 0; - ap_scoreboard_image->parent[slot].not_accepting = 0; -- ap_scoreboard_image->parent[slot].bucket = bucket; - event_note_child_started(slot, pid); - active_daemons++; - retained->total_daemons++; -@@ -2735,6 +2734,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) - * that threads_per_child is always > 0 */ - int status = SERVER_DEAD; - int child_threads_active = 0; -+ int bucket = i % num_buckets; - - if (i >= retained->max_daemons_limit && - free_length == retained->idle_spawn_rate[child_bucket]) { -@@ -2758,7 +2758,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) - */ - if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting - && ps->generation == retained->mpm->my_generation -- && ps->bucket == child_bucket) -+ && bucket == child_bucket) - { - ++idle_thread_count; - } -@@ -2769,7 +2769,9 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) - last_non_dead = i; - } - active_thread_count += child_threads_active; -- if (!ps->pid && free_length < retained->idle_spawn_rate[child_bucket]) -+ if (!ps->pid -+ && bucket == child_bucket -+ && free_length < retained->idle_spawn_rate[child_bucket]) - free_slots[free_length++] = i; - else if (child_threads_active == threads_per_child) - had_healthy_child = 1; -@@ -2962,13 +2964,14 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets) - retained->total_daemons--; - if (processed_status == APEXIT_CHILDSICK) { - /* resource shortage, minimize the fork rate */ -- retained->idle_spawn_rate[ps->bucket] = 1; -+ retained->idle_spawn_rate[child_slot % num_buckets] = 1; - } - else if (remaining_children_to_start) { - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ -- make_child(ap_server_conf, child_slot, ps->bucket); -+ make_child(ap_server_conf, child_slot, -+ child_slot % num_buckets); - --remaining_children_to_start; - } - } -diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c -index 8efda72ee18..7c006257301 100644 ---- a/server/mpm/prefork/prefork.c -+++ b/server/mpm/prefork/prefork.c -@@ -637,8 +637,9 @@ static void child_main(int child_num_arg, int child_bucket) - } - - --static int make_child(server_rec *s, int slot, int bucket) -+static int make_child(server_rec *s, int slot) - { -+ int bucket = slot % retained->mpm->num_buckets; - int pid; - - if (slot + 1 > retained->max_daemons_limit) { -@@ -716,7 +717,6 @@ static int make_child(server_rec *s, int slot, int bucket) - child_main(slot, bucket); - } - -- ap_scoreboard_image->parent[slot].bucket = bucket; - prefork_note_child_started(slot, pid); - - return 0; -@@ -732,7 +732,7 @@ static void startup_children(int number_to_start) - if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { - continue; - } -- if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) { -+ if (make_child(ap_server_conf, i) < 0) { - break; - } - --number_to_start; -@@ -741,8 +741,6 @@ static void startup_children(int number_to_start) - - static void perform_idle_server_maintenance(apr_pool_t *p) - { -- static int bucket_make_child_record = -1; -- static int bucket_kill_child_record = -1; - int i; - int idle_count; - worker_score *ws; -@@ -789,6 +787,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p) - } - retained->max_daemons_limit = last_non_dead + 1; - if (idle_count > ap_daemons_max_free) { -+ static int bucket_kill_child_record = -1; - /* kill off one child... we use the pod because that'll cause it to - * shut down gracefully, in case it happened to pick up a request - * while we were counting -@@ -819,10 +818,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p) - idle_count, total_non_dead); - } - for (i = 0; i < free_length; ++i) { -- bucket_make_child_record++; -- bucket_make_child_record %= retained->mpm->num_buckets; -- make_child(ap_server_conf, free_slots[i], -- bucket_make_child_record); -+ make_child(ap_server_conf, free_slots[i]); - } - /* the next time around we want to spawn twice as many if this - * wasn't good enough, but not if we've just done a graceful -@@ -867,7 +863,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) - - if (one_process) { - AP_MONCONTROL(1); -- make_child(ap_server_conf, 0, 0); -+ make_child(ap_server_conf, 0); - /* NOTREACHED */ - ap_assert(0); - return !OK; -@@ -976,8 +972,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ -- make_child(ap_server_conf, child_slot, -- ap_get_scoreboard_process(child_slot)->bucket); -+ make_child(ap_server_conf, child_slot); - --remaining_children_to_start; - } - #if APR_HAS_OTHER_CHILD -diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c -index 8012fe29d8d..a92794245c5 100644 ---- a/server/mpm/worker/worker.c -+++ b/server/mpm/worker/worker.c -@@ -1339,7 +1339,6 @@ static int make_child(server_rec *s, int slot, int bucket) - worker_note_child_lost_slot(slot, pid); - } - ap_scoreboard_image->parent[slot].quiescing = 0; -- ap_scoreboard_image->parent[slot].bucket = bucket; - worker_note_child_started(slot, pid); - return 0; - } -@@ -1388,6 +1387,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) - int any_dead_threads = 0; - int all_dead_threads = 1; - int child_threads_active = 0; -+ int bucket = i % num_buckets; - - if (i >= retained->max_daemons_limit && - totally_free_length == retained->idle_spawn_rate[child_bucket]) { -@@ -1420,7 +1420,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) - if (status <= SERVER_READY && - !ps->quiescing && - ps->generation == retained->mpm->my_generation && -- ps->bucket == child_bucket) { -+ bucket == child_bucket) { - ++idle_thread_count; - } - if (status >= SERVER_READY && status < SERVER_GRACEFUL) { -@@ -1430,6 +1430,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) - } - active_thread_count += child_threads_active; - if (any_dead_threads -+ && bucket == child_bucket - && totally_free_length < retained->idle_spawn_rate[child_bucket] - && free_length < MAX_SPAWN_RATE / num_buckets - && (!ps->pid /* no process in the slot */ -@@ -1615,14 +1616,15 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets) - ps->quiescing = 0; - if (processed_status == APEXIT_CHILDSICK) { - /* resource shortage, minimize the fork rate */ -- retained->idle_spawn_rate[ps->bucket] = 1; -+ retained->idle_spawn_rate[child_slot % num_buckets] = 1; - } - else if (remaining_children_to_start - && child_slot < ap_daemons_limit) { - /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ -- make_child(ap_server_conf, child_slot, ps->bucket); -+ make_child(ap_server_conf, child_slot, -+ child_slot % num_buckets); - --remaining_children_to_start; - } - } diff --git a/debian/patches/CVE-2019-0215.patch b/debian/patches/CVE-2019-0215.patch deleted file mode 100644 index 6c0461e..0000000 --- a/debian/patches/CVE-2019-0215.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 84edf5f49db23ced03259812bbf9426685f7d82a Mon Sep 17 00:00:00 2001 -From: Joe Orton <jorton@apache.org> -Date: Wed, 20 Mar 2019 15:45:16 +0000 -Subject: [PATCH] Merge r1855849 from trunk: - -* modules/ssl/ssl_engine_kernel.c (ssl_hook_Access_modern): Correctly - restore SSL verify state after PHA failure in TLSv1.3. - -Submitted by: Michael Kaufmann <mail michael-kaufmann.ch> -Reviewed by: jorton, covener, jim - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855917 13f79535-47bb-0310-9956-ffa450edef68 ---- - CHANGES | 3 +++ - modules/ssl/ssl_engine_kernel.c | 2 ++ - 2 files changed, 5 insertions(+) - -#diff --git a/CHANGES b/CHANGES -#index 6b03eadfa07..6f20d688ece 100644 -#--- a/CHANGES -#+++ b/CHANGES -#@@ -1,6 +1,9 @@ -# -*- coding: utf-8 -*- -# Changes with Apache 2.4.39 -# -#+ *) mod_ssl: Correctly restore SSL verify state after TLSv1.3 PHA failure. -#+ [Michael Kaufmann <mail michael-kaufmann.ch>] -#+ -# *) mod_log_config: Support %{c}h for conn-hostname, %h for useragent_host -# PR 55348 -# -Index: apache2-2.4.38/modules/ssl/ssl_engine_kernel.c -=================================================================== ---- apache2-2.4.38.orig/modules/ssl/ssl_engine_kernel.c 2019-04-03 14:31:14.279214679 -0400 -+++ apache2-2.4.38/modules/ssl/ssl_engine_kernel.c 2019-04-03 14:31:14.279214679 -0400 -@@ -1154,6 +1154,7 @@ static int ssl_hook_Access_modern(reques - ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server); - apr_table_setn(r->notes, "error-notes", - "Reason: Cannot perform Post-Handshake Authentication.<br />"); -+ SSL_set_verify(ssl, vmode_inplace, NULL); - return HTTP_FORBIDDEN; - } - -@@ -1175,6 +1176,7 @@ static int ssl_hook_Access_modern(reques - * Finally check for acceptable renegotiation results - */ - if (OK != (rc = ssl_check_post_client_verify(r, sc, dc, sslconn, ssl))) { -+ SSL_set_verify(ssl, vmode_inplace, NULL); - return rc; - } - } diff --git a/debian/patches/CVE-2019-0217.patch b/debian/patches/CVE-2019-0217.patch deleted file mode 100644 index e8f1090..0000000 --- a/debian/patches/CVE-2019-0217.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 44b3ddc560c490c60600998fa2bf59b142d08e05 Mon Sep 17 00:00:00 2001 -From: Joe Orton <jorton@apache.org> -Date: Tue, 12 Mar 2019 09:24:26 +0000 -Subject: [PATCH] Merge r1853190 from trunk: - -Fix a race condition. Authentication with valid credentials could be -refused in case of concurrent accesses from different users. - -PR: 63124 -Submitted by: Simon Kappel <simon.kappel axis.com> -Reviewed by: jailletc36, icing, jorton - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855298 13f79535-47bb-0310-9956-ffa450edef68 ---- - CHANGES | 4 ++++ - modules/aaa/mod_auth_digest.c | 26 ++++++++++++-------------- - 2 files changed, 16 insertions(+), 14 deletions(-) - -#diff --git a/CHANGES b/CHANGES -#index 08fc740db30..e79251389d5 100644 -#--- a/CHANGES -#+++ b/CHANGES -#@@ -1,6 +1,10 @@ -# -*- coding: utf-8 -*- -# Changes with Apache 2.4.39 -# -#+ *) mod_auth_digest: Fix a race condition. Authentication with valid -#+ credentials could be refused in case of concurrent accesses from -#+ different users. PR 63124. [Simon Kappel <simon.kappel axis.com>] -#+ -# *) mod_proxy_wstunnel: Fix websocket proxy over UDS. -# PR 62932 <pavel dcmsys.com> -# -diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c -index a67f06986f2..b76094114dd 100644 ---- a/modules/aaa/mod_auth_digest.c -+++ b/modules/aaa/mod_auth_digest.c -@@ -92,7 +92,6 @@ typedef struct digest_config_struct { - int check_nc; - const char *algorithm; - char *uri_list; -- const char *ha1; - } digest_config_rec; - - -@@ -153,6 +152,7 @@ typedef struct digest_header_struct { - apr_time_t nonce_time; - enum hdr_sts auth_hdr_sts; - int needed_auth; -+ const char *ha1; - client_entry *client; - } digest_header_rec; - -@@ -1304,7 +1304,7 @@ static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type) - */ - - static authn_status get_hash(request_rec *r, const char *user, -- digest_config_rec *conf) -+ digest_config_rec *conf, const char **rethash) - { - authn_status auth_result; - char *password; -@@ -1356,7 +1356,7 @@ static authn_status get_hash(request_rec *r, const char *user, - } while (current_provider); - - if (auth_result == AUTH_USER_FOUND) { -- conf->ha1 = password; -+ *rethash = password; - } - - return auth_result; -@@ -1483,25 +1483,24 @@ static int check_nonce(request_rec *r, digest_header_rec *resp, - - /* RFC-2069 */ - static const char *old_digest(const request_rec *r, -- const digest_header_rec *resp, const char *ha1) -+ const digest_header_rec *resp) - { - const char *ha2; - - ha2 = ap_md5(r->pool, (unsigned char *)apr_pstrcat(r->pool, resp->method, ":", - resp->uri, NULL)); - return ap_md5(r->pool, -- (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce, -- ":", ha2, NULL)); -+ (unsigned char *)apr_pstrcat(r->pool, resp->ha1, ":", -+ resp->nonce, ":", ha2, NULL)); - } - - /* RFC-2617 */ - static const char *new_digest(const request_rec *r, -- digest_header_rec *resp, -- const digest_config_rec *conf) -+ digest_header_rec *resp) - { - const char *ha1, *ha2, *a2; - -- ha1 = conf->ha1; -+ ha1 = resp->ha1; - - a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL); - ha2 = ap_md5(r->pool, (const unsigned char *)a2); -@@ -1514,7 +1513,6 @@ static const char *new_digest(const request_rec *r, - NULL)); - } - -- - static void copy_uri_components(apr_uri_t *dst, - apr_uri_t *src, request_rec *r) { - if (src->scheme && src->scheme[0] != '\0') { -@@ -1759,7 +1757,7 @@ static int authenticate_digest_user(request_rec *r) - return HTTP_UNAUTHORIZED; - } - -- return_code = get_hash(r, r->user, conf); -+ return_code = get_hash(r, r->user, conf, &resp->ha1); - - if (return_code == AUTH_USER_NOT_FOUND) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790) -@@ -1789,7 +1787,7 @@ static int authenticate_digest_user(request_rec *r) - - if (resp->message_qop == NULL) { - /* old (rfc-2069) style digest */ -- if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) { -+ if (strcmp(resp->digest, old_digest(r, resp))) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792) - "user %s: password mismatch: %s", r->user, - r->uri); -@@ -1819,7 +1817,7 @@ static int authenticate_digest_user(request_rec *r) - return HTTP_UNAUTHORIZED; - } - -- exp_digest = new_digest(r, resp, conf); -+ exp_digest = new_digest(r, resp); - if (!exp_digest) { - /* we failed to allocate a client struct */ - return HTTP_INTERNAL_SERVER_ERROR; -@@ -1903,7 +1901,7 @@ static int add_auth_info(request_rec *r) - - /* calculate rspauth attribute - */ -- ha1 = conf->ha1; -+ ha1 = resp->ha1; - - a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL); - ha2 = ap_md5(r->pool, (const unsigned char *)a2); diff --git a/debian/patches/CVE-2019-0220-1.patch b/debian/patches/CVE-2019-0220-1.patch deleted file mode 100644 index 021c369..0000000 --- a/debian/patches/CVE-2019-0220-1.patch +++ /dev/null @@ -1,278 +0,0 @@ -From 9bc1917a27a2323e535aadb081e38172ae0e3fc2 Mon Sep 17 00:00:00 2001 -From: Stefan Eissing <icing@apache.org> -Date: Mon, 18 Mar 2019 08:49:59 +0000 -Subject: [PATCH] Merge of r1855705 from trunk: - -core: merge consecutive slashes in the path - - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855737 13f79535-47bb-0310-9956-ffa450edef68 ---- - CHANGES | 4 ++++ - docs/manual/mod/core.xml | 26 ++++++++++++++++++++++++++ - include/ap_mmn.h | 4 +++- - include/http_core.h | 2 +- - include/httpd.h | 14 ++++++++++++-- - server/core.c | 13 +++++++++++++ - server/request.c | 25 +++++++++---------------- - server/util.c | 10 +++++++--- - 8 files changed, 75 insertions(+), 23 deletions(-) - -#diff --git a/CHANGES b/CHANGES -#index e3e8a98db24..9dd7045c232 100644 -#--- a/CHANGES -#+++ b/CHANGES -#@@ -1,6 +1,10 @@ -# -*- coding: utf-8 -*- -# Changes with Apache 2.4.39 -# -#+ *) core: new configuration option 'MergeSlashes on|off' that controls handling of -#+ multiple, consecutive slash ('/') characters in the path component of the request URL. -#+ [Eric Covener] -#+ -# *) mod_http2: when SSL renegotiation is inhibited and a 403 ErrorDocument is -# in play, the proper HTTP/2 stream reset did not trigger with H2_ERR_HTTP_1_1_REQUIRED. -# Fixed. [Michael Kaufmann] -#diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml -#index fc664116727..460b4367621 100644 -#--- a/docs/manual/mod/core.xml -#+++ b/docs/manual/mod/core.xml -#@@ -5138,4 +5138,30 @@ recognized methods to modules.</p> -# <seealso><directive module="mod_allowmethods">AllowMethods</directive></seealso> -# </directivesynopsis> -# -#+<directivesynopsis> -#+<name>MergeSlashes</name> -#+<description>Controls whether the server merges consecutive slashes in URLs. -#+</description> -#+<syntax>MergeSlashes ON|OFF</syntax> -#+<default>MergeSlashes ON</default> -#+<contextlist><context>server config</context><context>virtual host</context> -#+</contextlist> -#+<compatibility>Added in 2.5.1</compatibility> -#+ -#+<usage> -#+ <p>By default, the server merges (or collapses) multiple consecutive slash -#+ ('/') characters in the path component of the request URL.</p> -#+ -#+ <p>When mapping URL's to the filesystem, these multiple slashes are not -#+ significant. However, URL's handled other ways, such as by CGI or proxy, -#+ might prefer to retain the significance of multiple consecutive slashes. -#+ In these cases <directive>MergeSlashes</directive> can be set to -#+ <em>OFF</em> to retain the multiple consecutive slashes. In these -#+ configurations, regular expressions used in the configuration file that match -#+ the path component of the URL (<directive>LocationMatch</directive>, -#+ <directive>RewriteRule</directive>, ...) need to take into account multiple -#+ consecutive slashes.</p> -#+</usage> -#+</directivesynopsis> -#+ -# </modulesynopsis> -diff --git a/include/ap_mmn.h b/include/ap_mmn.h -index 2167baa0325..4739f7f64d3 100644 ---- a/include/ap_mmn.h -+++ b/include/ap_mmn.h -@@ -523,6 +523,8 @@ - * 20120211.82 (2.4.35-dev) Add optional function declaration for - * ap_proxy_balancer_get_best_worker to mod_proxy.h. - * 20120211.83 (2.4.35-dev) Add client64 field to worker_score struct -+ * 20120211.84 (2.4.35-dev) Add ap_no2slash_ex() and merge_slashes to -+ * core_server_conf. - * - */ - -@@ -531,7 +533,7 @@ - #ifndef MODULE_MAGIC_NUMBER_MAJOR - #define MODULE_MAGIC_NUMBER_MAJOR 20120211 - #endif --#define MODULE_MAGIC_NUMBER_MINOR 83 /* 0...n */ -+#define MODULE_MAGIC_NUMBER_MINOR 84 /* 0...n */ - - /** - * Determine if the server's current MODULE_MAGIC_NUMBER is at least a -diff --git a/include/http_core.h b/include/http_core.h -index 35df5dc9601..8e109882244 100644 ---- a/include/http_core.h -+++ b/include/http_core.h -@@ -740,7 +740,7 @@ typedef struct { - #define AP_HTTP_METHODS_LENIENT 1 - #define AP_HTTP_METHODS_REGISTERED 2 - char http_methods; -- -+ unsigned int merge_slashes; - } core_server_config; - - /* for AddOutputFiltersByType in core.c */ -diff --git a/include/httpd.h b/include/httpd.h -index 65392f83546..99f7f041aea 100644 ---- a/include/httpd.h -+++ b/include/httpd.h -@@ -1697,11 +1697,21 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes); - AP_DECLARE(int) ap_unescape_urlencoded(char *query); - - /** -- * Convert all double slashes to single slashes -- * @param name The string to convert -+ * Convert all double slashes to single slashes, except where significant -+ * to the filesystem on the current platform. -+ * @param name The string to convert, assumed to be a filesystem path - */ - AP_DECLARE(void) ap_no2slash(char *name); - -+/** -+ * Convert all double slashes to single slashes, except where significant -+ * to the filesystem on the current platform. -+ * @param name The string to convert -+ * @param is_fs_path if set to 0, the significance of any double-slashes is -+ * ignored. -+ */ -+AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path); -+ - /** - * Remove all ./ and xx/../ substrings from a file name. Also remove - * any leading ../ or /../ substrings. -diff --git a/server/core.c b/server/core.c -index e2a91c7a0c6..eacb54fecec 100644 ---- a/server/core.c -+++ b/server/core.c -@@ -490,6 +490,7 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s) - - conf->protocols = apr_array_make(a, 5, sizeof(const char *)); - conf->protocols_honor_order = -1; -+ conf->merge_slashes = AP_CORE_CONFIG_UNSET; - - return (void *)conf; - } -@@ -555,6 +556,7 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) - conf->protocols_honor_order = ((virt->protocols_honor_order < 0)? - base->protocols_honor_order : - virt->protocols_honor_order); -+ AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt); - - return conf; - } -@@ -1863,6 +1865,13 @@ static const char *set_qualify_redirect_url(cmd_parms *cmd, void *d_, int flag) - return NULL; - } - -+static const char *set_core_server_flag(cmd_parms *cmd, void *s_, int flag) -+{ -+ core_server_config *conf = -+ ap_get_core_module_config(cmd->server->module_config); -+ return ap_set_flag_slot(cmd, conf, flag); -+} -+ - static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[]) - { - core_dir_config *d = d_; -@@ -4562,6 +4571,10 @@ AP_INIT_ITERATE("HttpProtocolOptions", set_http_protocol_options, NULL, RSRC_CON - "'Unsafe' or 'Strict' (default). Sets HTTP acceptance rules"), - AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF, - "Registers non-standard HTTP methods"), -+AP_INIT_FLAG("MergeSlashes", set_core_server_flag, -+ (void *)APR_OFFSETOF(core_server_config, merge_slashes), -+ RSRC_CONF, -+ "Controls whether consecutive slashes in the URI path are merged"), - { NULL } - }; - -diff --git a/server/request.c b/server/request.c -index dbe3e07f150..1ce8908824b 100644 ---- a/server/request.c -+++ b/server/request.c -@@ -167,6 +167,8 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) - int file_req = (r->main && r->filename); - int access_status; - core_dir_config *d; -+ core_server_config *sconf = -+ ap_get_core_module_config(r->server->module_config); - - /* Ignore embedded %2F's in path for proxy requests */ - if (!r->proxyreq && r->parsed_uri.path) { -@@ -191,6 +193,10 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) - } - - ap_getparents(r->uri); /* OK --- shrinking transformations... */ -+ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { -+ ap_no2slash(r->uri); -+ ap_no2slash(r->parsed_uri.path); -+ } - - /* All file subrequests are a huge pain... they cannot bubble through the - * next several steps. Only file subrequests are allowed an empty uri, -@@ -1411,20 +1417,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) - - cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r); - cached = (cache->cached != NULL); -- -- /* Location and LocationMatch differ on their behaviour w.r.t. multiple -- * slashes. Location matches multiple slashes with a single slash, -- * LocationMatch doesn't. An exception, for backwards brokenness is -- * absoluteURIs... in which case neither match multiple slashes. -- */ -- if (r->uri[0] != '/') { -- entry_uri = r->uri; -- } -- else { -- char *uri = apr_pstrdup(r->pool, r->uri); -- ap_no2slash(uri); -- entry_uri = uri; -- } -+ entry_uri = r->uri; - - /* If we have an cache->cached location that matches r->uri, - * and the vhost's list of locations hasn't changed, we can skip -@@ -1491,7 +1484,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) - pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t)); - } - -- if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) { -+ if (ap_regexec(entry_core->r, entry_uri, nmatch, pmatch, 0)) { - continue; - } - -@@ -1501,7 +1494,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) - apr_table_setn(r->subprocess_env, - ((const char **)entry_core->refs->elts)[i], - apr_pstrndup(r->pool, -- r->uri + pmatch[i].rm_so, -+ entry_uri + pmatch[i].rm_so, - pmatch[i].rm_eo - pmatch[i].rm_so)); - } - } -diff --git a/server/util.c b/server/util.c -index fd7a0a14763..607c4850d86 100644 ---- a/server/util.c -+++ b/server/util.c -@@ -561,16 +561,16 @@ AP_DECLARE(void) ap_getparents(char *name) - name[l] = '\0'; - } - } -- --AP_DECLARE(void) ap_no2slash(char *name) -+AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path) - { -+ - char *d, *s; - - s = d = name; - - #ifdef HAVE_UNC_PATHS - /* Check for UNC names. Leave leading two slashes. */ -- if (s[0] == '/' && s[1] == '/') -+ if (is_fs_path && s[0] == '/' && s[1] == '/') - *d++ = *s++; - #endif - -@@ -587,6 +587,10 @@ AP_DECLARE(void) ap_no2slash(char *name) - *d = '\0'; - } - -+AP_DECLARE(void) ap_no2slash(char *name) -+{ -+ ap_no2slash_ex(name, 1); -+} - - /* - * copy at most n leading directories of s into d diff --git a/debian/patches/CVE-2019-0220-2.patch b/debian/patches/CVE-2019-0220-2.patch deleted file mode 100644 index 0204259..0000000 --- a/debian/patches/CVE-2019-0220-2.patch +++ /dev/null @@ -1,50 +0,0 @@ -From c4ef468b25718a26f2b92cbea3ca093729b79331 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Mon, 18 Mar 2019 12:10:15 +0000 -Subject: [PATCH] merge 1855743,1855744 ^/httpd/httpd/trunk . - -r->parsed_uri.path safety in recent backport - -*) core: fix SEGFAULT in CONNECT with recent change - 2.4.x: svn merge -c 1855743,1855744 ^/httpd/httpd/trunk . - +1: rpluem, icing, covener - - - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855751 13f79535-47bb-0310-9956-ffa450edef68 ---- - server/request.c | 4 +++- - server/util.c | 4 ++++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/server/request.c b/server/request.c -index 1ce8908824b..d5c558afa30 100644 ---- a/server/request.c -+++ b/server/request.c -@@ -195,7 +195,9 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) - ap_getparents(r->uri); /* OK --- shrinking transformations... */ - if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { - ap_no2slash(r->uri); -- ap_no2slash(r->parsed_uri.path); -+ if (r->parsed_uri.path) { -+ ap_no2slash(r->parsed_uri.path); -+ } - } - - /* All file subrequests are a huge pain... they cannot bubble through the -diff --git a/server/util.c b/server/util.c -index 607c4850d86..f3b17f1581e 100644 ---- a/server/util.c -+++ b/server/util.c -@@ -566,6 +566,10 @@ AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path) - - char *d, *s; - -+ if (!name || !*name) { -+ return; -+ } -+ - s = d = name; - - #ifdef HAVE_UNC_PATHS diff --git a/debian/patches/CVE-2019-0220-3.patch b/debian/patches/CVE-2019-0220-3.patch deleted file mode 100644 index 7b3ff6f..0000000 --- a/debian/patches/CVE-2019-0220-3.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 3451fc2bf8708b0dc8cd6a7d0ac0fe5b6401befc Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Tue, 19 Mar 2019 18:01:21 +0000 -Subject: [PATCH] *) maintainer mode fix for util.c no2slash_ex trunk - patch: http://svn.apache.org/r1855755 2.4.x patch svn merge -c 1855755 - ^/httpd/httpd/trunk . +1: covener, rpluem, jim, ylavic - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855853 13f79535-47bb-0310-9956-ffa450edef68 ---- - STATUS | 6 ------ - server/util.c | 2 +- - 2 files changed, 1 insertion(+), 7 deletions(-) - -#diff --git a/STATUS b/STATUS -#index ffe5d22550c..1f8cb2f7884 100644 -#--- a/STATUS -#+++ b/STATUS -#@@ -126,12 +126,6 @@ RELEASE SHOWSTOPPERS: -# PATCHES ACCEPTED TO BACKPORT FROM TRUNK: -# [ start all new proposals below, under PATCHES PROPOSED. ] -# -#- *) maintainer mode fix for util.c no2slash_ex -#- trunk patch: http://svn.apache.org/r1855755 -#- 2.4.x patch svn merge -c 1855755 ^/httpd/httpd/trunk . -#- +1: covener, rpluem, jim, ylavic -#- -#- -# PATCHES PROPOSED TO BACKPORT FROM TRUNK: -# [ New proposals should be added at the end of the list ] -# -diff --git a/server/util.c b/server/util.c -index f3b17f1581e..e0c558cee2d 100644 ---- a/server/util.c -+++ b/server/util.c -@@ -566,7 +566,7 @@ AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path) - - char *d, *s; - -- if (!name || !*name) { -+ if (!*name) { - return; - } - diff --git a/debian/patches/CVE-2019-10092.patch b/debian/patches/CVE-2019-10092.patch deleted file mode 100644 index eb3352c..0000000 --- a/debian/patches/CVE-2019-10092.patch +++ /dev/null @@ -1,193 +0,0 @@ -Description: Fix for CVE-2019-10092 -Author: Stefan Eissing -Origin: upstream, https://svn.apache.org/viewvc?view=revision&revision=1864191 -Bug: https://security-tracker.debian.org/tracker/CVE-2019-10092 -Forwarded: not-needed -Reviewed-By: Xavier Guimard <yadd@debian.org> -Last-Update: 2019-10-11 -[Salvatore Bonaccorso: Add additional change from https://svn.apache.org/r1864699 -to add missing APLOGNO's in mod_proxy.c and mod_proxy_ftp.c] ---- a/modules/http/http_protocol.c -+++ b/modules/http/http_protocol.c -@@ -1132,13 +1132,10 @@ - "\">here</a>.</p>\n", - NULL)); - case HTTP_USE_PROXY: -- return(apr_pstrcat(p, -- "<p>This resource is only accessible " -- "through the proxy\n", -- ap_escape_html(r->pool, location), -- "<br />\nYou will need to configure " -- "your client to use that proxy.</p>\n", -- NULL)); -+ return("<p>This resource is only accessible " -+ "through the proxy\n" -+ "<br />\nYou will need to configure " -+ "your client to use that proxy.</p>\n"); - case HTTP_PROXY_AUTHENTICATION_REQUIRED: - case HTTP_UNAUTHORIZED: - return("<p>This server could not verify that you\n" -@@ -1154,34 +1151,20 @@ - "error-notes", - "</p>\n")); - case HTTP_FORBIDDEN: -- s1 = apr_pstrcat(p, -- "<p>You don't have permission to access ", -- ap_escape_html(r->pool, r->uri), -- "\non this server.<br />\n", -- NULL); -- return(add_optional_notes(r, s1, "error-notes", "</p>\n")); -+ return(add_optional_notes(r, "<p>You don't have permission to access this resource.", "error-notes", "</p>\n")); - case HTTP_NOT_FOUND: -- return(apr_pstrcat(p, -- "<p>The requested URL ", -- ap_escape_html(r->pool, r->uri), -- " was not found on this server.</p>\n", -- NULL)); -+ return("<p>The requested URL was not found on this server.</p>\n"); - case HTTP_METHOD_NOT_ALLOWED: - return(apr_pstrcat(p, - "<p>The requested method ", - ap_escape_html(r->pool, r->method), -- " is not allowed for the URL ", -- ap_escape_html(r->pool, r->uri), -- ".</p>\n", -+ " is not allowed for this URL.</p>\n", - NULL)); - case HTTP_NOT_ACCEPTABLE: -- s1 = apr_pstrcat(p, -- "<p>An appropriate representation of the " -- "requested resource ", -- ap_escape_html(r->pool, r->uri), -- " could not be found on this server.</p>\n", -- NULL); -- return(add_optional_notes(r, s1, "variant-list", "")); -+ return(add_optional_notes(r, -+ "<p>An appropriate representation of the requested resource " -+ "could not be found on this server.</p>\n", -+ "variant-list", "")); - case HTTP_MULTIPLE_CHOICES: - return(add_optional_notes(r, "", "variant-list", "")); - case HTTP_LENGTH_REQUIRED: -@@ -1192,18 +1175,13 @@ - NULL); - return(add_optional_notes(r, s1, "error-notes", "</p>\n")); - case HTTP_PRECONDITION_FAILED: -- return(apr_pstrcat(p, -- "<p>The precondition on the request " -- "for the URL ", -- ap_escape_html(r->pool, r->uri), -- " evaluated to false.</p>\n", -- NULL)); -+ return("<p>The precondition on the request " -+ "for this URL evaluated to false.</p>\n"); - case HTTP_NOT_IMPLEMENTED: - s1 = apr_pstrcat(p, - "<p>", -- ap_escape_html(r->pool, r->method), " to ", -- ap_escape_html(r->pool, r->uri), -- " not supported.<br />\n", -+ ap_escape_html(r->pool, r->method), " ", -+ " not supported for current URL.<br />\n", - NULL); - return(add_optional_notes(r, s1, "error-notes", "</p>\n")); - case HTTP_BAD_GATEWAY: -@@ -1211,29 +1189,19 @@ - "response from an upstream server.<br />" CRLF; - return(add_optional_notes(r, s1, "error-notes", "</p>\n")); - case HTTP_VARIANT_ALSO_VARIES: -- return(apr_pstrcat(p, -- "<p>A variant for the requested " -- "resource\n<pre>\n", -- ap_escape_html(r->pool, r->uri), -- "\n</pre>\nis itself a negotiable resource. " -- "This indicates a configuration error.</p>\n", -- NULL)); -+ return("<p>A variant for the requested " -+ "resource\n<pre>\n" -+ "\n</pre>\nis itself a negotiable resource. " -+ "This indicates a configuration error.</p>\n"); - case HTTP_REQUEST_TIME_OUT: - return("<p>Server timeout waiting for the HTTP request from the client.</p>\n"); - case HTTP_GONE: -- return(apr_pstrcat(p, -- "<p>The requested resource<br />", -- ap_escape_html(r->pool, r->uri), -- "<br />\nis no longer available on this server " -- "and there is no forwarding address.\n" -- "Please remove all references to this " -- "resource.</p>\n", -- NULL)); -+ return("<p>The requested resource is no longer available on this server" -+ " and there is no forwarding address.\n" -+ "Please remove all references to this resource.</p>\n"); - case HTTP_REQUEST_ENTITY_TOO_LARGE: - return(apr_pstrcat(p, -- "The requested resource<br />", -- ap_escape_html(r->pool, r->uri), "<br />\n", -- "does not allow request data with ", -+ "The requested resource does not allow request data with ", - ap_escape_html(r->pool, r->method), - " requests, or the amount of data provided in\n" - "the request exceeds the capacity limit.\n", -@@ -1317,11 +1285,9 @@ - "the Server Name Indication (SNI) in use for this\n" - "connection.</p>\n"); - case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: -- s1 = apr_pstrcat(p, -- "<p>Access to ", ap_escape_html(r->pool, r->uri), -- "\nhas been denied for legal reasons.<br />\n", -- NULL); -- return(add_optional_notes(r, s1, "error-notes", "</p>\n")); -+ return(add_optional_notes(r, -+ "<p>Access to this URL has been denied for legal reasons.<br />\n", -+ "error-notes", "</p>\n")); - default: /* HTTP_INTERNAL_SERVER_ERROR */ - /* - * This comparison to expose error-notes could be modified to ---- a/modules/proxy/mod_proxy.c -+++ b/modules/proxy/mod_proxy.c -@@ -1049,9 +1049,10 @@ - char *end; - maxfwd = apr_strtoi64(str, &end, 10); - if (maxfwd < 0 || maxfwd == APR_INT64_MAX || *end) { -- return ap_proxyerror(r, HTTP_BAD_REQUEST, -- apr_psprintf(r->pool, -- "Max-Forwards value '%s' could not be parsed", str)); -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10188) -+ "Max-Forwards value '%s' could not be parsed", str); -+ return ap_proxyerror(r, HTTP_BAD_REQUEST, -+ "Max-Forwards request header could not be parsed"); - } - else if (maxfwd == 0) { - switch (r->method_number) { ---- a/modules/proxy/mod_proxy_ftp.c -+++ b/modules/proxy/mod_proxy_ftp.c -@@ -1024,8 +1024,9 @@ - /* We break the URL into host, port, path-search */ - if (r->parsed_uri.hostname == NULL) { - if (APR_SUCCESS != apr_uri_parse(p, url, &uri)) { -- return ap_proxyerror(r, HTTP_BAD_REQUEST, -- apr_psprintf(p, "URI cannot be parsed: %s", url)); -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10189) -+ "URI cannot be parsed: %s", url); -+ return ap_proxyerror(r, HTTP_BAD_REQUEST, "URI cannot be parsed"); - } - connectname = uri.hostname; - connectport = uri.port; ---- a/modules/proxy/proxy_util.c -+++ b/modules/proxy/proxy_util.c -@@ -368,12 +368,9 @@ - - PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message) - { -- const char *uri = ap_escape_html(r->pool, r->uri); - apr_table_setn(r->notes, "error-notes", - apr_pstrcat(r->pool, -- "The proxy server could not handle the request <em><a href=\"", -- uri, "\">", ap_escape_html(r->pool, r->method), " ", uri, -- "</a></em>.<p>\n" -+ "The proxy server could not handle the request<p>" - "Reason: <strong>", ap_escape_html(r->pool, message), - "</strong></p>", - NULL)); diff --git a/debian/patches/CVE-2019-10097.patch b/debian/patches/CVE-2019-10097.patch deleted file mode 100644 index 0be05f5..0000000 --- a/debian/patches/CVE-2019-10097.patch +++ /dev/null @@ -1,72 +0,0 @@ -Description: Fix for CVE-2019-10097 -Author: jorton -Origin: upstream, https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1864613 -Bug: https://security-tracker.debian.org/tracker/CVE-2019-10097 -Forwarded: not-needed -Reviewed-By: Xavier Guimard <yadd@debian.org> -Last-Update: 2019-08-17 - ---- a/modules/metadata/mod_remoteip.c -+++ b/modules/metadata/mod_remoteip.c -@@ -987,15 +987,13 @@ - return HDR_ERROR; - #endif - default: -- /* unsupported protocol, keep local connection address */ -- return HDR_DONE; -+ /* unsupported protocol */ -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10183) -+ "RemoteIPProxyProtocol: unsupported protocol %.2hx", -+ (unsigned short)hdr->v2.fam); -+ return HDR_ERROR; - } - break; /* we got a sockaddr now */ -- -- case 0x00: /* LOCAL command */ -- /* keep local connection address for LOCAL */ -- return HDR_DONE; -- - default: - /* not a supported command */ - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03507) -@@ -1087,11 +1085,24 @@ - /* try to read a header's worth of data */ - while (!ctx->done) { - if (APR_BRIGADE_EMPTY(ctx->bb)) { -- ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block, -- ctx->need - ctx->rcvd); -+ apr_off_t got, want = ctx->need - ctx->rcvd; -+ -+ ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block, want); - if (ret != APR_SUCCESS) { -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10184) -+ "failed reading input"); - return ret; - } -+ -+ ret = apr_brigade_length(ctx->bb, 1, &got); -+ if (ret || got > want) { -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10185) -+ "RemoteIPProxyProtocol header too long, " -+ "got %" APR_OFF_T_FMT " expected %" APR_OFF_T_FMT, -+ got, want); -+ f->c->aborted = 1; -+ return APR_ECONNABORTED; -+ } - } - if (APR_BRIGADE_EMPTY(ctx->bb)) { - return block == APR_NONBLOCK_READ ? APR_SUCCESS : APR_EOF; -@@ -1139,6 +1150,13 @@ - if (ctx->rcvd >= MIN_V2_HDR_LEN) { - ctx->need = MIN_V2_HDR_LEN + - remoteip_get_v2_len((proxy_header *) ctx->header); -+ if (ctx->need > sizeof(proxy_v2)) { -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(10186) -+ "RemoteIPProxyProtocol protocol header length too long"); -+ f->c->aborted = 1; -+ apr_brigade_destroy(ctx->bb); -+ return APR_ECONNABORTED; -+ } - } - if (ctx->rcvd >= ctx->need) { - psts = remoteip_process_v2_header(f->c, conn_conf, diff --git a/debian/patches/CVE-2019-10098.patch b/debian/patches/CVE-2019-10098.patch deleted file mode 100644 index b2c66b2..0000000 --- a/debian/patches/CVE-2019-10098.patch +++ /dev/null @@ -1,20 +0,0 @@ -Description: patch to set PCRE_DOTALL by default -Author: ylavic -Origin: upstream, https://svn.apache.org/viewvc?view=revision&revision=1864192 -Bug: https://security-tracker.debian.org/tracker/CVE-2019-10098 -Forwarded: not-needed -Reviewed-By: Xavier Guimard <yadd@debian.org> -Last-Update: 2019-08-18 - ---- a/server/util_pcre.c -+++ b/server/util_pcre.c -@@ -120,7 +120,8 @@ - * Compile a regular expression * - *************************************************/ - --static int default_cflags = AP_REG_DOLLAR_ENDONLY; -+static int default_cflags = AP_REG_DOTALL | -+ AP_REG_DOLLAR_ENDONLY; - - AP_DECLARE(int) ap_regcomp_get_default_cflags(void) - { diff --git a/debian/patches/CVE-2020-11984.patch b/debian/patches/CVE-2020-11984.patch deleted file mode 100644 index 409f958..0000000 --- a/debian/patches/CVE-2020-11984.patch +++ /dev/null @@ -1,45 +0,0 @@ -Description: fix error out on HTTP header larger than 16K - The uwsgi protocol does not let us serialize more than 16K of HTTP header, - so fail early with 500 if it happens. -Author: ylavic -Origin: upstream, https://github.com/apache/httpd/commit/0c543e3f -Bug: https://security-tracker.debian.org/tracker/CVE-2020-11984 -Forwarded: not-needed -Reviewed-By: Xavier Guimard <yadd@debian.org> -Last-Update: 2020-08-25 - ---- a/modules/proxy/mod_proxy_uwsgi.c -+++ b/modules/proxy/mod_proxy_uwsgi.c -@@ -136,7 +136,7 @@ - int j; - - apr_size_t headerlen = 4; -- apr_uint16_t pktsize, keylen, vallen; -+ apr_size_t pktsize, keylen, vallen; - const char *script_name; - const char *path_info; - const char *auth; -@@ -177,6 +177,14 @@ - for (j = 0; j < env_table->nelts; ++j) { - headerlen += 2 + strlen(env[j].key) + 2 + strlen(env[j].val); - } -+ pktsize = headerlen - 4; -+ if (pktsize > APR_UINT16_MAX) { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10259) -+ "can't send headers to %s:%u: packet size too " -+ "large (%" APR_SIZE_T_FMT ")", -+ conn->hostname, conn->port, pktsize); -+ return HTTP_INTERNAL_SERVER_ERROR; -+ } - - ptr = buf = apr_palloc(r->pool, headerlen); - -@@ -196,8 +204,6 @@ - ptr += vallen; - } - -- pktsize = headerlen - 4; -- - buf[0] = 0; - buf[1] = (apr_byte_t) (pktsize & 0xff); - buf[2] = (apr_byte_t) ((pktsize >> 8) & 0xff); diff --git a/debian/patches/CVE-2020-1927.patch b/debian/patches/CVE-2020-1927.patch deleted file mode 100644 index cbdd84f..0000000 --- a/debian/patches/CVE-2020-1927.patch +++ /dev/null @@ -1,92 +0,0 @@ -Description: fix for CVE-2020-1927 -Author: covener -Origin: upstream, https://svn.apache.org/r1873905 - https://svn.apache.org/r1874191 -Bug: https://security-tracker.debian.org/tracker/CVE-2020-1927 -Forwarded: not-needed -Reviewed-By: Xavier Guimard <yadd@debian.org> -Last-Update: 2020-08-25 - ---- a/include/ap_regex.h -+++ b/include/ap_regex.h -@@ -84,7 +84,11 @@ - - #define AP_REG_DOLLAR_ENDONLY 0x200 /* '$' matches at end of subject string only */ - --#define AP_REG_MATCH "MATCH_" /** suggested prefix for ap_regname */ -+#define AP_REG_NO_DEFAULT 0x400 /**< Don't implicitely add AP_REG_DEFAULT options */ -+ -+#define AP_REG_MATCH "MATCH_" /**< suggested prefix for ap_regname */ -+ -+#define AP_REG_DEFAULT (AP_REG_DOTALL|AP_REG_DOLLAR_ENDONLY) - - /* Error values: */ - enum { ---- a/modules/filters/mod_substitute.c -+++ b/modules/filters/mod_substitute.c -@@ -667,8 +667,10 @@ - - /* first see if we can compile the regex */ - if (!is_pattern) { -- r = ap_pregcomp(cmd->pool, from, AP_REG_EXTENDED | -- (ignore_case ? AP_REG_ICASE : 0)); -+ int flags = AP_REG_NO_DEFAULT -+ | (ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY) -+ | (ignore_case ? AP_REG_ICASE : 0); -+ r = ap_pregcomp(cmd->pool, from, flags); - if (!r) - return "Substitute could not compile regex"; - } ---- a/server/core.c -+++ b/server/core.c -@@ -4937,7 +4937,7 @@ - apr_pool_cleanup_register(pconf, NULL, reset_config_defines, - apr_pool_cleanup_null); - -- ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY); -+ ap_regcomp_set_default_cflags(AP_REG_DEFAULT); - - mpm_common_pre_config(pconf); - ---- a/server/util_pcre.c -+++ b/server/util_pcre.c -@@ -120,8 +120,7 @@ - * Compile a regular expression * - *************************************************/ - --static int default_cflags = AP_REG_DOTALL | -- AP_REG_DOLLAR_ENDONLY; -+static int default_cflags = AP_REG_DEFAULT; - - AP_DECLARE(int) ap_regcomp_get_default_cflags(void) - { -@@ -169,7 +168,9 @@ - int errcode = 0; - int options = PCRE_DUPNAMES; - -- cflags |= default_cflags; -+ if ((cflags & AP_REG_NO_DEFAULT) == 0) -+ cflags |= default_cflags; -+ - if ((cflags & AP_REG_ICASE) != 0) - options |= PCRE_CASELESS; - if ((cflags & AP_REG_NEWLINE) != 0) ---- a/server/util_regex.c -+++ b/server/util_regex.c -@@ -94,6 +94,7 @@ - } - - /* anything after the current delimiter is flags */ -+ ret->flags = ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY; - while (*++endp) { - switch (*endp) { - case 'i': ret->flags |= AP_REG_ICASE; break; -@@ -106,7 +107,7 @@ - default: break; /* we should probably be stricter here */ - } - } -- if (ap_regcomp(&ret->rx, rxstr, ret->flags) == 0) { -+ if (ap_regcomp(&ret->rx, rxstr, AP_REG_NO_DEFAULT | ret->flags) == 0) { - apr_pool_cleanup_register(pool, &ret->rx, rxplus_cleanup, - apr_pool_cleanup_null); - } diff --git a/debian/patches/CVE-2020-1934.patch b/debian/patches/CVE-2020-1934.patch deleted file mode 100644 index 295ab45..0000000 --- a/debian/patches/CVE-2020-1934.patch +++ /dev/null @@ -1,75 +0,0 @@ -Description: fix uninitialized memory when proxying to a malicious FTP server -Author: covener -Origin: upstream, https://svn.apache.org/viewvc?view=revision&revision=1873745 -Bug: https://security-tracker.debian.org/tracker/CVE-2020-1934 -Forwarded: not-needed -Reviewed-By: Xavier Guimard <yadd@debian.org> -Last-Update: 2020-08-25 - ---- a/modules/proxy/mod_proxy_ftp.c -+++ b/modules/proxy/mod_proxy_ftp.c -@@ -218,7 +218,7 @@ - * (EBCDIC) machines either. - */ - static apr_status_t ftp_string_read(conn_rec *c, apr_bucket_brigade *bb, -- char *buff, apr_size_t bufflen, int *eos) -+ char *buff, apr_size_t bufflen, int *eos, apr_size_t *outlen) - { - apr_bucket *e; - apr_status_t rv; -@@ -230,6 +230,7 @@ - /* start with an empty string */ - buff[0] = 0; - *eos = 0; -+ *outlen = 0; - - /* loop through each brigade */ - while (!found) { -@@ -273,6 +274,7 @@ - if (len > 0) { - memcpy(pos, response, len); - pos += len; -+ *outlen += len; - } - } - apr_bucket_delete(e); -@@ -385,28 +387,35 @@ - char buff[5]; - char *mb = msgbuf, *me = &msgbuf[msglen]; - apr_status_t rv; -+ apr_size_t nread; -+ - int eos; - -- if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) { -+ if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos, &nread))) { - return -1; - } - /* - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(03233) - "<%s", response); - */ -+ if (nread < 4) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(10229) "Malformed FTP response '%s'", response); -+ *mb = '\0'; -+ return -1; -+ } - if (!apr_isdigit(response[0]) || !apr_isdigit(response[1]) || -- !apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-')) -+ !apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-')) - status = 0; - else - status = 100 * response[0] + 10 * response[1] + response[2] - 111 * '0'; - - mb = apr_cpystrn(mb, response + 4, me - mb); - -- if (response[3] == '-') { -+ if (response[3] == '-') { /* multi-line reply "123-foo\nbar\n123 baz" */ - memcpy(buff, response, 3); - buff[3] = ' '; - do { -- if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) { -+ if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos, &nread))) { - return -1; - } - mb = apr_cpystrn(mb, response + (' ' == response[0] ? 1 : 4), me - mb); diff --git a/debian/patches/CVE-2020-35452.patch b/debian/patches/CVE-2020-35452.patch deleted file mode 100644 index 5204210..0000000 --- a/debian/patches/CVE-2020-35452.patch +++ /dev/null @@ -1,27 +0,0 @@ -Description: <short summary of the patch> -Author: Apache authors -Origin: upstream, https://github.com/apache/httpd/commit/3b6431e -Bug: https://httpd.apache.org/security/vulnerabilities_24.html#CVE-2020-35452 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-06-10 - ---- a/modules/aaa/mod_auth_digest.c -+++ b/modules/aaa/mod_auth_digest.c -@@ -1422,9 +1422,14 @@ - time_rec nonce_time; - char tmp, hash[NONCE_HASH_LEN+1]; - -- if (strlen(resp->nonce) != NONCE_LEN) { -+ /* Since the time part of the nonce is a base64 encoding of an -+ * apr_time_t (8 bytes), it should end with a '=', fail early otherwise. -+ */ -+ if (strlen(resp->nonce) != NONCE_LEN -+ || resp->nonce[NONCE_TIME_LEN - 1] != '=') { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01775) -- "invalid nonce %s received - length is not %d", -+ "invalid nonce '%s' received - length is not %d " -+ "or time encoding is incorrect", - resp->nonce, NONCE_LEN); - note_digest_auth_failure(r, conf, resp, 1); - return HTTP_UNAUTHORIZED; diff --git a/debian/patches/CVE-2021-26690.patch b/debian/patches/CVE-2021-26690.patch deleted file mode 100644 index 72c7457..0000000 --- a/debian/patches/CVE-2021-26690.patch +++ /dev/null @@ -1,20 +0,0 @@ -Description: <short summary of the patch> -Author: Apache authors -Origin: upstream, https://github.com/apache/httpd/commit/67bd9bfe -Bug: https://httpd.apache.org/security/vulnerabilities_24.html#CVE-2021-26690 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-06-10 - ---- a/modules/session/mod_session.c -+++ b/modules/session/mod_session.c -@@ -392,8 +392,8 @@ - char *plast = NULL; - const char *psep = "="; - char *key = apr_strtok(pair, psep, &plast); -- char *val = apr_strtok(NULL, psep, &plast); - if (key && *key) { -+ char *val = apr_strtok(NULL, sep, &plast); - if (!val || !*val) { - apr_table_unset(z->entries, key); - } diff --git a/debian/patches/CVE-2021-26691.patch b/debian/patches/CVE-2021-26691.patch deleted file mode 100644 index 7b96fad..0000000 --- a/debian/patches/CVE-2021-26691.patch +++ /dev/null @@ -1,18 +0,0 @@ -Description: mod_session: account for the '&' in identity_concat(). -Author: Apache authors -Origin: upstream, https://github.com/apache/httpd/commit/7e09dd71 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-06-10 - ---- a/modules/session/mod_session.c -+++ b/modules/session/mod_session.c -@@ -305,7 +305,7 @@ - static int identity_count(void *v, const char *key, const char *val) - { - int *count = v; -- *count += strlen(key) * 3 + strlen(val) * 3 + 1; -+ *count += strlen(key) * 3 + strlen(val) * 3 + 2; - return 1; - } - diff --git a/debian/patches/CVE-2021-30641.patch b/debian/patches/CVE-2021-30641.patch deleted file mode 100644 index 7486e1b..0000000 --- a/debian/patches/CVE-2021-30641.patch +++ /dev/null @@ -1,50 +0,0 @@ -Description: legacy default slash-matching behavior w/ 'MergeSlashes OFF' -Author: Apache authors -Origin: upstream, https://github.com/apache/httpd/commit/eb986059 -Bug: https://httpd.apache.org/security/vulnerabilities_24.html#CVE-2021-30641 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-06-10 - ---- a/server/request.c -+++ b/server/request.c -@@ -1419,7 +1419,20 @@ - - cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r); - cached = (cache->cached != NULL); -- entry_uri = r->uri; -+ -+ /* -+ * When merge_slashes is set to AP_CORE_CONFIG_OFF the slashes in r->uri -+ * have not been merged. But for Location walks we always go with merged -+ * slashes no matter what merge_slashes is set to. -+ */ -+ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { -+ entry_uri = r->uri; -+ } -+ else { -+ char *uri = apr_pstrdup(r->pool, r->uri); -+ ap_no2slash(uri); -+ entry_uri = uri; -+ } - - /* If we have an cache->cached location that matches r->uri, - * and the vhost's list of locations hasn't changed, we can skip -@@ -1486,7 +1499,7 @@ - pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t)); - } - -- if (ap_regexec(entry_core->r, entry_uri, nmatch, pmatch, 0)) { -+ if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) { - continue; - } - -@@ -1496,7 +1509,7 @@ - apr_table_setn(r->subprocess_env, - ((const char **)entry_core->refs->elts)[i], - apr_pstrndup(r->pool, -- entry_uri + pmatch[i].rm_so, -+ r->uri + pmatch[i].rm_so, - pmatch[i].rm_eo - pmatch[i].rm_so)); - } - } diff --git a/debian/patches/CVE-2021-31618.patch b/debian/patches/CVE-2021-31618.patch deleted file mode 100644 index 12d59c8..0000000 --- a/debian/patches/CVE-2021-31618.patch +++ /dev/null @@ -1,20 +0,0 @@ -Description: fix NULL pointer dereference on specially crafted HTTP/2 request -Author: Upstream -Origin: upstream, http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_stream.c?r1=1889759&r2=1889758&pathrev=1889759 -Bug: https://httpd.apache.org/security/vulnerabilities_24.html#CVE-2021-31618 -Bug-Debian: https://bugs.debian.org/989562 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-06-10 - ---- a/modules/http2/h2_stream.c -+++ b/modules/http2/h2_stream.c -@@ -638,7 +638,7 @@ - - static void set_error_response(h2_stream *stream, int http_status) - { -- if (!h2_stream_is_ready(stream)) { -+ if (!h2_stream_is_ready(stream) && stream->rtmp) { - conn_rec *c = stream->session->c; - apr_bucket *b; - h2_headers *response; diff --git a/debian/patches/CVE-2021-33193.patch b/debian/patches/CVE-2021-33193.patch deleted file mode 100644 index d2737b8..0000000 --- a/debian/patches/CVE-2021-33193.patch +++ /dev/null @@ -1,702 +0,0 @@ -Description: Fix for CVE-2021-33193: mod_proxy HTTP/2 validation bypass - A crafted method sent through HTTP/2 will bypass validation and be forwarded by - mod_proxy, which can lead to request splitting or cache poisoning. -Origin: other, https://git.centos.org/rpms/httpd/blob/c496dea5e0b6e82a9f503e973fc5d5ea93a94180/f/SOURCES/httpd-2.4.37-CVE-2021-33193.patch -Forwarded: not-needed -Applied-Upstream: 2.4.49, https://github.com/apache/httpd/commit/ecebcc035ccd8d0e2984fe41420d9e944f456b3c -Last-Update: 2023-02-24 ---- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- a/include/http_core.h -+++ b/include/http_core.h -@@ -741,6 +741,7 @@ - #define AP_HTTP_METHODS_REGISTERED 2 - char http_methods; - unsigned int merge_slashes; -+ unsigned int strict_host_check; - } core_server_config; - - /* for AddOutputFiltersByType in core.c */ -@@ -769,6 +770,11 @@ - typedef struct core_output_filter_ctx core_output_filter_ctx_t; - typedef struct core_filter_ctx core_ctx_t; - -+struct core_filter_ctx { -+ apr_bucket_brigade *b; -+ apr_bucket_brigade *tmpbb; -+}; -+ - typedef struct core_net_rec { - /** Connection to the client */ - apr_socket_t *client_socket; ---- a/include/http_protocol.h -+++ b/include/http_protocol.h -@@ -54,6 +54,13 @@ - */ - - /** -+ * Read an empty request and set reasonable defaults. -+ * @param c The current connection -+ * @return The new request_rec -+ */ -+AP_DECLARE(request_rec *) ap_create_request(conn_rec *c); -+ -+/** - * Read a request and fill in the fields. - * @param c The current connection - * @return The new request_rec -@@ -61,6 +68,20 @@ - request_rec *ap_read_request(conn_rec *c); - - /** -+ * Parse and validate the request line. -+ * @param r The current request -+ * @return 1 on success, 0 on failure -+ */ -+AP_DECLARE(int) ap_parse_request_line(request_rec *r); -+ -+/** -+ * Validate the request header and select vhost. -+ * @param r The current request -+ * @return 1 on success, 0 on failure -+ */ -+AP_DECLARE(int) ap_check_request_header(request_rec *r); -+ -+/** - * Read the mime-encoded headers. - * @param r The current request - */ ---- a/include/http_vhost.h -+++ b/include/http_vhost.h -@@ -100,6 +100,19 @@ - AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r); - - /** -+ * Updates r->server with the best name-based virtual host match, within -+ * the chain of matching virtual hosts selected by ap_update_vhost_given_ip. -+ * @param r The current request -+ * @param require_match 1 to return an HTTP error if the requested hostname is -+ * not explicitly matched to a VirtualHost. -+ * @return return HTTP_OK unless require_match was specified and the requested -+ * hostname did not match any ServerName, ServerAlias, or VirtualHost -+ * address-spec. -+ */ -+AP_DECLARE(int) ap_update_vhost_from_headers_ex(request_rec *r, int require_match); -+ -+ -+/** - * Match the host in the header with the hostname of the server for this - * request. - * @param r The current request ---- a/server/core.c -+++ b/server/core.c -@@ -494,6 +494,8 @@ - conf->protocols_honor_order = -1; - conf->merge_slashes = AP_CORE_CONFIG_UNSET; - -+ conf->strict_host_check= AP_CORE_CONFIG_UNSET; -+ - return (void *)conf; - } - -@@ -559,7 +561,13 @@ - base->protocols_honor_order : - virt->protocols_honor_order); - AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt); -- -+ -+ conf->strict_host_check = (virt->strict_host_check != AP_CORE_CONFIG_UNSET) -+ ? virt->strict_host_check -+ : base->strict_host_check; -+ -+ AP_CORE_MERGE_FLAG(strict_host_check, conf, base, virt); -+ - return conf; - } - -@@ -4518,7 +4526,10 @@ - AP_INIT_FLAG("QualifyRedirectURL", set_qualify_redirect_url, NULL, OR_FILEINFO, - "Controls whether HTTP authorization headers, normally hidden, will " - "be passed to scripts"), -- -+AP_INIT_FLAG("StrictHostCheck", set_core_server_flag, -+ (void *)APR_OFFSETOF(core_server_config, strict_host_check), -+ RSRC_CONF, -+ "Controls whether a hostname match is required"), - AP_INIT_TAKE1("ForceType", ap_set_string_slot_lower, - (void *)APR_OFFSETOF(core_dir_config, mime_type), OR_FILEINFO, - "a mime type that overrides other configured type"), -@@ -5492,4 +5503,3 @@ - core_cmds, /* command apr_table_t */ - register_hooks /* register hooks */ - }; -- ---- a/server/core_filters.c -+++ b/server/core_filters.c -@@ -84,11 +84,6 @@ - apr_size_t bytes_written; - }; - --struct core_filter_ctx { -- apr_bucket_brigade *b; -- apr_bucket_brigade *tmpbb; --}; -- - - apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, - ap_input_mode_t mode, apr_read_type_e block, ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -611,8 +611,15 @@ - } - - r->args = r->parsed_uri.query; -- r->uri = r->parsed_uri.path ? r->parsed_uri.path -- : apr_pstrdup(r->pool, "/"); -+ if (r->parsed_uri.path) { -+ r->uri = r->parsed_uri.path; -+ } -+ else if (r->method_number == M_OPTIONS) { -+ r->uri = apr_pstrdup(r->pool, "*"); -+ } -+ else { -+ r->uri = apr_pstrdup(r->pool, "/"); -+ } - - #if defined(OS2) || defined(WIN32) - /* Handle path translations for OS/2 and plug security hole. -@@ -649,13 +656,6 @@ - - static int read_request_line(request_rec *r, apr_bucket_brigade *bb) - { -- enum { -- rrl_none, rrl_badmethod, rrl_badwhitespace, rrl_excesswhitespace, -- rrl_missinguri, rrl_baduri, rrl_badprotocol, rrl_trailingtext, -- rrl_badmethod09, rrl_reject09 -- } deferred_error = rrl_none; -- char *ll; -- char *uri; - apr_size_t len; - int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES; - core_server_config *conf = ap_get_core_module_config(r->server->module_config); -@@ -720,6 +720,20 @@ - } - - r->request_time = apr_time_now(); -+ return 1; -+} -+ -+AP_DECLARE(int) ap_parse_request_line(request_rec *r) -+{ -+ core_server_config *conf = ap_get_core_module_config(r->server->module_config); -+ int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE); -+ enum { -+ rrl_none, rrl_badmethod, rrl_badwhitespace, rrl_excesswhitespace, -+ rrl_missinguri, rrl_baduri, rrl_badprotocol, rrl_trailingtext, -+ rrl_badmethod09, rrl_reject09 -+ } deferred_error = rrl_none; -+ apr_size_t len = 0; -+ char *uri, *ll; - - r->method = r->the_request; - -@@ -751,7 +765,6 @@ - if (deferred_error == rrl_none) - deferred_error = rrl_missinguri; - r->protocol = uri = ""; -- len = 0; - goto rrl_done; - } - else if (strict && ll[0] && apr_isspace(ll[1]) -@@ -782,7 +795,6 @@ - /* Verify URI terminated with a single SP, or mark as specific error */ - if (!ll) { - r->protocol = ""; -- len = 0; - goto rrl_done; - } - else if (strict && ll[0] && apr_isspace(ll[1]) -@@ -875,6 +887,14 @@ - r->header_only = 1; - - ap_parse_uri(r, uri); -+ if (r->status == HTTP_OK -+ && (r->parsed_uri.path != NULL) -+ && (r->parsed_uri.path[0] != '/') -+ && (r->method_number != M_OPTIONS -+ || strcmp(r->parsed_uri.path, "*") != 0)) { -+ /* Invalid request-target per RFC 7230 section 5.3 */ -+ r->status = HTTP_BAD_REQUEST; -+ } - - /* With the request understood, we can consider HTTP/0.9 specific errors */ - if (r->proto_num == HTTP_VERSION(0, 9) && deferred_error == rrl_none) { -@@ -982,6 +1002,79 @@ - return 0; - } - -+AP_DECLARE(int) ap_check_request_header(request_rec *r) -+{ -+ core_server_config *conf; -+ int strict_host_check; -+ const char *expect; -+ int access_status; -+ -+ conf = ap_get_core_module_config(r->server->module_config); -+ -+ /* update what we think the virtual host is based on the headers we've -+ * now read. may update status. -+ */ -+ strict_host_check = (conf->strict_host_check == AP_CORE_CONFIG_ON); -+ access_status = ap_update_vhost_from_headers_ex(r, strict_host_check); -+ if (strict_host_check && access_status != HTTP_OK) { -+ if (r->server == ap_server_conf) { -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10156) -+ "Requested hostname '%s' did not match any ServerName/ServerAlias " -+ "in the global server configuration ", r->hostname); -+ } -+ else { -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10157) -+ "Requested hostname '%s' did not match any ServerName/ServerAlias " -+ "in the matching virtual host (default vhost for " -+ "current connection is %s:%u)", -+ r->hostname, r->server->defn_name, r->server->defn_line_number); -+ } -+ r->status = access_status; -+ } -+ if (r->status != HTTP_OK) { -+ return 0; -+ } -+ -+ if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1, 1))) -+ || ((r->proto_num == HTTP_VERSION(1, 1)) -+ && !apr_table_get(r->headers_in, "Host"))) { -+ /* -+ * Client sent us an HTTP/1.1 or later request without telling us the -+ * hostname, either with a full URL or a Host: header. We therefore -+ * need to (as per the 1.1 spec) send an error. As a special case, -+ * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain -+ * a Host: header, and the server MUST respond with 400 if it doesn't. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00569) -+ "client sent HTTP/1.1 request without hostname " -+ "(see RFC2616 section 14.23): %s", r->uri); -+ r->status = HTTP_BAD_REQUEST; -+ return 0; -+ } -+ -+ if (((expect = apr_table_get(r->headers_in, "Expect")) != NULL) -+ && (expect[0] != '\0')) { -+ /* -+ * The Expect header field was added to HTTP/1.1 after RFC 2068 -+ * as a means to signal when a 100 response is desired and, -+ * unfortunately, to signal a poor man's mandatory extension that -+ * the server must understand or return 417 Expectation Failed. -+ */ -+ if (ap_cstr_casecmp(expect, "100-continue") == 0) { -+ r->expecting_100 = 1; -+ } -+ else { -+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00570) -+ "client sent an unrecognized expectation value " -+ "of Expect: %s", expect); -+ r->status = HTTP_EXPECTATION_FAILED; -+ return 0; -+ } -+ } -+ -+ return 1; -+} -+ - static int table_do_fn_check_lengths(void *r_, const char *key, - const char *value) - { -@@ -1265,16 +1358,10 @@ - apr_brigade_destroy(tmp_bb); - } - --request_rec *ap_read_request(conn_rec *conn) -+AP_DECLARE(request_rec *) ap_create_request(conn_rec *conn) - { - request_rec *r; - apr_pool_t *p; -- const char *expect; -- int access_status; -- apr_bucket_brigade *tmp_bb; -- apr_socket_t *csd; -- apr_interval_time_t cur_timeout; -- - - apr_pool_create(&p, conn->pool); - apr_pool_tag(p, "request"); -@@ -1313,6 +1400,7 @@ - r->read_body = REQUEST_NO_BODY; - - r->status = HTTP_OK; /* Until further notice */ -+ r->header_only = 0; - r->the_request = NULL; - - /* Begin by presuming any module can make its own path_info assumptions, -@@ -1323,12 +1411,33 @@ - r->useragent_addr = conn->client_addr; - r->useragent_ip = conn->client_ip; - -+ return r; -+} -+ -+/* Apply the server's timeout/config to the connection/request. */ -+static void apply_server_config(request_rec *r) -+{ -+ apr_socket_t *csd; -+ -+ csd = ap_get_conn_socket(r->connection); -+ apr_socket_timeout_set(csd, r->server->timeout); -+ -+ r->per_dir_config = r->server->lookup_defaults; -+} -+ -+request_rec *ap_read_request(conn_rec *conn) -+{ -+ int access_status; -+ apr_bucket_brigade *tmp_bb; -+ -+ request_rec *r = ap_create_request(conn); - tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); - - ap_run_pre_read_request(r, conn); - - /* Get the request... */ -- if (!read_request_line(r, tmp_bb)) { -+ if (!read_request_line(r, tmp_bb) || !ap_parse_request_line(r)) { -+ apr_brigade_cleanup(tmp_bb); - switch (r->status) { - case HTTP_REQUEST_URI_TOO_LARGE: - case HTTP_BAD_REQUEST: -@@ -1344,49 +1453,38 @@ - "request failed: malformed request line"); - } - access_status = r->status; -- r->status = HTTP_OK; -- ap_die(access_status, r); -- ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); -- ap_run_log_transaction(r); -- r = NULL; -- apr_brigade_destroy(tmp_bb); -- goto traceout; -+ goto die_unusable_input; -+ - case HTTP_REQUEST_TIME_OUT: -+ /* Just log, no further action on this connection. */ - ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL); - if (!r->connection->keepalives) - ap_run_log_transaction(r); -- apr_brigade_destroy(tmp_bb); -- goto traceout; -- default: -- apr_brigade_destroy(tmp_bb); -- r = NULL; -- goto traceout; -+ break; - } -+ /* Not worth dying with. */ -+ conn->keepalive = AP_CONN_CLOSE; -+ apr_pool_destroy(r->pool); -+ goto ignore; - } -+ apr_brigade_cleanup(tmp_bb); - - /* We may have been in keep_alive_timeout mode, so toggle back - * to the normal timeout mode as we fetch the header lines, - * as necessary. - */ -- csd = ap_get_conn_socket(conn); -- apr_socket_timeout_get(csd, &cur_timeout); -- if (cur_timeout != conn->base_server->timeout) { -- apr_socket_timeout_set(csd, conn->base_server->timeout); -- cur_timeout = conn->base_server->timeout; -- } -+ apply_server_config(r); - - if (!r->assbackwards) { - const char *tenc; - - ap_get_mime_headers_core(r, tmp_bb); -+ apr_brigade_cleanup(tmp_bb); - if (r->status != HTTP_OK) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00567) - "request failed: error reading the headers"); -- ap_send_error_response(r, 0); -- ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); -- ap_run_log_transaction(r); -- apr_brigade_destroy(tmp_bb); -- goto traceout; -+ access_status = r->status; -+ goto die_unusable_input; - } - - tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); -@@ -1402,13 +1500,8 @@ - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02539) - "client sent unknown Transfer-Encoding " - "(%s): %s", tenc, r->uri); -- r->status = HTTP_BAD_REQUEST; -- conn->keepalive = AP_CONN_CLOSE; -- ap_send_error_response(r, 0); -- ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); -- ap_run_log_transaction(r); -- apr_brigade_destroy(tmp_bb); -- goto traceout; -+ access_status = HTTP_BAD_REQUEST; -+ goto die_unusable_input; - } - - /* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23 -@@ -1421,88 +1514,81 @@ - } - } - -- apr_brigade_destroy(tmp_bb); -- -- /* update what we think the virtual host is based on the headers we've -- * now read. may update status. -- */ -- ap_update_vhost_from_headers(r); -- access_status = r->status; -- -- /* Toggle to the Host:-based vhost's timeout mode to fetch the -- * request body and send the response body, if needed. -- */ -- if (cur_timeout != r->server->timeout) { -- apr_socket_timeout_set(csd, r->server->timeout); -- cur_timeout = r->server->timeout; -- } -- -- /* we may have switched to another server */ -- r->per_dir_config = r->server->lookup_defaults; -- -- if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1, 1))) -- || ((r->proto_num == HTTP_VERSION(1, 1)) -- && !apr_table_get(r->headers_in, "Host"))) { -- /* -- * Client sent us an HTTP/1.1 or later request without telling us the -- * hostname, either with a full URL or a Host: header. We therefore -- * need to (as per the 1.1 spec) send an error. As a special case, -- * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain -- * a Host: header, and the server MUST respond with 400 if it doesn't. -- */ -- access_status = HTTP_BAD_REQUEST; -- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00569) -- "client sent HTTP/1.1 request without hostname " -- "(see RFC2616 section 14.23): %s", r->uri); -- } -- - /* - * Add the HTTP_IN filter here to ensure that ap_discard_request_body - * called by ap_die and by ap_send_error_response works correctly on - * status codes that do not cause the connection to be dropped and - * in situations where the connection should be kept alive. - */ -- - ap_add_input_filter_handle(ap_http_input_filter_handle, - NULL, r, r->connection); - -- if (access_status != HTTP_OK -- || (access_status = ap_post_read_request(r))) { -- ap_die(access_status, r); -- ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); -- ap_run_log_transaction(r); -- r = NULL; -- goto traceout; -+ /* Validate Host/Expect headers and select vhost. */ -+ if (!ap_check_request_header(r)) { -+ /* we may have switched to another server still */ -+ apply_server_config(r); -+ access_status = r->status; -+ goto die_before_hooks; - } - -- if (((expect = apr_table_get(r->headers_in, "Expect")) != NULL) -- && (expect[0] != '\0')) { -- /* -- * The Expect header field was added to HTTP/1.1 after RFC 2068 -- * as a means to signal when a 100 response is desired and, -- * unfortunately, to signal a poor man's mandatory extension that -- * the server must understand or return 417 Expectation Failed. -- */ -- if (strcasecmp(expect, "100-continue") == 0) { -- r->expecting_100 = 1; -- } -- else { -- r->status = HTTP_EXPECTATION_FAILED; -- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00570) -- "client sent an unrecognized expectation value of " -- "Expect: %s", expect); -- ap_send_error_response(r, 0); -- ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); -- ap_run_log_transaction(r); -- goto traceout; -- } -+ /* we may have switched to another server */ -+ apply_server_config(r); -+ -+ if ((access_status = ap_run_post_read_request(r))) { -+ goto die; - } - -- AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method, (char *)r->uri, (char *)r->server->defn_name, r->status); -+ AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method, -+ (char *)r->uri, (char *)r->server->defn_name, -+ r->status); -+ - return r; -- traceout: -+ -+ /* Everything falls through on failure */ -+ -+die_unusable_input: -+ /* Input filters are in an undeterminate state, cleanup (including -+ * CORE_IN's socket) such that any further attempt to read is EOF. -+ */ -+ { -+ ap_filter_t *f = conn->input_filters; -+ while (f) { -+ if (f->frec == ap_core_input_filter_handle) { -+ core_net_rec *net = f->ctx; -+ apr_brigade_cleanup(net->in_ctx->b); -+ break; -+ } -+ ap_remove_input_filter(f); -+ f = f->next; -+ } -+ conn->input_filters = r->input_filters = f; -+ conn->keepalive = AP_CONN_CLOSE; -+ } -+ -+die_before_hooks: -+ /* First call to ap_die() (non recursive) */ -+ r->status = HTTP_OK; -+ -+die: -+ ap_die(access_status, r); -+ -+ /* ap_die() sent the response through the output filters, we must now -+ * end the request with an EOR bucket for stream/pipeline accounting. -+ */ -+ { -+ apr_bucket_brigade *eor_bb; -+ eor_bb = apr_brigade_create(conn->pool, conn->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(eor_bb, -+ ap_bucket_eor_create(conn->bucket_alloc, r)); -+ ap_pass_brigade(conn->output_filters, eor_bb); -+ apr_brigade_cleanup(eor_bb); -+ } -+ -+ignore: -+ r = NULL; -+ - AP_READ_REQUEST_FAILURE((uintptr_t)r); -- return r; -+ return NULL; - } - - AP_DECLARE(int) ap_post_read_request(request_rec *r) ---- a/server/vhost.c -+++ b/server/vhost.c -@@ -34,6 +34,7 @@ - #include "http_vhost.h" - #include "http_protocol.h" - #include "http_core.h" -+#include "http_main.h" - - #if APR_HAVE_ARPA_INET_H - #include <arpa/inet.h> -@@ -973,7 +974,13 @@ - } - - --static void check_hostalias(request_rec *r) -+/* -+ * Updates r->server from ServerName/ServerAlias. Per the interaction -+ * of ip and name-based vhosts, it only looks in the best match from the -+ * connection-level ip-based matching. -+ * Returns HTTP_BAD_REQUEST if there was no match. -+ */ -+static int update_server_from_aliases(request_rec *r) - { - /* - * Even if the request has a Host: header containing a port we ignore -@@ -1050,11 +1057,18 @@ - goto found; - } - -- return; -+ if (!r->connection->vhost_lookup_data) { -+ if (matches_aliases(r->server, host)) { -+ s = r->server; -+ goto found; -+ } -+ } -+ return HTTP_BAD_REQUEST; - - found: - /* s is the first matching server, we're done */ - r->server = s; -+ return HTTP_OK; - } - - -@@ -1071,7 +1085,7 @@ - * This is in conjunction with the ServerPath code in http_core, so we - * get the right host attached to a non- Host-sending request. - * -- * See the comment in check_hostalias about how each vhost can be -+ * See the comment in update_server_from_aliases about how each vhost can be - * listed multiple times. - */ - -@@ -1135,10 +1149,16 @@ - - AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r) - { -+ ap_update_vhost_from_headers_ex(r, 0); -+} -+ -+AP_DECLARE(int) ap_update_vhost_from_headers_ex(request_rec *r, int require_match) -+{ - core_server_config *conf = ap_get_core_module_config(r->server->module_config); - const char *host_header = apr_table_get(r->headers_in, "Host"); - int is_v6literal = 0; - int have_hostname_from_url = 0; -+ int rc = HTTP_OK; - - if (r->hostname) { - /* -@@ -1151,8 +1171,8 @@ - else if (host_header != NULL) { - is_v6literal = fix_hostname(r, host_header, conf->http_conformance); - } -- if (r->status != HTTP_OK) -- return; -+ if (!require_match && r->status != HTTP_OK) -+ return HTTP_OK; - - if (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE) { - /* -@@ -1173,10 +1193,16 @@ - /* check if we tucked away a name_chain */ - if (r->connection->vhost_lookup_data) { - if (r->hostname) -- check_hostalias(r); -+ rc = update_server_from_aliases(r); - else - check_serverpath(r); - } -+ else if (require_match && r->hostname) { -+ /* check the base server config */ -+ rc = update_server_from_aliases(r); -+ } -+ -+ return rc; - } - - /** diff --git a/debian/patches/CVE-2021-34798.patch b/debian/patches/CVE-2021-34798.patch deleted file mode 100644 index bd6261a..0000000 --- a/debian/patches/CVE-2021-34798.patch +++ /dev/null @@ -1,40 +0,0 @@ -Description: Initialize the request fields on read failure to avoid NULLs -Origin: upstream, https://github.com/apache/httpd/commit/74c097f0, - https://github.com/apache/httpd/commit/6945bb2 -Bug: https://security-tracker.debian.org/tracker/CVE-2021-34798 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-09-21 - ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -643,6 +643,8 @@ - return end - field; - } - -+static const char m_invalid_str[] = "-"; -+ - static int read_request_line(request_rec *r, apr_bucket_brigade *bb) - { - enum { -@@ -685,6 +687,11 @@ - if (rv != APR_SUCCESS) { - r->request_time = apr_time_now(); - -+ /* Fall through with an invalid (non NULL) request */ -+ r->method = m_invalid_str; -+ r->method_number = M_INVALID; -+ r->uri = r->unparsed_uri = apr_pstrdup(r->pool, "-"); -+ - /* ap_rgetline returns APR_ENOSPC if it fills up the - * buffer before finding the end-of-line. This is only going to - * happen if it exceeds the configured limit for a request-line. -@@ -1330,7 +1337,7 @@ - "request failed: client's request-line exceeds LimitRequestLine (longer than %d)", - r->server->limit_req_line); - } -- else if (r->method == NULL) { -+ else if (r->method == m_invalid_str) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00566) - "request failed: malformed request line"); - } diff --git a/debian/patches/CVE-2021-36160-2.patch b/debian/patches/CVE-2021-36160-2.patch deleted file mode 100644 index cad5774..0000000 --- a/debian/patches/CVE-2021-36160-2.patch +++ /dev/null @@ -1,32 +0,0 @@ -Description: mod_proxy_uwsgi: Remove duplicate slashes at the beginning of PATH_INFO. - Relaxes the behaviour introduced by the CVE-2021-36160 fix -Author: Stefan Eissing <icing@apache.org> -Origin: upstream, https://github.com/apache/httpd/commit/8966e290a -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-12-21 - ---- a/modules/proxy/mod_proxy_uwsgi.c -+++ b/modules/proxy/mod_proxy_uwsgi.c -@@ -467,11 +467,20 @@ - - /* ADD PATH_INFO (unescaped) */ - u_path_info = ap_strchr(url + sizeof(UWSGI_SCHEME) + 2, '/'); -- if (!u_path_info || ap_unescape_url(u_path_info) != OK) { -+ if (!u_path_info) { -+ u_path_info = apr_pstrdup(r->pool, "/"); -+ } -+ else if (ap_unescape_url(u_path_info) != OK) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10100) - "unable to decode uwsgi uri: %s", url); - return HTTP_INTERNAL_SERVER_ERROR; - } -+ else { -+ /* Remove duplicate slashes at the beginning of PATH_INFO */ -+ while (u_path_info[1] == '/') { -+ u_path_info++; -+ } -+ } - apr_table_add(r->subprocess_env, "PATH_INFO", u_path_info); - - diff --git a/debian/patches/CVE-2021-36160.patch b/debian/patches/CVE-2021-36160.patch deleted file mode 100644 index fcd8087..0000000 --- a/debian/patches/CVE-2021-36160.patch +++ /dev/null @@ -1,51 +0,0 @@ -Description: mod_proxy_uwsgi: Fix PATH_INFO setting for generic worker -Author: Yann Ylavic <ylavic@apache.org> -Origin: upstream, https://github.com/apache/httpd/commit/b364cad7 -Bug: https://security-tracker.debian.org/tracker/CVE-2021-36160 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-09-21 - ---- a/modules/proxy/mod_proxy_uwsgi.c -+++ b/modules/proxy/mod_proxy_uwsgi.c -@@ -452,11 +452,8 @@ - const char *proxyname, apr_port_t proxyport) - { - int status; -- int delta = 0; -- int decode_status; - proxy_conn_rec *backend = NULL; - apr_pool_t *p = r->pool; -- size_t w_len; - char server_portstr[32]; - char *u_path_info; - apr_uri_t *uri; -@@ -468,23 +465,14 @@ - - uri = apr_palloc(r->pool, sizeof(*uri)); - -- /* ADD PATH_INFO */ --#if AP_MODULE_MAGIC_AT_LEAST(20111130,0) -- w_len = strlen(worker->s->name); --#else -- w_len = strlen(worker->name); --#endif -- u_path_info = r->filename + 6 + w_len; -- if (u_path_info[0] != '/') { -- delta = 1; -- } -- decode_status = ap_unescape_url(url + w_len - delta); -- if (decode_status) { -+ /* ADD PATH_INFO (unescaped) */ -+ u_path_info = ap_strchr(url + sizeof(UWSGI_SCHEME) + 2, '/'); -+ if (!u_path_info || ap_unescape_url(u_path_info) != OK) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10100) -- "unable to decode uri: %s", url + w_len - delta); -+ "unable to decode uwsgi uri: %s", url); - return HTTP_INTERNAL_SERVER_ERROR; - } -- apr_table_add(r->subprocess_env, "PATH_INFO", url + w_len - delta); -+ apr_table_add(r->subprocess_env, "PATH_INFO", u_path_info); - - - /* Create space for state information */ diff --git a/debian/patches/CVE-2021-39275.patch b/debian/patches/CVE-2021-39275.patch deleted file mode 100644 index d489891..0000000 --- a/debian/patches/CVE-2021-39275.patch +++ /dev/null @@ -1,35 +0,0 @@ -Description: Backport of - From c69d4cc90c0e27703030b3ff09f91bf4dcbcfd51 Mon Sep 17 00:00:00 2001 - From: Stefan Eissing <icing@apache.org> - Date: Tue, 10 Aug 2021 08:55:54 +0000 - Subject: [PATCH] Merged r1892012 from trunk: - . - and - From ac62c7e7436560cf4f7725ee586364ce95c07804 Mon Sep 17 00:00:00 2001 - From: Graham Leggett <minfrin@apache.org> - Date: Sat, 21 Aug 2021 21:35:04 +0000 - Subject: [PATCH] Backport: -Author: Moritz Muehlenhoff <jmm@inutil.org> -Origin: upstream -Forwarded: not-needed -Last-Update: 2021-09-30 - ---- a/server/util.c -+++ b/server/util.c -@@ -2460,13 +2460,12 @@ - * in front of every " that doesn't already have one. - */ - while (*inchr != '\0') { -- if ((*inchr == '\\') && (inchr[1] != '\0')) { -- *outchr++ = *inchr++; -- *outchr++ = *inchr++; -- } - if (*inchr == '"') { - *outchr++ = '\\'; - } -+ if ((*inchr == '\\') && (inchr[1] != '\0')) { -+ *outchr++ = *inchr++; -+ } - if (*inchr != '\0') { - *outchr++ = *inchr++; - } diff --git a/debian/patches/CVE-2021-40438.patch b/debian/patches/CVE-2021-40438.patch deleted file mode 100644 index 8cf60a7..0000000 --- a/debian/patches/CVE-2021-40438.patch +++ /dev/null @@ -1,124 +0,0 @@ -Description: Backport of the following patches: -Origin: upstream, - https://github.com/apache/httpd/commit/496c863776c68bd08cdbeb7d8fa5935ba63b76c2 - https://github.com/apache/httpd/commit/d4901cb32133bc0e59ad193a29d1665597080d67 - https://github.com/apache/httpd/commit/81a8b0133b46c4cf7dfc4b5476ad46eb34aa0a5c - https://github.com/apache/httpd/commit/6e768a811c59ca6a0769b72681aaef381823339f -Forwarded: not-needed -Reviewed-By: Moritz Muehlenhoff <jmm@inutil.org> -Last-Update: 2021-09-30 - ---- a/modules/mappers/mod_rewrite.c -+++ b/modules/mappers/mod_rewrite.c -@@ -620,6 +620,13 @@ - return 6; - } - break; -+ -+ case 'u': -+ case 'U': -+ if (!ap_cstr_casecmpn(uri, "nix:", 4)) { /* unix: */ -+ *sqs = 1; -+ return (uri[4] == '/' && uri[5] == '/') ? 7 : 5; -+ } - } - - return 0; ---- a/modules/proxy/mod_proxy.c -+++ b/modules/proxy/mod_proxy.c -@@ -1690,7 +1690,7 @@ - * the UDS path... ignore it - */ - if (!strncasecmp(url, "unix:", 5) && -- ((ptr = ap_strchr_c(url, '|')) != NULL)) { -+ ((ptr = ap_strchr_c(url + 5, '|')) != NULL)) { - /* move past the 'unix:...|' UDS path info */ - const char *ret, *c; - ---- a/modules/proxy/proxy_util.c -+++ b/modules/proxy/proxy_util.c -@@ -2077,33 +2077,43 @@ - * were passed a UDS url (eg: from mod_proxy) and adjust uds_path - * as required. - */ --static void fix_uds_filename(request_rec *r, char **url) -+static int fix_uds_filename(request_rec *r, char **url) - { -- char *ptr, *ptr2; -- if (!r || !r->filename) return; -+ char *uds_url = r->filename + 6, *origin_url; - - if (!strncmp(r->filename, "proxy:", 6) && -- (ptr2 = ap_strcasestr(r->filename, "unix:")) && -- (ptr = ap_strchr(ptr2, '|'))) { -+ !ap_cstr_casecmpn(uds_url, "unix:", 5) && -+ (origin_url = ap_strchr(uds_url + 5, '|'))) { -+ char *uds_path = NULL; -+ apr_size_t url_len; - apr_uri_t urisock; - apr_status_t rv; -- *ptr = '\0'; -- rv = apr_uri_parse(r->pool, ptr2, &urisock); -- if (rv == APR_SUCCESS) { -- char *rurl = ptr+1; -- char *sockpath = ap_runtime_dir_relative(r->pool, urisock.path); -- apr_table_setn(r->notes, "uds_path", sockpath); -- *url = apr_pstrdup(r->pool, rurl); /* so we get the scheme for the uds */ -- /* r->filename starts w/ "proxy:", so add after that */ -- memmove(r->filename+6, rurl, strlen(rurl)+1); -- ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, -- "*: rewrite of url due to UDS(%s): %s (%s)", -- sockpath, *url, r->filename); -+ -+ *origin_url = '\0'; -+ rv = apr_uri_parse(r->pool, uds_url, &urisock); -+ *origin_url++ = '|'; -+ -+ if (rv == APR_SUCCESS && urisock.path && (!urisock.hostname -+ || !urisock.hostname[0])) { -+ uds_path = ap_runtime_dir_relative(r->pool, urisock.path); - } -- else { -- *ptr = '|'; -+ if (!uds_path) { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10292) -+ "Invalid proxy UDS filename (%s)", r->filename); -+ return 0; - } -+ apr_table_setn(r->notes, "uds_path", uds_path); -+ -+ /* Remove the UDS path from *url and r->filename */ -+ url_len = strlen(origin_url); -+ *url = apr_pstrmemdup(r->pool, origin_url, url_len); -+ memcpy(uds_url, *url, url_len + 1); -+ -+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, -+ "*: rewrite of url due to UDS(%s): %s (%s)", -+ uds_path, *url, r->filename); - } -+ return 1; - } - - PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, -@@ -2121,7 +2131,9 @@ - "%s: found worker %s for %s", - (*worker)->s->scheme, (*worker)->s->name, *url); - *balancer = NULL; -- fix_uds_filename(r, url); -+ if (!fix_uds_filename(r, url)) { -+ return HTTP_INTERNAL_SERVER_ERROR; -+ } - access_status = OK; - } - else if (r->proxyreq == PROXYREQ_PROXY) { -@@ -2152,7 +2164,9 @@ - * regarding the Connection header in the request. - */ - apr_table_setn(r->subprocess_env, "proxy-nokeepalive", "1"); -- fix_uds_filename(r, url); -+ if (!fix_uds_filename(r, url)) { -+ return HTTP_INTERNAL_SERVER_ERROR; -+ } - } - } - } diff --git a/debian/patches/CVE-2021-44224-1.patch b/debian/patches/CVE-2021-44224-1.patch deleted file mode 100644 index 0f540c8..0000000 --- a/debian/patches/CVE-2021-44224-1.patch +++ /dev/null @@ -1,206 +0,0 @@ -Description: CVE-2021-44224 -Author: Yann Ylavic <ylavic@apache.org> -Origin: upstream, https://github.com/apache/httpd/commit/a962ba73 -Bug: https://security-tracker.debian.org/tracker/CVE-2021-44224 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-12-21 - ---- a/include/http_protocol.h -+++ b/include/http_protocol.h -@@ -75,6 +75,13 @@ - AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, - apr_bucket_brigade *bb); - -+/** -+ * Run post_read_request hook and validate. -+ * @param r The current request -+ * @return OK or HTTP_... -+ */ -+AP_DECLARE(int) ap_post_read_request(request_rec *r); -+ - /* Finish up stuff after a request */ - - /** ---- a/modules/http/http_request.c -+++ b/modules/http/http_request.c -@@ -681,7 +681,7 @@ - * to do their thing on internal redirects as well. Perhaps this is a - * misnamed function. - */ -- if ((access_status = ap_run_post_read_request(new))) { -+ if ((access_status = ap_post_read_request(new))) { - ap_die(access_status, new); - return NULL; - } ---- a/modules/http2/h2_request.c -+++ b/modules/http2/h2_request.c -@@ -337,7 +337,7 @@ - NULL, r, r->connection); - - if (access_status != HTTP_OK -- || (access_status = ap_run_post_read_request(r))) { -+ || (access_status = ap_post_read_request(r))) { - /* Request check post hooks failed. An example of this would be a - * request for a vhost where h2 is disabled --> 421. - */ ---- a/modules/proxy/mod_proxy.c -+++ b/modules/proxy/mod_proxy.c -@@ -576,13 +576,13 @@ - - /* Ick... msvc (perhaps others) promotes ternary short results to int */ - -- if (conf->req && r->parsed_uri.scheme) { -+ if (conf->req && r->parsed_uri.scheme && r->parsed_uri.hostname) { - /* but it might be something vhosted */ -- if (!(r->parsed_uri.hostname -- && !strcasecmp(r->parsed_uri.scheme, ap_http_scheme(r)) -- && ap_matches_request_vhost(r, r->parsed_uri.hostname, -- (apr_port_t)(r->parsed_uri.port_str ? r->parsed_uri.port -- : ap_default_port(r))))) { -+ if (strcasecmp(r->parsed_uri.scheme, ap_http_scheme(r)) != 0 -+ || !ap_matches_request_vhost(r, r->parsed_uri.hostname, -+ (apr_port_t)(r->parsed_uri.port_str -+ ? r->parsed_uri.port -+ : ap_default_port(r)))) { - r->proxyreq = PROXYREQ_PROXY; - r->uri = r->unparsed_uri; - r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL); -@@ -1722,6 +1722,7 @@ - struct proxy_alias *new; - char *f = cmd->path; - char *r = NULL; -+ const char *real; - char *word; - apr_table_t *params = apr_table_make(cmd->pool, 5); - const apr_array_header_t *arr; -@@ -1787,6 +1788,10 @@ - if (r == NULL) { - return "ProxyPass|ProxyPassMatch needs a path when not defined in a location"; - } -+ if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, r))) { -+ return "ProxyPass|ProxyPassMatch uses an invalid \"unix:\" URL"; -+ } -+ - - /* if per directory, save away the single alias */ - if (cmd->path) { -@@ -1803,7 +1808,7 @@ - } - - new->fake = apr_pstrdup(cmd->pool, f); -- new->real = apr_pstrdup(cmd->pool, ap_proxy_de_socketfy(cmd->pool, r)); -+ new->real = apr_pstrdup(cmd->pool, real); - new->flags = flags; - if (use_regex) { - new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); -@@ -2280,6 +2285,7 @@ - proxy_worker *worker; - char *path = cmd->path; - char *name = NULL; -+ const char *real; - char *word; - apr_table_t *params = apr_table_make(cmd->pool, 5); - const apr_array_header_t *arr; -@@ -2320,6 +2326,9 @@ - return "BalancerMember must define balancer name when outside <Proxy > section"; - if (!name) - return "BalancerMember must define remote proxy server"; -+ if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, name))) { -+ return "BalancerMember uses an invalid \"unix:\" URL"; -+ } - - ap_str_tolower(path); /* lowercase scheme://hostname */ - -@@ -2332,7 +2341,7 @@ - } - - /* Try to find existing worker */ -- worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, ap_proxy_de_socketfy(cmd->temp_pool, name)); -+ worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, real); - if (!worker) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147) - "Defining worker '%s' for balancer '%s'", -@@ -2421,7 +2430,14 @@ - } - } - else { -- worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, ap_proxy_de_socketfy(cmd->temp_pool, name)); -+ const char *real; -+ -+ if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, name))) { -+ return "ProxySet uses an invalid \"unix:\" URL"; -+ } -+ -+ worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, -+ real); - if (!worker) { - if (in_proxy_section) { - err = ap_proxy_define_worker(cmd->pool, &worker, NULL, -@@ -2563,8 +2579,14 @@ - } - } - else { -+ const char *real; -+ -+ if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, conf->p))) { -+ return "<Proxy/ProxyMatch > uses an invalid \"unix:\" URL"; -+ } -+ - worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf, -- ap_proxy_de_socketfy(cmd->temp_pool, (char*)conf->p)); -+ real); - if (!worker) { - err = ap_proxy_define_worker(cmd->pool, &worker, NULL, - sconf, conf->p, 0); ---- a/modules/proxy/proxy_util.c -+++ b/modules/proxy/proxy_util.c -@@ -1662,6 +1662,9 @@ - } - - url = ap_proxy_de_socketfy(p, url); -+ if (!url) { -+ return NULL; -+ } - - c = ap_strchr_c(url, ':'); - if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') { ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -1465,7 +1465,7 @@ - NULL, r, r->connection); - - if (access_status != HTTP_OK -- || (access_status = ap_run_post_read_request(r))) { -+ || (access_status = ap_post_read_request(r))) { - ap_die(access_status, r); - ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); - ap_run_log_transaction(r); -@@ -1503,6 +1503,27 @@ - return r; - } - -+AP_DECLARE(int) ap_post_read_request(request_rec *r) -+{ -+ int status; -+ -+ if ((status = ap_run_post_read_request(r))) { -+ return status; -+ } -+ -+ /* Enforce http(s) only scheme for non-forward-proxy requests */ -+ if (!r->proxyreq -+ && r->parsed_uri.scheme -+ && (ap_cstr_casecmpn(r->parsed_uri.scheme, "http", 4) != 0 -+ || (r->parsed_uri.scheme[4] != '\0' -+ && (apr_tolower(r->parsed_uri.scheme[4]) != 's' -+ || r->parsed_uri.scheme[5] != '\0')))) { -+ return HTTP_BAD_REQUEST; -+ } -+ -+ return OK; -+} -+ - /* if a request with a body creates a subrequest, remove original request's - * input headers which pertain to the body which has already been read. - * out-of-line helper function for ap_set_sub_req_protocol. diff --git a/debian/patches/CVE-2021-44224-2.patch b/debian/patches/CVE-2021-44224-2.patch deleted file mode 100644 index 6b841dd..0000000 --- a/debian/patches/CVE-2021-44224-2.patch +++ /dev/null @@ -1,93 +0,0 @@ -Description: mod_proxy: Don't prevent forwarding URIs w/ no hostname. - (fix for r1895955 already in 2.4.x) - . - Part not applied: - #--- a/modules/proxy/mod_proxy.h - #+++ b/modules/proxy/mod_proxy.h - #@@ -323,6 +323,8 @@ - # #define PROXY_WORKER_HC_FAIL_FLAG 'C' - # #define PROXY_WORKER_HOT_SPARE_FLAG 'R' - # - #+#define AP_PROXY_WORKER_NO_UDS (1u << 3) - #+ - # #define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \ - # PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR | \ - # PROXY_WORKER_HC_FAIL ) - #--- a/modules/proxy/proxy_util.c - #+++ b/modules/proxy/proxy_util.c - #@@ -1661,9 +1661,11 @@ - # return NULL; - # } - # - #- url = ap_proxy_de_socketfy(p, url); - #- if (!url) { - #- return NULL; - #+ if (!(mask & AP_PROXY_WORKER_NO_UDS)) { - #+ url = ap_proxy_de_socketfy(p, url); - #+ if (!url) { - #+ return NULL; - #+ } - # } - # - # c = ap_strchr_c(url, ':'); -Author: Stefan Eissing <icing@apache.org> -Origin: upstream, https://github.com/apache/httpd/commit/a0521d289 -Bug: https://security-tracker.debian.org/tracker/CVE-2021-44224 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-12-21 - ---- a/modules/proxy/mod_proxy.c -+++ b/modules/proxy/mod_proxy.c -@@ -576,9 +576,10 @@ - - /* Ick... msvc (perhaps others) promotes ternary short results to int */ - -- if (conf->req && r->parsed_uri.scheme && r->parsed_uri.hostname) { -+ if (conf->req && r->parsed_uri.scheme) { - /* but it might be something vhosted */ -- if (strcasecmp(r->parsed_uri.scheme, ap_http_scheme(r)) != 0 -+ if (!r->parsed_uri.hostname -+ || strcasecmp(r->parsed_uri.scheme, ap_http_scheme(r)) != 0 - || !ap_matches_request_vhost(r, r->parsed_uri.hostname, - (apr_port_t)(r->parsed_uri.port_str - ? r->parsed_uri.port ---- a/modules/proxy/proxy_util.c -+++ b/modules/proxy/proxy_util.c -@@ -2128,22 +2128,21 @@ - - access_status = proxy_run_pre_request(worker, balancer, r, conf, url); - if (access_status == DECLINED && *balancer == NULL) { -+ const int forward = (r->proxyreq == PROXYREQ_PROXY); - *worker = ap_proxy_get_worker(r->pool, NULL, conf, *url); - if (*worker) { - ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, - "%s: found worker %s for %s", - (*worker)->s->scheme, (*worker)->s->name, *url); -- *balancer = NULL; -- if (!fix_uds_filename(r, url)) { -+ if (!forward && !fix_uds_filename(r, url)) { - return HTTP_INTERNAL_SERVER_ERROR; - } - access_status = OK; - } -- else if (r->proxyreq == PROXYREQ_PROXY) { -+ else if (forward) { - if (conf->forward) { - ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, - "*: found forward proxy worker for %s", *url); -- *balancer = NULL; - *worker = conf->forward; - access_status = OK; - /* -@@ -2157,8 +2156,8 @@ - else if (r->proxyreq == PROXYREQ_REVERSE) { - if (conf->reverse) { - ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, -- "*: using default reverse proxy worker for %s (no keepalive)", *url); -- *balancer = NULL; -+ "*: using default reverse proxy worker for %s " -+ "(no keepalive)", *url); - *worker = conf->reverse; - access_status = OK; - /* diff --git a/debian/patches/CVE-2021-44790.patch b/debian/patches/CVE-2021-44790.patch deleted file mode 100644 index dbba745..0000000 --- a/debian/patches/CVE-2021-44790.patch +++ /dev/null @@ -1,18 +0,0 @@ -Description: Improve error handling -Author: Stefan Eissing <icing@apache.org> -Origin: upstream, https://github.com/apache/httpd/commit/07b9768c -Bug: https://security-tracker.debian.org/tracker/CVE-2021-44790 -Forwarded: not-needed -Reviewed-By: Yadd <yadd@debian.org> -Last-Update: 2021-12-21 - ---- a/modules/lua/lua_request.c -+++ b/modules/lua/lua_request.c -@@ -376,6 +376,7 @@ - if (end == NULL) break; - key = (char *) apr_pcalloc(r->pool, 256); - filename = (char *) apr_pcalloc(r->pool, 256); -+ if (end - crlf <= 8) break; - vlen = end - crlf - 8; - buffer = (char *) apr_pcalloc(r->pool, vlen+1); - memcpy(buffer, crlf + 4, vlen); diff --git a/debian/patches/CVE-2022-22719.patch b/debian/patches/CVE-2022-22719.patch deleted file mode 100644 index c52ceef..0000000 --- a/debian/patches/CVE-2022-22719.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 1b96582269d9ec7c82ee0fea1f67934e4b8176ad Mon Sep 17 00:00:00 2001 -From: Yann Ylavic <ylavic@apache.org> -Date: Mon, 7 Mar 2022 14:51:19 +0000 -Subject: [PATCH] mod_lua: Error out if lua_read_body() or lua_write_body() - fail. - -Otherwise r:requestbody() or r:parsebody() failures might go unnoticed for -the user. - - -Merge r1898689 from trunk. -Submitted by: rpluem -Reviewed by: rpluem, covener, ylavic - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1898694 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/lua/lua_request.c | 33 ++++++++++++++++++++------------- - 1 file changed, 20 insertions(+), 13 deletions(-) - -diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c -index 493b2bb431..1eab7b6a47 100644 ---- a/modules/lua/lua_request.c -+++ b/modules/lua/lua_request.c -@@ -235,14 +235,16 @@ static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size, - { - int rc = OK; - -+ *rbuf = NULL; -+ *size = 0; -+ - if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) { - return (rc); - } - if (ap_should_client_block(r)) { - - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -- char argsbuffer[HUGE_STRING_LEN]; -- apr_off_t rsize, len_read, rpos = 0; -+ apr_off_t len_read, rpos = 0; - apr_off_t length = r->remaining; - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - -@@ -250,18 +252,18 @@ static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size, - return APR_EINCOMPLETE; /* Only room for incomplete data chunk :( */ - } - *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length + 1)); -- *size = length; -- while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) { -- if ((rpos + len_read) > length) { -- rsize = length - rpos; -- } -- else { -- rsize = len_read; -- } -- -- memcpy((char *) *rbuf + rpos, argsbuffer, (size_t) rsize); -- rpos += rsize; -+ while ((rpos < length) -+ && (len_read = ap_get_client_block(r, (char *) *rbuf + rpos, -+ length - rpos)) > 0) { -+ rpos += len_read; -+ } -+ if (len_read < 0) { -+ return APR_EINCOMPLETE; - } -+ *size = rpos; -+ } -+ else { -+ rc = DONE; - } - - return (rc); -@@ -278,6 +280,8 @@ static apr_status_t lua_write_body(request_rec *r, apr_file_t *file, apr_off_t * - { - apr_status_t rc = OK; - -+ *size = 0; -+ - if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) - return rc; - if (ap_should_client_block(r)) { -@@ -303,6 +307,9 @@ static apr_status_t lua_write_body(request_rec *r, apr_file_t *file, apr_off_t * - rpos += rsize; - } - } -+ else { -+ rc = DONE; -+ } - - return rc; - } --- -2.30.2 - diff --git a/debian/patches/CVE-2022-22720.patch b/debian/patches/CVE-2022-22720.patch deleted file mode 100644 index a296824..0000000 --- a/debian/patches/CVE-2022-22720.patch +++ /dev/null @@ -1,190 +0,0 @@ -From 19aa2d83b379719420f3a178413325156d7a62f3 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic <ylavic@apache.org> -Date: Mon, 7 Mar 2022 14:46:08 +0000 -Subject: [PATCH] core: Simpler connection close logic if discarding the - request body fails. - -If ap_discard_request_body() sets AP_CONN_CLOSE by itself it simplifies and -allows to consolidate end_output_stream() and error_output_stream(). - - -Merge r1898683 from trunk. -Submitted by: ylavic, rpluem -Reviewed by: ylavic, rpluem, covener - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1898692 13f79535-47bb-0310-9956-ffa450edef68 ---- - changes-entries/discard_body.diff | 2 + - modules/http/http_filters.c | 69 ++++++++++++++++--------------- - server/protocol.c | 14 +++++-- - 3 files changed, 48 insertions(+), 37 deletions(-) - create mode 100644 changes-entries/discard_body.diff - -diff --git a/changes-entries/discard_body.diff b/changes-entries/discard_body.diff -new file mode 100644 -index 0000000000..6b467ac5ee ---- /dev/null -+++ b/changes-entries/discard_body.diff -@@ -0,0 +1,2 @@ -+ *) core: Simpler connection close logic if discarding the request body fails. -+ [Yann Ylavic, Ruediger Pluem] -\ No newline at end of file -diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c -index d9b3621215..43e8c6dd5d 100644 ---- a/modules/http/http_filters.c -+++ b/modules/http/http_filters.c -@@ -1598,9 +1598,9 @@ AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status) - */ - AP_DECLARE(int) ap_discard_request_body(request_rec *r) - { -+ int rc = OK; -+ conn_rec *c = r->connection; - apr_bucket_brigade *bb; -- int seen_eos; -- apr_status_t rv; - - /* Sometimes we'll get in a state where the input handling has - * detected an error where we want to drop the connection, so if -@@ -1609,54 +1609,57 @@ AP_DECLARE(int) ap_discard_request_body(request_rec *r) - * - * This function is also a no-op on a subrequest. - */ -- if (r->main || r->connection->keepalive == AP_CONN_CLOSE || -- ap_status_drops_connection(r->status)) { -+ if (r->main || c->keepalive == AP_CONN_CLOSE) { -+ return OK; -+ } -+ if (ap_status_drops_connection(r->status)) { -+ c->keepalive = AP_CONN_CLOSE; - return OK; - } - - bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); -- seen_eos = 0; -- do { -- apr_bucket *bucket; -+ for (;;) { -+ apr_status_t rv; - - rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, - APR_BLOCK_READ, HUGE_STRING_LEN); -- - if (rv != APR_SUCCESS) { -- apr_brigade_destroy(bb); -- return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); -+ rc = ap_map_http_request_error(rv, HTTP_BAD_REQUEST); -+ goto cleanup; - } - -- for (bucket = APR_BRIGADE_FIRST(bb); -- bucket != APR_BRIGADE_SENTINEL(bb); -- bucket = APR_BUCKET_NEXT(bucket)) -- { -- const char *data; -- apr_size_t len; -+ while (!APR_BRIGADE_EMPTY(bb)) { -+ apr_bucket *b = APR_BRIGADE_FIRST(bb); - -- if (APR_BUCKET_IS_EOS(bucket)) { -- seen_eos = 1; -- break; -- } -- -- /* These are metadata buckets. */ -- if (bucket->length == 0) { -- continue; -+ if (APR_BUCKET_IS_EOS(b)) { -+ goto cleanup; - } - -- /* We MUST read because in case we have an unknown-length -- * bucket or one that morphs, we want to exhaust it. -+ /* There is no need to read empty or metadata buckets or -+ * buckets of known length, but we MUST read buckets of -+ * unknown length in order to exhaust them. - */ -- rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); -- if (rv != APR_SUCCESS) { -- apr_brigade_destroy(bb); -- return HTTP_BAD_REQUEST; -+ if (b->length == (apr_size_t)-1) { -+ apr_size_t len; -+ const char *data; -+ -+ rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ); -+ if (rv != APR_SUCCESS) { -+ rc = HTTP_BAD_REQUEST; -+ goto cleanup; -+ } - } -+ -+ apr_bucket_delete(b); - } -- apr_brigade_cleanup(bb); -- } while (!seen_eos); -+ } - -- return OK; -+cleanup: -+ apr_brigade_cleanup(bb); -+ if (rc != OK) { -+ c->keepalive = AP_CONN_CLOSE; -+ } -+ return rc; - } - - /* Here we deal with getting the request message body from the client. -diff --git a/server/protocol.c b/server/protocol.c -index 2214f72b5a..298f61e1fb 100644 ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -1687,23 +1687,29 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, - rnew->main = (request_rec *) r; - } - --static void end_output_stream(request_rec *r) -+static void end_output_stream(request_rec *r, int status) - { - conn_rec *c = r->connection; - apr_bucket_brigade *bb; - apr_bucket *b; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); -+ if (status != OK) { -+ b = ap_bucket_error_create(status, NULL, r->pool, c->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(bb, b); -+ } - b = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); -+ - ap_pass_brigade(r->output_filters, bb); -+ apr_brigade_cleanup(bb); - } - - AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub) - { - /* tell the filter chain there is no more content coming */ - if (!sub->eos_sent) { -- end_output_stream(sub); -+ end_output_stream(sub, OK); - } - } - -@@ -1714,11 +1720,11 @@ AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub) - */ - AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r) - { -- (void) ap_discard_request_body(r); -+ int status = ap_discard_request_body(r); - - /* tell the filter chain there is no more content coming */ - if (!r->eos_sent) { -- end_output_stream(r); -+ end_output_stream(r, status); - } - } - --- -2.30.2 - diff --git a/debian/patches/CVE-2022-22721.patch b/debian/patches/CVE-2022-22721.patch deleted file mode 100644 index 2f607aa..0000000 --- a/debian/patches/CVE-2022-22721.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 5a72f0fe6f2f8ce35c45242e99a421dc19251ab5 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic <ylavic@apache.org> -Date: Mon, 7 Mar 2022 14:48:54 +0000 -Subject: [PATCH] core: Make sure and check that LimitXMLRequestBody fits in - system memory. - -LimitXMLRequestBody can not exceed the size needed to ap_escape_html2() the -body without failing to allocate memory, so enforce this at load time based -on APR_SIZE_MAX, and make sure that ap_escape_html2() is within the bounds. - -Document the limits for LimitXMLRequestBody in our docs. - - -Merge r1898686 from trunk. -Submitted by: ylavic, rpluem -Reviewed by: ylavic, covener, rpluem - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1898693 13f79535-47bb-0310-9956-ffa450edef68 ---- - changes-entries/AP_MAX_LIMIT_XML_BODY.diff | 2 ++ - docs/manual/mod/core.xml | 12 +++++++++--- - server/core.c | 9 +++++++++ - server/util.c | 8 ++++++-- - server/util_xml.c | 2 +- - 5 files changed, 27 insertions(+), 6 deletions(-) - create mode 100644 changes-entries/AP_MAX_LIMIT_XML_BODY.diff - -diff --git a/changes-entries/AP_MAX_LIMIT_XML_BODY.diff b/changes-entries/AP_MAX_LIMIT_XML_BODY.diff -new file mode 100644 -index 0000000000..07fef3c624 ---- /dev/null -+++ b/changes-entries/AP_MAX_LIMIT_XML_BODY.diff -@@ -0,0 +1,2 @@ -+ *) core: Make sure and check that LimitXMLRequestBody fits in system memory. -+ [Ruediger Pluem, Yann Ylavic] -\ No newline at end of file -diff --git a/server/core.c b/server/core.c -index 798212b480..090e397642 100644 ---- a/server/core.c -+++ b/server/core.c -@@ -72,6 +72,8 @@ - /* LimitXMLRequestBody handling */ - #define AP_LIMIT_UNSET ((long) -1) - #define AP_DEFAULT_LIMIT_XML_BODY ((apr_size_t)1000000) -+/* Hard limit for ap_escape_html2() */ -+#define AP_MAX_LIMIT_XML_BODY ((apr_size_t)(APR_SIZE_MAX / 6 - 1)) - - #define AP_MIN_SENDFILE_BYTES (256) - -@@ -3761,6 +3763,11 @@ static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_, - if (conf->limit_xml_body < 0) - return "LimitXMLRequestBody requires a non-negative integer."; - -+ /* zero is AP_MAX_LIMIT_XML_BODY (implicitly) */ -+ if ((apr_size_t)conf->limit_xml_body > AP_MAX_LIMIT_XML_BODY) -+ return apr_psprintf(cmd->pool, "LimitXMLRequestBody must not exceed " -+ "%" APR_SIZE_T_FMT, AP_MAX_LIMIT_XML_BODY); -+ - return NULL; - } - -@@ -3849,6 +3856,8 @@ AP_DECLARE(apr_size_t) ap_get_limit_xml_body(const request_rec *r) - conf = ap_get_core_module_config(r->per_dir_config); - if (conf->limit_xml_body == AP_LIMIT_UNSET) - return AP_DEFAULT_LIMIT_XML_BODY; -+ if (conf->limit_xml_body == 0) -+ return AP_MAX_LIMIT_XML_BODY; - - return (apr_size_t)conf->limit_xml_body; - } -diff --git a/server/util.c b/server/util.c -index 6cfe0035c4..604be1a1ce 100644 ---- a/server/util.c -+++ b/server/util.c -@@ -2142,11 +2142,14 @@ AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *buffer) - - AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc) - { -- int i, j; -+ apr_size_t i, j; - char *x; - - /* first, count the number of extra characters */ -- for (i = 0, j = 0; s[i] != '\0'; i++) -+ for (i = 0, j = 0; s[i] != '\0'; i++) { -+ if (i + j > APR_SIZE_MAX - 6) { -+ abort(); -+ } - if (s[i] == '<' || s[i] == '>') - j += 3; - else if (s[i] == '&') -@@ -2155,6 +2158,7 @@ AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc) - j += 5; - else if (toasc && !apr_isascii(s[i])) - j += 5; -+ } - - if (j == 0) - return apr_pstrmemdup(p, s, i); -diff --git a/server/util_xml.c b/server/util_xml.c -index 4845194656..22806fa8a4 100644 ---- a/server/util_xml.c -+++ b/server/util_xml.c -@@ -85,7 +85,7 @@ AP_DECLARE(int) ap_xml_parse_input(request_rec * r, apr_xml_doc **pdoc) - } - - total_read += len; -- if (limit_xml_body && total_read > limit_xml_body) { -+ if (total_read > limit_xml_body) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00539) - "XML request body is larger than the configured " - "limit of %lu", (unsigned long)limit_xml_body); --- -2.30.2 - diff --git a/debian/patches/CVE-2022-23943-1.patch b/debian/patches/CVE-2022-23943-1.patch deleted file mode 100644 index d82fd1d..0000000 --- a/debian/patches/CVE-2022-23943-1.patch +++ /dev/null @@ -1,360 +0,0 @@ -From 943f57b336f264d77e5b780c82ab73daf3d14deb Mon Sep 17 00:00:00 2001 -From: Yann Ylavic <ylavic@apache.org> -Date: Mon, 7 Mar 2022 14:52:42 +0000 -Subject: [PATCH] mod_sed: use size_t to allow for larger buffer sizes and - unsigned arithmetics. - -Let's switch to apr_size_t buffers and get rid of the ints. - - -Merge r1898690 from trunk. -Submitted by: rpluem -Reviewed by: rpluem, covener, ylavic - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1898695 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/filters/libsed.h | 12 +++--- - modules/filters/mod_sed.c | 10 ++--- - modules/filters/sed1.c | 79 +++++++++++++++++++++++---------------- - 3 files changed, 58 insertions(+), 43 deletions(-) - -diff --git a/modules/filters/libsed.h b/modules/filters/libsed.h -index 76cbc0ce8a..0256b1ea83 100644 ---- a/modules/filters/libsed.h -+++ b/modules/filters/libsed.h -@@ -60,7 +60,7 @@ struct sed_label_s { - }; - - typedef apr_status_t (sed_err_fn_t)(void *data, const char *error); --typedef apr_status_t (sed_write_fn_t)(void *ctx, char *buf, int sz); -+typedef apr_status_t (sed_write_fn_t)(void *ctx, char *buf, apr_size_t sz); - - typedef struct sed_commands_s sed_commands_t; - #define NWFILES 11 /* 10 plus one for standard output */ -@@ -69,7 +69,7 @@ struct sed_commands_s { - sed_err_fn_t *errfn; - void *data; - -- unsigned lsize; -+ apr_size_t lsize; - char *linebuf; - char *lbend; - const char *saveq; -@@ -116,15 +116,15 @@ struct sed_eval_s { - apr_int64_t lnum; - void *fout; - -- unsigned lsize; -+ apr_size_t lsize; - char *linebuf; - char *lspend; - -- unsigned hsize; -+ apr_size_t hsize; - char *holdbuf; - char *hspend; - -- unsigned gsize; -+ apr_size_t gsize; - char *genbuf; - char *lcomend; - -@@ -160,7 +160,7 @@ apr_status_t sed_init_eval(sed_eval_t *eval, sed_commands_t *commands, - sed_err_fn_t *errfn, void *data, - sed_write_fn_t *writefn, apr_pool_t *p); - apr_status_t sed_reset_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data); --apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, int bufsz, void *fout); -+apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz, void *fout); - apr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout); - apr_status_t sed_finalize_eval(sed_eval_t *eval, void *f); - void sed_destroy_eval(sed_eval_t *eval); -diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c -index 9b408029a8..7092dd5e7f 100644 ---- a/modules/filters/mod_sed.c -+++ b/modules/filters/mod_sed.c -@@ -51,7 +51,7 @@ typedef struct sed_filter_ctxt - apr_bucket_brigade *bbinp; - char *outbuf; - char *curoutbuf; -- int bufsize; -+ apr_size_t bufsize; - apr_pool_t *tpool; - int numbuckets; - } sed_filter_ctxt; -@@ -100,7 +100,7 @@ static void alloc_outbuf(sed_filter_ctxt* ctx) - /* append_bucket - * Allocate a new bucket from buf and sz and append to ctx->bb - */ --static apr_status_t append_bucket(sed_filter_ctxt* ctx, char* buf, int sz) -+static apr_status_t append_bucket(sed_filter_ctxt* ctx, char* buf, apr_size_t sz) - { - apr_status_t status = APR_SUCCESS; - apr_bucket *b; -@@ -133,7 +133,7 @@ static apr_status_t append_bucket(sed_filter_ctxt* ctx, char* buf, int sz) - */ - static apr_status_t flush_output_buffer(sed_filter_ctxt *ctx) - { -- int size = ctx->curoutbuf - ctx->outbuf; -+ apr_size_t size = ctx->curoutbuf - ctx->outbuf; - char *out; - apr_status_t status = APR_SUCCESS; - if ((ctx->outbuf == NULL) || (size <=0)) -@@ -147,12 +147,12 @@ static apr_status_t flush_output_buffer(sed_filter_ctxt *ctx) - /* This is a call back function. When libsed wants to generate the output, - * this function will be invoked. - */ --static apr_status_t sed_write_output(void *dummy, char *buf, int sz) -+static apr_status_t sed_write_output(void *dummy, char *buf, apr_size_t sz) - { - /* dummy is basically filter context. Context is passed during invocation - * of sed_eval_buffer - */ -- int remainbytes = 0; -+ apr_size_t remainbytes = 0; - apr_status_t status = APR_SUCCESS; - sed_filter_ctxt *ctx = (sed_filter_ctxt *) dummy; - if (ctx->outbuf == NULL) { -diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c -index be03506788..67a8d06515 100644 ---- a/modules/filters/sed1.c -+++ b/modules/filters/sed1.c -@@ -71,7 +71,7 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, - static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2); - static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - step_vars_storage *step_vars); --static apr_status_t wline(sed_eval_t *eval, char *buf, int sz); -+static apr_status_t wline(sed_eval_t *eval, char *buf, apr_size_t sz); - static apr_status_t arout(sed_eval_t *eval); - - static void eval_errf(sed_eval_t *eval, const char *fmt, ...) -@@ -92,11 +92,11 @@ static void eval_errf(sed_eval_t *eval, const char *fmt, ...) - * grow_buffer - */ - static void grow_buffer(apr_pool_t *pool, char **buffer, -- char **spend, unsigned int *cursize, -- unsigned int newsize) -+ char **spend, apr_size_t *cursize, -+ apr_size_t newsize) - { - char* newbuffer = NULL; -- int spendsize = 0; -+ apr_size_t spendsize = 0; - if (*cursize >= newsize) - return; - /* Avoid number of times realloc is called. It could cause huge memory -@@ -124,7 +124,7 @@ static void grow_buffer(apr_pool_t *pool, char **buffer, - /* - * grow_line_buffer - */ --static void grow_line_buffer(sed_eval_t *eval, int newsize) -+static void grow_line_buffer(sed_eval_t *eval, apr_size_t newsize) - { - grow_buffer(eval->pool, &eval->linebuf, &eval->lspend, - &eval->lsize, newsize); -@@ -133,7 +133,7 @@ static void grow_line_buffer(sed_eval_t *eval, int newsize) - /* - * grow_hold_buffer - */ --static void grow_hold_buffer(sed_eval_t *eval, int newsize) -+static void grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize) - { - grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend, - &eval->hsize, newsize); -@@ -142,7 +142,7 @@ static void grow_hold_buffer(sed_eval_t *eval, int newsize) - /* - * grow_gen_buffer - */ --static void grow_gen_buffer(sed_eval_t *eval, int newsize, -+static void grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize, - char **gspend) - { - if (gspend == NULL) { -@@ -156,9 +156,9 @@ static void grow_gen_buffer(sed_eval_t *eval, int newsize, - /* - * appendmem_to_linebuf - */ --static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, int len) -+static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len) - { -- unsigned int reqsize = (eval->lspend - eval->linebuf) + len; -+ apr_size_t reqsize = (eval->lspend - eval->linebuf) + len; - if (eval->lsize < reqsize) { - grow_line_buffer(eval, reqsize); - } -@@ -169,21 +169,36 @@ static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, int len) - /* - * append_to_linebuf - */ --static void append_to_linebuf(sed_eval_t *eval, const char* sz) -+static void append_to_linebuf(sed_eval_t *eval, const char* sz, -+ step_vars_storage *step_vars) - { -- int len = strlen(sz); -+ apr_size_t len = strlen(sz); -+ char *old_linebuf = eval->linebuf; - /* Copy string including null character */ - appendmem_to_linebuf(eval, sz, len + 1); - --eval->lspend; /* lspend will now point to NULL character */ -+ /* Sync step_vars after a possible linebuf expansion */ -+ if (step_vars && old_linebuf != eval->linebuf) { -+ if (step_vars->loc1) { -+ step_vars->loc1 = step_vars->loc1 - old_linebuf + eval->linebuf; -+ } -+ if (step_vars->loc2) { -+ step_vars->loc2 = step_vars->loc2 - old_linebuf + eval->linebuf; -+ } -+ if (step_vars->locs) { -+ step_vars->locs = step_vars->locs - old_linebuf + eval->linebuf; -+ } -+ } - } - - /* - * copy_to_linebuf - */ --static void copy_to_linebuf(sed_eval_t *eval, const char* sz) -+static void copy_to_linebuf(sed_eval_t *eval, const char* sz, -+ step_vars_storage *step_vars) - { - eval->lspend = eval->linebuf; -- append_to_linebuf(eval, sz); -+ append_to_linebuf(eval, sz, step_vars); - } - - /* -@@ -191,8 +206,8 @@ static void copy_to_linebuf(sed_eval_t *eval, const char* sz) - */ - static void append_to_holdbuf(sed_eval_t *eval, const char* sz) - { -- int len = strlen(sz); -- unsigned int reqsize = (eval->hspend - eval->holdbuf) + len + 1; -+ apr_size_t len = strlen(sz); -+ apr_size_t reqsize = (eval->hspend - eval->holdbuf) + len + 1; - if (eval->hsize <= reqsize) { - grow_hold_buffer(eval, reqsize); - } -@@ -215,8 +230,8 @@ static void copy_to_holdbuf(sed_eval_t *eval, const char* sz) - */ - static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend) - { -- int len = strlen(sz); -- unsigned int reqsize = (*gspend - eval->genbuf) + len + 1; -+ apr_size_t len = strlen(sz); -+ apr_size_t reqsize = (*gspend - eval->genbuf) + len + 1; - if (eval->gsize < reqsize) { - grow_gen_buffer(eval, reqsize, gspend); - } -@@ -230,8 +245,8 @@ static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend) - */ - static void copy_to_genbuf(sed_eval_t *eval, const char* sz) - { -- int len = strlen(sz); -- unsigned int reqsize = len + 1; -+ apr_size_t len = strlen(sz); -+ apr_size_t reqsize = len + 1; - if (eval->gsize < reqsize) { - grow_gen_buffer(eval, reqsize, NULL); - } -@@ -353,7 +368,7 @@ apr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout) - /* - * sed_eval_buffer - */ --apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, int bufsz, void *fout) -+apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz, void *fout) - { - apr_status_t rv; - -@@ -383,7 +398,7 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, int bufsz, void - - while (bufsz) { - char *n; -- int llen; -+ apr_size_t llen; - - n = memchr(buf, '\n', bufsz); - if (n == NULL) -@@ -442,7 +457,7 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout) - * buffer is not a newline. - */ - /* Assure space for NULL */ -- append_to_linebuf(eval, ""); -+ append_to_linebuf(eval, "", NULL); - } - - *eval->lspend = '\0'; -@@ -666,7 +681,7 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, - lp = step_vars->loc2; - step_vars->loc2 = sp - eval->genbuf + eval->linebuf; - append_to_genbuf(eval, lp, &sp); -- copy_to_linebuf(eval, eval->genbuf); -+ copy_to_linebuf(eval, eval->genbuf, step_vars); - return rv; - } - -@@ -676,8 +691,8 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, - static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2) - { - char *sp = asp; -- int n = al2 - al1; -- unsigned int reqsize = (sp - eval->genbuf) + n + 1; -+ apr_size_t n = al2 - al1; -+ apr_size_t reqsize = (sp - eval->genbuf) + n + 1; - - if (eval->gsize < reqsize) { - grow_gen_buffer(eval, reqsize, &sp); -@@ -735,7 +750,7 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - } - - p1++; -- copy_to_linebuf(eval, p1); -+ copy_to_linebuf(eval, p1, step_vars); - eval->jflag++; - break; - -@@ -745,12 +760,12 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - break; - - case GCOM: -- copy_to_linebuf(eval, eval->holdbuf); -+ copy_to_linebuf(eval, eval->holdbuf, step_vars); - break; - - case CGCOM: -- append_to_linebuf(eval, "\n"); -- append_to_linebuf(eval, eval->holdbuf); -+ append_to_linebuf(eval, "\n", step_vars); -+ append_to_linebuf(eval, eval->holdbuf, step_vars); - break; - - case HCOM: -@@ -881,7 +896,7 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - if (rv != APR_SUCCESS) - return rv; - } -- append_to_linebuf(eval, "\n"); -+ append_to_linebuf(eval, "\n", step_vars); - eval->pending = ipc->next; - break; - -@@ -956,7 +971,7 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - - case XCOM: - copy_to_genbuf(eval, eval->linebuf); -- copy_to_linebuf(eval, eval->holdbuf); -+ copy_to_linebuf(eval, eval->holdbuf, step_vars); - copy_to_holdbuf(eval, eval->genbuf); - break; - -@@ -1013,7 +1028,7 @@ static apr_status_t arout(sed_eval_t *eval) - /* - * wline - */ --static apr_status_t wline(sed_eval_t *eval, char *buf, int sz) -+static apr_status_t wline(sed_eval_t *eval, char *buf, apr_size_t sz) - { - apr_status_t rv = APR_SUCCESS; - rv = eval->writefn(eval->fout, buf, sz); --- -2.30.2 - diff --git a/debian/patches/CVE-2022-23943-2.patch b/debian/patches/CVE-2022-23943-2.patch deleted file mode 100644 index bcf883c..0000000 --- a/debian/patches/CVE-2022-23943-2.patch +++ /dev/null @@ -1,63 +0,0 @@ -From e266bd09c313a668d7cca17a8b096d189148be49 Mon Sep 17 00:00:00 2001 -From: Ruediger Pluem <rpluem@apache.org> -Date: Wed, 9 Mar 2022 07:41:40 +0000 -Subject: [PATCH] Merge r1898735 from trunk: - -* Improve the logic flow - -Reviewed by: rpluem, covener, ylavic - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1898772 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/filters/mod_sed.c | 30 +++++++++++++++++++----------- - 1 file changed, 19 insertions(+), 11 deletions(-) - -diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c -index 7092dd5e7f..4bdb4ce33a 100644 ---- a/modules/filters/mod_sed.c -+++ b/modules/filters/mod_sed.c -@@ -168,21 +168,29 @@ static apr_status_t sed_write_output(void *dummy, char *buf, apr_size_t sz) - } - /* buffer is now full */ - status = append_bucket(ctx, ctx->outbuf, ctx->bufsize); -- /* old buffer is now used so allocate new buffer */ -- alloc_outbuf(ctx); -- /* if size is bigger than the allocated buffer directly add to output -- * brigade */ -- if ((status == APR_SUCCESS) && (sz >= ctx->bufsize)) { -- char* newbuf = apr_pmemdup(ctx->tpool, buf, sz); -- status = append_bucket(ctx, newbuf, sz); -- /* pool might get clear after append_bucket */ -- if (ctx->outbuf == NULL) { -+ if (status == APR_SUCCESS) { -+ /* if size is bigger than the allocated buffer directly add to output -+ * brigade */ -+ if (sz >= ctx->bufsize) { -+ char* newbuf = apr_pmemdup(ctx->tpool, buf, sz); -+ status = append_bucket(ctx, newbuf, sz); -+ if (status == APR_SUCCESS) { -+ /* old buffer is now used so allocate new buffer */ -+ alloc_outbuf(ctx); -+ } -+ else { -+ clear_ctxpool(ctx); -+ } -+ } -+ else { -+ /* old buffer is now used so allocate new buffer */ - alloc_outbuf(ctx); -+ memcpy(ctx->curoutbuf, buf, sz); -+ ctx->curoutbuf += sz; - } - } - else { -- memcpy(ctx->curoutbuf, buf, sz); -- ctx->curoutbuf += sz; -+ clear_ctxpool(ctx); - } - } - else { --- -2.30.2 - diff --git a/debian/patches/CVE-2022-26377.patch b/debian/patches/CVE-2022-26377.patch deleted file mode 100644 index af59776..0000000 --- a/debian/patches/CVE-2022-26377.patch +++ /dev/null @@ -1,39 +0,0 @@ -From f7f15f3d8bfe3032926c8c39eb8434529f680bd4 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic <ylavic@apache.org> -Date: Wed, 1 Jun 2022 13:48:21 +0000 -Subject: [PATCH] mod_proxy_ajp: T-E has precedence over C-L. - -Merge r1901521 from trunk. -Submitted by: rpluem - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901522 13f79535-47bb-0310-9956-ffa450edef68 -Origin: https://github.com/apache/httpd/commit/f7f15f3d8bfe3032926c8c39eb8434529f680bd4 ---- - modules/proxy/mod_proxy_ajp.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - ---- a/modules/proxy/mod_proxy_ajp.c -+++ b/modules/proxy/mod_proxy_ajp.c -@@ -245,9 +245,18 @@ - /* read the first bloc of data */ - input_brigade = apr_brigade_create(p, r->connection->bucket_alloc); - tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); -- if (tenc && (strcasecmp(tenc, "chunked") == 0)) { -- /* The AJP protocol does not want body data yet */ -- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870) "request is chunked"); -+ if (tenc) { -+ if (strcasecmp(tenc, "chunked") == 0) { -+ /* The AJP protocol does not want body data yet */ -+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870) -+ "request is chunked"); -+ } -+ else { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10396) -+ "%s Transfer-Encoding is not supported", -+ tenc); -+ return HTTP_INTERNAL_SERVER_ERROR; -+ } - } else { - /* Get client provided Content-Length header */ - content_length = get_content_length(r); diff --git a/debian/patches/CVE-2022-28614.patch b/debian/patches/CVE-2022-28614.patch deleted file mode 100644 index fdd8f6b..0000000 --- a/debian/patches/CVE-2022-28614.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 8c14927162cf3b4f810683e1c5505e9ef9e1f123 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Wed, 1 Jun 2022 12:34:16 +0000 -Subject: [PATCH] Merge r1901500 from trunk: - -handle large writes in ap_rputs - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901501 13f79535-47bb-0310-9956-ffa450edef68 -Origin: https://github.com/apache/httpd/commit/8c14927162cf3b4f810683e1c5505e9ef9e1f123 ---- - include/http_protocol.h | 22 +++++++++++++++++++++- - server/protocol.c | 3 +++ - 2 files changed, 24 insertions(+), 1 deletion(-) - -diff --git a/include/http_protocol.h b/include/http_protocol.h -index 20bd202226..94c481e5f4 100644 ---- a/include/http_protocol.h -+++ b/include/http_protocol.h -@@ -475,7 +475,27 @@ AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r); - */ - static APR_INLINE int ap_rputs(const char *str, request_rec *r) - { -- return ap_rwrite(str, (int)strlen(str), r); -+ apr_size_t len; -+ -+ len = strlen(str); -+ -+ for (;;) { -+ if (len <= INT_MAX) { -+ return ap_rwrite(str, (int)len, r); -+ } -+ else { -+ int rc; -+ -+ rc = ap_rwrite(str, INT_MAX, r); -+ if (rc < 0) { -+ return rc; -+ } -+ else { -+ str += INT_MAX; -+ len -= INT_MAX; -+ } -+ } -+ } - } - - /** -diff --git a/server/protocol.c b/server/protocol.c -index 298f61e1fb..7adc7f75c1 100644 ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -2128,6 +2128,9 @@ AP_DECLARE(int) ap_rputc(int c, request_rec *r) - - AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r) - { -+ if (nbyte < 0) -+ return -1; -+ - if (r->connection->aborted) - return -1; - --- -2.30.2 - diff --git a/debian/patches/CVE-2022-28615.patch b/debian/patches/CVE-2022-28615.patch deleted file mode 100644 index 2c15157..0000000 --- a/debian/patches/CVE-2022-28615.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6503d09ab51047554c384a6d03646ce1a8848120 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Wed, 1 Jun 2022 12:21:45 +0000 -Subject: [PATCH] Merge r1901494 from trunk: - -fix types - - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901495 13f79535-47bb-0310-9956-ffa450edef68 -Origin: https://github.com/apache/httpd/commit/6503d09ab51047554c384a6d03646ce1a8848120 ---- - server/util.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/server/util.c -+++ b/server/util.c -@@ -186,7 +186,7 @@ - */ - AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected) - { -- int x, y; -+ apr_size_t x, y; - - for (x = 0, y = 0; expected[y]; ++y, ++x) { - if ((!str[x]) && (expected[y] != '*')) -@@ -210,7 +210,7 @@ - - AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected) - { -- int x, y; -+ apr_size_t x, y; - - for (x = 0, y = 0; expected[y]; ++y, ++x) { - if (!str[x] && expected[y] != '*') diff --git a/debian/patches/CVE-2022-29404.patch b/debian/patches/CVE-2022-29404.patch deleted file mode 100644 index 259e920..0000000 --- a/debian/patches/CVE-2022-29404.patch +++ /dev/null @@ -1,82 +0,0 @@ -From ce259c4061905bf834f9af51c92456cfe8335ddc Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Wed, 1 Jun 2022 12:31:48 +0000 -Subject: [PATCH] Merge r1901497 from trunk: - -use a liberal default limit for LimitRequestBody of 1GB - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901499 13f79535-47bb-0310-9956-ffa450edef68 -Origin: https://github.com/apache/httpd/commit/ce259c4061905bf834f9af51c92456cfe8335ddc ---- - modules/http/http_filters.c | 6 ++++++ - modules/proxy/mod_proxy_http.c | 14 -------------- - server/core.c | 2 +- - 3 files changed, 7 insertions(+), 15 deletions(-) - ---- a/modules/http/http_filters.c -+++ b/modules/http/http_filters.c -@@ -1657,6 +1657,7 @@ - { - const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); - const char *lenp = apr_table_get(r->headers_in, "Content-Length"); -+ apr_off_t limit_req_body = ap_get_limit_req_body(r); - - r->read_body = read_policy; - r->read_chunked = 0; -@@ -1695,6 +1696,11 @@ - return HTTP_REQUEST_ENTITY_TOO_LARGE; - } - -+ if (limit_req_body > 0 && (r->remaining > limit_req_body)) { -+ /* will be logged when the body is discarded */ -+ return HTTP_REQUEST_ENTITY_TOO_LARGE; -+ } -+ - #ifdef AP_DEBUG - { - /* Make sure ap_getline() didn't leave any droppings. */ ---- a/server/core.c -+++ b/server/core.c -@@ -61,7 +61,7 @@ - - /* LimitRequestBody handling */ - #define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1) --#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0) -+#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */ - - /* LimitXMLRequestBody handling */ - #define AP_LIMIT_UNSET ((long) -1) ---- a/modules/proxy/mod_proxy_http.c -+++ b/modules/proxy/mod_proxy_http.c -@@ -512,12 +512,9 @@ - apr_bucket *e; - apr_off_t bytes, bytes_spooled = 0, fsize = 0; - apr_file_t *tmpfile = NULL; -- apr_off_t limit; - - body_brigade = apr_brigade_create(p, bucket_alloc); - -- limit = ap_get_limit_req_body(r); -- - while (!APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) - { - /* If this brigade contains EOS, either stop or remove it. */ -@@ -532,17 +529,6 @@ - apr_brigade_length(input_brigade, 1, &bytes); - - if (bytes_spooled + bytes > MAX_MEM_SPOOL) { -- /* -- * LimitRequestBody does not affect Proxy requests (Should it?). -- * Let it take effect if we decide to store the body in a -- * temporary file on disk. -- */ -- if (limit && (bytes_spooled + bytes > limit)) { -- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01088) -- "Request body is larger than the configured " -- "limit of %" APR_OFF_T_FMT, limit); -- return HTTP_REQUEST_ENTITY_TOO_LARGE; -- } - /* can't spool any more in memory; write latest brigade to disk */ - if (tmpfile == NULL) { - const char *temp_dir; diff --git a/debian/patches/CVE-2022-30522.patch b/debian/patches/CVE-2022-30522.patch deleted file mode 100644 index 5ad124e..0000000 --- a/debian/patches/CVE-2022-30522.patch +++ /dev/null @@ -1,561 +0,0 @@ -From db47781128e42bd49f55076665b3f6ca4e2bc5e2 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Wed, 1 Jun 2022 12:50:40 +0000 -Subject: [PATCH] Merge r1901506 from trunk: - -limit mod_sed memory use - -Resync mod_sed.c with trunk due to merge conflicts. - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901509 13f79535-47bb-0310-9956-ffa450edef68 -Origin: https://github.com/apache/httpd/commit/db47781128e42bd49f55076665b3f6ca4e2bc5e2 ---- - modules/filters/mod_sed.c | 75 ++++++++---------- - modules/filters/sed1.c | 158 +++++++++++++++++++++++++++----------- - 2 files changed, 147 insertions(+), 86 deletions(-) - -diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c -index 4bdb4ce33a..12cb04a20f 100644 ---- a/modules/filters/mod_sed.c -+++ b/modules/filters/mod_sed.c -@@ -59,7 +59,7 @@ typedef struct sed_filter_ctxt - module AP_MODULE_DECLARE_DATA sed_module; - - /* This function will be call back from libsed functions if there is any error -- * happend during execution of sed scripts -+ * happened during execution of sed scripts - */ - static apr_status_t log_sed_errf(void *data, const char *error) - { -@@ -277,7 +277,7 @@ static apr_status_t sed_response_filter(ap_filter_t *f, - apr_bucket_brigade *bb) - { - apr_bucket *b; -- apr_status_t status; -+ apr_status_t status = APR_SUCCESS; - sed_config *cfg = ap_get_module_config(f->r->per_dir_config, - &sed_module); - sed_filter_ctxt *ctx = f->ctx; -@@ -302,9 +302,9 @@ static apr_status_t sed_response_filter(ap_filter_t *f, - return status; - ctx = f->ctx; - apr_table_unset(f->r->headers_out, "Content-Length"); -- } - -- ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); -+ ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); -+ } - - /* Here is the main logic. Iterate through all the buckets, read the - * content of the bucket, call sed_eval_buffer on the data. -@@ -326,63 +326,52 @@ static apr_status_t sed_response_filter(ap_filter_t *f, - * in sed's internal buffer which can't be flushed until new line - * character is arrived. - */ -- for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb);) { -- const char *buf = NULL; -- apr_size_t bytes = 0; -+ while (!APR_BRIGADE_EMPTY(bb)) { -+ b = APR_BRIGADE_FIRST(bb); - if (APR_BUCKET_IS_EOS(b)) { -- apr_bucket *b1 = APR_BUCKET_NEXT(b); - /* Now clean up the internal sed buffer */ - sed_finalize_eval(&ctx->eval, ctx); - status = flush_output_buffer(ctx); - if (status != APR_SUCCESS) { -- clear_ctxpool(ctx); -- return status; -+ break; - } -+ /* Move the eos bucket to ctx->bb brigade */ - APR_BUCKET_REMOVE(b); -- /* Insert the eos bucket to ctx->bb brigade */ - APR_BRIGADE_INSERT_TAIL(ctx->bb, b); -- b = b1; - } - else if (APR_BUCKET_IS_FLUSH(b)) { -- apr_bucket *b1 = APR_BUCKET_NEXT(b); -- APR_BUCKET_REMOVE(b); - status = flush_output_buffer(ctx); - if (status != APR_SUCCESS) { -- clear_ctxpool(ctx); -- return status; -+ break; - } -+ /* Move the flush bucket to ctx->bb brigade */ -+ APR_BUCKET_REMOVE(b); - APR_BRIGADE_INSERT_TAIL(ctx->bb, b); -- b = b1; -- } -- else if (APR_BUCKET_IS_METADATA(b)) { -- b = APR_BUCKET_NEXT(b); - } -- else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) -- == APR_SUCCESS) { -- apr_bucket *b1 = APR_BUCKET_NEXT(b); -- status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx); -- if (status != APR_SUCCESS) { -- clear_ctxpool(ctx); -- return status; -+ else { -+ if (!APR_BUCKET_IS_METADATA(b)) { -+ const char *buf = NULL; -+ apr_size_t bytes = 0; -+ -+ status = apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ); -+ if (status == APR_SUCCESS) { -+ status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx); -+ } -+ if (status != APR_SUCCESS) { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10394) "error evaluating sed on output"); -+ break; -+ } - } -- APR_BUCKET_REMOVE(b); - apr_bucket_delete(b); -- b = b1; -- } -- else { -- apr_bucket *b1 = APR_BUCKET_NEXT(b); -- APR_BUCKET_REMOVE(b); -- b = b1; - } - } -- apr_brigade_cleanup(bb); -- status = flush_output_buffer(ctx); -- if (status != APR_SUCCESS) { -- clear_ctxpool(ctx); -- return status; -+ if (status == APR_SUCCESS) { -+ status = flush_output_buffer(ctx); - } - if (!APR_BRIGADE_EMPTY(ctx->bb)) { -- status = ap_pass_brigade(f->next, ctx->bb); -+ if (status == APR_SUCCESS) { -+ status = ap_pass_brigade(f->next, ctx->bb); -+ } - apr_brigade_cleanup(ctx->bb); - } - clear_ctxpool(ctx); -@@ -433,7 +422,7 @@ static apr_status_t sed_request_filter(ap_filter_t *f, - * the buckets in bbinp and read the data from buckets and invoke - * sed_eval_buffer on the data. libsed will generate its output using - * sed_write_output which will add data in ctx->bb. Do it until it have -- * atleast one bucket in ctx->bb. At the end of data eos bucket -+ * at least one bucket in ctx->bb. At the end of data eos bucket - * should be there. - * - * Once eos bucket is seen, then invoke sed_finalize_eval to clear the -@@ -475,8 +464,10 @@ static apr_status_t sed_request_filter(ap_filter_t *f, - if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) - == APR_SUCCESS) { - status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx); -- if (status != APR_SUCCESS) -+ if (status != APR_SUCCESS) { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10395) "error evaluating sed on input"); - return status; -+ } - flush_output_buffer(ctx); - } - } -diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c -index 67a8d06515..047f49ba13 100644 ---- a/modules/filters/sed1.c -+++ b/modules/filters/sed1.c -@@ -87,18 +87,20 @@ static void eval_errf(sed_eval_t *eval, const char *fmt, ...) - } - - #define INIT_BUF_SIZE 1024 -+#define MAX_BUF_SIZE 1024*8192 - - /* - * grow_buffer - */ --static void grow_buffer(apr_pool_t *pool, char **buffer, -+static apr_status_t grow_buffer(apr_pool_t *pool, char **buffer, - char **spend, apr_size_t *cursize, - apr_size_t newsize) - { - char* newbuffer = NULL; - apr_size_t spendsize = 0; -- if (*cursize >= newsize) -- return; -+ if (*cursize >= newsize) { -+ return APR_SUCCESS; -+ } - /* Avoid number of times realloc is called. It could cause huge memory - * requirement if line size is huge e.g 2 MB */ - if (newsize < *cursize * 2) { -@@ -107,6 +109,9 @@ static void grow_buffer(apr_pool_t *pool, char **buffer, - - /* Align it to 4 KB boundary */ - newsize = (newsize + ((1 << 12) - 1)) & ~((1 << 12) - 1); -+ if (newsize > MAX_BUF_SIZE) { -+ return APR_ENOMEM; -+ } - newbuffer = apr_pcalloc(pool, newsize); - if (*spend && *buffer && (*cursize > 0)) { - spendsize = *spend - *buffer; -@@ -119,63 +124,77 @@ static void grow_buffer(apr_pool_t *pool, char **buffer, - if (spend != buffer) { - *spend = *buffer + spendsize; - } -+ return APR_SUCCESS; - } - - /* - * grow_line_buffer - */ --static void grow_line_buffer(sed_eval_t *eval, apr_size_t newsize) -+static apr_status_t grow_line_buffer(sed_eval_t *eval, apr_size_t newsize) - { -- grow_buffer(eval->pool, &eval->linebuf, &eval->lspend, -+ return grow_buffer(eval->pool, &eval->linebuf, &eval->lspend, - &eval->lsize, newsize); - } - - /* - * grow_hold_buffer - */ --static void grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize) -+static apr_status_t grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize) - { -- grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend, -+ return grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend, - &eval->hsize, newsize); - } - - /* - * grow_gen_buffer - */ --static void grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize, -+static apr_status_t grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize, - char **gspend) - { -+ apr_status_t rc = 0; - if (gspend == NULL) { - gspend = &eval->genbuf; - } -- grow_buffer(eval->pool, &eval->genbuf, gspend, -- &eval->gsize, newsize); -- eval->lcomend = &eval->genbuf[71]; -+ rc = grow_buffer(eval->pool, &eval->genbuf, gspend, -+ &eval->gsize, newsize); -+ if (rc == APR_SUCCESS) { -+ eval->lcomend = &eval->genbuf[71]; -+ } -+ return rc; - } - - /* - * appendmem_to_linebuf - */ --static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len) -+static apr_status_t appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len) - { -+ apr_status_t rc = 0; - apr_size_t reqsize = (eval->lspend - eval->linebuf) + len; - if (eval->lsize < reqsize) { -- grow_line_buffer(eval, reqsize); -+ rc = grow_line_buffer(eval, reqsize); -+ if (rc != APR_SUCCESS) { -+ return rc; -+ } - } - memcpy(eval->lspend, sz, len); - eval->lspend += len; -+ return APR_SUCCESS; - } - - /* - * append_to_linebuf - */ --static void append_to_linebuf(sed_eval_t *eval, const char* sz, -+static apr_status_t append_to_linebuf(sed_eval_t *eval, const char* sz, - step_vars_storage *step_vars) - { - apr_size_t len = strlen(sz); - char *old_linebuf = eval->linebuf; -+ apr_status_t rc = 0; - /* Copy string including null character */ -- appendmem_to_linebuf(eval, sz, len + 1); -+ rc = appendmem_to_linebuf(eval, sz, len + 1); -+ if (rc != APR_SUCCESS) { -+ return rc; -+ } - --eval->lspend; /* lspend will now point to NULL character */ - /* Sync step_vars after a possible linebuf expansion */ - if (step_vars && old_linebuf != eval->linebuf) { -@@ -189,68 +208,84 @@ static void append_to_linebuf(sed_eval_t *eval, const char* sz, - step_vars->locs = step_vars->locs - old_linebuf + eval->linebuf; - } - } -+ return APR_SUCCESS; - } - - /* - * copy_to_linebuf - */ --static void copy_to_linebuf(sed_eval_t *eval, const char* sz, -+static apr_status_t copy_to_linebuf(sed_eval_t *eval, const char* sz, - step_vars_storage *step_vars) - { - eval->lspend = eval->linebuf; -- append_to_linebuf(eval, sz, step_vars); -+ return append_to_linebuf(eval, sz, step_vars); - } - - /* - * append_to_holdbuf - */ --static void append_to_holdbuf(sed_eval_t *eval, const char* sz) -+static apr_status_t append_to_holdbuf(sed_eval_t *eval, const char* sz) - { - apr_size_t len = strlen(sz); - apr_size_t reqsize = (eval->hspend - eval->holdbuf) + len + 1; -+ apr_status_t rc = 0; - if (eval->hsize <= reqsize) { -- grow_hold_buffer(eval, reqsize); -+ rc = grow_hold_buffer(eval, reqsize); -+ if (rc != APR_SUCCESS) { -+ return rc; -+ } - } - memcpy(eval->hspend, sz, len + 1); - /* hspend will now point to NULL character */ - eval->hspend += len; -+ return APR_SUCCESS; - } - - /* - * copy_to_holdbuf - */ --static void copy_to_holdbuf(sed_eval_t *eval, const char* sz) -+static apr_status_t copy_to_holdbuf(sed_eval_t *eval, const char* sz) - { - eval->hspend = eval->holdbuf; -- append_to_holdbuf(eval, sz); -+ return append_to_holdbuf(eval, sz); - } - - /* - * append_to_genbuf - */ --static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend) -+static apr_status_t append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend) - { - apr_size_t len = strlen(sz); - apr_size_t reqsize = (*gspend - eval->genbuf) + len + 1; -+ apr_status_t rc = 0; - if (eval->gsize < reqsize) { -- grow_gen_buffer(eval, reqsize, gspend); -+ rc = grow_gen_buffer(eval, reqsize, gspend); -+ if (rc != APR_SUCCESS) { -+ return rc; -+ } - } - memcpy(*gspend, sz, len + 1); - /* *gspend will now point to NULL character */ - *gspend += len; -+ return APR_SUCCESS; - } - - /* - * copy_to_genbuf - */ --static void copy_to_genbuf(sed_eval_t *eval, const char* sz) -+static apr_status_t copy_to_genbuf(sed_eval_t *eval, const char* sz) - { - apr_size_t len = strlen(sz); - apr_size_t reqsize = len + 1; -+ apr_status_t rc = APR_SUCCESS;; - if (eval->gsize < reqsize) { -- grow_gen_buffer(eval, reqsize, NULL); -+ rc = grow_gen_buffer(eval, reqsize, NULL); -+ if (rc != APR_SUCCESS) { -+ return rc; -+ } - } - memcpy(eval->genbuf, sz, len + 1); -+ return rc; - } - - /* -@@ -397,6 +432,7 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz - } - - while (bufsz) { -+ apr_status_t rc = 0; - char *n; - apr_size_t llen; - -@@ -411,7 +447,10 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz - break; - } - -- appendmem_to_linebuf(eval, buf, llen + 1); -+ rc = appendmem_to_linebuf(eval, buf, llen + 1); -+ if (rc != APR_SUCCESS) { -+ return rc; -+ } - --eval->lspend; - /* replace new line character with NULL */ - *eval->lspend = '\0'; -@@ -426,7 +465,10 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz - - /* Save the leftovers for later */ - if (bufsz) { -- appendmem_to_linebuf(eval, buf, bufsz); -+ apr_status_t rc = appendmem_to_linebuf(eval, buf, bufsz); -+ if (rc != APR_SUCCESS) { -+ return rc; -+ } - } - - return APR_SUCCESS; -@@ -448,6 +490,7 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout) - /* Process leftovers */ - if (eval->lspend > eval->linebuf) { - apr_status_t rv; -+ apr_status_t rc = 0; - - if (eval->lreadyflag) { - eval->lreadyflag = 0; -@@ -457,7 +500,10 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout) - * buffer is not a newline. - */ - /* Assure space for NULL */ -- append_to_linebuf(eval, "", NULL); -+ rc = append_to_linebuf(eval, "", NULL); -+ if (rc != APR_SUCCESS) { -+ return rc; -+ } - } - - *eval->lspend = '\0'; -@@ -655,11 +701,15 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, - sp = eval->genbuf; - rp = rhsbuf; - sp = place(eval, sp, lp, step_vars->loc1); -+ if (sp == NULL) { -+ return APR_EGENERAL; -+ } - while ((c = *rp++) != 0) { - if (c == '&') { - sp = place(eval, sp, step_vars->loc1, step_vars->loc2); -- if (sp == NULL) -+ if (sp == NULL) { - return APR_EGENERAL; -+ } - } - else if (c == '\\') { - c = *rp++; -@@ -675,13 +725,19 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, - *sp++ = c; - if (sp >= eval->genbuf + eval->gsize) { - /* expand genbuf and set the sp appropriately */ -- grow_gen_buffer(eval, eval->gsize + 1024, &sp); -+ rv = grow_gen_buffer(eval, eval->gsize + 1024, &sp); -+ if (rv != APR_SUCCESS) { -+ return rv; -+ } - } - } - lp = step_vars->loc2; - step_vars->loc2 = sp - eval->genbuf + eval->linebuf; -- append_to_genbuf(eval, lp, &sp); -- copy_to_linebuf(eval, eval->genbuf, step_vars); -+ rv = append_to_genbuf(eval, lp, &sp); -+ if (rv != APR_SUCCESS) { -+ return rv; -+ } -+ rv = copy_to_linebuf(eval, eval->genbuf, step_vars); - return rv; - } - -@@ -695,7 +751,10 @@ static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2) - apr_size_t reqsize = (sp - eval->genbuf) + n + 1; - - if (eval->gsize < reqsize) { -- grow_gen_buffer(eval, reqsize, &sp); -+ apr_status_t rc = grow_gen_buffer(eval, reqsize, &sp); -+ if (rc != APR_SUCCESS) { -+ return NULL; -+ } - } - memcpy(sp, al1, n); - return sp + n; -@@ -750,7 +809,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - } - - p1++; -- copy_to_linebuf(eval, p1, step_vars); -+ rv = copy_to_linebuf(eval, p1, step_vars); -+ if (rv != APR_SUCCESS) return rv; - eval->jflag++; - break; - -@@ -760,21 +820,27 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - break; - - case GCOM: -- copy_to_linebuf(eval, eval->holdbuf, step_vars); -+ rv = copy_to_linebuf(eval, eval->holdbuf, step_vars); -+ if (rv != APR_SUCCESS) return rv; - break; - - case CGCOM: -- append_to_linebuf(eval, "\n", step_vars); -- append_to_linebuf(eval, eval->holdbuf, step_vars); -+ rv = append_to_linebuf(eval, "\n", step_vars); -+ if (rv != APR_SUCCESS) return rv; -+ rv = append_to_linebuf(eval, eval->holdbuf, step_vars); -+ if (rv != APR_SUCCESS) return rv; - break; - - case HCOM: -- copy_to_holdbuf(eval, eval->linebuf); -+ rv = copy_to_holdbuf(eval, eval->linebuf); -+ if (rv != APR_SUCCESS) return rv; - break; - - case CHCOM: -- append_to_holdbuf(eval, "\n"); -- append_to_holdbuf(eval, eval->linebuf); -+ rv = append_to_holdbuf(eval, "\n"); -+ if (rv != APR_SUCCESS) return rv; -+ rv = append_to_holdbuf(eval, eval->linebuf); -+ if (rv != APR_SUCCESS) return rv; - break; - - case ICOM: -@@ -896,7 +962,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - if (rv != APR_SUCCESS) - return rv; - } -- append_to_linebuf(eval, "\n", step_vars); -+ rv = append_to_linebuf(eval, "\n", step_vars); -+ if (rv != APR_SUCCESS) return rv; - eval->pending = ipc->next; - break; - -@@ -970,9 +1037,12 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, - break; - - case XCOM: -- copy_to_genbuf(eval, eval->linebuf); -- copy_to_linebuf(eval, eval->holdbuf, step_vars); -- copy_to_holdbuf(eval, eval->genbuf); -+ rv = copy_to_genbuf(eval, eval->linebuf); -+ if (rv != APR_SUCCESS) return rv; -+ rv = copy_to_linebuf(eval, eval->holdbuf, step_vars); -+ if (rv != APR_SUCCESS) return rv; -+ rv = copy_to_holdbuf(eval, eval->genbuf); -+ if (rv != APR_SUCCESS) return rv; - break; - - case YCOM: --- -2.30.2 - diff --git a/debian/patches/CVE-2022-30556.patch b/debian/patches/CVE-2022-30556.patch deleted file mode 100644 index f9b541d..0000000 --- a/debian/patches/CVE-2022-30556.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 3a561759fcb37af179585adb8478922dc9bc6a85 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Wed, 1 Jun 2022 12:36:39 +0000 -Subject: [PATCH] Merge r1901502 from trunk: - -use filters consistently - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901503 13f79535-47bb-0310-9956-ffa450edef68 -Origin: https://github.com/apache/httpd/commit/3a561759fcb37af179585adb8478922dc9bc6a85 ---- - modules/lua/lua_request.c | 144 ++++++++++++++------------------------ - 1 file changed, 53 insertions(+), 91 deletions(-) - -diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c -index a3e3b613bc..2ec453e86b 100644 ---- a/modules/lua/lua_request.c -+++ b/modules/lua/lua_request.c -@@ -2227,23 +2227,20 @@ static int lua_websocket_greet(lua_State *L) - return 0; - } - --static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer, -- apr_off_t len) -+static apr_status_t lua_websocket_readbytes(conn_rec* c, -+ apr_bucket_brigade *brigade, -+ char* buffer, apr_off_t len) - { -- apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc); -+ apr_size_t delivered; - apr_status_t rv; -+ - rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES, - APR_BLOCK_READ, len); - if (rv == APR_SUCCESS) { -- if (!APR_BRIGADE_EMPTY(brigade)) { -- apr_bucket* bucket = APR_BRIGADE_FIRST(brigade); -- const char* data = NULL; -- apr_size_t data_length = 0; -- rv = apr_bucket_read(bucket, &data, &data_length, APR_BLOCK_READ); -- if (rv == APR_SUCCESS) { -- memcpy(buffer, data, len); -- } -- apr_bucket_delete(bucket); -+ delivered = len; -+ rv = apr_brigade_flatten(brigade, buffer, &delivered); -+ if ((rv == APR_SUCCESS) && (delivered < len)) { -+ rv = APR_INCOMPLETE; - } - } - apr_brigade_cleanup(brigade); -@@ -2273,35 +2270,28 @@ static int lua_websocket_peek(lua_State *L) - - static int lua_websocket_read(lua_State *L) - { -- apr_socket_t *sock; - apr_status_t rv; - int do_read = 1; - int n = 0; -- apr_size_t len = 1; - apr_size_t plen = 0; - unsigned short payload_short = 0; - apr_uint64_t payload_long = 0; - unsigned char *mask_bytes; - char byte; -- int plaintext; -- -- -+ apr_bucket_brigade *brigade; -+ conn_rec* c; -+ - request_rec *r = ap_lua_check_request_rec(L, 1); -- plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1; -+ c = r->connection; - -- - mask_bytes = apr_pcalloc(r->pool, 4); -- sock = ap_get_conn_socket(r->connection); -+ -+ brigade = apr_brigade_create(r->pool, c->bucket_alloc); - - while (do_read) { - do_read = 0; - /* Get opcode and FIN bit */ -- if (plaintext) { -- rv = apr_socket_recv(sock, &byte, &len); -- } -- else { -- rv = lua_websocket_readbytes(r->connection, &byte, 1); -- } -+ rv = lua_websocket_readbytes(c, brigade, &byte, 1); - if (rv == APR_SUCCESS) { - unsigned char ubyte, fin, opcode, mask, payload; - ubyte = (unsigned char)byte; -@@ -2311,12 +2301,7 @@ static int lua_websocket_read(lua_State *L) - opcode = ubyte & 0xf; - - /* Get the payload length and mask bit */ -- if (plaintext) { -- rv = apr_socket_recv(sock, &byte, &len); -- } -- else { -- rv = lua_websocket_readbytes(r->connection, &byte, 1); -- } -+ rv = lua_websocket_readbytes(c, brigade, &byte, 1); - if (rv == APR_SUCCESS) { - ubyte = (unsigned char)byte; - /* Mask is the first bit */ -@@ -2327,40 +2312,25 @@ static int lua_websocket_read(lua_State *L) - - /* Extended payload? */ - if (payload == 126) { -- len = 2; -- if (plaintext) { -- /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */ -- rv = apr_socket_recv(sock, (char*) &payload_short, &len); -- } -- else { -- rv = lua_websocket_readbytes(r->connection, -- (char*) &payload_short, 2); -- } -- payload_short = ntohs(payload_short); -+ rv = lua_websocket_readbytes(c, brigade, -+ (char*) &payload_short, 2); - -- if (rv == APR_SUCCESS) { -- plen = payload_short; -- } -- else { -+ if (rv != APR_SUCCESS) { - return 0; - } -+ -+ plen = ntohs(payload_short); - } - /* Super duper extended payload? */ - if (payload == 127) { -- len = 8; -- if (plaintext) { -- rv = apr_socket_recv(sock, (char*) &payload_long, &len); -- } -- else { -- rv = lua_websocket_readbytes(r->connection, -- (char*) &payload_long, 8); -- } -- if (rv == APR_SUCCESS) { -- plen = ap_ntoh64(&payload_long); -- } -- else { -+ rv = lua_websocket_readbytes(c, brigade, -+ (char*) &payload_long, 8); -+ -+ if (rv != APR_SUCCESS) { - return 0; - } -+ -+ plen = ap_ntoh64(&payload_long); - } - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210) - "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s", -@@ -2369,46 +2339,27 @@ static int lua_websocket_read(lua_State *L) - mask ? "on" : "off", - fin ? "This is a final frame" : "more to follow"); - if (mask) { -- len = 4; -- if (plaintext) { -- rv = apr_socket_recv(sock, (char*) mask_bytes, &len); -- } -- else { -- rv = lua_websocket_readbytes(r->connection, -- (char*) mask_bytes, 4); -- } -+ rv = lua_websocket_readbytes(c, brigade, -+ (char*) mask_bytes, 4); -+ - if (rv != APR_SUCCESS) { - return 0; - } - } - if (plen < (HUGE_STRING_LEN*1024) && plen > 0) { - apr_size_t remaining = plen; -- apr_size_t received; -- apr_off_t at = 0; - char *buffer = apr_palloc(r->pool, plen+1); - buffer[plen] = 0; - -- if (plaintext) { -- while (remaining > 0) { -- received = remaining; -- rv = apr_socket_recv(sock, buffer+at, &received); -- if (received > 0 ) { -- remaining -= received; -- at += received; -- } -- } -- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, -- "Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack", -- at); -- } -- else { -- rv = lua_websocket_readbytes(r->connection, buffer, -- remaining); -- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, -- "Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\ -- "pushed to Lua stack", -- remaining); -+ rv = lua_websocket_readbytes(c, brigade, buffer, remaining); -+ -+ if (rv != APR_SUCCESS) { -+ return 0; - } -+ -+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, -+ "Websocket: Frame contained %" APR_SIZE_T_FMT \ -+ " bytes, pushed to Lua stack", remaining); - if (mask) { - for (n = 0; n < plen; n++) { - buffer[n] ^= mask_bytes[n%4]; -@@ -2420,14 +2371,25 @@ static int lua_websocket_read(lua_State *L) - return 2; - } - -- - /* Decide if we need to react to the opcode or not */ - if (opcode == 0x09) { /* ping */ - char frame[2]; -- plen = 2; -+ apr_bucket *b; -+ - frame[0] = 0x8A; - frame[1] = 0; -- apr_socket_send(sock, frame, &plen); /* Pong! */ -+ -+ /* Pong! */ -+ b = apr_bucket_transient_create(frame, 2, c->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(brigade, b); -+ -+ rv = ap_pass_brigade(c->output_filters, brigade); -+ apr_brigade_cleanup(brigade); -+ -+ if (rv != APR_SUCCESS) { -+ return 0; -+ } -+ - do_read = 1; - } - } --- -2.30.2 - diff --git a/debian/patches/CVE-2022-31813.patch b/debian/patches/CVE-2022-31813.patch deleted file mode 100644 index d2bd341..0000000 --- a/debian/patches/CVE-2022-31813.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 956f708b094698ac9ad570d640d4f30eb0df7305 Mon Sep 17 00:00:00 2001 -From: Stefan Eissing <icing@apache.org> -Date: Wed, 1 Jun 2022 07:51:04 +0000 -Subject: [PATCH] Merge r1901461 from trunk via #320: - - *) mod_proxy: ap_proxy_create_hdrbrgd() to clear hop-by-hop first and fixup last. - - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901480 13f79535-47bb-0310-9956-ffa450edef68 -Origin: https://github.com/apache/httpd/commit/956f708b094698ac9ad570d640d4f30eb0df7305 ---- - modules/proxy/proxy_util.c | 153 ++++++++++++++++++++++----------------------- - 1 file changed, 77 insertions(+), 76 deletions(-) - ---- a/modules/proxy/proxy_util.c -+++ b/modules/proxy/proxy_util.c -@@ -3396,12 +3396,14 @@ - char **old_cl_val, - char **old_te_val) - { -+ int rc = OK; - conn_rec *c = r->connection; - int counter; - char *buf; -+ apr_table_t *saved_headers_in = r->headers_in; -+ const char *saved_host = apr_table_get(saved_headers_in, "Host"); - const apr_array_header_t *headers_in_array; - const apr_table_entry_t *headers_in; -- apr_table_t *saved_headers_in; - apr_bucket *e; - int do_100_continue; - conn_rec *origin = p_conn->connection; -@@ -3437,6 +3439,52 @@ - ap_xlate_proto_to_ascii(buf, strlen(buf)); - e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); -+ -+ /* -+ * Make a copy on r->headers_in for the request we make to the backend, -+ * modify the copy in place according to our configuration and connection -+ * handling, use it to fill in the forwarded headers' brigade, and finally -+ * restore the saved/original ones in r->headers_in. -+ * -+ * Note: We need to take r->pool for apr_table_copy as the key / value -+ * pairs in r->headers_in have been created out of r->pool and -+ * p might be (and actually is) a longer living pool. -+ * This would trigger the bad pool ancestry abort in apr_table_copy if -+ * apr is compiled with APR_POOL_DEBUG. -+ * -+ * icing: if p indeed lives longer than r->pool, we should allocate -+ * all new header values from r->pool as well and avoid leakage. -+ */ -+ r->headers_in = apr_table_copy(r->pool, saved_headers_in); -+ -+ /* Return the original Transfer-Encoding and/or Content-Length values -+ * then drop the headers, they must be set by the proxy handler based -+ * on the actual body being forwarded. -+ */ -+ if ((*old_te_val = (char *)apr_table_get(r->headers_in, -+ "Transfer-Encoding"))) { -+ apr_table_unset(r->headers_in, "Transfer-Encoding"); -+ } -+ if ((*old_cl_val = (char *)apr_table_get(r->headers_in, -+ "Content-Length"))) { -+ apr_table_unset(r->headers_in, "Content-Length"); -+ } -+ -+ /* Clear out hop-by-hop request headers not to forward */ -+ if (ap_proxy_clear_connection(r, r->headers_in) < 0) { -+ rc = HTTP_BAD_REQUEST; -+ goto cleanup; -+ } -+ -+ /* RFC2616 13.5.1 says we should strip these */ -+ apr_table_unset(r->headers_in, "Keep-Alive"); -+ apr_table_unset(r->headers_in, "Upgrade"); -+ apr_table_unset(r->headers_in, "Trailer"); -+ apr_table_unset(r->headers_in, "TE"); -+ -+ /* We used to send `Host: ` always first, so let's keep it that -+ * way. No telling which legacy backend is relying no this. -+ */ - if (dconf->preserve_host == 0) { - if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */ - if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) { -@@ -3458,7 +3506,7 @@ - /* don't want to use r->hostname, as the incoming header might have a - * port attached - */ -- const char* hostname = apr_table_get(r->headers_in,"Host"); -+ const char* hostname = saved_host; - if (!hostname) { - hostname = r->server->server_hostname; - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01092) -@@ -3472,21 +3520,7 @@ - ap_xlate_proto_to_ascii(buf, strlen(buf)); - e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); -- -- /* -- * Save the original headers in here and restore them when leaving, since -- * we will apply proxy purpose only modifications (eg. clearing hop-by-hop -- * headers, add Via or X-Forwarded-* or Expect...), whereas the originals -- * will be needed later to prepare the correct response and logging. -- * -- * Note: We need to take r->pool for apr_table_copy as the key / value -- * pairs in r->headers_in have been created out of r->pool and -- * p might be (and actually is) a longer living pool. -- * This would trigger the bad pool ancestry abort in apr_table_copy if -- * apr is compiled with APR_POOL_DEBUG. -- */ -- saved_headers_in = r->headers_in; -- r->headers_in = apr_table_copy(r->pool, saved_headers_in); -+ apr_table_unset(r->headers_in, "Host"); - - /* handle Via */ - if (conf->viaopt == via_block) { -@@ -3561,8 +3595,6 @@ - */ - if (dconf->add_forwarded_headers) { - if (PROXYREQ_REVERSE == r->proxyreq) { -- const char *buf; -- - /* Add X-Forwarded-For: so that the upstream has a chance to - * determine, where the original request came from. - */ -@@ -3572,8 +3604,9 @@ - /* Add X-Forwarded-Host: so that upstream knows what the - * original request hostname was. - */ -- if ((buf = apr_table_get(r->headers_in, "Host"))) { -- apr_table_mergen(r->headers_in, "X-Forwarded-Host", buf); -+ if (saved_host) { -+ apr_table_mergen(r->headers_in, "X-Forwarded-Host", -+ saved_host); - } - - /* Add X-Forwarded-Server: so that upstream knows what the -@@ -3585,67 +3618,37 @@ - } - } - -- proxy_run_fixups(r); -- if (ap_proxy_clear_connection(r, r->headers_in) < 0) { -- return HTTP_BAD_REQUEST; -+ /* Do we want to strip Proxy-Authorization ? -+ * If we haven't used it, then NO -+ * If we have used it then MAYBE: RFC2616 says we MAY propagate it. -+ * So let's make it configurable by env. -+ */ -+ if (r->user != NULL /* we've authenticated */ -+ && !apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) { -+ apr_table_unset(r->headers_in, "Proxy-Authorization"); - } - -+ /* for sub-requests, ignore freshness/expiry headers */ -+ if (r->main) { -+ apr_table_unset(r->headers_in, "If-Match"); -+ apr_table_unset(r->headers_in, "If-Modified-Since"); -+ apr_table_unset(r->headers_in, "If-Range"); -+ apr_table_unset(r->headers_in, "If-Unmodified-Since"); -+ apr_table_unset(r->headers_in, "If-None-Match"); -+ } -+ -+ /* run hook to fixup the request we are about to send */ -+ proxy_run_fixups(r); -+ - /* send request headers */ - headers_in_array = apr_table_elts(r->headers_in); - headers_in = (const apr_table_entry_t *) headers_in_array->elts; - for (counter = 0; counter < headers_in_array->nelts; counter++) { - if (headers_in[counter].key == NULL -- || headers_in[counter].val == NULL -- -- /* Already sent */ -- || !strcasecmp(headers_in[counter].key, "Host") -- -- /* Clear out hop-by-hop request headers not to send -- * RFC2616 13.5.1 says we should strip these headers -- */ -- || !strcasecmp(headers_in[counter].key, "Keep-Alive") -- || !strcasecmp(headers_in[counter].key, "TE") -- || !strcasecmp(headers_in[counter].key, "Trailer") -- || !strcasecmp(headers_in[counter].key, "Upgrade") -- -- ) { -- continue; -- } -- /* Do we want to strip Proxy-Authorization ? -- * If we haven't used it, then NO -- * If we have used it then MAYBE: RFC2616 says we MAY propagate it. -- * So let's make it configurable by env. -- */ -- if (!strcasecmp(headers_in[counter].key,"Proxy-Authorization")) { -- if (r->user != NULL) { /* we've authenticated */ -- if (!apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) { -- continue; -- } -- } -- } -- -- /* Skip Transfer-Encoding and Content-Length for now. -- */ -- if (!strcasecmp(headers_in[counter].key, "Transfer-Encoding")) { -- *old_te_val = headers_in[counter].val; -- continue; -- } -- if (!strcasecmp(headers_in[counter].key, "Content-Length")) { -- *old_cl_val = headers_in[counter].val; -+ || headers_in[counter].val == NULL) { - continue; - } - -- /* for sub-requests, ignore freshness/expiry headers */ -- if (r->main) { -- if ( !strcasecmp(headers_in[counter].key, "If-Match") -- || !strcasecmp(headers_in[counter].key, "If-Modified-Since") -- || !strcasecmp(headers_in[counter].key, "If-Range") -- || !strcasecmp(headers_in[counter].key, "If-Unmodified-Since") -- || !strcasecmp(headers_in[counter].key, "If-None-Match")) { -- continue; -- } -- } -- - buf = apr_pstrcat(p, headers_in[counter].key, ": ", - headers_in[counter].val, CRLF, - NULL); -@@ -3654,11 +3657,9 @@ - APR_BRIGADE_INSERT_TAIL(header_brigade, e); - } - -- /* Restore the original headers in (see comment above), -- * we won't modify them anymore. -- */ -+cleanup: - r->headers_in = saved_headers_in; -- return OK; -+ return rc; - } - - PROXY_DECLARE(int) ap_proxy_pass_brigade(apr_bucket_alloc_t *bucket_alloc, diff --git a/debian/patches/CVE-2022-36760.patch b/debian/patches/CVE-2022-36760.patch deleted file mode 100644 index ebeefa3..0000000 --- a/debian/patches/CVE-2022-36760.patch +++ /dev/null @@ -1,27 +0,0 @@ -From d93e61e3e9622bacff746772cb9c97fdcaed8baf Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Tue, 10 Jan 2023 13:20:55 +0000 -Subject: [PATCH] Merge r1906540 from trunk: - -cleanup on error - - -Reviewed By: rpluem, gbechis, covener - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1906542 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/proxy/mod_proxy_ajp.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/modules/proxy/mod_proxy_ajp.c -+++ b/modules/proxy/mod_proxy_ajp.c -@@ -255,6 +255,8 @@ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10396) - "%s Transfer-Encoding is not supported", - tenc); -+ /* We had a failure: Close connection to backend */ -+ conn->close = 1; - return HTTP_INTERNAL_SERVER_ERROR; - } - } else { diff --git a/debian/patches/CVE-2022-37436.patch b/debian/patches/CVE-2022-37436.patch deleted file mode 100644 index a123959..0000000 --- a/debian/patches/CVE-2022-37436.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 8b6d55f6a047acf62675e32606b037f5eea8ccc7 Mon Sep 17 00:00:00 2001 -From: Eric Covener <covener@apache.org> -Date: Tue, 10 Jan 2023 13:20:09 +0000 -Subject: [PATCH] Merge r1906539 from trunk: - -fail on bad header - -Submitted By: covener -Reviewed By: covener, rpluem, gbechis - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1906541 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/proxy/mod_proxy_http.c | 46 ++++++++++++++++++++-------------- - server/protocol.c | 2 ++ - 2 files changed, 29 insertions(+), 19 deletions(-) - ---- a/modules/proxy/mod_proxy_http.c -+++ b/modules/proxy/mod_proxy_http.c -@@ -1011,7 +1011,7 @@ - * any sense at all, since we depend on buffer still containing - * what was read by ap_getline() upon return. - */ --static void ap_proxy_read_headers(request_rec *r, request_rec *rr, -+static apr_status_t ap_proxy_read_headers(request_rec *r, request_rec *rr, - char *buffer, int size, - conn_rec *c, int *pread_len) - { -@@ -1043,19 +1043,26 @@ - rc = ap_proxygetline(tmp_bb, buffer, size, rr, - AP_GETLINE_FOLD | AP_GETLINE_NOSPC_EOL, &len); - -- if (len <= 0) -- break; - -- if (APR_STATUS_IS_ENOSPC(rc)) { -- /* The header could not fit in the provided buffer, warn. -- * XXX: falls through with the truncated header, 5xx instead? -- */ -- int trunc = (len > 128 ? 128 : len) / 2; -- ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10124) -- "header size is over the limit allowed by " -- "ResponseFieldSize (%d bytes). " -- "Bad response header: '%.*s[...]%s'", -- size, trunc, buffer, buffer + len - trunc); -+ if (rc != APR_SUCCESS) { -+ if (APR_STATUS_IS_ENOSPC(rc)) { -+ int trunc = (len > 128 ? 128 : len) / 2; -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10124) -+ "header size is over the limit allowed by " -+ "ResponseFieldSize (%d bytes). " -+ "Bad response header: '%.*s[...]%s'", -+ size, trunc, buffer, buffer + len - trunc); -+ } -+ else { -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10404) -+ "Error reading headers from backend"); -+ } -+ r->headers_out = NULL; -+ return rc; -+ } -+ -+ if (len <= 0) { -+ break; - } - else { - ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "%s", buffer); -@@ -1078,7 +1085,7 @@ - if (psc->badopt == bad_error) { - /* Nope, it wasn't even an extra HTTP header. Give up. */ - r->headers_out = NULL; -- return; -+ return APR_EINVAL; - } - else if (psc->badopt == bad_body) { - /* if we've already started loading headers_out, then -@@ -1092,13 +1099,13 @@ - "in headers returned by %s (%s)", - r->uri, r->method); - *pread_len = len; -- return; -+ return APR_SUCCESS; - } - else { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01099) - "No HTTP headers returned by %s (%s)", - r->uri, r->method); -- return; -+ return APR_SUCCESS; - } - } - } -@@ -1128,6 +1135,7 @@ - process_proxy_header(r, dconf, buffer, value); - saw_headers = 1; - } -+ return APR_SUCCESS; - } - - -@@ -1398,10 +1406,10 @@ - "Set-Cookie", NULL); - - /* shove the headers direct into r->headers_out */ -- ap_proxy_read_headers(r, backend->r, buffer, response_field_size, origin, -- &pread_len); -+ rc = ap_proxy_read_headers(r, backend->r, buffer, response_field_size, -+ origin, &pread_len); - -- if (r->headers_out == NULL) { -+ if (rc != APR_SUCCESS || r->headers_out == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01106) - "bad HTTP/%d.%d header returned by %s (%s)", - major, minor, r->uri, r->method); ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -508,6 +508,8 @@ - /* PR#43039: We shouldn't accept NULL bytes within the line */ - bytes_handled = strlen(*s); - if (bytes_handled < *read) { -+ ap_log_data(APLOG_MARK, APLOG_DEBUG, ap_server_conf, -+ "NULL bytes in header", *s, *read, 0); - *read = bytes_handled; - if (rv == APR_SUCCESS) { - rv = APR_EINVAL; diff --git a/debian/patches/build_suexec-custom.patch b/debian/patches/build_suexec-custom.patch index e03d54b..a509cd5 100644 --- a/debian/patches/build_suexec-custom.patch +++ b/debian/patches/build_suexec-custom.patch @@ -4,7 +4,7 @@ Author: Stefan Fritsch <sf@debian.org> Last-Update: 2012-02-25 --- a/Makefile.in +++ b/Makefile.in -@@ -272,23 +272,26 @@ +@@ -293,23 +293,26 @@ install-suexec: install-suexec-$(INSTALL_SUEXEC) install-suexec-binary: diff --git a/debian/patches/customize_apxs.patch b/debian/patches/customize_apxs.patch index 9c75ff1..281b910 100644 --- a/debian/patches/customize_apxs.patch +++ b/debian/patches/customize_apxs.patch @@ -8,7 +8,7 @@ Last-Update: 2012-03-17 --- a/support/apxs.in +++ b/support/apxs.in -@@ -38,7 +38,7 @@ +@@ -48,7 +48,7 @@ my $CFG_TARGET = get_vars("progname"); my $CFG_SYSCONFDIR = get_vars("sysconfdir"); my $CFG_CFLAGS = join ' ', map { get_vars($_) } @@ -16,8 +16,8 @@ Last-Update: 2012-03-17 + qw(SHLTCFLAGS CFLAGS CPPFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS); my $CFG_LDFLAGS = join ' ', map { get_vars($_) } qw(LDFLAGS NOTEST_LDFLAGS SH_LDFLAGS); - my $includedir = get_vars("includedir"); -@@ -49,7 +49,7 @@ + my $includedir = $destdir . get_vars("includedir"); +@@ -59,7 +59,7 @@ my $sbindir = get_vars("sbindir"); my $CFG_SBINDIR = eval qq("$sbindir"); my $ltflags = $ENV{'LTFLAGS'}; @@ -26,7 +26,7 @@ Last-Update: 2012-03-17 my %internal_vars = map {$_ => 1} qw(TARGET CC CFLAGS CFLAGS_SHLIB LD_SHLIB LDFLAGS_SHLIB LIBS_SHLIB -@@ -276,6 +276,7 @@ +@@ -286,6 +286,7 @@ $data =~ s|%TARGET%|$CFG_TARGET|sg; $data =~ s|%PREFIX%|$prefix|sg; $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg; @@ -34,7 +34,7 @@ Last-Update: 2012-03-17 my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s); -@@ -428,7 +429,7 @@ +@@ -438,7 +439,7 @@ $la =~ s|\.c$|.la|; my $o = $s; $o =~ s|\.c$|.o|; @@ -43,7 +43,7 @@ Last-Update: 2012-03-17 unshift(@objs, $lo); } -@@ -469,7 +470,7 @@ +@@ -479,7 +480,7 @@ $opt .= " -rpath $CFG_LIBEXECDIR -module -avoid-version $apr_ldflags"; } @@ -52,16 +52,16 @@ Last-Update: 2012-03-17 # execute the commands &execute_cmds(@cmds); -@@ -503,7 +504,7 @@ +@@ -513,7 +514,7 @@ if ($opt_i) { - push(@cmds, "$installbuilddir/instdso.sh SH_LIBTOOL='" . + push(@cmds, $destdir . "$installbuilddir/instdso.sh SH_LIBTOOL='" . "$libtool' $f $CFG_LIBEXECDIR"); - push(@cmds, "chmod 755 $CFG_LIBEXECDIR/$t"); + push(@cmds, "chmod 644 $CFG_LIBEXECDIR/$t"); } # determine module symbolname and filename -@@ -539,10 +540,11 @@ +@@ -549,10 +550,11 @@ $filename = "mod_${name}.c"; } my $dir = $CFG_LIBEXECDIR; @@ -75,7 +75,7 @@ Last-Update: 2012-03-17 } # execute the commands -@@ -550,108 +552,35 @@ +@@ -560,108 +562,35 @@ # activate module via LoadModule/AddModule directive if ($opt_a or $opt_A) { @@ -207,7 +207,7 @@ Last-Update: 2012-03-17 } } -@@ -671,8 +600,8 @@ +@@ -681,8 +610,8 @@ ## builddir=. diff --git a/debian/patches/fhs_compliance.patch b/debian/patches/fhs_compliance.patch index 00f8f71..986d8bc 100644 --- a/debian/patches/fhs_compliance.patch +++ b/debian/patches/fhs_compliance.patch @@ -1,33 +1,31 @@ Description: Fix up FHS file locations for apache2 droppings. Forwarded: not-needed Author: Adam Conrad <adconrad@0c3.net> -Last-Update: 2012-02-25 +Reviewed-By: Yadd <yadd@debian.org> +Last-Update: 2023-10-19 + --- a/configure +++ b/configure -@@ -39688,17 +39688,17 @@ +@@ -42812,13 +42812,13 @@ + ap_prefix="${ap_cur}" - cat >>confdefs.h <<_ACEOF --#define HTTPD_ROOT "${ap_prefix}" -+#define HTTPD_ROOT "/etc/apache2" - _ACEOF +-printf "%s\n" "#define HTTPD_ROOT \"${ap_prefix}\"" >>confdefs.h ++printf "%s\n" "#define HTTPD_ROOT \"/etc/apache2\"" >>confdefs.h - cat >>confdefs.h <<_ACEOF --#define SERVER_CONFIG_FILE "${rel_sysconfdir}/${progname}.conf" -+#define SERVER_CONFIG_FILE "${progname}.conf" - _ACEOF +-printf "%s\n" "#define SERVER_CONFIG_FILE \"${rel_sysconfdir}/${progname}.conf\"" >>confdefs.h ++printf "%s\n" "#define SERVER_CONFIG_FILE \"${progname}.conf\"" >>confdefs.h - cat >>confdefs.h <<_ACEOF --#define AP_TYPES_CONFIG_FILE "${rel_sysconfdir}/mime.types" -+#define AP_TYPES_CONFIG_FILE "mime.types" - _ACEOF +-printf "%s\n" "#define AP_TYPES_CONFIG_FILE \"${rel_sysconfdir}/mime.types\"" >>confdefs.h ++printf "%s\n" "#define AP_TYPES_CONFIG_FILE \"mime.types\"" >>confdefs.h + perlbin=`$ac_aux_dir/PrintPath perl` --- a/configure.in +++ b/configure.in -@@ -871,11 +871,11 @@ +@@ -928,11 +928,11 @@ echo $MODLIST | $AWK -f $srcdir/build/build-modules-c.awk > modules.c APR_EXPAND_VAR(ap_prefix, $prefix) @@ -53,12 +51,16 @@ Last-Update: 2012-02-25 #endif /* AP_CONFIG_LAYOUT_H */ --- a/include/httpd.h +++ b/include/httpd.h -@@ -109,7 +109,7 @@ - #define DOCUMENT_LOCATION HTTPD_ROOT "/docs" +@@ -107,10 +107,10 @@ + #ifndef DOCUMENT_LOCATION + #ifdef OS2 + /* Set default for OS/2 file system */ +-#define DOCUMENT_LOCATION HTTPD_ROOT "/docs" ++#define DOCUMENT_LOCATION "/var/www/html" #else /* Set default for non OS/2 file system */ -#define DOCUMENT_LOCATION HTTPD_ROOT "/htdocs" -+#define DOCUMENT_LOCATION "/var/www/html" ++#define DOCUMENT_LOCATION "/var/www/html" #endif #endif /* DOCUMENT_LOCATION */ diff --git a/debian/patches/fix-macro.patch b/debian/patches/fix-macro.patch new file mode 100644 index 0000000..ea83a64 --- /dev/null +++ b/debian/patches/fix-macro.patch @@ -0,0 +1,160 @@ +Description: add macro_ignore_empty and macro_ignore_bad_nesting parameters +Author: Upstream authors +Origin: upstream, https://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/mod_macro.c?r1=1770843&r2=1770842&pathrev=1770843 +Forwarded: not-needed +Reviewed-By: Yadd <yadd@debian.org> +Last-Update: 2021-10-25 + +--- a/modules/core/mod_macro.c ++++ b/modules/core/mod_macro.c +@@ -49,6 +49,10 @@ + + /********************************************************** MACRO MANAGEMENT */ + ++/* Global warning modifiers */ ++int ignore_empty = FALSE; /* no warning about empty argument */ ++int ignore_bad_nesting = FALSE; /* no warning about bad nesting */ ++ + /* + this is a macro: name, arguments, contents, location. + */ +@@ -58,6 +62,8 @@ + apr_array_header_t *arguments; /* of char*, macro parameter names */ + apr_array_header_t *contents; /* of char*, macro body */ + char *location; /* of macro definition, for error messages */ ++ int ignore_empty; /* no warning about empty argument */ ++ int ignore_bad_nesting; /* no warning about bad nesting */ + } ap_macro_t; + + /* configuration tokens. +@@ -67,6 +73,10 @@ + #define USE_MACRO "Use" + #define UNDEF_MACRO "UndefMacro" + ++#define IGNORE_EMPTY_MACRO_FLAG "/IgnoreEmptyArgs" ++#define IGNORE_BAD_NESTING_MACRO_FLAG "/IgnoreBadNesting" ++#define IGNORE_EMPTY_MACRO_DIRECTIVE "MacroIgnoreEmptyArgs" ++#define IGNORE_BAD_NESTING_MACRO_DIRECTIVE "MacroIgnoreBadNesting" + /* + Macros are kept globally... + They are not per-server or per-directory entities. +@@ -135,7 +145,8 @@ + const char *end_token, + const char *begin_token, + const char *where, +- apr_array_header_t ** plines) ++ apr_array_header_t ** plines, ++ int ignore_nesting) + { + apr_array_header_t *lines = apr_array_make(pool, 1, sizeof(char *)); + char line[MAX_STRING_LEN]; /* sorry, but this is expected by getline:-( */ +@@ -153,7 +164,7 @@ + /* detect nesting... */ + if (!strncmp(first, "</", 2)) { + any_nesting--; +- if (any_nesting < 0) { ++ if (!ignore_nesting && (any_nesting < 0)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, + 0, NULL, APLOGNO(02793) + "bad (negative) nesting on line %d of %s", +@@ -180,7 +191,7 @@ + + macro_nesting--; + if (!macro_nesting) { +- if (any_nesting) { ++ if (!ignore_nesting && any_nesting) { + ap_log_error(APLOG_MARK, + APLOG_WARNING, 0, NULL, APLOGNO(02795) + "bad cumulated nesting (%+d) in %s", +@@ -255,6 +266,13 @@ + tab[i], i + 1, ARG_PREFIX); + } + ++ if ((tab[i][0] == '$') && (tab[i][1] == '{')) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02805) ++ "macro '%s' (%s) " ++ "argument name '%s' (#%d) clashes with 'Define' syntax '${...}', better use '$(...)'.", ++ macro->name, macro->location, tab[i], i + 1); ++ } ++ + for (j = i + 1; j < nelts; j++) { + size_t ltabj = strlen(tab[j]); + +@@ -763,7 +781,25 @@ + where, ARG_PREFIX); + } + +- /* get macro parameters */ ++ /* get/remove macro modifiers from parameters */ ++#define CHECK_MACRO_FLAG(arg_, flag_str, flag_val) if (!strncasecmp(arg_, flag_str, strlen(flag_str))) { flag_val = TRUE; arg_ += strlen(flag_str); if (!*arg) break;} ++ while (*arg == '/') { ++ CHECK_MACRO_FLAG(arg, IGNORE_EMPTY_MACRO_FLAG, macro->ignore_empty); ++ CHECK_MACRO_FLAG(arg, IGNORE_BAD_NESTING_MACRO_FLAG, macro->ignore_bad_nesting); ++ if (*arg != ' ') { ++ char *c = ap_strchr(arg, ' '); ++ if (c) *c = '\0'; ++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02804) ++ "%s: unknown flag '%s'", where, arg); ++ if (c) { ++ *c = ' '; ++ arg = c; ++ } ++ } ++ arg++; ++ } ++ ++ /* get macro parameters */ + macro->arguments = get_arguments(pool, arg); + + errmsg = check_macro_arguments(cmd->temp_pool, macro); +@@ -774,7 +810,7 @@ + + errmsg = get_lines_till_end_token(pool, cmd->config_file, + END_MACRO, BEGIN_MACRO, +- where, ¯o->contents); ++ where, ¯o->contents, ignore_bad_nesting || macro->ignore_bad_nesting); + + if (errmsg) { + return apr_psprintf(cmd->temp_pool, +@@ -860,7 +896,8 @@ + cmd->config_file->line_number, + cmd->config_file->name); + +- check_macro_use_arguments(where, replacements); ++ if (!ignore_empty && !macro->ignore_empty) ++ check_macro_use_arguments(where, replacements); + + errmsg = process_content(cmd->temp_pool, macro, replacements, + NULL, &contents); +@@ -911,6 +948,18 @@ + return NULL; + } + ++static const char *macro_ignore_empty(cmd_parms * cmd, void *dummy) ++{ ++ ignore_empty = TRUE; ++ return NULL; ++} ++ ++static const char *macro_ignore_bad_nesting(cmd_parms * cmd, void *dummy) ++{ ++ ignore_bad_nesting = TRUE; ++ return NULL; ++} ++ + /************************************************************* EXPORT MODULE */ + + /* +@@ -924,7 +973,11 @@ + AP_INIT_RAW_ARGS(USE_MACRO, use_macro, NULL, EXEC_ON_READ | OR_ALL, + "Use of a macro."), + AP_INIT_TAKE1(UNDEF_MACRO, undef_macro, NULL, EXEC_ON_READ | OR_ALL, +- "Remove a macro definition."), ++ "Remove a macro definition."), ++ AP_INIT_NO_ARGS(IGNORE_EMPTY_MACRO_DIRECTIVE, macro_ignore_empty, NULL, EXEC_ON_READ | OR_ALL, ++ "Globally ignore warnings about empty arguments."), ++ AP_INIT_NO_ARGS(IGNORE_BAD_NESTING_MACRO_DIRECTIVE, macro_ignore_bad_nesting, NULL, EXEC_ON_READ | OR_ALL, ++ "Globally ignore warnings about bad nesting."), + + {NULL} + }; diff --git a/debian/patches/import-http2-module-from-2.4.46.patch b/debian/patches/import-http2-module-from-2.4.46.patch deleted file mode 100644 index cdca37d..0000000 --- a/debian/patches/import-http2-module-from-2.4.46.patch +++ /dev/null @@ -1,7588 +0,0 @@ -Description: import http2 module from 2.4.41 - There are too many changes in http2 module to distiguish CVE-2019-9517, - CVE-2019-10082 and CVE-2019-10081 changes. -Author: Apache authors -Bug: https://security-tracker.debian.org/tracker/CVE-2019-9517 - https://security-tracker.debian.org/tracker/CVE-2019-10082 - https://security-tracker.debian.org/tracker/CVE-2019-10081 - https://security-tracker.debian.org/tracker/CVE-2020-9490 - https://security-tracker.debian.org/tracker/CVE-2020-11993 -Forwarded: not-needed -Reviewed-By: Xavier Guimard <yadd@debian.org> -Last-Update: 2020-08-25 - ---- a/modules/http2/config2.m4 -+++ b/modules/http2/config2.m4 -@@ -31,7 +31,6 @@ - h2_h2.lo dnl - h2_headers.lo dnl - h2_mplx.lo dnl --h2_ngn_shed.lo dnl - h2_push.lo dnl - h2_request.lo dnl - h2_session.lo dnl ---- a/modules/http2/h2.h -+++ b/modules/http2/h2.h -@@ -48,12 +48,12 @@ - #define H2_HEADER_PATH_LEN 5 - #define H2_CRLF "\r\n" - --/* Max data size to write so it fits inside a TLS record */ --#define H2_DATA_CHUNK_SIZE ((16*1024) - 100 - 9) -- - /* Size of the frame header itself in HTTP/2 */ - #define H2_FRAME_HDR_LEN 9 - -+/* Max data size to write so it fits inside a TLS record */ -+#define H2_DATA_CHUNK_SIZE ((16*1024) - 100 - H2_FRAME_HDR_LEN) -+ - /* Maximum number of padding bytes in a frame, rfc7540 */ - #define H2_MAX_PADLEN 256 - /* Initial default window size, RFC 7540 ch. 6.5.2 */ -@@ -138,7 +138,7 @@ - apr_table_t *headers; - - apr_time_t request_time; -- unsigned int chunked : 1; /* iff requst body needs to be forwarded as chunked */ -+ unsigned int chunked : 1; /* iff request body needs to be forwarded as chunked */ - unsigned int serialize : 1; /* iff this request is written in HTTP/1.1 serialization */ - apr_off_t raw_bytes; /* RAW network bytes that generated this request - if known. */ - }; -@@ -162,5 +162,6 @@ - #define H2_FILTER_DEBUG_NOTE "http2-debug" - #define H2_HDR_CONFORMANCE "http2-hdr-conformance" - #define H2_HDR_CONFORMANCE_UNSAFE "unsafe" -+#define H2_PUSH_MODE_NOTE "http2-push-mode" - - #endif /* defined(__mod_h2__h2__) */ ---- a/modules/http2/h2_alt_svc.c -+++ b/modules/http2/h2_alt_svc.c -@@ -75,7 +75,7 @@ - - static int h2_alt_svc_handler(request_rec *r) - { -- const h2_config *cfg; -+ apr_array_header_t *alt_svcs; - int i; - - if (r->connection->keepalives > 0) { -@@ -87,8 +87,8 @@ - return DECLINED; - } - -- cfg = h2_config_sget(r->server); -- if (r->hostname && cfg && cfg->alt_svcs && cfg->alt_svcs->nelts > 0) { -+ alt_svcs = h2_config_alt_svcs(r); -+ if (r->hostname && alt_svcs && alt_svcs->nelts > 0) { - const char *alt_svc_used = apr_table_get(r->headers_in, "Alt-Svc-Used"); - if (!alt_svc_used) { - /* We have alt-svcs defined and client is not already using -@@ -99,7 +99,7 @@ - const char *alt_svc = ""; - const char *svc_ma = ""; - int secure = h2_h2_is_tls(r->connection); -- int ma = h2_config_geti(cfg, H2_CONF_ALT_SVC_MAX_AGE); -+ int ma = h2_config_rgeti(r, H2_CONF_ALT_SVC_MAX_AGE); - if (ma >= 0) { - svc_ma = apr_psprintf(r->pool, "; ma=%d", ma); - } -@@ -107,8 +107,8 @@ - "h2_alt_svc: announce %s for %s:%d", - (secure? "secure" : "insecure"), - r->hostname, (int)r->server->port); -- for (i = 0; i < cfg->alt_svcs->nelts; ++i) { -- h2_alt_svc *as = h2_alt_svc_IDX(cfg->alt_svcs, i); -+ for (i = 0; i < alt_svcs->nelts; ++i) { -+ h2_alt_svc *as = h2_alt_svc_IDX(alt_svcs, i); - const char *ahost = as->host; - if (ahost && !apr_strnatcasecmp(ahost, r->hostname)) { - ahost = NULL; ---- a/modules/http2/h2_bucket_beam.c -+++ b/modules/http2/h2_bucket_beam.c -@@ -196,7 +196,7 @@ - * bucket beam that can transport buckets across threads - ******************************************************************************/ - --static void mutex_leave(void *ctx, apr_thread_mutex_t *lock) -+static void mutex_leave(apr_thread_mutex_t *lock) - { - apr_thread_mutex_unlock(lock); - } -@@ -217,7 +217,7 @@ - static void leave_yellow(h2_bucket_beam *beam, h2_beam_lock *pbl) - { - if (pbl->leave) { -- pbl->leave(pbl->leave_ctx, pbl->mutex); -+ pbl->leave(pbl->mutex); - } - } - ---- a/modules/http2/h2_bucket_beam.h -+++ b/modules/http2/h2_bucket_beam.h -@@ -126,12 +126,11 @@ - * buffers until the transmission is complete. Star gates use a similar trick. - */ - --typedef void h2_beam_mutex_leave(void *ctx, struct apr_thread_mutex_t *lock); -+typedef void h2_beam_mutex_leave(struct apr_thread_mutex_t *lock); - - typedef struct { - apr_thread_mutex_t *mutex; - h2_beam_mutex_leave *leave; -- void *leave_ctx; - } h2_beam_lock; - - typedef struct h2_bucket_beam h2_bucket_beam; ---- a/modules/http2/h2_config.c -+++ b/modules/http2/h2_config.c -@@ -42,6 +42,55 @@ - #define H2_CONFIG_GET(a, b, n) \ - (((a)->n == DEF_VAL)? (b) : (a))->n - -+#define H2_CONFIG_SET(a, n, v) \ -+ ((a)->n = v) -+ -+#define CONFIG_CMD_SET(cmd,dir,var,val) \ -+ h2_config_seti(((cmd)->path? (dir) : NULL), h2_config_sget((cmd)->server), var, val) -+ -+#define CONFIG_CMD_SET64(cmd,dir,var,val) \ -+ h2_config_seti64(((cmd)->path? (dir) : NULL), h2_config_sget((cmd)->server), var, val) -+ -+/* Apache httpd module configuration for h2. */ -+typedef struct h2_config { -+ const char *name; -+ int h2_max_streams; /* max concurrent # streams (http2) */ -+ int h2_window_size; /* stream window size (http2) */ -+ int min_workers; /* min # of worker threads/child */ -+ int max_workers; /* max # of worker threads/child */ -+ int max_worker_idle_secs; /* max # of idle seconds for worker */ -+ int stream_max_mem_size; /* max # bytes held in memory/stream */ -+ apr_array_header_t *alt_svcs; /* h2_alt_svc specs for this server */ -+ int alt_svc_max_age; /* seconds clients can rely on alt-svc info*/ -+ int serialize_headers; /* Use serialized HTTP/1.1 headers for -+ processing, better compatibility */ -+ int h2_direct; /* if mod_h2 is active directly */ -+ int modern_tls_only; /* Accept only modern TLS in HTTP/2 connections */ -+ int h2_upgrade; /* Allow HTTP/1 upgrade to h2/h2c */ -+ apr_int64_t tls_warmup_size; /* Amount of TLS data to send before going full write size */ -+ int tls_cooldown_secs; /* Seconds of idle time before going back to small TLS records */ -+ int h2_push; /* if HTTP/2 server push is enabled */ -+ struct apr_hash_t *priorities;/* map of content-type to h2_priority records */ -+ -+ int push_diary_size; /* # of entries in push diary */ -+ int copy_files; /* if files shall be copied vs setaside on output */ -+ apr_array_header_t *push_list;/* list of h2_push_res configurations */ -+ int early_hints; /* support status code 103 */ -+ int padding_bits; -+ int padding_always; -+} h2_config; -+ -+typedef struct h2_dir_config { -+ const char *name; -+ apr_array_header_t *alt_svcs; /* h2_alt_svc specs for this server */ -+ int alt_svc_max_age; /* seconds clients can rely on alt-svc info*/ -+ int h2_upgrade; /* Allow HTTP/1 upgrade to h2/h2c */ -+ int h2_push; /* if HTTP/2 server push is enabled */ -+ apr_array_header_t *push_list;/* list of h2_push_res configurations */ -+ int early_hints; /* support status code 103 */ -+} h2_dir_config; -+ -+ - static h2_config defconf = { - "default", - 100, /* max_streams */ -@@ -64,6 +113,18 @@ - 0, /* copy files across threads */ - NULL, /* push list */ - 0, /* early hints, http status 103 */ -+ 0, /* padding bits */ -+ 1, /* padding always */ -+}; -+ -+static h2_dir_config defdconf = { -+ "default", -+ NULL, /* no alt-svcs */ -+ -1, /* alt-svc max age */ -+ -1, /* HTTP/1 Upgrade support */ -+ -1, /* HTTP/2 server push enabled */ -+ NULL, /* push list */ -+ -1, /* early hints, http status 103 */ - }; - - void h2_config_init(apr_pool_t *pool) -@@ -71,12 +132,10 @@ - (void)pool; - } - --static void *h2_config_create(apr_pool_t *pool, -- const char *prefix, const char *x) -+void *h2_config_create_svr(apr_pool_t *pool, server_rec *s) - { - h2_config *conf = (h2_config *)apr_pcalloc(pool, sizeof(h2_config)); -- const char *s = x? x : "unknown"; -- char *name = apr_pstrcat(pool, prefix, "[", s, "]", NULL); -+ char *name = apr_pstrcat(pool, "srv[", s->defn_name, "]", NULL); - - conf->name = name; - conf->h2_max_streams = DEF_VAL; -@@ -98,19 +157,11 @@ - conf->copy_files = DEF_VAL; - conf->push_list = NULL; - conf->early_hints = DEF_VAL; -+ conf->padding_bits = DEF_VAL; -+ conf->padding_always = DEF_VAL; - return conf; - } - --void *h2_config_create_svr(apr_pool_t *pool, server_rec *s) --{ -- return h2_config_create(pool, "srv", s->defn_name); --} -- --void *h2_config_create_dir(apr_pool_t *pool, char *x) --{ -- return h2_config_create(pool, "dir", x); --} -- - static void *h2_config_merge(apr_pool_t *pool, void *basev, void *addv) - { - h2_config *base = (h2_config *)basev; -@@ -149,25 +200,52 @@ - n->push_list = add->push_list? add->push_list : base->push_list; - } - n->early_hints = H2_CONFIG_GET(add, base, early_hints); -+ n->padding_bits = H2_CONFIG_GET(add, base, padding_bits); -+ n->padding_always = H2_CONFIG_GET(add, base, padding_always); - return n; - } - --void *h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv) -+void *h2_config_merge_svr(apr_pool_t *pool, void *basev, void *addv) - { - return h2_config_merge(pool, basev, addv); - } - --void *h2_config_merge_svr(apr_pool_t *pool, void *basev, void *addv) -+void *h2_config_create_dir(apr_pool_t *pool, char *x) - { -- return h2_config_merge(pool, basev, addv); -+ h2_dir_config *conf = (h2_dir_config *)apr_pcalloc(pool, sizeof(h2_dir_config)); -+ const char *s = x? x : "unknown"; -+ char *name = apr_pstrcat(pool, "dir[", s, "]", NULL); -+ -+ conf->name = name; -+ conf->alt_svc_max_age = DEF_VAL; -+ conf->h2_upgrade = DEF_VAL; -+ conf->h2_push = DEF_VAL; -+ conf->early_hints = DEF_VAL; -+ return conf; - } - --int h2_config_geti(const h2_config *conf, h2_config_var_t var) -+void *h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv) - { -- return (int)h2_config_geti64(conf, var); -+ h2_dir_config *base = (h2_dir_config *)basev; -+ h2_dir_config *add = (h2_dir_config *)addv; -+ h2_dir_config *n = (h2_dir_config *)apr_pcalloc(pool, sizeof(h2_dir_config)); -+ -+ n->name = apr_pstrcat(pool, "merged[", add->name, ", ", base->name, "]", NULL); -+ n->alt_svcs = add->alt_svcs? add->alt_svcs : base->alt_svcs; -+ n->alt_svc_max_age = H2_CONFIG_GET(add, base, alt_svc_max_age); -+ n->h2_upgrade = H2_CONFIG_GET(add, base, h2_upgrade); -+ n->h2_push = H2_CONFIG_GET(add, base, h2_push); -+ if (add->push_list && base->push_list) { -+ n->push_list = apr_array_append(pool, base->push_list, add->push_list); -+ } -+ else { -+ n->push_list = add->push_list? add->push_list : base->push_list; -+ } -+ n->early_hints = H2_CONFIG_GET(add, base, early_hints); -+ return n; - } - --apr_int64_t h2_config_geti64(const h2_config *conf, h2_config_var_t var) -+static apr_int64_t h2_srv_config_geti64(const h2_config *conf, h2_config_var_t var) - { - switch(var) { - case H2_CONF_MAX_STREAMS: -@@ -204,12 +282,93 @@ - return H2_CONFIG_GET(conf, &defconf, copy_files); - case H2_CONF_EARLY_HINTS: - return H2_CONFIG_GET(conf, &defconf, early_hints); -+ case H2_CONF_PADDING_BITS: -+ return H2_CONFIG_GET(conf, &defconf, padding_bits); -+ case H2_CONF_PADDING_ALWAYS: -+ return H2_CONFIG_GET(conf, &defconf, padding_always); - default: - return DEF_VAL; - } - } - --const h2_config *h2_config_sget(server_rec *s) -+static void h2_srv_config_seti(h2_config *conf, h2_config_var_t var, int val) -+{ -+ switch(var) { -+ case H2_CONF_MAX_STREAMS: -+ H2_CONFIG_SET(conf, h2_max_streams, val); -+ break; -+ case H2_CONF_WIN_SIZE: -+ H2_CONFIG_SET(conf, h2_window_size, val); -+ break; -+ case H2_CONF_MIN_WORKERS: -+ H2_CONFIG_SET(conf, min_workers, val); -+ break; -+ case H2_CONF_MAX_WORKERS: -+ H2_CONFIG_SET(conf, max_workers, val); -+ break; -+ case H2_CONF_MAX_WORKER_IDLE_SECS: -+ H2_CONFIG_SET(conf, max_worker_idle_secs, val); -+ break; -+ case H2_CONF_STREAM_MAX_MEM: -+ H2_CONFIG_SET(conf, stream_max_mem_size, val); -+ break; -+ case H2_CONF_ALT_SVC_MAX_AGE: -+ H2_CONFIG_SET(conf, alt_svc_max_age, val); -+ break; -+ case H2_CONF_SER_HEADERS: -+ H2_CONFIG_SET(conf, serialize_headers, val); -+ break; -+ case H2_CONF_MODERN_TLS_ONLY: -+ H2_CONFIG_SET(conf, modern_tls_only, val); -+ break; -+ case H2_CONF_UPGRADE: -+ H2_CONFIG_SET(conf, h2_upgrade, val); -+ break; -+ case H2_CONF_DIRECT: -+ H2_CONFIG_SET(conf, h2_direct, val); -+ break; -+ case H2_CONF_TLS_WARMUP_SIZE: -+ H2_CONFIG_SET(conf, tls_warmup_size, val); -+ break; -+ case H2_CONF_TLS_COOLDOWN_SECS: -+ H2_CONFIG_SET(conf, tls_cooldown_secs, val); -+ break; -+ case H2_CONF_PUSH: -+ H2_CONFIG_SET(conf, h2_push, val); -+ break; -+ case H2_CONF_PUSH_DIARY_SIZE: -+ H2_CONFIG_SET(conf, push_diary_size, val); -+ break; -+ case H2_CONF_COPY_FILES: -+ H2_CONFIG_SET(conf, copy_files, val); -+ break; -+ case H2_CONF_EARLY_HINTS: -+ H2_CONFIG_SET(conf, early_hints, val); -+ break; -+ case H2_CONF_PADDING_BITS: -+ H2_CONFIG_SET(conf, padding_bits, val); -+ break; -+ case H2_CONF_PADDING_ALWAYS: -+ H2_CONFIG_SET(conf, padding_always, val); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void h2_srv_config_seti64(h2_config *conf, h2_config_var_t var, apr_int64_t val) -+{ -+ switch(var) { -+ case H2_CONF_TLS_WARMUP_SIZE: -+ H2_CONFIG_SET(conf, tls_warmup_size, val); -+ break; -+ default: -+ h2_srv_config_seti(conf, var, (int)val); -+ break; -+ } -+} -+ -+static h2_config *h2_config_sget(server_rec *s) - { - h2_config *cfg = (h2_config *)ap_get_module_config(s->module_config, - &http2_module); -@@ -217,9 +376,162 @@ - return cfg; - } - --const struct h2_priority *h2_config_get_priority(const h2_config *conf, -- const char *content_type) -+static const h2_dir_config *h2_config_rget(request_rec *r) -+{ -+ h2_dir_config *cfg = (h2_dir_config *)ap_get_module_config(r->per_dir_config, -+ &http2_module); -+ ap_assert(cfg); -+ return cfg; -+} -+ -+static apr_int64_t h2_dir_config_geti64(const h2_dir_config *conf, h2_config_var_t var) -+{ -+ switch(var) { -+ case H2_CONF_ALT_SVC_MAX_AGE: -+ return H2_CONFIG_GET(conf, &defdconf, alt_svc_max_age); -+ case H2_CONF_UPGRADE: -+ return H2_CONFIG_GET(conf, &defdconf, h2_upgrade); -+ case H2_CONF_PUSH: -+ return H2_CONFIG_GET(conf, &defdconf, h2_push); -+ case H2_CONF_EARLY_HINTS: -+ return H2_CONFIG_GET(conf, &defdconf, early_hints); -+ -+ default: -+ return DEF_VAL; -+ } -+} -+ -+static void h2_config_seti(h2_dir_config *dconf, h2_config *conf, h2_config_var_t var, int val) -+{ -+ int set_srv = !dconf; -+ if (dconf) { -+ switch(var) { -+ case H2_CONF_ALT_SVC_MAX_AGE: -+ H2_CONFIG_SET(dconf, alt_svc_max_age, val); -+ break; -+ case H2_CONF_UPGRADE: -+ H2_CONFIG_SET(dconf, h2_upgrade, val); -+ break; -+ case H2_CONF_PUSH: -+ H2_CONFIG_SET(dconf, h2_push, val); -+ break; -+ case H2_CONF_EARLY_HINTS: -+ H2_CONFIG_SET(dconf, early_hints, val); -+ break; -+ default: -+ /* not handled in dir_conf */ -+ set_srv = 1; -+ break; -+ } -+ } -+ -+ if (set_srv) { -+ h2_srv_config_seti(conf, var, val); -+ } -+} -+ -+static void h2_config_seti64(h2_dir_config *dconf, h2_config *conf, h2_config_var_t var, apr_int64_t val) - { -+ int set_srv = !dconf; -+ if (dconf) { -+ switch(var) { -+ default: -+ /* not handled in dir_conf */ -+ set_srv = 1; -+ break; -+ } -+ } -+ -+ if (set_srv) { -+ h2_srv_config_seti64(conf, var, val); -+ } -+} -+ -+static const h2_config *h2_config_get(conn_rec *c) -+{ -+ h2_ctx *ctx = h2_ctx_get(c, 0); -+ -+ if (ctx) { -+ if (ctx->config) { -+ return ctx->config; -+ } -+ else if (ctx->server) { -+ ctx->config = h2_config_sget(ctx->server); -+ return ctx->config; -+ } -+ } -+ -+ return h2_config_sget(c->base_server); -+} -+ -+int h2_config_cgeti(conn_rec *c, h2_config_var_t var) -+{ -+ return (int)h2_srv_config_geti64(h2_config_get(c), var); -+} -+ -+apr_int64_t h2_config_cgeti64(conn_rec *c, h2_config_var_t var) -+{ -+ return h2_srv_config_geti64(h2_config_get(c), var); -+} -+ -+int h2_config_sgeti(server_rec *s, h2_config_var_t var) -+{ -+ return (int)h2_srv_config_geti64(h2_config_sget(s), var); -+} -+ -+apr_int64_t h2_config_sgeti64(server_rec *s, h2_config_var_t var) -+{ -+ return h2_srv_config_geti64(h2_config_sget(s), var); -+} -+ -+int h2_config_geti(request_rec *r, server_rec *s, h2_config_var_t var) -+{ -+ return (int)h2_config_geti64(r, s, var); -+} -+ -+apr_int64_t h2_config_geti64(request_rec *r, server_rec *s, h2_config_var_t var) -+{ -+ apr_int64_t mode = r? (int)h2_dir_config_geti64(h2_config_rget(r), var) : DEF_VAL; -+ return (mode != DEF_VAL)? mode : h2_config_sgeti64(s, var); -+} -+ -+int h2_config_rgeti(request_rec *r, h2_config_var_t var) -+{ -+ return h2_config_geti(r, r->server, var); -+} -+ -+apr_int64_t h2_config_rgeti64(request_rec *r, h2_config_var_t var) -+{ -+ return h2_config_geti64(r, r->server, var); -+} -+ -+apr_array_header_t *h2_config_push_list(request_rec *r) -+{ -+ const h2_config *sconf; -+ const h2_dir_config *conf = h2_config_rget(r); -+ -+ if (conf && conf->push_list) { -+ return conf->push_list; -+ } -+ sconf = h2_config_sget(r->server); -+ return sconf? sconf->push_list : NULL; -+} -+ -+apr_array_header_t *h2_config_alt_svcs(request_rec *r) -+{ -+ const h2_config *sconf; -+ const h2_dir_config *conf = h2_config_rget(r); -+ -+ if (conf && conf->alt_svcs) { -+ return conf->alt_svcs; -+ } -+ sconf = h2_config_sget(r->server); -+ return sconf? sconf->alt_svcs : NULL; -+} -+ -+const struct h2_priority *h2_cconfig_get_priority(conn_rec *c, const char *content_type) -+{ -+ const h2_config *conf = h2_config_get(c); - if (content_type && conf->priorities) { - size_t len = strcspn(content_type, "; \t"); - h2_priority *prio = apr_hash_get(conf->priorities, content_type, len); -@@ -228,166 +540,156 @@ - return NULL; - } - --static const char *h2_conf_set_max_streams(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_max_streams(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- cfg->h2_max_streams = (int)apr_atoi64(value); -- (void)arg; -- if (cfg->h2_max_streams < 1) { -+ apr_int64_t ival = (int)apr_atoi64(value); -+ if (ival < 1) { - return "value must be > 0"; - } -+ CONFIG_CMD_SET64(cmd, dirconf, H2_CONF_MAX_STREAMS, ival); - return NULL; - } - --static const char *h2_conf_set_window_size(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_window_size(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- cfg->h2_window_size = (int)apr_atoi64(value); -- (void)arg; -- if (cfg->h2_window_size < 1024) { -+ int val = (int)apr_atoi64(value); -+ if (val < 1024) { - return "value must be >= 1024"; - } -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_WIN_SIZE, val); - return NULL; - } - --static const char *h2_conf_set_min_workers(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_min_workers(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- cfg->min_workers = (int)apr_atoi64(value); -- (void)arg; -- if (cfg->min_workers < 1) { -+ int val = (int)apr_atoi64(value); -+ if (val < 1) { - return "value must be > 0"; - } -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MIN_WORKERS, val); - return NULL; - } - --static const char *h2_conf_set_max_workers(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_max_workers(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- cfg->max_workers = (int)apr_atoi64(value); -- (void)arg; -- if (cfg->max_workers < 1) { -+ int val = (int)apr_atoi64(value); -+ if (val < 1) { - return "value must be > 0"; - } -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MAX_WORKERS, val); - return NULL; - } - --static const char *h2_conf_set_max_worker_idle_secs(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_max_worker_idle_secs(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- cfg->max_worker_idle_secs = (int)apr_atoi64(value); -- (void)arg; -- if (cfg->max_worker_idle_secs < 1) { -+ int val = (int)apr_atoi64(value); -+ if (val < 1) { - return "value must be > 0"; - } -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MAX_WORKER_IDLE_SECS, val); - return NULL; - } - --static const char *h2_conf_set_stream_max_mem_size(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_stream_max_mem_size(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- -- -- cfg->stream_max_mem_size = (int)apr_atoi64(value); -- (void)arg; -- if (cfg->stream_max_mem_size < 1024) { -+ int val = (int)apr_atoi64(value); -+ if (val < 1024) { - return "value must be >= 1024"; - } -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_STREAM_MAX_MEM, val); - return NULL; - } - --static const char *h2_add_alt_svc(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_add_alt_svc(cmd_parms *cmd, -+ void *dirconf, const char *value) - { - if (value && *value) { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- h2_alt_svc *as = h2_alt_svc_parse(value, parms->pool); -+ h2_alt_svc *as = h2_alt_svc_parse(value, cmd->pool); - if (!as) { - return "unable to parse alt-svc specifier"; - } -- if (!cfg->alt_svcs) { -- cfg->alt_svcs = apr_array_make(parms->pool, 5, sizeof(h2_alt_svc*)); -+ -+ if (cmd->path) { -+ h2_dir_config *dcfg = (h2_dir_config *)dirconf; -+ if (!dcfg->alt_svcs) { -+ dcfg->alt_svcs = apr_array_make(cmd->pool, 5, sizeof(h2_alt_svc*)); -+ } -+ APR_ARRAY_PUSH(dcfg->alt_svcs, h2_alt_svc*) = as; -+ } -+ else { -+ h2_config *cfg = (h2_config *)h2_config_sget(cmd->server); -+ if (!cfg->alt_svcs) { -+ cfg->alt_svcs = apr_array_make(cmd->pool, 5, sizeof(h2_alt_svc*)); -+ } -+ APR_ARRAY_PUSH(cfg->alt_svcs, h2_alt_svc*) = as; - } -- APR_ARRAY_PUSH(cfg->alt_svcs, h2_alt_svc*) = as; - } -- (void)arg; - return NULL; - } - --static const char *h2_conf_set_alt_svc_max_age(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_alt_svc_max_age(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- cfg->alt_svc_max_age = (int)apr_atoi64(value); -- (void)arg; -+ int val = (int)apr_atoi64(value); -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_ALT_SVC_MAX_AGE, val); - return NULL; - } - --static const char *h2_conf_set_session_extra_files(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_session_extra_files(cmd_parms *cmd, -+ void *dirconf, const char *value) - { - /* deprecated, ignore */ -- (void)arg; -+ (void)dirconf; - (void)value; -- ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, parms->pool, /* NO LOGNO */ -+ ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool, /* NO LOGNO */ - "H2SessionExtraFiles is obsolete and will be ignored"); - return NULL; - } - --static const char *h2_conf_set_serialize_headers(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_serialize_headers(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); - if (!strcasecmp(value, "On")) { -- cfg->serialize_headers = 1; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_SER_HEADERS, 1); - return NULL; - } - else if (!strcasecmp(value, "Off")) { -- cfg->serialize_headers = 0; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_SER_HEADERS, 0); - return NULL; - } -- -- (void)arg; - return "value must be On or Off"; - } - --static const char *h2_conf_set_direct(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_direct(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); - if (!strcasecmp(value, "On")) { -- cfg->h2_direct = 1; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_DIRECT, 1); - return NULL; - } - else if (!strcasecmp(value, "Off")) { -- cfg->h2_direct = 0; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_DIRECT, 0); - return NULL; - } -- -- (void)arg; - return "value must be On or Off"; - } - --static const char *h2_conf_set_push(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_push(cmd_parms *cmd, void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); - if (!strcasecmp(value, "On")) { -- cfg->h2_push = 1; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH, 1); - return NULL; - } - else if (!strcasecmp(value, "Off")) { -- cfg->h2_push = 0; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH, 0); - return NULL; - } -- -- (void)arg; - return "value must be On or Off"; - } - -@@ -419,7 +721,7 @@ - else if (!strcasecmp("BEFORE", sdependency)) { - dependency = H2_DEPENDANT_BEFORE; - if (sweight) { -- return "dependency 'Before' does not allow a weight"; -+ return "dependecy 'Before' does not allow a weight"; - } - } - else if (!strcasecmp("INTERLEAVED", sdependency)) { -@@ -447,100 +749,88 @@ - return NULL; - } - --static const char *h2_conf_set_modern_tls_only(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_modern_tls_only(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); - if (!strcasecmp(value, "On")) { -- cfg->modern_tls_only = 1; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MODERN_TLS_ONLY, 1); - return NULL; - } - else if (!strcasecmp(value, "Off")) { -- cfg->modern_tls_only = 0; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MODERN_TLS_ONLY, 0); - return NULL; - } -- -- (void)arg; - return "value must be On or Off"; - } - --static const char *h2_conf_set_upgrade(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_upgrade(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); - if (!strcasecmp(value, "On")) { -- cfg->h2_upgrade = 1; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_UPGRADE, 1); - return NULL; - } - else if (!strcasecmp(value, "Off")) { -- cfg->h2_upgrade = 0; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_UPGRADE, 0); - return NULL; - } -- -- (void)arg; - return "value must be On or Off"; - } - --static const char *h2_conf_set_tls_warmup_size(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_tls_warmup_size(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- cfg->tls_warmup_size = apr_atoi64(value); -- (void)arg; -+ apr_int64_t val = apr_atoi64(value); -+ CONFIG_CMD_SET64(cmd, dirconf, H2_CONF_TLS_WARMUP_SIZE, val); - return NULL; - } - --static const char *h2_conf_set_tls_cooldown_secs(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_tls_cooldown_secs(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- cfg->tls_cooldown_secs = (int)apr_atoi64(value); -- (void)arg; -+ apr_int64_t val = (int)apr_atoi64(value); -+ CONFIG_CMD_SET64(cmd, dirconf, H2_CONF_TLS_COOLDOWN_SECS, val); - return NULL; - } - --static const char *h2_conf_set_push_diary_size(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_push_diary_size(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- (void)arg; -- cfg->push_diary_size = (int)apr_atoi64(value); -- if (cfg->push_diary_size < 0) { -+ int val = (int)apr_atoi64(value); -+ if (val < 0) { - return "value must be >= 0"; - } -- if (cfg->push_diary_size > 0 && (cfg->push_diary_size & (cfg->push_diary_size-1))) { -+ if (val > 0 && (val & (val-1))) { - return "value must a power of 2"; - } -- if (cfg->push_diary_size > (1 << 15)) { -+ if (val > (1 << 15)) { - return "value must <= 65536"; - } -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH_DIARY_SIZE, val); - return NULL; - } - --static const char *h2_conf_set_copy_files(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_copy_files(cmd_parms *cmd, -+ void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)arg; - if (!strcasecmp(value, "On")) { -- cfg->copy_files = 1; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_COPY_FILES, 1); - return NULL; - } - else if (!strcasecmp(value, "Off")) { -- cfg->copy_files = 0; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_COPY_FILES, 0); - return NULL; - } -- -- (void)arg; - return "value must be On or Off"; - } - --static void add_push(apr_pool_t *pool, h2_config *conf, h2_push_res *push) -+static void add_push(apr_array_header_t **plist, apr_pool_t *pool, h2_push_res *push) - { - h2_push_res *new; -- if (!conf->push_list) { -- conf->push_list = apr_array_make(pool, 10, sizeof(*push)); -+ if (!*plist) { -+ *plist = apr_array_make(pool, 10, sizeof(*push)); - } -- new = apr_array_push(conf->push_list); -+ new = apr_array_push(*plist); - new->uri_ref = push->uri_ref; - new->critical = push->critical; - } -@@ -549,8 +839,6 @@ - const char *arg1, const char *arg2, - const char *arg3) - { -- h2_config *dconf = (h2_config*)dirconf ; -- h2_config *sconf = (h2_config*)h2_config_sget(cmd->server); - h2_push_res push; - const char *last = arg3; - -@@ -575,42 +863,54 @@ - } - } - -- /* server command? set both */ -- if (cmd->path == NULL) { -- add_push(cmd->pool, sconf, &push); -- add_push(cmd->pool, dconf, &push); -+ if (cmd->path) { -+ add_push(&(((h2_dir_config*)dirconf)->push_list), cmd->pool, &push); - } - else { -- add_push(cmd->pool, dconf, &push); -+ add_push(&(h2_config_sget(cmd->server)->push_list), cmd->pool, &push); - } -+ return NULL; -+} - -+static const char *h2_conf_set_early_hints(cmd_parms *cmd, -+ void *dirconf, const char *value) -+{ -+ int val; -+ -+ if (!strcasecmp(value, "On")) val = 1; -+ else if (!strcasecmp(value, "Off")) val = 0; -+ else return "value must be On or Off"; -+ -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_EARLY_HINTS, val); -+ if (cmd->path) { -+ ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool, -+ "H2EarlyHints = %d on path %s", val, cmd->path); -+ } - return NULL; - } - --static const char *h2_conf_set_early_hints(cmd_parms *parms, -- void *arg, const char *value) -+static const char *h2_conf_set_padding(cmd_parms *cmd, void *dirconf, const char *value) - { -- h2_config *cfg = (h2_config *)h2_config_sget(parms->server); -- if (!strcasecmp(value, "On")) { -- cfg->early_hints = 1; -- return NULL; -+ int val; -+ -+ val = (int)apr_atoi64(value); -+ if (val < 0) { -+ return "number of bits must be >= 0"; - } -- else if (!strcasecmp(value, "Off")) { -- cfg->early_hints = 0; -- return NULL; -+ if (val > 8) { -+ return "number of bits must be <= 8"; - } -- -- (void)arg; -- return "value must be On or Off"; -+ CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PADDING_BITS, val); -+ return NULL; - } - -+ - void h2_get_num_workers(server_rec *s, int *minw, int *maxw) - { - int threads_per_child = 0; -- const h2_config *config = h2_config_sget(s); - -- *minw = h2_config_geti(config, H2_CONF_MIN_WORKERS); -- *maxw = h2_config_geti(config, H2_CONF_MAX_WORKERS); -+ *minw = h2_config_sgeti(s, H2_CONF_MIN_WORKERS); -+ *maxw = h2_config_sgeti(s, H2_CONF_MAX_WORKERS); - ap_mpm_query(AP_MPMQ_MAX_THREADS, &threads_per_child); - - if (*minw <= 0) { -@@ -652,7 +952,7 @@ - AP_INIT_TAKE1("H2ModernTLSOnly", h2_conf_set_modern_tls_only, NULL, - RSRC_CONF, "off to not impose RFC 7540 restrictions on TLS"), - AP_INIT_TAKE1("H2Upgrade", h2_conf_set_upgrade, NULL, -- RSRC_CONF, "on to allow HTTP/1 Upgrades to h2/h2c"), -+ RSRC_CONF|OR_AUTHCFG, "on to allow HTTP/1 Upgrades to h2/h2c"), - AP_INIT_TAKE1("H2Direct", h2_conf_set_direct, NULL, - RSRC_CONF, "on to enable direct HTTP/2 mode"), - AP_INIT_TAKE1("H2SessionExtraFiles", h2_conf_set_session_extra_files, NULL, -@@ -662,7 +962,7 @@ - AP_INIT_TAKE1("H2TLSCoolDownSecs", h2_conf_set_tls_cooldown_secs, NULL, - RSRC_CONF, "seconds of idle time on TLS before shrinking writes"), - AP_INIT_TAKE1("H2Push", h2_conf_set_push, NULL, -- RSRC_CONF, "off to disable HTTP/2 server push"), -+ RSRC_CONF|OR_AUTHCFG, "off to disable HTTP/2 server push"), - AP_INIT_TAKE23("H2PushPriority", h2_conf_add_push_priority, NULL, - RSRC_CONF, "define priority of PUSHed resources per content type"), - AP_INIT_TAKE1("H2PushDiarySize", h2_conf_set_push_diary_size, NULL, -@@ -670,33 +970,12 @@ - AP_INIT_TAKE1("H2CopyFiles", h2_conf_set_copy_files, NULL, - OR_FILEINFO, "on to perform copy of file data"), - AP_INIT_TAKE123("H2PushResource", h2_conf_add_push_res, NULL, -- OR_FILEINFO, "add a resource to be pushed in this location/on this server."), -+ OR_FILEINFO|OR_AUTHCFG, "add a resource to be pushed in this location/on this server."), - AP_INIT_TAKE1("H2EarlyHints", h2_conf_set_early_hints, NULL, - RSRC_CONF, "on to enable interim status 103 responses"), -+ AP_INIT_TAKE1("H2Padding", h2_conf_set_padding, NULL, -+ RSRC_CONF, "set payload padding"), - AP_END_CMD - }; - - --const h2_config *h2_config_rget(request_rec *r) --{ -- h2_config *cfg = (h2_config *)ap_get_module_config(r->per_dir_config, -- &http2_module); -- return cfg? cfg : h2_config_sget(r->server); --} -- --const h2_config *h2_config_get(conn_rec *c) --{ -- h2_ctx *ctx = h2_ctx_get(c, 0); -- -- if (ctx) { -- if (ctx->config) { -- return ctx->config; -- } -- else if (ctx->server) { -- ctx->config = h2_config_sget(ctx->server); -- return ctx->config; -- } -- } -- -- return h2_config_sget(c->base_server); --} ---- a/modules/http2/h2_config.h -+++ b/modules/http2/h2_config.h -@@ -42,6 +42,8 @@ - H2_CONF_PUSH_DIARY_SIZE, - H2_CONF_COPY_FILES, - H2_CONF_EARLY_HINTS, -+ H2_CONF_PADDING_BITS, -+ H2_CONF_PADDING_ALWAYS, - } h2_config_var_t; - - struct apr_hash_t; -@@ -53,33 +55,6 @@ - int critical; - } h2_push_res; - --/* Apache httpd module configuration for h2. */ --typedef struct h2_config { -- const char *name; -- int h2_max_streams; /* max concurrent # streams (http2) */ -- int h2_window_size; /* stream window size (http2) */ -- int min_workers; /* min # of worker threads/child */ -- int max_workers; /* max # of worker threads/child */ -- int max_worker_idle_secs; /* max # of idle seconds for worker */ -- int stream_max_mem_size; /* max # bytes held in memory/stream */ -- apr_array_header_t *alt_svcs; /* h2_alt_svc specs for this server */ -- int alt_svc_max_age; /* seconds clients can rely on alt-svc info*/ -- int serialize_headers; /* Use serialized HTTP/1.1 headers for -- processing, better compatibility */ -- int h2_direct; /* if mod_h2 is active directly */ -- int modern_tls_only; /* Accept only modern TLS in HTTP/2 connections */ -- int h2_upgrade; /* Allow HTTP/1 upgrade to h2/h2c */ -- apr_int64_t tls_warmup_size; /* Amount of TLS data to send before going full write size */ -- int tls_cooldown_secs; /* Seconds of idle time before going back to small TLS records */ -- int h2_push; /* if HTTP/2 server push is enabled */ -- struct apr_hash_t *priorities;/* map of content-type to h2_priority records */ -- -- int push_diary_size; /* # of entries in push diary */ -- int copy_files; /* if files shall be copied vs setaside on output */ -- apr_array_header_t *push_list;/* list of h2_push_res configurations */ -- int early_hints; /* support status code 103 */ --} h2_config; -- - - void *h2_config_create_dir(apr_pool_t *pool, char *x); - void *h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv); -@@ -88,19 +63,37 @@ - - extern const command_rec h2_cmds[]; - --const h2_config *h2_config_get(conn_rec *c); --const h2_config *h2_config_sget(server_rec *s); --const h2_config *h2_config_rget(request_rec *r); -+int h2_config_geti(request_rec *r, server_rec *s, h2_config_var_t var); -+apr_int64_t h2_config_geti64(request_rec *r, server_rec *s, h2_config_var_t var); - --int h2_config_geti(const h2_config *conf, h2_config_var_t var); --apr_int64_t h2_config_geti64(const h2_config *conf, h2_config_var_t var); -+/** -+ * Get the configured value for variable <var> at the given connection. -+ */ -+int h2_config_cgeti(conn_rec *c, h2_config_var_t var); -+apr_int64_t h2_config_cgeti64(conn_rec *c, h2_config_var_t var); -+ -+/** -+ * Get the configured value for variable <var> at the given server. -+ */ -+int h2_config_sgeti(server_rec *s, h2_config_var_t var); -+apr_int64_t h2_config_sgeti64(server_rec *s, h2_config_var_t var); -+ -+/** -+ * Get the configured value for variable <var> at the given request, -+ * if configured for the request location. -+ * Fallback to request server config otherwise. -+ */ -+int h2_config_rgeti(request_rec *r, h2_config_var_t var); -+apr_int64_t h2_config_rgeti64(request_rec *r, h2_config_var_t var); - --void h2_get_num_workers(server_rec *s, int *minw, int *maxw); -+apr_array_header_t *h2_config_push_list(request_rec *r); -+apr_array_header_t *h2_config_alt_svcs(request_rec *r); - -+ -+void h2_get_num_workers(server_rec *s, int *minw, int *maxw); - void h2_config_init(apr_pool_t *pool); - --const struct h2_priority *h2_config_get_priority(const h2_config *conf, -- const char *content_type); -+const struct h2_priority *h2_cconfig_get_priority(conn_rec *c, const char *content_type); - - #endif /* __mod_h2__h2_config_h__ */ - ---- a/modules/http2/h2_conn.c -+++ b/modules/http2/h2_conn.c -@@ -18,6 +18,7 @@ - #include <apr_strings.h> - - #include <ap_mpm.h> -+#include <ap_mmn.h> - - #include <httpd.h> - #include <http_core.h> -@@ -79,7 +80,7 @@ - mpm_type = H2_MPM_PREFORK; - mpm_module = m; - /* While http2 can work really well on prefork, it collides -- * today's use case for prefork: runnning single-thread app engines -+ * today's use case for prefork: running single-thread app engines - * like php. If we restrict h2_workers to 1 per process, php will - * work fine, but browser will be limited to 1 active request at a - * time. */ -@@ -109,7 +110,6 @@ - - apr_status_t h2_conn_child_init(apr_pool_t *pool, server_rec *s) - { -- const h2_config *config = h2_config_sget(s); - apr_status_t status = APR_SUCCESS; - int minw, maxw; - int max_threads_per_child = 0; -@@ -129,7 +129,7 @@ - - h2_get_num_workers(s, &minw, &maxw); - -- idle_secs = h2_config_geti(config, H2_CONF_MAX_WORKER_IDLE_SECS); -+ idle_secs = h2_config_sgeti(s, H2_CONF_MAX_WORKER_IDLE_SECS); - ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, - "h2_workers: min=%d max=%d, mthrpchild=%d, idle_secs=%d", - minw, maxw, max_threads_per_child, idle_secs); -@@ -138,7 +138,7 @@ - ap_register_input_filter("H2_IN", h2_filter_core_input, - NULL, AP_FTYPE_CONNECTION); - -- status = h2_mplx_child_init(pool, s); -+ status = h2_mplx_m_child_init(pool, s); - - if (status == APR_SUCCESS) { - status = apr_socket_create(&dummy_socket, APR_INET, SOCK_STREAM, -@@ -172,9 +172,10 @@ - return mpm_module; - } - --apr_status_t h2_conn_setup(h2_ctx *ctx, conn_rec *c, request_rec *r) -+apr_status_t h2_conn_setup(conn_rec *c, request_rec *r, server_rec *s) - { - h2_session *session; -+ h2_ctx *ctx; - apr_status_t status; - - if (!workers) { -@@ -183,24 +184,25 @@ - return APR_EGENERAL; - } - -- if (r) { -- status = h2_session_rcreate(&session, r, ctx, workers); -- } -- else { -- status = h2_session_create(&session, c, ctx, workers); -- } -- -- if (status == APR_SUCCESS) { -+ if (APR_SUCCESS == (status = h2_session_create(&session, c, r, s, workers))) { -+ ctx = h2_ctx_get(c, 1); - h2_ctx_session_set(ctx, session); -+ -+ /* remove the input filter of mod_reqtimeout, now that the connection -+ * is established and we have swtiched to h2. reqtimeout has supervised -+ * possibly configured handshake timeouts and needs to get out of the way -+ * now since the rest of its state handling assumes http/1.x to take place. */ -+ ap_remove_input_filter_byhandle(c->input_filters, "reqtimeout"); - } -+ - return status; - } - --apr_status_t h2_conn_run(struct h2_ctx *ctx, conn_rec *c) -+apr_status_t h2_conn_run(conn_rec *c) - { - apr_status_t status; - int mpm_state = 0; -- h2_session *session = h2_ctx_session_get(ctx); -+ h2_session *session = h2_ctx_get_session(c); - - ap_assert(session); - do { -@@ -235,6 +237,13 @@ - case H2_SESSION_ST_BUSY: - case H2_SESSION_ST_WAIT: - c->cs->state = CONN_STATE_WRITE_COMPLETION; -+ if (c->cs && (session->open_streams || !session->remote.emitted_count)) { -+ /* let the MPM know that we are not done and want -+ * the Timeout behaviour instead of a KeepAliveTimeout -+ * See PR 63534. -+ */ -+ c->cs->sense = CONN_SENSE_WANT_READ; -+ } - break; - case H2_SESSION_ST_CLEANUP: - case H2_SESSION_ST_DONE: -@@ -249,7 +258,7 @@ - - apr_status_t h2_conn_pre_close(struct h2_ctx *ctx, conn_rec *c) - { -- h2_session *session = h2_ctx_session_get(ctx); -+ h2_session *session = h2_ctx_get_session(c); - if (session) { - apr_status_t status = h2_session_pre_close(session, async_mpm); - return (status == APR_SUCCESS)? DONE : status; -@@ -257,7 +266,7 @@ - return DONE; - } - --conn_rec *h2_slave_create(conn_rec *master, int slave_id, apr_pool_t *parent) -+conn_rec *h2_secondary_create(conn_rec *master, int sec_id, apr_pool_t *parent) - { - apr_allocator_t *allocator; - apr_status_t status; -@@ -268,11 +277,11 @@ - - ap_assert(master); - ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, master, -- "h2_stream(%ld-%d): create slave", master->id, slave_id); -+ "h2_stream(%ld-%d): create secondary", master->id, sec_id); - - /* We create a pool with its own allocator to be used for - * processing a request. This is the only way to have the processing -- * independant of its parent pool in the sense that it can work in -+ * independent of its parent pool in the sense that it can work in - * another thread. Also, the new allocator needs its own mutex to - * synchronize sub-pools. - */ -@@ -281,18 +290,18 @@ - status = apr_pool_create_ex(&pool, parent, NULL, allocator); - if (status != APR_SUCCESS) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, status, master, -- APLOGNO(10004) "h2_session(%ld-%d): create slave pool", -- master->id, slave_id); -+ APLOGNO(10004) "h2_session(%ld-%d): create secondary pool", -+ master->id, sec_id); - return NULL; - } - apr_allocator_owner_set(allocator, pool); -- apr_pool_tag(pool, "h2_slave_conn"); -+ apr_pool_tag(pool, "h2_secondary_conn"); - - c = (conn_rec *) apr_palloc(pool, sizeof(conn_rec)); - if (c == NULL) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, master, -- APLOGNO(02913) "h2_session(%ld-%d): create slave", -- master->id, slave_id); -+ APLOGNO(02913) "h2_session(%ld-%d): create secondary", -+ master->id, sec_id); - apr_pool_destroy(pool); - return NULL; - } -@@ -310,26 +319,28 @@ - c->filter_conn_ctx = NULL; - #endif - c->bucket_alloc = apr_bucket_alloc_create(pool); -+#if !AP_MODULE_MAGIC_AT_LEAST(20180720, 1) - c->data_in_input_filters = 0; - c->data_in_output_filters = 0; -+#endif - /* prevent mpm_event from making wrong assumptions about this connection, - * like e.g. using its socket for an async read check. */ - c->clogging_input_filters = 1; - c->log = NULL; - c->log_id = apr_psprintf(pool, "%ld-%d", -- master->id, slave_id); -+ master->id, sec_id); - c->aborted = 0; -- /* We cannot install the master connection socket on the slaves, as -+ /* We cannot install the master connection socket on the secondary, as - * modules mess with timeouts/blocking of the socket, with - * unwanted side effects to the master connection processing. -- * Fortunately, since we never use the slave socket, we can just install -+ * Fortunately, since we never use the secondary socket, we can just install - * a single, process-wide dummy and everyone is happy. - */ - ap_set_module_config(c->conn_config, &core_module, dummy_socket); - /* TODO: these should be unique to this thread */ - c->sbh = master->sbh; -- /* TODO: not all mpm modules have learned about slave connections yet. -- * copy their config from master to slave. -+ /* TODO: not all mpm modules have learned about secondary connections yet. -+ * copy their config from master to secondary. - */ - if ((mpm = h2_conn_mpm_module()) != NULL) { - cfg = ap_get_module_config(master->conn_config, mpm); -@@ -337,38 +348,38 @@ - } - - ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c, -- "h2_slave(%s): created", c->log_id); -+ "h2_secondary(%s): created", c->log_id); - return c; - } - --void h2_slave_destroy(conn_rec *slave) -+void h2_secondary_destroy(conn_rec *secondary) - { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, slave, -- "h2_slave(%s): destroy", slave->log_id); -- slave->sbh = NULL; -- apr_pool_destroy(slave->pool); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, secondary, -+ "h2_secondary(%s): destroy", secondary->log_id); -+ secondary->sbh = NULL; -+ apr_pool_destroy(secondary->pool); - } - --apr_status_t h2_slave_run_pre_connection(conn_rec *slave, apr_socket_t *csd) -+apr_status_t h2_secondary_run_pre_connection(conn_rec *secondary, apr_socket_t *csd) - { -- if (slave->keepalives == 0) { -+ if (secondary->keepalives == 0) { - /* Simulate that we had already a request on this connection. Some - * hooks trigger special behaviour when keepalives is 0. - * (Not necessarily in pre_connection, but later. Set it here, so it - * is in place.) */ -- slave->keepalives = 1; -+ secondary->keepalives = 1; - /* We signal that this connection will be closed after the request. - * Which is true in that sense that we throw away all traffic data -- * on this slave connection after each requests. Although we might -+ * on this secondary connection after each requests. Although we might - * reuse internal structures like memory pools. - * The wanted effect of this is that httpd does not try to clean up - * any dangling data on this connection when a request is done. Which -- * is unneccessary on a h2 stream. -+ * is unnecessary on a h2 stream. - */ -- slave->keepalive = AP_CONN_CLOSE; -- return ap_run_pre_connection(slave, csd); -+ secondary->keepalive = AP_CONN_CLOSE; -+ return ap_run_pre_connection(secondary, csd); - } -- ap_assert(slave->output_filters); -+ ap_assert(secondary->output_filters); - return APR_SUCCESS; - } - ---- a/modules/http2/h2_conn.h -+++ b/modules/http2/h2_conn.h -@@ -23,21 +23,21 @@ - /** - * Setup the connection and our context for HTTP/2 processing - * -- * @param ctx the http2 context to setup - * @param c the connection HTTP/2 is starting on - * @param r the upgrade request that still awaits an answer, optional -+ * @param s the server selected for this connection (can be != c->base_server) - */ --apr_status_t h2_conn_setup(struct h2_ctx *ctx, conn_rec *c, request_rec *r); -+apr_status_t h2_conn_setup(conn_rec *c, request_rec *r, server_rec *s); - - /** - * Run the HTTP/2 connection in synchronous fashion. - * Return when the HTTP/2 session is done - * and the connection will close or a fatal error occurred. - * -- * @param ctx the http2 context to run -+ * @param c the http2 connection to run - * @return APR_SUCCESS when session is done. - */ --apr_status_t h2_conn_run(struct h2_ctx *ctx, conn_rec *c); -+apr_status_t h2_conn_run(conn_rec *c); - - /** - * The connection is about to close. If we have not send a GOAWAY -@@ -68,10 +68,10 @@ - const char *h2_conn_mpm_name(void); - int h2_mpm_supported(void); - --conn_rec *h2_slave_create(conn_rec *master, int slave_id, apr_pool_t *parent); --void h2_slave_destroy(conn_rec *slave); -+conn_rec *h2_secondary_create(conn_rec *master, int sec_id, apr_pool_t *parent); -+void h2_secondary_destroy(conn_rec *secondary); - --apr_status_t h2_slave_run_pre_connection(conn_rec *slave, apr_socket_t *csd); --void h2_slave_run_connection(conn_rec *slave); -+apr_status_t h2_secondary_run_pre_connection(conn_rec *secondary, apr_socket_t *csd); -+void h2_secondary_run_connection(conn_rec *secondary); - - #endif /* defined(__mod_h2__h2_conn__) */ ---- a/modules/http2/h2_conn_io.c -+++ b/modules/http2/h2_conn_io.c -@@ -40,12 +40,17 @@ - * ~= 1300 bytes */ - #define WRITE_SIZE_INITIAL 1300 - --/* Calculated like this: max TLS record size 16*1024 -- * - 40 (IP) - 20 (TCP) - 40 (TCP options) -- * - TLS overhead (60-100) -- * which seems to create less TCP packets overall -+/* The maximum we'd like to write in one chunk is -+ * the max size of a TLS record. When pushing -+ * many frames down the h2 connection, this might -+ * align differently because of headers and other -+ * frames or simply as not sufficient data is -+ * in a response body. -+ * However keeping frames at or below this limit -+ * should make optimizations at the layer that writes -+ * to TLS easier. - */ --#define WRITE_SIZE_MAX (TLS_DATA_MAX - 100) -+#define WRITE_SIZE_MAX (TLS_DATA_MAX) - - - static void h2_conn_io_bb_log(conn_rec *c, int stream_id, int level, -@@ -123,21 +128,20 @@ - - } - --apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, -- const h2_config *cfg) -+apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, server_rec *s) - { - io->c = c; - io->output = apr_brigade_create(c->pool, c->bucket_alloc); - io->is_tls = h2_h2_is_tls(c); - io->buffer_output = io->is_tls; -- io->flush_threshold = (apr_size_t)h2_config_geti64(cfg, H2_CONF_STREAM_MAX_MEM); -+ io->flush_threshold = (apr_size_t)h2_config_sgeti64(s, H2_CONF_STREAM_MAX_MEM); - - if (io->is_tls) { - /* This is what we start with, - * see https://issues.apache.org/jira/browse/TS-2503 - */ -- io->warmup_size = h2_config_geti64(cfg, H2_CONF_TLS_WARMUP_SIZE); -- io->cooldown_usecs = (h2_config_geti(cfg, H2_CONF_TLS_COOLDOWN_SECS) -+ io->warmup_size = h2_config_sgeti64(s, H2_CONF_TLS_WARMUP_SIZE); -+ io->cooldown_usecs = (h2_config_sgeti(s, H2_CONF_TLS_COOLDOWN_SECS) - * APR_USEC_PER_SEC); - io->write_size = (io->cooldown_usecs > 0? - WRITE_SIZE_INITIAL : WRITE_SIZE_MAX); ---- a/modules/http2/h2_conn_io.h -+++ b/modules/http2/h2_conn_io.h -@@ -48,8 +48,7 @@ - apr_size_t slen; - } h2_conn_io; - --apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, -- const struct h2_config *cfg); -+apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, server_rec *s); - - /** - * Append data to the buffered output. ---- a/modules/http2/h2_ctx.c -+++ b/modules/http2/h2_ctx.c -@@ -29,8 +29,8 @@ - { - h2_ctx *ctx = apr_pcalloc(c->pool, sizeof(h2_ctx)); - ap_assert(ctx); -+ h2_ctx_server_update(ctx, c->base_server); - ap_set_module_config(c->conn_config, &http2_module, ctx); -- h2_ctx_server_set(ctx, c->base_server); - return ctx; - } - -@@ -79,8 +79,9 @@ - return ctx; - } - --h2_session *h2_ctx_session_get(h2_ctx *ctx) -+h2_session *h2_ctx_get_session(conn_rec *c) - { -+ h2_ctx *ctx = h2_ctx_get(c, 0); - return ctx? ctx->session : NULL; - } - -@@ -89,33 +90,17 @@ - ctx->session = session; - } - --server_rec *h2_ctx_server_get(h2_ctx *ctx) -+h2_ctx *h2_ctx_server_update(h2_ctx *ctx, server_rec *s) - { -- return ctx? ctx->server : NULL; --} -- --h2_ctx *h2_ctx_server_set(h2_ctx *ctx, server_rec *s) --{ -- ctx->server = s; -+ if (ctx->server != s) { -+ ctx->server = s; -+ } - return ctx; - } - --int h2_ctx_is_task(h2_ctx *ctx) --{ -- return ctx && ctx->task; --} -- --h2_task *h2_ctx_get_task(h2_ctx *ctx) -+h2_task *h2_ctx_get_task(conn_rec *c) - { -+ h2_ctx *ctx = h2_ctx_get(c, 0); - return ctx? ctx->task : NULL; - } - --h2_task *h2_ctx_cget_task(conn_rec *c) --{ -- return h2_ctx_get_task(h2_ctx_get(c, 0)); --} -- --h2_task *h2_ctx_rget_task(request_rec *r) --{ -- return h2_ctx_get_task(h2_ctx_rget(r)); --} ---- a/modules/http2/h2_ctx.h -+++ b/modules/http2/h2_ctx.h -@@ -56,12 +56,11 @@ - */ - h2_ctx *h2_ctx_protocol_set(h2_ctx *ctx, const char *proto); - --/* Set the server_rec relevant for this context. -+/* Update the server_rec relevant for this context. A server for -+ * a connection may change during SNI handling, for example. - */ --h2_ctx *h2_ctx_server_set(h2_ctx *ctx, server_rec *s); --server_rec *h2_ctx_server_get(h2_ctx *ctx); -+h2_ctx *h2_ctx_server_update(h2_ctx *ctx, server_rec *s); - --struct h2_session *h2_ctx_session_get(h2_ctx *ctx); - void h2_ctx_session_set(h2_ctx *ctx, struct h2_session *session); - - /** -@@ -69,10 +68,8 @@ - */ - const char *h2_ctx_protocol_get(const conn_rec *c); - --int h2_ctx_is_task(h2_ctx *ctx); -+struct h2_session *h2_ctx_get_session(conn_rec *c); -+struct h2_task *h2_ctx_get_task(conn_rec *c); - --struct h2_task *h2_ctx_get_task(h2_ctx *ctx); --struct h2_task *h2_ctx_cget_task(conn_rec *c); --struct h2_task *h2_ctx_rget_task(request_rec *r); - - #endif /* defined(__mod_h2__h2_ctx__) */ ---- a/modules/http2/h2_filter.c -+++ b/modules/http2/h2_filter.c -@@ -54,6 +54,7 @@ - const char *data; - ssize_t n; - -+ (void)c; - status = apr_bucket_read(b, &data, &len, block); - - while (status == APR_SUCCESS && len > 0) { -@@ -71,10 +72,10 @@ - } - else { - session->io.bytes_read += n; -- if (len <= n) { -+ if ((apr_ssize_t)len <= n) { - break; - } -- len -= n; -+ len -= (apr_size_t)n; - data += n; - } - } -@@ -277,6 +278,7 @@ - apr_bucket_brigade *dest, - const apr_bucket *src) - { -+ (void)beam; - if (H2_BUCKET_IS_OBSERVER(src)) { - h2_bucket_observer *l = (h2_bucket_observer *)src->data; - apr_bucket *b = h2_bucket_observer_create(dest->bucket_alloc, -@@ -311,8 +313,7 @@ - bbout(bb, " \"settings\": {\n"); - bbout(bb, " \"SETTINGS_MAX_CONCURRENT_STREAMS\": %d,\n", m->max_streams); - bbout(bb, " \"SETTINGS_MAX_FRAME_SIZE\": %d,\n", 16*1024); -- bbout(bb, " \"SETTINGS_INITIAL_WINDOW_SIZE\": %d,\n", -- h2_config_geti(s->config, H2_CONF_WIN_SIZE)); -+ bbout(bb, " \"SETTINGS_INITIAL_WINDOW_SIZE\": %d,\n", h2_config_sgeti(s->s, H2_CONF_WIN_SIZE)); - bbout(bb, " \"SETTINGS_ENABLE_PUSH\": %d\n", h2_session_push_enabled(s)); - bbout(bb, " }%s\n", last? "" : ","); - } -@@ -369,7 +370,7 @@ - x.s = s; - x.idx = 0; - bbout(bb, " \"streams\": {"); -- h2_mplx_stream_do(s->mplx, add_stream, &x); -+ h2_mplx_m_stream_do(s->mplx, add_stream, &x); - bbout(bb, "\n }%s\n", last? "" : ","); - } - -@@ -431,41 +432,38 @@ - - static apr_status_t h2_status_insert(h2_task *task, apr_bucket *b) - { -- conn_rec *c = task->c->master; -- h2_ctx *h2ctx = h2_ctx_get(c, 0); -- h2_session *session; -- h2_stream *stream; -+ h2_mplx *m = task->mplx; -+ h2_stream *stream = h2_mplx_t_stream_get(m, task); -+ h2_session *s; -+ conn_rec *c; -+ - apr_bucket_brigade *bb; - apr_bucket *e; - int32_t connFlowIn, connFlowOut; - -- -- if (!h2ctx || (session = h2_ctx_session_get(h2ctx)) == NULL) { -- return APR_SUCCESS; -- } -- -- stream = h2_session_stream_get(session, task->stream_id); - if (!stream) { - /* stream already done */ - return APR_SUCCESS; - } -+ s = stream->session; -+ c = s->c; - - bb = apr_brigade_create(stream->pool, c->bucket_alloc); - -- connFlowIn = nghttp2_session_get_effective_local_window_size(session->ngh2); -- connFlowOut = nghttp2_session_get_remote_window_size(session->ngh2); -+ connFlowIn = nghttp2_session_get_effective_local_window_size(s->ngh2); -+ connFlowOut = nghttp2_session_get_remote_window_size(s->ngh2); - - bbout(bb, "{\n"); - bbout(bb, " \"version\": \"draft-01\",\n"); -- add_settings(bb, session, 0); -- add_peer_settings(bb, session, 0); -+ add_settings(bb, s, 0); -+ add_peer_settings(bb, s, 0); - bbout(bb, " \"connFlowIn\": %d,\n", connFlowIn); - bbout(bb, " \"connFlowOut\": %d,\n", connFlowOut); -- bbout(bb, " \"sentGoAway\": %d,\n", session->local.shutdown); -+ bbout(bb, " \"sentGoAway\": %d,\n", s->local.shutdown); - -- add_streams(bb, session, 0); -+ add_streams(bb, s, 0); - -- add_stats(bb, session, stream, 1); -+ add_stats(bb, s, stream, 1); - bbout(bb, "}\n"); - - while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) { -@@ -495,9 +493,54 @@ - return APR_SUCCESS; - } - -+static apr_status_t discard_body(request_rec *r, apr_off_t maxlen) -+{ -+ apr_bucket_brigade *bb; -+ int seen_eos; -+ apr_status_t rv; -+ -+ bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); -+ seen_eos = 0; -+ do { -+ apr_bucket *bucket; -+ -+ rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, -+ APR_BLOCK_READ, HUGE_STRING_LEN); -+ -+ if (rv != APR_SUCCESS) { -+ apr_brigade_destroy(bb); -+ return rv; -+ } -+ -+ for (bucket = APR_BRIGADE_FIRST(bb); -+ bucket != APR_BRIGADE_SENTINEL(bb); -+ bucket = APR_BUCKET_NEXT(bucket)) -+ { -+ const char *data; -+ apr_size_t len; -+ -+ if (APR_BUCKET_IS_EOS(bucket)) { -+ seen_eos = 1; -+ break; -+ } -+ if (bucket->length == 0) { -+ continue; -+ } -+ rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); -+ if (rv != APR_SUCCESS) { -+ apr_brigade_destroy(bb); -+ return rv; -+ } -+ maxlen -= bucket->length; -+ } -+ apr_brigade_cleanup(bb); -+ } while (!seen_eos && maxlen >= 0); -+ -+ return APR_SUCCESS; -+} -+ - int h2_filter_h2_status_handler(request_rec *r) - { -- h2_ctx *ctx = h2_ctx_rget(r); - conn_rec *c = r->connection; - h2_task *task; - apr_bucket_brigade *bb; -@@ -511,10 +554,12 @@ - return DECLINED; - } - -- task = ctx? h2_ctx_get_task(ctx) : NULL; -+ task = h2_ctx_get_task(r->connection); - if (task) { -- -- if ((status = ap_discard_request_body(r)) != OK) { -+ /* In this handler, we do some special sauce to send footers back, -+ * IFF we received footers in the request. This is used in our test -+ * cases, since CGI has no way of handling those. */ -+ if ((status = discard_body(r, 1024)) != OK) { - return status; - } - ---- a/modules/http2/h2_from_h1.c -+++ b/modules/http2/h2_from_h1.c -@@ -315,6 +315,7 @@ - int http_status; - apr_array_header_t *hlines; - apr_bucket_brigade *tmp; -+ apr_bucket_brigade *saveto; - } h2_response_parser; - - static apr_status_t parse_header(h2_response_parser *parser, char *line) { -@@ -351,13 +352,17 @@ - parser->tmp = apr_brigade_create(task->pool, task->c->bucket_alloc); - } - status = apr_brigade_split_line(parser->tmp, bb, APR_BLOCK_READ, -- HUGE_STRING_LEN); -+ len); - if (status == APR_SUCCESS) { - --len; - status = apr_brigade_flatten(parser->tmp, line, &len); - if (status == APR_SUCCESS) { - /* we assume a non-0 containing line and remove trailing crlf. */ - line[len] = '\0'; -+ /* -+ * XXX: What to do if there is an LF but no CRLF? -+ * Should we error out? -+ */ - if (len >= 2 && !strcmp(H2_CRLF, line + len - 2)) { - len -= 2; - line[len] = '\0'; -@@ -367,10 +372,47 @@ - task->id, line); - } - else { -+ apr_off_t brigade_length; -+ -+ /* -+ * If the brigade parser->tmp becomes longer than our buffer -+ * for flattening we never have a chance to get a complete -+ * line. This can happen if we are called multiple times after -+ * previous calls did not find a H2_CRLF and we returned -+ * APR_EAGAIN. In this case parser->tmp (correctly) grows -+ * with each call to apr_brigade_split_line. -+ * -+ * XXX: Currently a stack based buffer of HUGE_STRING_LEN is -+ * used. This means we cannot cope with lines larger than -+ * HUGE_STRING_LEN which might be an issue. -+ */ -+ status = apr_brigade_length(parser->tmp, 0, &brigade_length); -+ if ((status != APR_SUCCESS) || (brigade_length > len)) { -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, task->c, APLOGNO(10257) -+ "h2_task(%s): read response, line too long", -+ task->id); -+ return APR_ENOSPC; -+ } - /* this does not look like a complete line yet */ - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, task->c, - "h2_task(%s): read response, incomplete line: %s", - task->id, line); -+ if (!parser->saveto) { -+ parser->saveto = apr_brigade_create(task->pool, -+ task->c->bucket_alloc); -+ } -+ /* -+ * Be on the save side and save the parser->tmp brigade -+ * as it could contain transient buckets which could be -+ * invalid next time we are here. -+ * -+ * NULL for the filter parameter is ok since we -+ * provide our own brigade as second parameter -+ * and ap_save_brigade does not need to create one. -+ */ -+ ap_save_brigade(NULL, &(parser->saveto), &(parser->tmp), -+ parser->tmp->p); -+ APR_BRIGADE_CONCAT(parser->tmp, parser->saveto); - return APR_EAGAIN; - } - } -@@ -594,18 +636,20 @@ - } - } - -- if (r->header_only) { -+ if (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status)) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c, -- "h2_task(%s): header_only, cleanup output brigade", -+ "h2_task(%s): headers only, cleanup output brigade", - task->id); - b = body_bucket? body_bucket : APR_BRIGADE_FIRST(bb); - while (b != APR_BRIGADE_SENTINEL(bb)) { - next = APR_BUCKET_NEXT(b); - if (APR_BUCKET_IS_EOS(b) || AP_BUCKET_IS_EOR(b)) { - break; -- } -- APR_BUCKET_REMOVE(b); -- apr_bucket_destroy(b); -+ } -+ if (!H2_BUCKET_IS_HEADERS(b)) { -+ APR_BUCKET_REMOVE(b); -+ apr_bucket_destroy(b); -+ } - b = next; - } - } ---- a/modules/http2/h2_h2.c -+++ b/modules/http2/h2_h2.c -@@ -463,19 +463,18 @@ - return opt_ssl_is_https && opt_ssl_is_https(c); - } - --int h2_is_acceptable_connection(conn_rec *c, int require_all) -+int h2_is_acceptable_connection(conn_rec *c, request_rec *r, int require_all) - { - int is_tls = h2_h2_is_tls(c); -- const h2_config *cfg = h2_config_get(c); - -- if (is_tls && h2_config_geti(cfg, H2_CONF_MODERN_TLS_ONLY) > 0) { -+ if (is_tls && h2_config_cgeti(c, H2_CONF_MODERN_TLS_ONLY) > 0) { - /* Check TLS connection for modern TLS parameters, as defined in - * RFC 7540 and https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility - */ - apr_pool_t *pool = c->pool; - server_rec *s = c->base_server; - char *val; -- -+ - if (!opt_ssl_var_lookup) { - /* unable to check */ - return 0; -@@ -521,33 +520,29 @@ - return 1; - } - --int h2_allows_h2_direct(conn_rec *c) -+static int h2_allows_h2_direct(conn_rec *c) - { -- const h2_config *cfg = h2_config_get(c); - int is_tls = h2_h2_is_tls(c); - const char *needed_protocol = is_tls? "h2" : "h2c"; -- int h2_direct = h2_config_geti(cfg, H2_CONF_DIRECT); -+ int h2_direct = h2_config_cgeti(c, H2_CONF_DIRECT); - - if (h2_direct < 0) { - h2_direct = is_tls? 0 : 1; - } -- return (h2_direct -- && ap_is_allowed_protocol(c, NULL, NULL, needed_protocol)); -+ return (h2_direct && ap_is_allowed_protocol(c, NULL, NULL, needed_protocol)); - } - --int h2_allows_h2_upgrade(conn_rec *c) -+int h2_allows_h2_upgrade(request_rec *r) - { -- const h2_config *cfg = h2_config_get(c); -- int h2_upgrade = h2_config_geti(cfg, H2_CONF_UPGRADE); -- -- return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(c)); -+ int h2_upgrade = h2_config_rgeti(r, H2_CONF_UPGRADE); -+ return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(r->connection)); - } - - /******************************************************************************* - * Register various hooks - */ - static const char* const mod_ssl[] = { "mod_ssl.c", NULL}; --static const char* const mod_reqtimeout[] = { "mod_reqtimeout.c", NULL}; -+static const char* const mod_reqtimeout[] = { "mod_ssl.c", "mod_reqtimeout.c", NULL}; - - void h2_h2_register_hooks(void) - { -@@ -558,7 +553,7 @@ - * a chance to take over before it. - */ - ap_hook_process_connection(h2_h2_process_conn, -- mod_ssl, mod_reqtimeout, APR_HOOK_LAST); -+ mod_reqtimeout, NULL, APR_HOOK_LAST); - - /* One last chance to properly say goodbye if we have not done so - * already. */ -@@ -581,14 +576,17 @@ - { - apr_status_t status; - h2_ctx *ctx; -+ server_rec *s; - - if (c->master) { - return DECLINED; - } - - ctx = h2_ctx_get(c, 0); -+ s = ctx? ctx->server : c->base_server; -+ - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn"); -- if (h2_ctx_is_task(ctx)) { -+ if (ctx && ctx->task) { - /* our stream pseudo connection */ - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "h2_h2, task, declined"); - return DECLINED; -@@ -601,19 +599,19 @@ - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn, " - "new connection using protocol '%s', direct=%d, " - "tls acceptable=%d", proto, h2_allows_h2_direct(c), -- h2_is_acceptable_connection(c, 1)); -+ h2_is_acceptable_connection(c, NULL, 1)); - } - - if (!strcmp(AP_PROTOCOL_HTTP1, proto) - && h2_allows_h2_direct(c) -- && h2_is_acceptable_connection(c, 1)) { -+ && h2_is_acceptable_connection(c, NULL, 1)) { - /* Fresh connection still is on http/1.1 and H2Direct is enabled. - * Otherwise connection is in a fully acceptable state. - * -> peek at the first 24 incoming bytes - */ - apr_bucket_brigade *temp; -- char *s = NULL; -- apr_size_t slen; -+ char *peek = NULL; -+ apr_size_t peeklen; - - temp = apr_brigade_create(c->pool, c->bucket_alloc); - status = ap_get_brigade(c->input_filters, temp, -@@ -626,8 +624,8 @@ - return DECLINED; - } - -- apr_brigade_pflatten(temp, &s, &slen, c->pool); -- if ((slen >= 24) && !memcmp(H2_MAGIC_TOKEN, s, 24)) { -+ apr_brigade_pflatten(temp, &peek, &peeklen, c->pool); -+ if ((peeklen >= 24) && !memcmp(H2_MAGIC_TOKEN, peek, 24)) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, - "h2_h2, direct mode detected"); - if (!ctx) { -@@ -638,7 +636,7 @@ - else if (APLOGctrace2(c)) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, - "h2_h2, not detected in %d bytes(base64): %s", -- (int)slen, h2_util_base64url_encode(s, slen, c->pool)); -+ (int)peeklen, h2_util_base64url_encode(peek, peeklen, c->pool)); - } - - apr_brigade_destroy(temp); -@@ -647,15 +645,16 @@ - - if (ctx) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "process_conn"); -- if (!h2_ctx_session_get(ctx)) { -- status = h2_conn_setup(ctx, c, NULL); -+ -+ if (!h2_ctx_get_session(c)) { -+ status = h2_conn_setup(c, NULL, s); - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, c, "conn_setup"); - if (status != APR_SUCCESS) { - h2_ctx_clear(c); - return !OK; - } - } -- h2_conn_run(ctx, c); -+ h2_conn_run(c); - return OK; - } - -@@ -667,7 +666,7 @@ - { - h2_ctx *ctx; - -- /* slave connection? */ -+ /* secondary connection? */ - if (c->master) { - return DECLINED; - } -@@ -684,16 +683,17 @@ - - static void check_push(request_rec *r, const char *tag) - { -- const h2_config *conf = h2_config_rget(r); -- if (!r->expecting_100 -- && conf && conf->push_list && conf->push_list->nelts > 0) { -+ apr_array_header_t *push_list = h2_config_push_list(r); -+ -+ if (!r->expecting_100 && push_list && push_list->nelts > 0) { - int i, old_status; - const char *old_line; -+ - ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, - "%s, early announcing %d resources for push", -- tag, conf->push_list->nelts); -- for (i = 0; i < conf->push_list->nelts; ++i) { -- h2_push_res *push = &APR_ARRAY_IDX(conf->push_list, i, h2_push_res); -+ tag, push_list->nelts); -+ for (i = 0; i < push_list->nelts; ++i) { -+ h2_push_res *push = &APR_ARRAY_IDX(push_list, i, h2_push_res); - apr_table_add(r->headers_out, "Link", - apr_psprintf(r->pool, "<%s>; rel=preload%s", - push->uri_ref, push->critical? "; critical" : "")); -@@ -710,10 +710,9 @@ - - static int h2_h2_post_read_req(request_rec *r) - { -- /* slave connection? */ -+ /* secondary connection? */ - if (r->connection->master) { -- h2_ctx *ctx = h2_ctx_rget(r); -- struct h2_task *task = h2_ctx_get_task(ctx); -+ struct h2_task *task = h2_ctx_get_task(r->connection); - /* This hook will get called twice on internal redirects. Take care - * that we manipulate filters only once. */ - if (task && !task->filters_set) { -@@ -730,7 +729,7 @@ - ap_add_output_filter("H2_RESPONSE", task, r, r->connection); - - for (f = r->input_filters; f; f = f->next) { -- if (!strcmp("H2_SLAVE_IN", f->frec->name)) { -+ if (!strcmp("H2_SECONDARY_IN", f->frec->name)) { - f->r = r; - break; - } -@@ -744,17 +743,15 @@ - - static int h2_h2_late_fixups(request_rec *r) - { -- /* slave connection? */ -+ /* secondary connection? */ - if (r->connection->master) { -- h2_ctx *ctx = h2_ctx_rget(r); -- struct h2_task *task = h2_ctx_get_task(ctx); -+ struct h2_task *task = h2_ctx_get_task(r->connection); - if (task) { - /* check if we copy vs. setaside files in this location */ -- task->output.copy_files = h2_config_geti(h2_config_rget(r), -- H2_CONF_COPY_FILES); -+ task->output.copy_files = h2_config_rgeti(r, H2_CONF_COPY_FILES); - if (task->output.copy_files) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c, -- "h2_slave_out(%s): copy_files on", task->id); -+ "h2_secondary_out(%s): copy_files on", task->id); - h2_beam_on_file_beam(task->output.beam, h2_beam_no_files, NULL); - } - check_push(r, "late_fixup"); ---- a/modules/http2/h2_h2.h -+++ b/modules/http2/h2_h2.h -@@ -57,23 +57,15 @@ - * the handshake is still ongoing. - * @return != 0 iff connection requirements are met - */ --int h2_is_acceptable_connection(conn_rec *c, int require_all); -- --/** -- * Check if the "direct" HTTP/2 mode of protocol handling is enabled -- * for the given connection. -- * @param c the connection to check -- * @return != 0 iff direct mode is enabled -- */ --int h2_allows_h2_direct(conn_rec *c); -+int h2_is_acceptable_connection(conn_rec *c, request_rec *r, int require_all); - - /** - * Check if the "Upgrade" HTTP/1.1 mode of protocol switching is enabled -- * for the given connection. -- * @param c the connection to check -+ * for the given request. -+ * @param r the request to check - * @return != 0 iff Upgrade switching is enabled - */ --int h2_allows_h2_upgrade(conn_rec *c); -+int h2_allows_h2_upgrade(request_rec *r); - - - #endif /* defined(__mod_h2__h2_h2__) */ ---- a/modules/http2/h2_headers.c -+++ b/modules/http2/h2_headers.c -@@ -28,6 +28,7 @@ - - #include "h2_private.h" - #include "h2_h2.h" -+#include "h2_config.h" - #include "h2_util.h" - #include "h2_request.h" - #include "h2_headers.h" -@@ -101,8 +102,9 @@ - const apr_bucket *src) - { - if (H2_BUCKET_IS_HEADERS(src)) { -- h2_headers *r = ((h2_bucket_headers *)src->data)->headers; -- apr_bucket *b = h2_bucket_headers_create(dest->bucket_alloc, r); -+ h2_headers *src_headers = ((h2_bucket_headers *)src->data)->headers; -+ apr_bucket *b = h2_bucket_headers_create(dest->bucket_alloc, -+ h2_headers_clone(dest->p, src_headers)); - APR_BRIGADE_INSERT_TAIL(dest, b); - return b; - } -@@ -128,28 +130,41 @@ - { - h2_headers *headers = h2_headers_create(status, header, r->notes, 0, pool); - if (headers->status == HTTP_FORBIDDEN) { -- const char *cause = apr_table_get(r->notes, "ssl-renegotiate-forbidden"); -- if (cause) { -- /* This request triggered a TLS renegotiation that is now allowed -- * in HTTP/2. Tell the client that it should use HTTP/1.1 for this. -- */ -- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, headers->status, r, -- APLOGNO(03061) -- "h2_headers(%ld): renegotiate forbidden, cause: %s", -- (long)r->connection->id, cause); -- headers->status = H2_ERR_HTTP_1_1_REQUIRED; -+ request_rec *r_prev; -+ for (r_prev = r; r_prev != NULL; r_prev = r_prev->prev) { -+ const char *cause = apr_table_get(r_prev->notes, "ssl-renegotiate-forbidden"); -+ if (cause) { -+ /* This request triggered a TLS renegotiation that is not allowed -+ * in HTTP/2. Tell the client that it should use HTTP/1.1 for this. -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, headers->status, r, -+ APLOGNO(03061) -+ "h2_headers(%ld): renegotiate forbidden, cause: %s", -+ (long)r->connection->id, cause); -+ headers->status = H2_ERR_HTTP_1_1_REQUIRED; -+ break; -+ } - } - } - if (is_unsafe(r->server)) { -- apr_table_setn(headers->notes, H2_HDR_CONFORMANCE, -- H2_HDR_CONFORMANCE_UNSAFE); -+ apr_table_setn(headers->notes, H2_HDR_CONFORMANCE, H2_HDR_CONFORMANCE_UNSAFE); -+ } -+ if (h2_config_rgeti(r, H2_CONF_PUSH) == 0 && h2_config_sgeti(r->server, H2_CONF_PUSH) != 0) { -+ apr_table_setn(headers->notes, H2_PUSH_MODE_NOTE, "0"); - } - return headers; - } - - h2_headers *h2_headers_copy(apr_pool_t *pool, h2_headers *h) - { -- return h2_headers_create(h->status, h->headers, h->notes, h->raw_bytes, pool); -+ return h2_headers_create(h->status, apr_table_copy(pool, h->headers), -+ apr_table_copy(pool, h->notes), h->raw_bytes, pool); -+} -+ -+h2_headers *h2_headers_clone(apr_pool_t *pool, h2_headers *h) -+{ -+ return h2_headers_create(h->status, apr_table_clone(pool, h->headers), -+ apr_table_clone(pool, h->notes), h->raw_bytes, pool); - } - - h2_headers *h2_headers_die(apr_status_t type, ---- a/modules/http2/h2_headers.h -+++ b/modules/http2/h2_headers.h -@@ -59,12 +59,18 @@ - apr_table_t *header, apr_pool_t *pool); - - /** -- * Clone the headers into another pool. This will not copy any -+ * Copy the headers into another pool. This will not copy any - * header strings. - */ - h2_headers *h2_headers_copy(apr_pool_t *pool, h2_headers *h); - - /** -+ * Clone the headers into another pool. This will also clone any -+ * header strings. -+ */ -+h2_headers *h2_headers_clone(apr_pool_t *pool, h2_headers *h); -+ -+/** - * Create the headers for the given error. - * @param stream_id id of the stream to create the headers for - * @param type the error code ---- a/modules/http2/h2_mplx.c -+++ b/modules/http2/h2_mplx.c -@@ -40,7 +40,6 @@ - #include "h2_ctx.h" - #include "h2_h2.h" - #include "h2_mplx.h" --#include "h2_ngn_shed.h" - #include "h2_request.h" - #include "h2_stream.h" - #include "h2_session.h" -@@ -54,9 +53,21 @@ - h2_mplx *m; - h2_stream *stream; - apr_time_t now; -+ apr_size_t count; - } stream_iter_ctx; - --apr_status_t h2_mplx_child_init(apr_pool_t *pool, server_rec *s) -+/** -+ * Naming convention for static functions: -+ * - m_*: function only called from the master connection -+ * - s_*: function only called from a secondary connection -+ * - t_*: function only called from a h2_task holder -+ * - mst_*: function called from everyone -+ */ -+ -+static apr_status_t s_mplx_be_happy(h2_mplx *m, h2_task *task); -+static apr_status_t m_be_annoyed(h2_mplx *m); -+ -+apr_status_t h2_mplx_m_child_init(apr_pool_t *pool, server_rec *s) - { - return APR_SUCCESS; - } -@@ -72,46 +83,40 @@ - #define H2_MPLX_ENTER_ALWAYS(m) \ - apr_thread_mutex_lock(m->lock) - --#define H2_MPLX_ENTER_MAYBE(m, lock) \ -- if (lock) apr_thread_mutex_lock(m->lock) -+#define H2_MPLX_ENTER_MAYBE(m, dolock) \ -+ if (dolock) apr_thread_mutex_lock(m->lock) - --#define H2_MPLX_LEAVE_MAYBE(m, lock) \ -- if (lock) apr_thread_mutex_unlock(m->lock) -+#define H2_MPLX_LEAVE_MAYBE(m, dolock) \ -+ if (dolock) apr_thread_mutex_unlock(m->lock) - --static void check_data_for(h2_mplx *m, h2_stream *stream, int lock); -+static void mst_check_data_for(h2_mplx *m, h2_stream *stream, int mplx_is_locked); - --static void stream_output_consumed(void *ctx, -- h2_bucket_beam *beam, apr_off_t length) -+static void mst_stream_output_consumed(void *ctx, h2_bucket_beam *beam, apr_off_t length) - { -- h2_stream *stream = ctx; -- h2_task *task = stream->task; -- -- if (length > 0 && task && task->assigned) { -- h2_req_engine_out_consumed(task->assigned, task->c, length); -- } - } - --static void stream_input_ev(void *ctx, h2_bucket_beam *beam) -+static void mst_stream_input_ev(void *ctx, h2_bucket_beam *beam) - { - h2_stream *stream = ctx; - h2_mplx *m = stream->session->mplx; - apr_atomic_set32(&m->event_pending, 1); - } - --static void stream_input_consumed(void *ctx, h2_bucket_beam *beam, apr_off_t length) -+static void m_stream_input_consumed(void *ctx, h2_bucket_beam *beam, apr_off_t length) - { - h2_stream_in_consumed(ctx, length); - } - --static void stream_joined(h2_mplx *m, h2_stream *stream) -+static void ms_stream_joined(h2_mplx *m, h2_stream *stream) - { -- ap_assert(!stream->task || stream->task->worker_done); -+ ap_assert(!h2_task_has_started(stream->task) || stream->task->worker_done); - -+ h2_ififo_remove(m->readyq, stream->id); - h2_ihash_remove(m->shold, stream->id); - h2_ihash_add(m->spurge, stream); - } - --static void stream_cleanup(h2_mplx *m, h2_stream *stream) -+static void m_stream_cleanup(h2_mplx *m, h2_stream *stream) - { - ap_assert(stream->state == H2_SS_CLEANUP); - -@@ -128,15 +133,16 @@ - - h2_ihash_remove(m->streams, stream->id); - h2_iq_remove(m->q, stream->id); -- h2_ififo_remove(m->readyq, stream->id); -- h2_ihash_add(m->shold, stream); - -- if (!stream->task || stream->task->worker_done) { -- stream_joined(m, stream); -+ if (!h2_task_has_started(stream->task) || stream->task->done_done) { -+ ms_stream_joined(m, stream); - } -- else if (stream->task) { -- stream->task->c->aborted = 1; -- apr_thread_cond_broadcast(m->task_thawed); -+ else { -+ h2_ififo_remove(m->readyq, stream->id); -+ h2_ihash_add(m->shold, stream); -+ if (stream->task) { -+ stream->task->c->aborted = 1; -+ } - } - } - -@@ -151,29 +157,23 @@ - * their HTTP/1 cousins, the separate allocator seems to work better - * than protecting a shared h2_session one with an own lock. - */ --h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *parent, -- const h2_config *conf, -- h2_workers *workers) -+h2_mplx *h2_mplx_m_create(conn_rec *c, server_rec *s, apr_pool_t *parent, -+ h2_workers *workers) - { - apr_status_t status = APR_SUCCESS; - apr_allocator_t *allocator; - apr_thread_mutex_t *mutex; - h2_mplx *m; -- h2_ctx *ctx = h2_ctx_get(c, 0); -- ap_assert(conf); - - m = apr_pcalloc(parent, sizeof(h2_mplx)); - if (m) { - m->id = c->id; - m->c = c; -- m->s = (ctx? h2_ctx_server_get(ctx) : NULL); -- if (!m->s) { -- m->s = c->base_server; -- } -+ m->s = s; - - /* We create a pool with its own allocator to be used for -- * processing slave connections. This is the only way to have the -- * processing independant of its parent pool in the sense that it -+ * processing secondary connections. This is the only way to have the -+ * processing independent of its parent pool in the sense that it - * can work in another thread. Also, the new allocator needs its own - * mutex to synchronize sub-pools. - */ -@@ -204,17 +204,10 @@ - return NULL; - } - -- status = apr_thread_cond_create(&m->task_thawed, m->pool); -- if (status != APR_SUCCESS) { -- apr_pool_destroy(m->pool); -- return NULL; -- } -- -- m->max_streams = h2_config_geti(conf, H2_CONF_MAX_STREAMS); -- m->stream_max_mem = h2_config_geti(conf, H2_CONF_STREAM_MAX_MEM); -+ m->max_streams = h2_config_sgeti(s, H2_CONF_MAX_STREAMS); -+ m->stream_max_mem = h2_config_sgeti(s, H2_CONF_STREAM_MAX_MEM); - - m->streams = h2_ihash_create(m->pool, offsetof(h2_stream,id)); -- m->sredo = h2_ihash_create(m->pool, offsetof(h2_stream,id)); - m->shold = h2_ihash_create(m->pool, offsetof(h2_stream,id)); - m->spurge = h2_ihash_create(m->pool, offsetof(h2_stream,id)); - m->q = h2_iq_create(m->pool, m->max_streams); -@@ -228,19 +221,15 @@ - m->workers = workers; - m->max_active = workers->max_workers; - m->limit_active = 6; /* the original h1 max parallel connections */ -- m->last_limit_change = m->last_idle_block = apr_time_now(); -- m->limit_change_interval = apr_time_from_msec(100); -- -- m->spare_slaves = apr_array_make(m->pool, 10, sizeof(conn_rec*)); -+ m->last_mood_change = apr_time_now(); -+ m->mood_update_interval = apr_time_from_msec(100); - -- m->ngn_shed = h2_ngn_shed_create(m->pool, m->c, m->max_streams, -- m->stream_max_mem); -- h2_ngn_shed_set_ctx(m->ngn_shed , m); -+ m->spare_secondary = apr_array_make(m->pool, 10, sizeof(conn_rec*)); - } - return m; - } - --int h2_mplx_shutdown(h2_mplx *m) -+int h2_mplx_m_shutdown(h2_mplx *m) - { - int max_stream_started = 0; - -@@ -254,7 +243,7 @@ - return max_stream_started; - } - --static int input_consumed_signal(h2_mplx *m, h2_stream *stream) -+static int m_input_consumed_signal(h2_mplx *m, h2_stream *stream) - { - if (stream->input) { - return h2_beam_report_consumption(stream->input); -@@ -262,12 +251,12 @@ - return 0; - } - --static int report_consumption_iter(void *ctx, void *val) -+static int m_report_consumption_iter(void *ctx, void *val) - { - h2_stream *stream = val; - h2_mplx *m = ctx; - -- input_consumed_signal(m, stream); -+ m_input_consumed_signal(m, stream); - if (stream->state == H2_SS_CLOSED_L - && (!stream->task || stream->task->worker_done)) { - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, -@@ -278,7 +267,7 @@ - return 1; - } - --static int output_consumed_signal(h2_mplx *m, h2_task *task) -+static int s_output_consumed_signal(h2_mplx *m, h2_task *task) - { - if (task->output.beam) { - return h2_beam_report_consumption(task->output.beam); -@@ -286,7 +275,7 @@ - return 0; - } - --static int stream_destroy_iter(void *ctx, void *val) -+static int m_stream_destroy_iter(void *ctx, void *val) - { - h2_mplx *m = ctx; - h2_stream *stream = val; -@@ -296,7 +285,7 @@ - - if (stream->input) { - /* Process outstanding events before destruction */ -- input_consumed_signal(m, stream); -+ m_input_consumed_signal(m, stream); - h2_beam_log(stream->input, m->c, APLOG_TRACE2, "stream_destroy"); - h2_beam_destroy(stream->input); - stream->input = NULL; -@@ -304,12 +293,12 @@ - - if (stream->task) { - h2_task *task = stream->task; -- conn_rec *slave; -- int reuse_slave = 0; -+ conn_rec *secondary; -+ int reuse_secondary = 0; - - stream->task = NULL; -- slave = task->c; -- if (slave) { -+ secondary = task->c; -+ if (secondary) { - /* On non-serialized requests, the IO logging has not accounted for any - * meta data send over the network: response headers and h2 frame headers. we - * counted this on the stream and need to add this now. -@@ -318,26 +307,25 @@ - if (task->request && !task->request->serialize && h2_task_logio_add_bytes_out) { - apr_off_t unaccounted = stream->out_frame_octets - stream->out_data_octets; - if (unaccounted > 0) { -- h2_task_logio_add_bytes_out(slave, unaccounted); -+ h2_task_logio_add_bytes_out(secondary, unaccounted); - } - } - -- if (m->s->keep_alive_max == 0 || slave->keepalives < m->s->keep_alive_max) { -- reuse_slave = ((m->spare_slaves->nelts < (m->limit_active * 3 / 2)) -- && !task->rst_error); -+ if (m->s->keep_alive_max == 0 || secondary->keepalives < m->s->keep_alive_max) { -+ reuse_secondary = ((m->spare_secondary->nelts < (m->limit_active * 3 / 2)) -+ && !task->rst_error); - } - -- task->c = NULL; -- if (reuse_slave) { -+ if (reuse_secondary) { - h2_beam_log(task->output.beam, m->c, APLOG_DEBUG, -- APLOGNO(03385) "h2_task_destroy, reuse slave"); -+ APLOGNO(03385) "h2_task_destroy, reuse secondary"); - h2_task_destroy(task); -- APR_ARRAY_PUSH(m->spare_slaves, conn_rec*) = slave; -+ APR_ARRAY_PUSH(m->spare_secondary, conn_rec*) = secondary; - } - else { - h2_beam_log(task->output.beam, m->c, APLOG_TRACE1, -- "h2_task_destroy, destroy slave"); -- h2_slave_destroy(slave); -+ "h2_task_destroy, destroy secondary"); -+ h2_secondary_destroy(secondary); - } - } - } -@@ -345,11 +333,11 @@ - return 0; - } - --static void purge_streams(h2_mplx *m, int lock) -+static void m_purge_streams(h2_mplx *m, int lock) - { - if (!h2_ihash_empty(m->spurge)) { - H2_MPLX_ENTER_MAYBE(m, lock); -- while (!h2_ihash_iter(m->spurge, stream_destroy_iter, m)) { -+ while (!h2_ihash_iter(m->spurge, m_stream_destroy_iter, m)) { - /* repeat until empty */ - } - H2_MPLX_LEAVE_MAYBE(m, lock); -@@ -361,13 +349,13 @@ - void *ctx; - } stream_iter_ctx_t; - --static int stream_iter_wrap(void *ctx, void *stream) -+static int m_stream_iter_wrap(void *ctx, void *stream) - { - stream_iter_ctx_t *x = ctx; - return x->cb(stream, x->ctx); - } - --apr_status_t h2_mplx_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx) -+apr_status_t h2_mplx_m_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx) - { - stream_iter_ctx_t x; - -@@ -375,13 +363,13 @@ - - x.cb = cb; - x.ctx = ctx; -- h2_ihash_iter(m->streams, stream_iter_wrap, &x); -+ h2_ihash_iter(m->streams, m_stream_iter_wrap, &x); - - H2_MPLX_LEAVE(m); - return APR_SUCCESS; - } - --static int report_stream_iter(void *ctx, void *val) { -+static int m_report_stream_iter(void *ctx, void *val) { - h2_mplx *m = ctx; - h2_stream *stream = val; - h2_task *task = stream->task; -@@ -394,10 +382,10 @@ - if (task) { - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, /* NO APLOGNO */ - H2_STRM_MSG(stream, "->03198: %s %s %s" -- "[started=%d/done=%d/frozen=%d]"), -+ "[started=%d/done=%d]"), - task->request->method, task->request->authority, - task->request->path, task->worker_started, -- task->worker_done, task->frozen); -+ task->worker_done); - } - else { - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, /* NO APLOGNO */ -@@ -406,7 +394,7 @@ - return 1; - } - --static int unexpected_stream_iter(void *ctx, void *val) { -+static int m_unexpected_stream_iter(void *ctx, void *val) { - h2_mplx *m = ctx; - h2_stream *stream = val; - ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, /* NO APLOGNO */ -@@ -415,7 +403,7 @@ - return 1; - } - --static int stream_cancel_iter(void *ctx, void *val) { -+static int m_stream_cancel_iter(void *ctx, void *val) { - h2_mplx *m = ctx; - h2_stream *stream = val; - -@@ -429,14 +417,14 @@ - h2_stream_rst(stream, H2_ERR_NO_ERROR); - /* All connection data has been sent, simulate cleanup */ - h2_stream_dispatch(stream, H2_SEV_EOS_SENT); -- stream_cleanup(m, stream); -+ m_stream_cleanup(m, stream); - return 0; - } - --void h2_mplx_release_and_join(h2_mplx *m, apr_thread_cond_t *wait) -+void h2_mplx_m_release_and_join(h2_mplx *m, apr_thread_cond_t *wait) - { - apr_status_t status; -- int i, wait_secs = 60; -+ int i, wait_secs = 60, old_aborted; - - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, - "h2_mplx(%ld): start release", m->id); -@@ -447,15 +435,23 @@ - - H2_MPLX_ENTER_ALWAYS(m); - -+ /* While really terminating any secondary connections, treat the master -+ * connection as aborted. It's not as if we could send any more data -+ * at this point. */ -+ old_aborted = m->c->aborted; -+ m->c->aborted = 1; -+ - /* How to shut down a h2 connection: - * 1. cancel all streams still active */ -- while (!h2_ihash_iter(m->streams, stream_cancel_iter, m)) { -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, -+ "h2_mplx(%ld): release, %d/%d/%d streams (total/hold/purge), %d active tasks", -+ m->id, (int)h2_ihash_count(m->streams), -+ (int)h2_ihash_count(m->shold), (int)h2_ihash_count(m->spurge), m->tasks_active); -+ while (!h2_ihash_iter(m->streams, m_stream_cancel_iter, m)) { - /* until empty */ - } - -- /* 2. terminate ngn_shed, no more streams -- * should be scheduled or in the active set */ -- h2_ngn_shed_abort(m->ngn_shed); -+ /* 2. no more streams should be scheduled or in the active set */ - ap_assert(h2_ihash_empty(m->streams)); - ap_assert(h2_iq_empty(m->q)); - -@@ -473,65 +469,60 @@ - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, APLOGNO(03198) - "h2_mplx(%ld): waited %d sec for %d tasks", - m->id, i*wait_secs, (int)h2_ihash_count(m->shold)); -- h2_ihash_iter(m->shold, report_stream_iter, m); -+ h2_ihash_iter(m->shold, m_report_stream_iter, m); - } - } -- ap_assert(m->tasks_active == 0); - m->join_wait = NULL; -- -- /* 4. close the h2_req_enginge shed */ -- h2_ngn_shed_destroy(m->ngn_shed); -- m->ngn_shed = NULL; -- -+ - /* 4. With all workers done, all streams should be in spurge */ -+ ap_assert(m->tasks_active == 0); - if (!h2_ihash_empty(m->shold)) { - ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, APLOGNO(03516) - "h2_mplx(%ld): unexpected %d streams in hold", - m->id, (int)h2_ihash_count(m->shold)); -- h2_ihash_iter(m->shold, unexpected_stream_iter, m); -+ h2_ihash_iter(m->shold, m_unexpected_stream_iter, m); - } - -+ m->c->aborted = old_aborted; - H2_MPLX_LEAVE(m); - -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, -- "h2_mplx(%ld): released", m->id); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, "h2_mplx(%ld): released", m->id); - } - --apr_status_t h2_mplx_stream_cleanup(h2_mplx *m, h2_stream *stream) -+apr_status_t h2_mplx_m_stream_cleanup(h2_mplx *m, h2_stream *stream) - { - H2_MPLX_ENTER(m); - - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, - H2_STRM_MSG(stream, "cleanup")); -- stream_cleanup(m, stream); -+ m_stream_cleanup(m, stream); - - H2_MPLX_LEAVE(m); - return APR_SUCCESS; - } - --h2_stream *h2_mplx_stream_get(h2_mplx *m, int id) -+h2_stream *h2_mplx_t_stream_get(h2_mplx *m, h2_task *task) - { - h2_stream *s = NULL; - - H2_MPLX_ENTER_ALWAYS(m); - -- s = h2_ihash_get(m->streams, id); -+ s = h2_ihash_get(m->streams, task->stream_id); - - H2_MPLX_LEAVE(m); - return s; - } - --static void output_produced(void *ctx, h2_bucket_beam *beam, apr_off_t bytes) -+static void mst_output_produced(void *ctx, h2_bucket_beam *beam, apr_off_t bytes) - { - h2_stream *stream = ctx; - h2_mplx *m = stream->session->mplx; - -- check_data_for(m, stream, 1); -+ mst_check_data_for(m, stream, 0); - } - --static apr_status_t out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam) -+static apr_status_t t_out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam) - { -- apr_status_t status = APR_SUCCESS; - h2_stream *stream = h2_ihash_get(m->streams, stream_id); - - if (!stream || !stream->task || m->aborted) { -@@ -542,26 +533,26 @@ - stream->output = beam; - - if (APLOGctrace2(m->c)) { -- h2_beam_log(beam, m->c, APLOG_TRACE2, "out_open"); -+ h2_beam_log(beam, stream->task->c, APLOG_TRACE2, "out_open"); - } - else { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, m->c, -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->task->c, - "h2_mplx(%s): out open", stream->task->id); - } - -- h2_beam_on_consumed(stream->output, NULL, stream_output_consumed, stream); -- h2_beam_on_produced(stream->output, output_produced, stream); -+ h2_beam_on_consumed(stream->output, NULL, mst_stream_output_consumed, stream); -+ h2_beam_on_produced(stream->output, mst_output_produced, stream); - if (stream->task->output.copy_files) { - h2_beam_on_file_beam(stream->output, h2_beam_no_files, NULL); - } - - /* we might see some file buckets in the output, see - * if we have enough handles reserved. */ -- check_data_for(m, stream, 0); -- return status; -+ mst_check_data_for(m, stream, 1); -+ return APR_SUCCESS; - } - --apr_status_t h2_mplx_out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam) -+apr_status_t h2_mplx_t_out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam) - { - apr_status_t status; - -@@ -571,14 +562,14 @@ - status = APR_ECONNABORTED; - } - else { -- status = out_open(m, stream_id, beam); -+ status = t_out_open(m, stream_id, beam); - } - - H2_MPLX_LEAVE(m); - return status; - } - --static apr_status_t out_close(h2_mplx *m, h2_task *task) -+static apr_status_t s_out_close(h2_mplx *m, h2_task *task) - { - apr_status_t status = APR_SUCCESS; - h2_stream *stream; -@@ -595,17 +586,17 @@ - return APR_ECONNABORTED; - } - -- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, m->c, -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, task->c, - "h2_mplx(%s): close", task->id); - status = h2_beam_close(task->output.beam); -- h2_beam_log(task->output.beam, m->c, APLOG_TRACE2, "out_close"); -- output_consumed_signal(m, task); -- check_data_for(m, stream, 0); -+ h2_beam_log(task->output.beam, task->c, APLOG_TRACE2, "out_close"); -+ s_output_consumed_signal(m, task); -+ mst_check_data_for(m, stream, 1); - return status; - } - --apr_status_t h2_mplx_out_trywait(h2_mplx *m, apr_interval_time_t timeout, -- apr_thread_cond_t *iowait) -+apr_status_t h2_mplx_m_out_trywait(h2_mplx *m, apr_interval_time_t timeout, -+ apr_thread_cond_t *iowait) - { - apr_status_t status; - -@@ -614,12 +605,12 @@ - if (m->aborted) { - status = APR_ECONNABORTED; - } -- else if (h2_mplx_has_master_events(m)) { -+ else if (h2_mplx_m_has_master_events(m)) { - status = APR_SUCCESS; - } - else { -- purge_streams(m, 0); -- h2_ihash_iter(m->streams, report_consumption_iter, m); -+ m_purge_streams(m, 0); -+ h2_ihash_iter(m->streams, m_report_consumption_iter, m); - m->added_output = iowait; - status = apr_thread_cond_timedwait(m->added_output, m->lock, timeout); - if (APLOGctrace2(m->c)) { -@@ -634,19 +625,27 @@ - return status; - } - --static void check_data_for(h2_mplx *m, h2_stream *stream, int lock) -+static void mst_check_data_for(h2_mplx *m, h2_stream *stream, int mplx_is_locked) - { -+ /* If m->lock is already held, we must release during h2_ififo_push() -+ * which can wait on its not_full condition, causing a deadlock because -+ * no one would then be able to acquire m->lock to empty the fifo. -+ */ -+ H2_MPLX_LEAVE_MAYBE(m, mplx_is_locked); - if (h2_ififo_push(m->readyq, stream->id) == APR_SUCCESS) { -+ H2_MPLX_ENTER_ALWAYS(m); - apr_atomic_set32(&m->event_pending, 1); -- H2_MPLX_ENTER_MAYBE(m, lock); - if (m->added_output) { - apr_thread_cond_signal(m->added_output); - } -- H2_MPLX_LEAVE_MAYBE(m, lock); -+ H2_MPLX_LEAVE_MAYBE(m, !mplx_is_locked); -+ } -+ else { -+ H2_MPLX_ENTER_MAYBE(m, mplx_is_locked); - } - } - --apr_status_t h2_mplx_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx) -+apr_status_t h2_mplx_m_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx) - { - apr_status_t status; - -@@ -666,22 +665,22 @@ - return status; - } - --static void register_if_needed(h2_mplx *m) -+static void ms_register_if_needed(h2_mplx *m, int from_master) - { - if (!m->aborted && !m->is_registered && !h2_iq_empty(m->q)) { - apr_status_t status = h2_workers_register(m->workers, m); - if (status == APR_SUCCESS) { - m->is_registered = 1; - } -- else { -+ else if (from_master) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, status, m->c, APLOGNO(10021) - "h2_mplx(%ld): register at workers", m->id); - } - } - } - --apr_status_t h2_mplx_process(h2_mplx *m, struct h2_stream *stream, -- h2_stream_pri_cmp *cmp, void *ctx) -+apr_status_t h2_mplx_m_process(h2_mplx *m, struct h2_stream *stream, -+ h2_stream_pri_cmp *cmp, void *ctx) - { - apr_status_t status; - -@@ -695,13 +694,13 @@ - h2_ihash_add(m->streams, stream); - if (h2_stream_is_ready(stream)) { - /* already have a response */ -- check_data_for(m, stream, 0); -+ mst_check_data_for(m, stream, 1); - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, - H2_STRM_MSG(stream, "process, add to readyq")); - } - else { - h2_iq_add(m->q, stream->id, cmp, ctx); -- register_if_needed(m); -+ ms_register_if_needed(m, 1); - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, - H2_STRM_MSG(stream, "process, added to q")); - } -@@ -711,7 +710,7 @@ - return status; - } - --static h2_task *next_stream_task(h2_mplx *m) -+static h2_task *s_next_stream_task(h2_mplx *m) - { - h2_stream *stream; - int sid; -@@ -720,40 +719,39 @@ - - stream = h2_ihash_get(m->streams, sid); - if (stream) { -- conn_rec *slave, **pslave; -+ conn_rec *secondary, **psecondary; - -- pslave = (conn_rec **)apr_array_pop(m->spare_slaves); -- if (pslave) { -- slave = *pslave; -- slave->aborted = 0; -+ psecondary = (conn_rec **)apr_array_pop(m->spare_secondary); -+ if (psecondary) { -+ secondary = *psecondary; -+ secondary->aborted = 0; - } - else { -- slave = h2_slave_create(m->c, stream->id, m->pool); -+ secondary = h2_secondary_create(m->c, stream->id, m->pool); - } - - if (!stream->task) { -- - if (sid > m->max_stream_started) { - m->max_stream_started = sid; - } - if (stream->input) { -- h2_beam_on_consumed(stream->input, stream_input_ev, -- stream_input_consumed, stream); -+ h2_beam_on_consumed(stream->input, mst_stream_input_ev, -+ m_stream_input_consumed, stream); - } - -- stream->task = h2_task_create(slave, stream->id, -+ stream->task = h2_task_create(secondary, stream->id, - stream->request, m, stream->input, - stream->session->s->timeout, - m->stream_max_mem); - if (!stream->task) { -- ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, slave, -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, secondary, - H2_STRM_LOG(APLOGNO(02941), stream, - "create task")); - return NULL; - } -- - } - -+ stream->task->started_at = apr_time_now(); - ++m->tasks_active; - return stream->task; - } -@@ -761,7 +759,7 @@ - return NULL; - } - --apr_status_t h2_mplx_pop_task(h2_mplx *m, h2_task **ptask) -+apr_status_t h2_mplx_s_pop_task(h2_mplx *m, h2_task **ptask) - { - apr_status_t rv = APR_EOF; - -@@ -777,7 +775,7 @@ - rv = APR_EOF; - } - else { -- *ptask = next_stream_task(m); -+ *ptask = s_next_stream_task(m); - rv = (*ptask != NULL && !h2_iq_empty(m->q))? APR_EAGAIN : APR_SUCCESS; - } - if (APR_EAGAIN != rv) { -@@ -787,127 +785,87 @@ - return rv; - } - --static void task_done(h2_mplx *m, h2_task *task, h2_req_engine *ngn) -+static void s_task_done(h2_mplx *m, h2_task *task) - { - h2_stream *stream; - -- if (task->frozen) { -- /* this task was handed over to an engine for processing -- * and the original worker has finished. That means the -- * engine may start processing now. */ -- h2_task_thaw(task); -- apr_thread_cond_broadcast(m->task_thawed); -- return; -- } -- -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c, - "h2_mplx(%ld): task(%s) done", m->id, task->id); -- out_close(m, task); -- -- if (ngn) { -- apr_off_t bytes = 0; -- h2_beam_send(task->output.beam, NULL, APR_NONBLOCK_READ); -- bytes += h2_beam_get_buffered(task->output.beam); -- if (bytes > 0) { -- /* we need to report consumed and current buffered output -- * to the engine. The request will be streamed out or cancelled, -- * no more data is coming from it and the engine should update -- * its calculations before we destroy this information. */ -- h2_req_engine_out_consumed(ngn, task->c, bytes); -- } -- } -- -- if (task->engine) { -- if (!m->aborted && !task->c->aborted -- && !h2_req_engine_is_shutdown(task->engine)) { -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, APLOGNO(10022) -- "h2_mplx(%ld): task(%s) has not-shutdown " -- "engine(%s)", m->id, task->id, -- h2_req_engine_get_id(task->engine)); -- } -- h2_ngn_shed_done_ngn(m->ngn_shed, task->engine); -- } -+ s_out_close(m, task); - - task->worker_done = 1; - task->done_at = apr_time_now(); -- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, task->c, - "h2_mplx(%s): request done, %f ms elapsed", task->id, - (task->done_at - task->started_at) / 1000.0); - -- if (task->started_at > m->last_idle_block) { -- /* this task finished without causing an 'idle block', e.g. -- * a block by flow control. -- */ -- if (task->done_at- m->last_limit_change >= m->limit_change_interval -- && m->limit_active < m->max_active) { -- /* Well behaving stream, allow it more workers */ -- m->limit_active = H2MIN(m->limit_active * 2, -- m->max_active); -- m->last_limit_change = task->done_at; -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, -- "h2_mplx(%ld): increase worker limit to %d", -- m->id, m->limit_active); -- } -+ if (task->c && !task->c->aborted && task->started_at > m->last_mood_change) { -+ s_mplx_be_happy(m, task); - } - -+ ap_assert(task->done_done == 0); -+ - stream = h2_ihash_get(m->streams, task->stream_id); - if (stream) { - /* stream not done yet. */ -- if (!m->aborted && h2_ihash_get(m->sredo, stream->id)) { -+ if (!m->aborted && task->redo) { - /* reset and schedule again */ - h2_task_redo(task); -- h2_ihash_remove(m->sredo, stream->id); - h2_iq_add(m->q, stream->id, NULL, NULL); -+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, task->c, -+ H2_STRM_MSG(stream, "redo, added to q")); - } - else { - /* stream not cleaned up, stay around */ -- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, -+ task->done_done = 1; -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, task->c, - H2_STRM_MSG(stream, "task_done, stream open")); - if (stream->input) { - h2_beam_leave(stream->input); - } - - /* more data will not arrive, resume the stream */ -- check_data_for(m, stream, 0); -+ mst_check_data_for(m, stream, 1); - } - } - else if ((stream = h2_ihash_get(m->shold, task->stream_id)) != NULL) { - /* stream is done, was just waiting for this. */ -- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, -+ task->done_done = 1; -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, task->c, - H2_STRM_MSG(stream, "task_done, in hold")); - if (stream->input) { - h2_beam_leave(stream->input); - } -- stream_joined(m, stream); -+ ms_stream_joined(m, stream); - } - else if ((stream = h2_ihash_get(m->spurge, task->stream_id)) != NULL) { -- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, -+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, task->c, - H2_STRM_LOG(APLOGNO(03517), stream, "already in spurge")); - ap_assert("stream should not be in spurge" == NULL); - } - else { -- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, APLOGNO(03518) -+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, task->c, APLOGNO(03518) - "h2_mplx(%s): task_done, stream not found", - task->id); - ap_assert("stream should still be available" == NULL); - } - } - --void h2_mplx_task_done(h2_mplx *m, h2_task *task, h2_task **ptask) -+void h2_mplx_s_task_done(h2_mplx *m, h2_task *task, h2_task **ptask) - { - H2_MPLX_ENTER_ALWAYS(m); - -- task_done(m, task, NULL); - --m->tasks_active; -+ s_task_done(m, task); - - if (m->join_wait) { - apr_thread_cond_signal(m->join_wait); - } - if (ptask) { - /* caller wants another task */ -- *ptask = next_stream_task(m); -+ *ptask = s_next_stream_task(m); - } -- register_if_needed(m); -+ ms_register_if_needed(m, 0); - - H2_MPLX_LEAVE(m); - } -@@ -916,94 +874,161 @@ - * h2_mplx DoS protection - ******************************************************************************/ - --static int latest_repeatable_unsubmitted_iter(void *data, void *val) -+static int m_timed_out_busy_iter(void *data, void *val) - { - stream_iter_ctx *ctx = data; - h2_stream *stream = val; -- -- if (stream->task && !stream->task->worker_done -- && h2_task_can_redo(stream->task) -- && !h2_ihash_get(ctx->m->sredo, stream->id)) { -- if (!h2_stream_is_ready(stream)) { -- /* this task occupies a worker, the response has not been submitted -- * yet, not been cancelled and it is a repeatable request -- * -> it can be re-scheduled later */ -- if (!ctx->stream -- || (ctx->stream->task->started_at < stream->task->started_at)) { -- /* we did not have one or this one was started later */ -- ctx->stream = stream; -- } -- } -+ if (h2_task_has_started(stream->task) && !stream->task->worker_done -+ && (ctx->now - stream->task->started_at) > stream->task->timeout) { -+ /* timed out stream occupying a worker, found */ -+ ctx->stream = stream; -+ return 0; - } - return 1; - } - --static h2_stream *get_latest_repeatable_unsubmitted_stream(h2_mplx *m) -+static h2_stream *m_get_timed_out_busy_stream(h2_mplx *m) - { - stream_iter_ctx ctx; - ctx.m = m; - ctx.stream = NULL; -- h2_ihash_iter(m->streams, latest_repeatable_unsubmitted_iter, &ctx); -+ ctx.now = apr_time_now(); -+ h2_ihash_iter(m->streams, m_timed_out_busy_iter, &ctx); - return ctx.stream; - } - --static int timed_out_busy_iter(void *data, void *val) -+static int m_latest_repeatable_unsubmitted_iter(void *data, void *val) - { - stream_iter_ctx *ctx = data; - h2_stream *stream = val; -- if (stream->task && !stream->task->worker_done -- && (ctx->now - stream->task->started_at) > stream->task->timeout) { -- /* timed out stream occupying a worker, found */ -- ctx->stream = stream; -- return 0; -+ -+ if (!stream->task) goto leave; -+ if (!h2_task_has_started(stream->task) || stream->task->worker_done) goto leave; -+ if (h2_stream_is_ready(stream)) goto leave; -+ if (stream->task->redo) { -+ ++ctx->count; -+ goto leave; -+ } -+ if (h2_task_can_redo(stream->task)) { -+ /* this task occupies a worker, the response has not been submitted -+ * yet, not been cancelled and it is a repeatable request -+ * -> we could redo it later */ -+ if (!ctx->stream -+ || (ctx->stream->task->started_at < stream->task->started_at)) { -+ /* we did not have one or this one was started later */ -+ ctx->stream = stream; -+ } - } -+leave: - return 1; - } - --static h2_stream *get_timed_out_busy_stream(h2_mplx *m) -+static apr_status_t m_assess_task_to_throttle(h2_task **ptask, h2_mplx *m) - { - stream_iter_ctx ctx; -+ -+ /* count the running tasks already marked for redo and get one that could -+ * be throttled */ -+ *ptask = NULL; - ctx.m = m; - ctx.stream = NULL; -- ctx.now = apr_time_now(); -- h2_ihash_iter(m->streams, timed_out_busy_iter, &ctx); -- return ctx.stream; -+ ctx.count = 0; -+ h2_ihash_iter(m->streams, m_latest_repeatable_unsubmitted_iter, &ctx); -+ if (m->tasks_active - ctx.count > m->limit_active) { -+ /* we are above the limit of running tasks, accounting for the ones -+ * already throttled. */ -+ if (ctx.stream && ctx.stream->task) { -+ *ptask = ctx.stream->task; -+ return APR_EAGAIN; -+ } -+ /* above limit, be seeing no candidate for easy throttling */ -+ if (m_get_timed_out_busy_stream(m)) { -+ /* Too many busy workers, unable to cancel enough streams -+ * and with a busy, timed out stream, we tell the client -+ * to go away... */ -+ return APR_TIMEUP; -+ } -+ } -+ return APR_SUCCESS; - } - --static apr_status_t unschedule_slow_tasks(h2_mplx *m) -+static apr_status_t m_unschedule_slow_tasks(h2_mplx *m) - { -- h2_stream *stream; -- int n; -+ h2_task *task; -+ apr_status_t rv; - - /* Try to get rid of streams that occupy workers. Look for safe requests - * that are repeatable. If none found, fail the connection. - */ -- n = (m->tasks_active - m->limit_active - (int)h2_ihash_count(m->sredo)); -- while (n > 0 && (stream = get_latest_repeatable_unsubmitted_stream(m))) { -+ while (APR_EAGAIN == (rv = m_assess_task_to_throttle(&task, m))) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, - "h2_mplx(%s): unschedule, resetting task for redo later", -- stream->task->id); -- h2_task_rst(stream->task, H2_ERR_CANCEL); -- h2_ihash_add(m->sredo, stream); -- --n; -+ task->id); -+ task->redo = 1; -+ h2_task_rst(task, H2_ERR_CANCEL); - } - -- if ((m->tasks_active - h2_ihash_count(m->sredo)) > m->limit_active) { -- h2_stream *stream = get_timed_out_busy_stream(m); -- if (stream) { -- /* Too many busy workers, unable to cancel enough streams -- * and with a busy, timed out stream, we tell the client -- * to go away... */ -- return APR_TIMEUP; -- } -+ return rv; -+} -+ -+static apr_status_t s_mplx_be_happy(h2_mplx *m, h2_task *task) -+{ -+ apr_time_t now; -+ -+ --m->irritations_since; -+ now = apr_time_now(); -+ if (m->limit_active < m->max_active -+ && (now - m->last_mood_change >= m->mood_update_interval -+ || m->irritations_since < -m->limit_active)) { -+ m->limit_active = H2MIN(m->limit_active * 2, m->max_active); -+ m->last_mood_change = now; -+ m->irritations_since = 0; -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c, -+ "h2_mplx(%ld): mood update, increasing worker limit to %d", -+ m->id, m->limit_active); - } - return APR_SUCCESS; - } - --apr_status_t h2_mplx_idle(h2_mplx *m) -+static apr_status_t m_be_annoyed(h2_mplx *m) - { - apr_status_t status = APR_SUCCESS; - apr_time_t now; -+ -+ ++m->irritations_since; -+ now = apr_time_now(); -+ if (m->limit_active > 2 && -+ ((now - m->last_mood_change >= m->mood_update_interval) -+ || (m->irritations_since >= m->limit_active))) { -+ -+ if (m->limit_active > 16) { -+ m->limit_active = 16; -+ } -+ else if (m->limit_active > 8) { -+ m->limit_active = 8; -+ } -+ else if (m->limit_active > 4) { -+ m->limit_active = 4; -+ } -+ else if (m->limit_active > 2) { -+ m->limit_active = 2; -+ } -+ m->last_mood_change = now; -+ m->irritations_since = 0; -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, -+ "h2_mplx(%ld): mood update, decreasing worker limit to %d", -+ m->id, m->limit_active); -+ } -+ -+ if (m->tasks_active > m->limit_active) { -+ status = m_unschedule_slow_tasks(m); -+ } -+ return status; -+} -+ -+apr_status_t h2_mplx_m_idle(h2_mplx *m) -+{ -+ apr_status_t status = APR_SUCCESS; - apr_size_t scount; - - H2_MPLX_ENTER(m); -@@ -1023,31 +1048,7 @@ - * of busy workers we allow for this connection until it - * well behaves. - */ -- now = apr_time_now(); -- m->last_idle_block = now; -- if (m->limit_active > 2 -- && now - m->last_limit_change >= m->limit_change_interval) { -- if (m->limit_active > 16) { -- m->limit_active = 16; -- } -- else if (m->limit_active > 8) { -- m->limit_active = 8; -- } -- else if (m->limit_active > 4) { -- m->limit_active = 4; -- } -- else if (m->limit_active > 2) { -- m->limit_active = 2; -- } -- m->last_limit_change = now; -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, -- "h2_mplx(%ld): decrease worker limit to %d", -- m->id, m->limit_active); -- } -- -- if (m->tasks_active > m->limit_active) { -- status = unschedule_slow_tasks(m); -- } -+ status = m_be_annoyed(m); - } - else if (!h2_iq_empty(m->q)) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, -@@ -1077,167 +1078,30 @@ - h2_beam_is_closed(stream->output), - (long)h2_beam_get_buffered(stream->output)); - h2_ihash_add(m->streams, stream); -- check_data_for(m, stream, 0); -+ mst_check_data_for(m, stream, 1); - stream->out_checked = 1; - status = APR_EAGAIN; - } - } - } - } -- register_if_needed(m); -+ ms_register_if_needed(m, 1); - - H2_MPLX_LEAVE(m); - return status; - } - - /******************************************************************************* -- * HTTP/2 request engines -- ******************************************************************************/ -- --typedef struct { -- h2_mplx * m; -- h2_req_engine *ngn; -- int streams_updated; --} ngn_update_ctx; -- --static int ngn_update_window(void *ctx, void *val) --{ -- ngn_update_ctx *uctx = ctx; -- h2_stream *stream = val; -- if (stream->task && stream->task->assigned == uctx->ngn -- && output_consumed_signal(uctx->m, stream->task)) { -- ++uctx->streams_updated; -- } -- return 1; --} -- --static apr_status_t ngn_out_update_windows(h2_mplx *m, h2_req_engine *ngn) --{ -- ngn_update_ctx ctx; -- -- ctx.m = m; -- ctx.ngn = ngn; -- ctx.streams_updated = 0; -- h2_ihash_iter(m->streams, ngn_update_window, &ctx); -- -- return ctx.streams_updated? APR_SUCCESS : APR_EAGAIN; --} -- --apr_status_t h2_mplx_req_engine_push(const char *ngn_type, -- request_rec *r, -- http2_req_engine_init *einit) --{ -- apr_status_t status; -- h2_mplx *m; -- h2_task *task; -- h2_stream *stream; -- -- task = h2_ctx_rget_task(r); -- if (!task) { -- return APR_ECONNABORTED; -- } -- m = task->mplx; -- -- H2_MPLX_ENTER(m); -- -- stream = h2_ihash_get(m->streams, task->stream_id); -- if (stream) { -- status = h2_ngn_shed_push_request(m->ngn_shed, ngn_type, r, einit); -- } -- else { -- status = APR_ECONNABORTED; -- } -- -- H2_MPLX_LEAVE(m); -- return status; --} -- --apr_status_t h2_mplx_req_engine_pull(h2_req_engine *ngn, -- apr_read_type_e block, -- int capacity, -- request_rec **pr) --{ -- h2_ngn_shed *shed = h2_ngn_shed_get_shed(ngn); -- h2_mplx *m = h2_ngn_shed_get_ctx(shed); -- apr_status_t status; -- int want_shutdown; -- -- H2_MPLX_ENTER(m); -- -- want_shutdown = (block == APR_BLOCK_READ); -- -- /* Take this opportunity to update output consummation -- * for this engine */ -- ngn_out_update_windows(m, ngn); -- -- if (want_shutdown && !h2_iq_empty(m->q)) { -- /* For a blocking read, check first if requests are to be -- * had and, if not, wait a short while before doing the -- * blocking, and if unsuccessful, terminating read. -- */ -- status = h2_ngn_shed_pull_request(shed, ngn, capacity, 1, pr); -- if (APR_STATUS_IS_EAGAIN(status)) { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, -- "h2_mplx(%ld): start block engine pull", m->id); -- apr_thread_cond_timedwait(m->task_thawed, m->lock, -- apr_time_from_msec(20)); -- status = h2_ngn_shed_pull_request(shed, ngn, capacity, 1, pr); -- } -- } -- else { -- status = h2_ngn_shed_pull_request(shed, ngn, capacity, -- want_shutdown, pr); -- } -- -- H2_MPLX_LEAVE(m); -- return status; --} -- --void h2_mplx_req_engine_done(h2_req_engine *ngn, conn_rec *r_conn, -- apr_status_t status) --{ -- h2_task *task = h2_ctx_cget_task(r_conn); -- -- if (task) { -- h2_mplx *m = task->mplx; -- h2_stream *stream; -- -- H2_MPLX_ENTER_ALWAYS(m); -- -- stream = h2_ihash_get(m->streams, task->stream_id); -- -- ngn_out_update_windows(m, ngn); -- h2_ngn_shed_done_task(m->ngn_shed, ngn, task); -- -- if (status != APR_SUCCESS && stream -- && h2_task_can_redo(task) -- && !h2_ihash_get(m->sredo, stream->id)) { -- h2_ihash_add(m->sredo, stream); -- } -- -- if (task->engine) { -- /* cannot report that as done until engine returns */ -- } -- else { -- task_done(m, task, ngn); -- } -- -- H2_MPLX_LEAVE(m); -- } --} -- --/******************************************************************************* - * mplx master events dispatching - ******************************************************************************/ - --int h2_mplx_has_master_events(h2_mplx *m) -+int h2_mplx_m_has_master_events(h2_mplx *m) - { - return apr_atomic_read32(&m->event_pending) > 0; - } - --apr_status_t h2_mplx_dispatch_master_events(h2_mplx *m, -- stream_ev_callback *on_resume, -- void *on_ctx) -+apr_status_t h2_mplx_m_dispatch_master_events(h2_mplx *m, stream_ev_callback *on_resume, -+ void *on_ctx) - { - h2_stream *stream; - int n, id; -@@ -1247,8 +1111,8 @@ - apr_atomic_set32(&m->event_pending, 0); - - /* update input windows for streams */ -- h2_ihash_iter(m->streams, report_consumption_iter, m); -- purge_streams(m, 1); -+ h2_ihash_iter(m->streams, m_report_consumption_iter, m); -+ m_purge_streams(m, 1); - - n = h2_ififo_count(m->readyq); - while (n > 0 -@@ -1263,13 +1127,13 @@ - return APR_SUCCESS; - } - --apr_status_t h2_mplx_keep_active(h2_mplx *m, h2_stream *stream) -+apr_status_t h2_mplx_m_keep_active(h2_mplx *m, h2_stream *stream) - { -- check_data_for(m, stream, 1); -+ mst_check_data_for(m, stream, 0); - return APR_SUCCESS; - } - --int h2_mplx_awaits_data(h2_mplx *m) -+int h2_mplx_m_awaits_data(h2_mplx *m) - { - int waiting = 1; - -@@ -1278,11 +1142,24 @@ - if (h2_ihash_empty(m->streams)) { - waiting = 0; - } -- else if (!m->tasks_active && !h2_ififo_count(m->readyq) -- && h2_iq_empty(m->q)) { -+ else if (!m->tasks_active && !h2_ififo_count(m->readyq) && h2_iq_empty(m->q)) { - waiting = 0; - } - - H2_MPLX_LEAVE(m); - return waiting; - } -+ -+apr_status_t h2_mplx_m_client_rst(h2_mplx *m, int stream_id) -+{ -+ h2_stream *stream; -+ apr_status_t status = APR_SUCCESS; -+ -+ H2_MPLX_ENTER_ALWAYS(m); -+ stream = h2_ihash_get(m->streams, stream_id); -+ if (stream && stream->task) { -+ status = m_be_annoyed(m); -+ } -+ H2_MPLX_LEAVE(m); -+ return status; -+} ---- a/modules/http2/h2_mplx.h -+++ b/modules/http2/h2_mplx.h -@@ -31,8 +31,10 @@ - * queued in the multiplexer. If a task thread tries to write more - * data, it is blocked until space becomes available. - * -- * Writing input is never blocked. In order to use flow control on the input, -- * the mplx can be polled for input data consumption. -+ * Naming Convention: -+ * "h2_mplx_m_" are methods only to be called by the main connection -+ * "h2_mplx_s_" are method only to be called by a secondary connection -+ * "h2_mplx_t_" are method only to be called by a task handler (can be master or secondary) - */ - - struct apr_pool_t; -@@ -47,8 +49,6 @@ - struct apr_thread_cond_t; - struct h2_workers; - struct h2_iqueue; --struct h2_ngn_shed; --struct h2_req_engine; - - #include <apr_queue.h> - -@@ -65,7 +65,6 @@ - unsigned int is_registered; /* is registered at h2_workers */ - - struct h2_ihash_t *streams; /* all streams currently processing */ -- struct h2_ihash_t *sredo; /* all streams that need to be re-started */ - struct h2_ihash_t *shold; /* all streams done with task ongoing */ - struct h2_ihash_t *spurge; /* all streams done, ready for destroy */ - -@@ -79,41 +78,35 @@ - int tasks_active; /* # of tasks being processed from this mplx */ - int limit_active; /* current limit on active tasks, dynamic */ - int max_active; /* max, hard limit # of active tasks in a process */ -- apr_time_t last_idle_block; /* last time, this mplx entered IDLE while -- * streams were ready */ -- apr_time_t last_limit_change; /* last time, worker limit changed */ -- apr_interval_time_t limit_change_interval; -+ -+ apr_time_t last_mood_change; /* last time, we worker limit changed */ -+ apr_interval_time_t mood_update_interval; /* how frequent we update at most */ -+ int irritations_since; /* irritations (>0) or happy events (<0) since last mood change */ - - apr_thread_mutex_t *lock; - struct apr_thread_cond_t *added_output; -- struct apr_thread_cond_t *task_thawed; - struct apr_thread_cond_t *join_wait; - - apr_size_t stream_max_mem; - - apr_pool_t *spare_io_pool; -- apr_array_header_t *spare_slaves; /* spare slave connections */ -+ apr_array_header_t *spare_secondary; /* spare secondary connections */ - - struct h2_workers *workers; -- -- struct h2_ngn_shed *ngn_shed; - }; - -- -- - /******************************************************************************* -- * Object lifecycle and information. -+ * From the main connection processing: h2_mplx_m_* - ******************************************************************************/ - --apr_status_t h2_mplx_child_init(apr_pool_t *pool, server_rec *s); -+apr_status_t h2_mplx_m_child_init(apr_pool_t *pool, server_rec *s); - - /** - * Create the multiplexer for the given HTTP2 session. - * Implicitly has reference count 1. - */ --h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *master, -- const struct h2_config *conf, -- struct h2_workers *workers); -+h2_mplx *h2_mplx_m_create(conn_rec *c, server_rec *s, apr_pool_t *master, -+ struct h2_workers *workers); - - /** - * Decreases the reference counter of this mplx and waits for it -@@ -123,26 +116,14 @@ - * @param m the mplx to be released and destroyed - * @param wait condition var to wait on for ref counter == 0 - */ --void h2_mplx_release_and_join(h2_mplx *m, struct apr_thread_cond_t *wait); -- --apr_status_t h2_mplx_pop_task(h2_mplx *m, struct h2_task **ptask); -- --void h2_mplx_task_done(h2_mplx *m, struct h2_task *task, struct h2_task **ptask); -+void h2_mplx_m_release_and_join(h2_mplx *m, struct apr_thread_cond_t *wait); - - /** - * Shut down the multiplexer gracefully. Will no longer schedule new streams - * but let the ongoing ones finish normally. - * @return the highest stream id being/been processed - */ --int h2_mplx_shutdown(h2_mplx *m); -- --int h2_mplx_is_busy(h2_mplx *m); -- --/******************************************************************************* -- * IO lifetime of streams. -- ******************************************************************************/ -- --struct h2_stream *h2_mplx_stream_get(h2_mplx *m, int id); -+int h2_mplx_m_shutdown(h2_mplx *m); - - /** - * Notifies mplx that a stream has been completely handled on the main -@@ -151,20 +132,16 @@ - * @param m the mplx itself - * @param stream the stream ready for cleanup - */ --apr_status_t h2_mplx_stream_cleanup(h2_mplx *m, struct h2_stream *stream); -+apr_status_t h2_mplx_m_stream_cleanup(h2_mplx *m, struct h2_stream *stream); - - /** - * Waits on output data from any stream in this session to become available. - * Returns APR_TIMEUP if no data arrived in the given time. - */ --apr_status_t h2_mplx_out_trywait(h2_mplx *m, apr_interval_time_t timeout, -- struct apr_thread_cond_t *iowait); -+apr_status_t h2_mplx_m_out_trywait(h2_mplx *m, apr_interval_time_t timeout, -+ struct apr_thread_cond_t *iowait); - --apr_status_t h2_mplx_keep_active(h2_mplx *m, struct h2_stream *stream); -- --/******************************************************************************* -- * Stream processing. -- ******************************************************************************/ -+apr_status_t h2_mplx_m_keep_active(h2_mplx *m, struct h2_stream *stream); - - /** - * Process a stream request. -@@ -175,8 +152,8 @@ - * @param cmp the stream priority compare function - * @param ctx context data for the compare function - */ --apr_status_t h2_mplx_process(h2_mplx *m, struct h2_stream *stream, -- h2_stream_pri_cmp *cmp, void *ctx); -+apr_status_t h2_mplx_m_process(h2_mplx *m, struct h2_stream *stream, -+ h2_stream_pri_cmp *cmp, void *ctx); - - /** - * Stream priorities have changed, reschedule pending requests. -@@ -185,7 +162,7 @@ - * @param cmp the stream priority compare function - * @param ctx context data for the compare function - */ --apr_status_t h2_mplx_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx); -+apr_status_t h2_mplx_m_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx); - - typedef apr_status_t stream_ev_callback(void *ctx, struct h2_stream *stream); - -@@ -193,7 +170,7 @@ - * Check if the multiplexer has events for the master connection pending. - * @return != 0 iff there are events pending - */ --int h2_mplx_has_master_events(h2_mplx *m); -+int h2_mplx_m_has_master_events(h2_mplx *m); - - /** - * Dispatch events for the master connection, such as -@@ -201,130 +178,46 @@ - * @param on_resume new output data has arrived for a suspended stream - * @param ctx user supplied argument to invocation. - */ --apr_status_t h2_mplx_dispatch_master_events(h2_mplx *m, -- stream_ev_callback *on_resume, -- void *ctx); -+apr_status_t h2_mplx_m_dispatch_master_events(h2_mplx *m, stream_ev_callback *on_resume, -+ void *ctx); - --int h2_mplx_awaits_data(h2_mplx *m); -+int h2_mplx_m_awaits_data(h2_mplx *m); - - typedef int h2_mplx_stream_cb(struct h2_stream *s, void *ctx); - --apr_status_t h2_mplx_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx); -+apr_status_t h2_mplx_m_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx); - --/******************************************************************************* -- * Output handling of streams. -- ******************************************************************************/ -+apr_status_t h2_mplx_m_client_rst(h2_mplx *m, int stream_id); - - /** -- * Opens the output for the given stream with the specified response. -+ * Master connection has entered idle mode. -+ * @param m the mplx instance of the master connection -+ * @return != SUCCESS iff connection should be terminated - */ --apr_status_t h2_mplx_out_open(h2_mplx *mplx, int stream_id, -- struct h2_bucket_beam *beam); -+apr_status_t h2_mplx_m_idle(h2_mplx *m); - - /******************************************************************************* -- * h2_mplx list Manipulation. -+ * From a secondary connection processing: h2_mplx_s_* - ******************************************************************************/ -- --/** -- * The magic pointer value that indicates the head of a h2_mplx list -- * @param b The mplx list -- * @return The magic pointer value -- */ --#define H2_MPLX_LIST_SENTINEL(b) APR_RING_SENTINEL((b), h2_mplx, link) -- --/** -- * Determine if the mplx list is empty -- * @param b The list to check -- * @return true or false -- */ --#define H2_MPLX_LIST_EMPTY(b) APR_RING_EMPTY((b), h2_mplx, link) -- --/** -- * Return the first mplx in a list -- * @param b The list to query -- * @return The first mplx in the list -- */ --#define H2_MPLX_LIST_FIRST(b) APR_RING_FIRST(b) -- --/** -- * Return the last mplx in a list -- * @param b The list to query -- * @return The last mplx int he list -- */ --#define H2_MPLX_LIST_LAST(b) APR_RING_LAST(b) -- --/** -- * Insert a single mplx at the front of a list -- * @param b The list to add to -- * @param e The mplx to insert -- */ --#define H2_MPLX_LIST_INSERT_HEAD(b, e) do { \ --h2_mplx *ap__b = (e); \ --APR_RING_INSERT_HEAD((b), ap__b, h2_mplx, link); \ --} while (0) -- --/** -- * Insert a single mplx at the end of a list -- * @param b The list to add to -- * @param e The mplx to insert -- */ --#define H2_MPLX_LIST_INSERT_TAIL(b, e) do { \ --h2_mplx *ap__b = (e); \ --APR_RING_INSERT_TAIL((b), ap__b, h2_mplx, link); \ --} while (0) -- --/** -- * Get the next mplx in the list -- * @param e The current mplx -- * @return The next mplx -- */ --#define H2_MPLX_NEXT(e) APR_RING_NEXT((e), link) --/** -- * Get the previous mplx in the list -- * @param e The current mplx -- * @return The previous mplx -- */ --#define H2_MPLX_PREV(e) APR_RING_PREV((e), link) -- --/** -- * Remove a mplx from its list -- * @param e The mplx to remove -- */ --#define H2_MPLX_REMOVE(e) APR_RING_REMOVE((e), link) -+apr_status_t h2_mplx_s_pop_task(h2_mplx *m, struct h2_task **ptask); -+void h2_mplx_s_task_done(h2_mplx *m, struct h2_task *task, struct h2_task **ptask); - - /******************************************************************************* -- * h2_mplx DoS protection -+ * From a h2_task owner: h2_mplx_s_* -+ * (a task is transfered from master to secondary connection and back in -+ * its normal lifetime). - ******************************************************************************/ - - /** -- * Master connection has entered idle mode. -- * @param m the mplx instance of the master connection -- * @return != SUCCESS iff connection should be terminated -+ * Opens the output for the given stream with the specified response. - */ --apr_status_t h2_mplx_idle(h2_mplx *m); -+apr_status_t h2_mplx_t_out_open(h2_mplx *mplx, int stream_id, -+ struct h2_bucket_beam *beam); - --/******************************************************************************* -- * h2_req_engine handling -- ******************************************************************************/ -+/** -+ * Get the stream that belongs to the given task. -+ */ -+struct h2_stream *h2_mplx_t_stream_get(h2_mplx *m, struct h2_task *task); - --typedef void h2_output_consumed(void *ctx, conn_rec *c, apr_off_t consumed); --typedef apr_status_t h2_mplx_req_engine_init(struct h2_req_engine *engine, -- const char *id, -- const char *type, -- apr_pool_t *pool, -- apr_size_t req_buffer_size, -- request_rec *r, -- h2_output_consumed **pconsumed, -- void **pbaton); -- --apr_status_t h2_mplx_req_engine_push(const char *ngn_type, -- request_rec *r, -- h2_mplx_req_engine_init *einit); --apr_status_t h2_mplx_req_engine_pull(struct h2_req_engine *ngn, -- apr_read_type_e block, -- int capacity, -- request_rec **pr); --void h2_mplx_req_engine_done(struct h2_req_engine *ngn, conn_rec *r_conn, -- apr_status_t status); - - #endif /* defined(__mod_h2__h2_mplx__) */ ---- a/modules/http2/h2_proxy_session.c -+++ b/modules/http2/h2_proxy_session.c -@@ -45,6 +45,7 @@ - unsigned int suspended : 1; - unsigned int waiting_on_100 : 1; - unsigned int waiting_on_ping : 1; -+ unsigned int headers_ended : 1; - uint32_t error_code; - - apr_bucket_brigade *input; -@@ -61,7 +62,123 @@ - static void ping_arrived(h2_proxy_session *session); - static apr_status_t check_suspended(h2_proxy_session *session); - static void stream_resume(h2_proxy_stream *stream); -+static apr_status_t submit_trailers(h2_proxy_stream *stream); - -+/* -+ * The H2_PING connection sub-state: a state independant of the H2_SESSION state -+ * of the connection: -+ * - H2_PING_ST_NONE: no interference with request handling, ProxyTimeout in effect. -+ * When entered, all suspended streams are unsuspended again. -+ * - H2_PING_ST_AWAIT_ANY: new requests are suspended, a possibly configured "ping" -+ * timeout is in effect. Any frame received transits to H2_PING_ST_NONE. -+ * - H2_PING_ST_AWAIT_PING: same as above, but only a PING frame transits -+ * to H2_PING_ST_NONE. -+ * -+ * An AWAIT state is entered on a new connection or when re-using a connection and -+ * the last frame received has been some time ago. The latter sends a PING frame -+ * and insists on an answer, the former is satisfied by any frame received from the -+ * backend. -+ * -+ * This works for new connections as there is always at least one SETTINGS frame -+ * that the backend sends. When re-using connection, we send a PING and insist on -+ * receiving one back, as there might be frames in our connection buffers from -+ * some time ago. Since some servers have protections against PING flooding, we -+ * only ever have one PING unanswered. -+ * -+ * Requests are suspended while in a PING state, as we do not want to send data -+ * before we can be reasonably sure that the connection is working (at least on -+ * the h2 protocol level). This also means that the session can do blocking reads -+ * when expecting PING answers. -+ */ -+static void set_ping_timeout(h2_proxy_session *session) -+{ -+ if (session->ping_timeout != -1 && session->save_timeout == -1) { -+ apr_socket_t *socket = NULL; -+ -+ socket = ap_get_conn_socket(session->c); -+ if (socket) { -+ apr_socket_timeout_get(socket, &session->save_timeout); -+ apr_socket_timeout_set(socket, session->ping_timeout); -+ } -+ } -+} -+ -+static void unset_ping_timeout(h2_proxy_session *session) -+{ -+ if (session->save_timeout != -1) { -+ apr_socket_t *socket = NULL; -+ -+ socket = ap_get_conn_socket(session->c); -+ if (socket) { -+ apr_socket_timeout_set(socket, session->save_timeout); -+ session->save_timeout = -1; -+ } -+ } -+} -+ -+static void enter_ping_state(h2_proxy_session *session, h2_ping_state_t state) -+{ -+ if (session->ping_state == state) return; -+ switch (session->ping_state) { -+ case H2_PING_ST_NONE: -+ /* leaving NONE, enforce timeout, send frame maybe */ -+ if (H2_PING_ST_AWAIT_PING == state) { -+ unset_ping_timeout(session); -+ nghttp2_submit_ping(session->ngh2, 0, (const uint8_t *)"nevergonnagiveyouup"); -+ } -+ set_ping_timeout(session); -+ session->ping_state = state; -+ break; -+ default: -+ /* no switching between the != NONE states */ -+ if (H2_PING_ST_NONE == state) { -+ session->ping_state = state; -+ unset_ping_timeout(session); -+ ping_arrived(session); -+ } -+ break; -+ } -+} -+ -+static void ping_new_session(h2_proxy_session *session, proxy_conn_rec *p_conn) -+{ -+ session->save_timeout = -1; -+ session->ping_timeout = (p_conn->worker->s->ping_timeout_set? -+ p_conn->worker->s->ping_timeout : -1); -+ session->ping_state = H2_PING_ST_NONE; -+ enter_ping_state(session, H2_PING_ST_AWAIT_ANY); -+} -+ -+static void ping_reuse_session(h2_proxy_session *session) -+{ -+ if (H2_PING_ST_NONE == session->ping_state) { -+ apr_interval_time_t age = apr_time_now() - session->last_frame_received; -+ if (age > apr_time_from_sec(1)) { -+ enter_ping_state(session, H2_PING_ST_AWAIT_PING); -+ } -+ } -+} -+ -+static void ping_ev_frame_received(h2_proxy_session *session, const nghttp2_frame *frame) -+{ -+ session->last_frame_received = apr_time_now(); -+ switch (session->ping_state) { -+ case H2_PING_ST_NONE: -+ /* nop */ -+ break; -+ case H2_PING_ST_AWAIT_ANY: -+ enter_ping_state(session, H2_PING_ST_NONE); -+ break; -+ case H2_PING_ST_AWAIT_PING: -+ if (NGHTTP2_PING == frame->hd.type) { -+ enter_ping_state(session, H2_PING_ST_NONE); -+ } -+ /* we may receive many other frames while we are waiting for the -+ * PING answer. They may come all from our connection buffers and -+ * say nothing about the current state of the backend. */ -+ break; -+ } -+} - - static apr_status_t proxy_session_pre_close(void *theconn) - { -@@ -152,7 +269,8 @@ - session->id, buffer); - } - -- session->last_frame_received = apr_time_now(); -+ ping_ev_frame_received(session, frame); -+ /* Action for frame types: */ - switch (frame->hd.type) { - case NGHTTP2_HEADERS: - stream = nghttp2_session_get_stream_user_data(ngh2, frame->hd.stream_id); -@@ -193,10 +311,6 @@ - stream_resume(stream); - break; - case NGHTTP2_PING: -- if (session->check_ping) { -- session->check_ping = 0; -- ping_arrived(session); -- } - break; - case NGHTTP2_PUSH_PROMISE: - break; -@@ -241,7 +355,8 @@ - return 1; - } - --static void process_proxy_header(h2_proxy_stream *stream, const char *n, const char *v) -+static void process_proxy_header(apr_table_t *headers, h2_proxy_stream *stream, -+ const char *n, const char *v) - { - static const struct { - const char *name; -@@ -262,20 +377,18 @@ - if (!dconf->preserve_host) { - for (i = 0; transform_hdrs[i].name; ++i) { - if (!ap_cstr_casecmp(transform_hdrs[i].name, n)) { -- apr_table_add(r->headers_out, n, -- (*transform_hdrs[i].func)(r, dconf, v)); -+ apr_table_add(headers, n, (*transform_hdrs[i].func)(r, dconf, v)); - return; - } - } - if (!ap_cstr_casecmp("Link", n)) { - dconf = ap_get_module_config(r->per_dir_config, &proxy_module); -- apr_table_add(r->headers_out, n, -- h2_proxy_link_reverse_map(r, dconf, -- stream->real_server_uri, stream->p_server_uri, v)); -+ apr_table_add(headers, n, h2_proxy_link_reverse_map(r, dconf, -+ stream->real_server_uri, stream->p_server_uri, v)); - return; - } - } -- apr_table_add(r->headers_out, n, v); -+ apr_table_add(headers, n, v); - } - - static apr_status_t h2_proxy_stream_add_header_out(h2_proxy_stream *stream, -@@ -299,8 +412,13 @@ - return APR_SUCCESS; - } - -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c, -+ "h2_proxy_stream(%s-%d): on_header %s: %s", -+ stream->session->id, stream->id, n, v); - if (!h2_proxy_res_ignore_header(n, nlen)) { - char *hname, *hvalue; -+ apr_table_t *headers = (stream->headers_ended? -+ stream->r->trailers_out : stream->r->headers_out); - - hname = apr_pstrndup(stream->pool, n, nlen); - h2_proxy_util_camel_case_header(hname, nlen); -@@ -309,7 +427,7 @@ - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c, - "h2_proxy_stream(%s-%d): got header %s: %s", - stream->session->id, stream->id, hname, hvalue); -- process_proxy_header(stream, hname, hvalue); -+ process_proxy_header(headers, stream, hname, hvalue); - } - return APR_SUCCESS; - } -@@ -374,6 +492,7 @@ - server_name, portstr) - ); - } -+ if (r->status >= 200) stream->headers_ended = 1; - - if (APLOGrtrace2(stream->r)) { - ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, stream->r, -@@ -429,12 +548,6 @@ - stream_id, NGHTTP2_STREAM_CLOSED); - return NGHTTP2_ERR_STREAM_CLOSING; - } -- if (stream->standalone) { -- nghttp2_session_consume(ngh2, stream_id, len); -- ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, stream->r, -- "h2_proxy_session(%s): stream %d, win_update %d bytes", -- session->id, stream_id, (int)len); -- } - return 0; - } - -@@ -493,12 +606,12 @@ - stream = nghttp2_session_get_stream_user_data(ngh2, stream_id); - if (!stream) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03361) -- "h2_proxy_stream(%s): data_read, stream %d not found", -- stream->session->id, stream_id); -+ "h2_proxy_stream(NULL): data_read, stream %d not found", -+ stream_id); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - -- if (stream->session->check_ping) { -+ if (stream->session->ping_state != H2_PING_ST_NONE) { - /* suspend until we hear from the other side */ - stream->waiting_on_ping = 1; - status = APR_EAGAIN; -@@ -553,9 +666,14 @@ - stream->data_sent += readlen; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(03468) - "h2_proxy_stream(%d): request DATA %ld, %ld" -- " total, flags=%d", -- stream->id, (long)readlen, (long)stream->data_sent, -+ " total, flags=%d", stream->id, (long)readlen, (long)stream->data_sent, - (int)*data_flags); -+ if ((*data_flags & NGHTTP2_DATA_FLAG_EOF) && !apr_is_empty_table(stream->r->trailers_in)) { -+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(10179) -+ "h2_proxy_stream(%d): submit trailers", stream->id); -+ *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM; -+ submit_trailers(stream); -+ } - return readlen; - } - else if (APR_STATUS_IS_EAGAIN(status)) { -@@ -641,23 +759,20 @@ - - nghttp2_option_new(&option); - nghttp2_option_set_peer_max_concurrent_streams(option, 100); -- nghttp2_option_set_no_auto_window_update(option, 1); -+ nghttp2_option_set_no_auto_window_update(option, 0); - - nghttp2_session_client_new2(&session->ngh2, cbs, session, option); - - nghttp2_option_del(option); - nghttp2_session_callbacks_del(cbs); - -+ ping_new_session(session, p_conn); - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03362) - "setup session for %s", p_conn->hostname); - } - else { - h2_proxy_session *session = p_conn->data; -- apr_interval_time_t age = apr_time_now() - session->last_frame_received; -- if (age > apr_time_from_sec(1)) { -- session->check_ping = 1; -- nghttp2_submit_ping(session->ngh2, 0, (const uint8_t *)"nevergonnagiveyouup"); -- } -+ ping_reuse_session(session); - } - return p_conn->data; - } -@@ -740,6 +855,8 @@ - stream->real_server_uri = apr_psprintf(stream->pool, "%s://%s", scheme, authority); - stream->p_server_uri = apr_psprintf(stream->pool, "%s://%s", puri.scheme, authority); - path = apr_uri_unparse(stream->pool, &puri, APR_URI_UNP_OMITSITEPART); -+ -+ - h2_proxy_req_make(stream->req, stream->pool, r->method, scheme, - authority, path, r->headers_in); - -@@ -826,6 +943,16 @@ - return APR_EGENERAL; - } - -+static apr_status_t submit_trailers(h2_proxy_stream *stream) -+{ -+ h2_proxy_ngheader *hd; -+ int rv; -+ -+ hd = h2_proxy_util_nghd_make(stream->pool, stream->r->trailers_in); -+ rv = nghttp2_submit_trailer(stream->session->ngh2, stream->id, hd->nv, hd->nvlen); -+ return rv == 0? APR_SUCCESS: APR_EGENERAL; -+} -+ - static apr_status_t feed_brigade(h2_proxy_session *session, apr_bucket_brigade *bb) - { - apr_status_t status = APR_SUCCESS; -@@ -882,7 +1009,7 @@ - apr_socket_t *socket = NULL; - apr_time_t save_timeout = -1; - -- if (block) { -+ if (block && timeout > 0) { - socket = ap_get_conn_socket(session->c); - if (socket) { - apr_socket_timeout_get(socket, &save_timeout); -@@ -954,6 +1081,14 @@ - dispatch_event(session, H2_PROXYS_EV_STREAM_RESUMED, 0, NULL); - } - -+static int is_waiting_for_backend(h2_proxy_session *session) -+{ -+ return ((session->ping_state != H2_PING_ST_NONE) -+ || ((session->suspended->nelts <= 0) -+ && !nghttp2_session_want_write(session->ngh2) -+ && nghttp2_session_want_read(session->ngh2))); -+} -+ - static apr_status_t check_suspended(h2_proxy_session *session) - { - h2_proxy_stream *stream; -@@ -1408,7 +1543,22 @@ - break; - - case H2_PROXYS_ST_WAIT: -- if (check_suspended(session) == APR_EAGAIN) { -+ if (is_waiting_for_backend(session)) { -+ /* we can do a blocking read with the default timeout (as -+ * configured via ProxyTimeout in our socket. There is -+ * nothing we want to send or check until we get more data -+ * from the backend. */ -+ status = h2_proxy_session_read(session, 1, 0); -+ if (status == APR_SUCCESS) { -+ have_read = 1; -+ dispatch_event(session, H2_PROXYS_EV_DATA_READ, 0, NULL); -+ } -+ else { -+ dispatch_event(session, H2_PROXYS_EV_CONN_ERROR, status, NULL); -+ return status; -+ } -+ } -+ else if (check_suspended(session) == APR_EAGAIN) { - /* no stream has become resumed. Do a blocking read with - * ever increasing timeouts... */ - if (session->wait_timeout < 25) { -@@ -1423,7 +1573,7 @@ - ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, session->c, - APLOGNO(03365) - "h2_proxy_session(%s): WAIT read, timeout=%fms", -- session->id, (float)session->wait_timeout/1000.0); -+ session->id, session->wait_timeout/1000.0); - if (status == APR_SUCCESS) { - have_read = 1; - dispatch_event(session, H2_PROXYS_EV_DATA_READ, 0, NULL); -@@ -1543,42 +1693,3 @@ - int updated; - } win_update_ctx; - --static int win_update_iter(void *udata, void *val) --{ -- win_update_ctx *ctx = udata; -- h2_proxy_stream *stream = val; -- -- if (stream->r && stream->r->connection == ctx->c) { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, ctx->session->c, -- "h2_proxy_session(%s-%d): win_update %ld bytes", -- ctx->session->id, (int)stream->id, (long)ctx->bytes); -- nghttp2_session_consume(ctx->session->ngh2, stream->id, ctx->bytes); -- ctx->updated = 1; -- return 0; -- } -- return 1; --} -- -- --void h2_proxy_session_update_window(h2_proxy_session *session, -- conn_rec *c, apr_off_t bytes) --{ -- if (!h2_proxy_ihash_empty(session->streams)) { -- win_update_ctx ctx; -- ctx.session = session; -- ctx.c = c; -- ctx.bytes = bytes; -- ctx.updated = 0; -- h2_proxy_ihash_iter(session->streams, win_update_iter, &ctx); -- -- if (!ctx.updated) { -- /* could not find the stream any more, possibly closed, update -- * the connection window at least */ -- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c, -- "h2_proxy_session(%s): win_update conn %ld bytes", -- session->id, (long)bytes); -- nghttp2_session_consume_connection(session->ngh2, (size_t)bytes); -- } -- } --} -- ---- a/modules/http2/h2_proxy_session.h -+++ b/modules/http2/h2_proxy_session.h -@@ -60,6 +60,11 @@ - H2_PROXYS_EV_PRE_CLOSE, /* connection will close after this */ - } h2_proxys_event_t; - -+typedef enum { -+ H2_PING_ST_NONE, /* normal connection mode, ProxyTimeout rules */ -+ H2_PING_ST_AWAIT_ANY, /* waiting for any frame from backend */ -+ H2_PING_ST_AWAIT_PING, /* waiting for PING frame from backend */ -+} h2_ping_state_t; - - typedef struct h2_proxy_session h2_proxy_session; - typedef void h2_proxy_request_done(h2_proxy_session *s, request_rec *r, -@@ -74,7 +79,6 @@ - nghttp2_session *ngh2; /* the nghttp2 session itself */ - - unsigned int aborted : 1; -- unsigned int check_ping : 1; - unsigned int h2_front : 1; /* if front-end connection is HTTP/2 */ - - h2_proxy_request_done *done; -@@ -94,6 +98,10 @@ - - apr_bucket_brigade *input; - apr_bucket_brigade *output; -+ -+ h2_ping_state_t ping_state; -+ apr_time_t ping_timeout; -+ apr_time_t save_timeout; - }; - - h2_proxy_session *h2_proxy_session_setup(const char *id, proxy_conn_rec *p_conn, -@@ -120,9 +128,6 @@ - - void h2_proxy_session_cleanup(h2_proxy_session *s, h2_proxy_request_done *done); - --void h2_proxy_session_update_window(h2_proxy_session *s, -- conn_rec *c, apr_off_t bytes); -- - #define H2_PROXY_REQ_URL_NOTE "h2-proxy-req-url" - - #endif /* h2_proxy_session_h */ ---- a/modules/http2/h2_proxy_util.c -+++ b/modules/http2/h2_proxy_util.c -@@ -452,6 +452,22 @@ - return ngh; - } - -+h2_proxy_ngheader *h2_proxy_util_nghd_make(apr_pool_t *p, apr_table_t *headers) -+{ -+ -+ h2_proxy_ngheader *ngh; -+ size_t n; -+ -+ n = 0; -+ apr_table_do(count_header, &n, headers, NULL); -+ -+ ngh = apr_pcalloc(p, sizeof(h2_proxy_ngheader)); -+ ngh->nv = apr_pcalloc(p, n * sizeof(nghttp2_nv)); -+ apr_table_do(add_table_header, ngh, headers, NULL); -+ -+ return ngh; -+} -+ - /******************************************************************************* - * header HTTP/1 <-> HTTP/2 conversions - ******************************************************************************/ -@@ -609,6 +625,7 @@ - apr_table_t *headers) - { - h1_ctx x; -+ const char *val; - - req->method = method; - req->scheme = scheme; -@@ -623,6 +640,11 @@ - x.pool = pool; - x.headers = req->headers; - apr_table_do(set_h1_header, &x, headers, NULL); -+ if ((val = apr_table_get(headers, "TE")) && ap_find_token(pool, val, "trailers")) { -+ /* client accepts trailers, forward this information */ -+ apr_table_addn(req->headers, "TE", "trailers"); -+ } -+ apr_table_setn(req->headers, "te", "trailers"); - return APR_SUCCESS; - } - -@@ -915,12 +937,12 @@ - nlen = (int)strlen(ns); - delta = nlen - olen; - plen = ctx->slen + delta + 1; -- p = apr_pcalloc(ctx->pool, plen); -+ p = apr_palloc(ctx->pool, plen); - memcpy(p, ctx->s, start); - memcpy(p + start, ns, nlen); - strcpy(p + start + nlen, ctx->s + end); - ctx->s = p; -- ctx->slen = (int)strlen(p); -+ ctx->slen = plen - 1; /* (int)strlen(p) */ - if (ctx->i >= end) { - ctx->i += delta; - } ---- a/modules/http2/h2_proxy_util.h -+++ b/modules/http2/h2_proxy_util.h -@@ -168,6 +168,8 @@ - h2_proxy_ngheader *h2_proxy_util_nghd_make_req(apr_pool_t *p, - const struct h2_proxy_request *req); - -+h2_proxy_ngheader *h2_proxy_util_nghd_make(apr_pool_t *p, apr_table_t *headers); -+ - /******************************************************************************* - * h2_proxy_request helpers - ******************************************************************************/ -@@ -183,7 +185,7 @@ - - apr_time_t request_time; - -- unsigned int chunked : 1; /* iff requst body needs to be forwarded as chunked */ -+ unsigned int chunked : 1; /* iff request body needs to be forwarded as chunked */ - unsigned int serialize : 1; /* iff this request is written in HTTP/1.1 serialization */ - }; - ---- a/modules/http2/h2_push.c -+++ b/modules/http2/h2_push.c -@@ -464,33 +464,6 @@ - return NULL; - } - --/******************************************************************************* -- * push diary -- * -- * - The push diary keeps track of resources already PUSHed via HTTP/2 on this -- * connection. It records a hash value from the absolute URL of the resource -- * pushed. -- * - Lacking openssl, it uses 'apr_hashfunc_default' for the value -- * - with openssl, it uses SHA256 to calculate the hash value -- * - whatever the method to generate the hash, the diary keeps a maximum of 64 -- * bits per hash, limiting the memory consumption to about -- * H2PushDiarySize * 8 -- * bytes. Entries are sorted by most recently used and oldest entries are -- * forgotten first. -- * - Clients can initialize/replace the push diary by sending a 'Cache-Digest' -- * header. Currently, this is the base64url encoded value of the cache digest -- * as specified in https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/ -- * This draft can be expected to evolve and the definition of the header -- * will be added there and refined. -- * - The cache digest header is a Golomb Coded Set of hash values, but it may -- * limit the amount of bits per hash value even further. For a good description -- * of GCS, read here: -- * http://giovanni.bajo.it/post/47119962313/golomb-coded-sets-smaller-than-bloom-filters -- * - The means that the push diary might be initialized with hash values of much -- * less than 64 bits, leading to more false positives, but smaller digest size. -- ******************************************************************************/ -- -- - #define GCSLOG_LEVEL APLOG_TRACE1 - - typedef struct h2_push_diary_entry { -@@ -617,38 +590,48 @@ - return -1; - } - --static h2_push_diary_entry *move_to_last(h2_push_diary *diary, apr_size_t idx) -+static void move_to_last(h2_push_diary *diary, apr_size_t idx) - { - h2_push_diary_entry *entries = (h2_push_diary_entry*)diary->entries->elts; - h2_push_diary_entry e; -- apr_size_t lastidx = diary->entries->nelts-1; -+ int lastidx; - -+ /* Move an existing entry to the last place */ -+ if (diary->entries->nelts <= 0) -+ return; -+ - /* move entry[idx] to the end */ -+ lastidx = diary->entries->nelts - 1; - if (idx < lastidx) { - e = entries[idx]; -- memmove(entries+idx, entries+idx+1, sizeof(e) * (lastidx - idx)); -+ memmove(entries+idx, entries+idx+1, sizeof(h2_push_diary_entry) * (lastidx - idx)); - entries[lastidx] = e; - } -- return &entries[lastidx]; - } - --static void h2_push_diary_append(h2_push_diary *diary, h2_push_diary_entry *e) -+static void remove_first(h2_push_diary *diary) - { -- h2_push_diary_entry *ne; -+ h2_push_diary_entry *entries = (h2_push_diary_entry*)diary->entries->elts; -+ int lastidx; - -- if (diary->entries->nelts < diary->N) { -- /* append a new diary entry at the end */ -- APR_ARRAY_PUSH(diary->entries, h2_push_diary_entry) = *e; -- ne = &APR_ARRAY_IDX(diary->entries, diary->entries->nelts-1, h2_push_diary_entry); -- } -- else { -- /* replace content with new digest. keeps memory usage constant once diary is full */ -- ne = move_to_last(diary, 0); -- *ne = *e; -+ /* move remaining entries to index 0 */ -+ lastidx = diary->entries->nelts - 1; -+ if (lastidx > 0) { -+ --diary->entries->nelts; -+ memmove(entries, entries+1, sizeof(h2_push_diary_entry) * diary->entries->nelts); - } -+} -+ -+static void h2_push_diary_append(h2_push_diary *diary, h2_push_diary_entry *e) -+{ -+ while (diary->entries->nelts >= diary->N) { -+ remove_first(diary); -+ } -+ /* append a new diary entry at the end */ -+ APR_ARRAY_PUSH(diary->entries, h2_push_diary_entry) = *e; - /* Intentional no APLOGNO */ - ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, diary->entries->pool, -- "push_diary_append: %"APR_UINT64_T_HEX_FMT, ne->hash); -+ "push_diary_append: %"APR_UINT64_T_HEX_FMT, e->hash); - } - - apr_array_header_t *h2_push_diary_update(h2_session *session, apr_array_header_t *pushes) -@@ -691,30 +674,12 @@ - const struct h2_request *req, - const struct h2_headers *res) - { -- h2_session *session = stream->session; -- const char *cache_digest = apr_table_get(req->headers, "Cache-Digest"); - apr_array_header_t *pushes; -- apr_status_t status; - -- if (cache_digest && session->push_diary) { -- status = h2_push_diary_digest64_set(session->push_diary, req->authority, -- cache_digest, stream->pool); -- if (status != APR_SUCCESS) { -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, session->c, -- H2_SSSN_LOG(APLOGNO(03057), session, -- "push diary set from Cache-Digest: %s"), cache_digest); -- } -- } - pushes = h2_push_collect(stream->pool, req, stream->push_policy, res); - return h2_push_diary_update(stream->session, pushes); - } - --static apr_int32_t h2_log2inv(unsigned char log2) --{ -- return log2? (1 << log2) : 1; --} -- -- - typedef struct { - h2_push_diary *diary; - unsigned char log2p; -@@ -829,16 +794,11 @@ - apr_size_t hash_count; - - nelts = diary->entries->nelts; -- -- if (nelts > APR_UINT32_MAX) { -- /* should not happen */ -- return APR_ENOTIMPL; -- } - N = ceil_power_of_2(nelts); - log2n = h2_log2(N); - - /* Now log2p is the max number of relevant bits, so that -- * log2p + log2n == mask_bits. We can uise a lower log2p -+ * log2p + log2n == mask_bits. We can use a lower log2p - * and have a shorter set encoding... - */ - log2pmax = h2_log2(ceil_power_of_2(maxP)); -@@ -895,166 +855,3 @@ - return APR_SUCCESS; - } - --typedef struct { -- h2_push_diary *diary; -- apr_pool_t *pool; -- unsigned char log2p; -- const unsigned char *data; -- apr_size_t datalen; -- apr_size_t offset; -- unsigned int bit; -- apr_uint64_t last_val; --} gset_decoder; -- --static int gset_decode_next_bit(gset_decoder *decoder) --{ -- if (++decoder->bit >= 8) { -- if (++decoder->offset >= decoder->datalen) { -- return -1; -- } -- decoder->bit = 0; -- } -- return (decoder->data[decoder->offset] & cbit_mask[decoder->bit])? 1 : 0; --} -- --static apr_status_t gset_decode_next(gset_decoder *decoder, apr_uint64_t *phash) --{ -- apr_uint64_t flex = 0, fixed = 0, delta; -- int i; -- -- /* read 1 bits until we encounter 0, then read log2n(diary-P) bits. -- * On a malformed bit-string, this will not fail, but produce results -- * which are pbly too large. Luckily, the diary will modulo the hash. -- */ -- while (1) { -- int bit = gset_decode_next_bit(decoder); -- if (bit == -1) { -- return APR_EINVAL; -- } -- if (!bit) { -- break; -- } -- ++flex; -- } -- -- for (i = 0; i < decoder->log2p; ++i) { -- int bit = gset_decode_next_bit(decoder); -- if (bit == -1) { -- return APR_EINVAL; -- } -- fixed = (fixed << 1) | bit; -- } -- -- delta = (flex << decoder->log2p) | fixed; -- *phash = delta + decoder->last_val; -- decoder->last_val = *phash; -- -- /* Intentional no APLOGNO */ -- ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, decoder->pool, -- "h2_push_diary_digest_dec: val=%"APR_UINT64_T_HEX_FMT", delta=%" -- APR_UINT64_T_HEX_FMT", flex=%d, fixed=%"APR_UINT64_T_HEX_FMT, -- *phash, delta, (int)flex, fixed); -- -- return APR_SUCCESS; --} -- --/** -- * Initialize the push diary by a cache digest as described in -- * https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/ -- * . -- * @param diary the diary to set the digest into -- * @param data the binary cache digest -- * @param len the length of the cache digest -- * @return APR_EINVAL if digest was not successfully parsed -- */ --apr_status_t h2_push_diary_digest_set(h2_push_diary *diary, const char *authority, -- const char *data, apr_size_t len) --{ -- gset_decoder decoder; -- unsigned char log2n, log2p; -- int N, i; -- apr_pool_t *pool = diary->entries->pool; -- h2_push_diary_entry e; -- apr_status_t status = APR_SUCCESS; -- -- if (len < 2) { -- /* at least this should be there */ -- return APR_EINVAL; -- } -- log2n = data[0]; -- log2p = data[1]; -- diary->mask_bits = log2n + log2p; -- if (diary->mask_bits > 64) { -- /* cannot handle */ -- return APR_ENOTIMPL; -- } -- -- /* whatever is in the digest, it replaces the diary entries */ -- apr_array_clear(diary->entries); -- if (!authority || !strcmp("*", authority)) { -- diary->authority = NULL; -- } -- else if (!diary->authority || strcmp(diary->authority, authority)) { -- diary->authority = apr_pstrdup(diary->entries->pool, authority); -- } -- -- N = h2_log2inv(log2n + log2p); -- -- decoder.diary = diary; -- decoder.pool = pool; -- decoder.log2p = log2p; -- decoder.data = (const unsigned char*)data; -- decoder.datalen = len; -- decoder.offset = 1; -- decoder.bit = 8; -- decoder.last_val = 0; -- -- diary->N = N; -- /* Determine effective N we use for storage */ -- if (!N) { -- /* a totally empty cache digest. someone tells us that she has no -- * entries in the cache at all. Use our own preferences for N+mask -- */ -- diary->N = diary->NMax; -- return APR_SUCCESS; -- } -- else if (N > diary->NMax) { -- /* Store not more than diary is configured to hold. We open us up -- * to DOS attacks otherwise. */ -- diary->N = diary->NMax; -- } -- -- /* Intentional no APLOGNO */ -- ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool, -- "h2_push_diary_digest_set: N=%d, log2n=%d, " -- "diary->mask_bits=%d, dec.log2p=%d", -- (int)diary->N, (int)log2n, diary->mask_bits, -- (int)decoder.log2p); -- -- for (i = 0; i < diary->N; ++i) { -- if (gset_decode_next(&decoder, &e.hash) != APR_SUCCESS) { -- /* the data may have less than N values */ -- break; -- } -- h2_push_diary_append(diary, &e); -- } -- -- /* Intentional no APLOGNO */ -- ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool, -- "h2_push_diary_digest_set: diary now with %d entries, mask_bits=%d", -- (int)diary->entries->nelts, diary->mask_bits); -- return status; --} -- --apr_status_t h2_push_diary_digest64_set(h2_push_diary *diary, const char *authority, -- const char *data64url, apr_pool_t *pool) --{ -- const char *data; -- apr_size_t len = h2_util_base64url_decode(&data, data64url, pool); -- /* Intentional no APLOGNO */ -- ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool, -- "h2_push_diary_digest64_set: digest=%s, dlen=%d", -- data64url, (int)len); -- return h2_push_diary_digest_set(diary, authority, data, len); --} -- ---- a/modules/http2/h2_push.h -+++ b/modules/http2/h2_push.h -@@ -35,6 +35,44 @@ - H2_PUSH_DIGEST_SHA256 - } h2_push_digest_type; - -+/******************************************************************************* -+ * push diary -+ * -+ * - The push diary keeps track of resources already PUSHed via HTTP/2 on this -+ * connection. It records a hash value from the absolute URL of the resource -+ * pushed. -+ * - Lacking openssl, -+ * - with openssl, it uses SHA256 to calculate the hash value, otherwise it -+ * falls back to apr_hashfunc_default() -+ * - whatever the method to generate the hash, the diary keeps a maximum of 64 -+ * bits per hash, limiting the memory consumption to about -+ * H2PushDiarySize * 8 -+ * bytes. Entries are sorted by most recently used and oldest entries are -+ * forgotten first. -+ * - While useful by itself to avoid duplicated PUSHes on the same connection, -+ * the original idea was that clients provided a 'Cache-Digest' header with -+ * the values of *their own* cached resources. This was described in -+ * <https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/> -+ * and some subsequent revisions that tweaked values but kept the overall idea. -+ * - The draft was abandoned by the IETF http-wg, as support from major clients, -+ * e.g. browsers, was lacking for various reasons. -+ * - For these reasons, mod_h2 abandoned its support for client supplied values -+ * but keeps the diary. It seems to provide value for applications using PUSH, -+ * is configurable in size and defaults to a very moderate amount of memory -+ * used. -+ * - The cache digest header is a Golomb Coded Set of hash values, but it may -+ * limit the amount of bits per hash value even further. For a good description -+ * of GCS, read here: -+ * <http://giovanni.bajo.it/post/47119962313/golomb-coded-sets-smaller-than-bloom-filters> -+ ******************************************************************************/ -+ -+ -+/* -+ * The push diary is based on the abandoned draft -+ * <https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/> -+ * that describes how to use golomb filters. -+ */ -+ - typedef struct h2_push_diary h2_push_diary; - - typedef void h2_push_digest_calc(h2_push_diary *diary, apr_uint64_t *phash, h2_push *push); -@@ -101,20 +139,4 @@ - int maxP, const char *authority, - const char **pdata, apr_size_t *plen); - --/** -- * Initialize the push diary by a cache digest as described in -- * https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/ -- * . -- * @param diary the diary to set the digest into -- * @param authority the authority to set the data for -- * @param data the binary cache digest -- * @param len the length of the cache digest -- * @return APR_EINVAL if digest was not successfully parsed -- */ --apr_status_t h2_push_diary_digest_set(h2_push_diary *diary, const char *authority, -- const char *data, apr_size_t len); -- --apr_status_t h2_push_diary_digest64_set(h2_push_diary *diary, const char *authority, -- const char *data64url, apr_pool_t *pool); -- - #endif /* defined(__mod_h2__h2_push__) */ ---- a/modules/http2/h2_request.c -+++ b/modules/http2/h2_request.c -@@ -17,6 +17,7 @@ - #include <assert.h> - - #include <apr_strings.h> -+#include <ap_mmn.h> - - #include <httpd.h> - #include <http_core.h> -@@ -46,9 +47,9 @@ - static int set_h1_header(void *ctx, const char *key, const char *value) - { - h1_ctx *x = ctx; -- x->status = h2_req_add_header(x->headers, x->pool, key, strlen(key), -- value, strlen(value)); -- return (x->status == APR_SUCCESS)? 1 : 0; -+ int was_added; -+ h2_req_add_header(x->headers, x->pool, key, strlen(key), value, strlen(value), 0, &was_added); -+ return 1; - } - - apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool, -@@ -84,8 +85,7 @@ - req->path = path; - req->headers = apr_table_make(pool, 10); - if (r->server) { -- req->serialize = h2_config_geti(h2_config_sget(r->server), -- H2_CONF_SER_HEADERS); -+ req->serialize = h2_config_rgeti(r, H2_CONF_SER_HEADERS); - } - - x.pool = pool; -@@ -99,10 +99,12 @@ - - apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool, - const char *name, size_t nlen, -- const char *value, size_t vlen) -+ const char *value, size_t vlen, -+ size_t max_field_len, int *pwas_added) - { - apr_status_t status = APR_SUCCESS; - -+ *pwas_added = 0; - if (nlen <= 0) { - return status; - } -@@ -143,8 +145,9 @@ - } - } - else { -- /* non-pseudo header, append to work bucket of stream */ -- status = h2_req_add_header(req->headers, pool, name, nlen, value, vlen); -+ /* non-pseudo header, add to table */ -+ status = h2_req_add_header(req->headers, pool, name, nlen, value, vlen, -+ max_field_len, pwas_added); - } - - return status; -@@ -156,7 +159,7 @@ - - /* rfc7540, ch. 8.1.2.3: - * - if we have :authority, it overrides any Host header -- * - :authority MUST be ommited when converting h1->h2, so we -+ * - :authority MUST be omitted when converting h1->h2, so we - * might get a stream without, but then Host needs to be there */ - if (!req->authority) { - const char *host = apr_table_get(req->headers, "Host"); -@@ -206,13 +209,11 @@ - return dst; - } - --request_rec *h2_request_create_rec(const h2_request *req, conn_rec *c) -+#if !AP_MODULE_MAGIC_AT_LEAST(20150222, 13) -+static request_rec *my_ap_create_request(conn_rec *c) - { -- int access_status = HTTP_OK; -- const char *rpath; - apr_pool_t *p; - request_rec *r; -- const char *s; - - apr_pool_create(&p, c->pool); - apr_pool_tag(p, "request"); -@@ -226,8 +227,8 @@ - r->ap_auth_type = NULL; - - r->allowed_methods = ap_make_method_list(p, 2); -- -- r->headers_in = apr_table_clone(r->pool, req->headers); -+ -+ r->headers_in = apr_table_make(r->pool, 5); - r->trailers_in = apr_table_make(r->pool, 5); - r->subprocess_env = apr_table_make(r->pool, 25); - r->headers_out = apr_table_make(r->pool, 12); -@@ -262,6 +263,24 @@ - r->useragent_addr = c->client_addr; - r->useragent_ip = c->client_ip; - -+ return r; -+} -+#endif -+ -+request_rec *h2_request_create_rec(const h2_request *req, conn_rec *c) -+{ -+ int access_status = HTTP_OK; -+ const char *rpath; -+ const char *s; -+ -+#if AP_MODULE_MAGIC_AT_LEAST(20150222, 13) -+ request_rec *r = ap_create_request(c); -+#else -+ request_rec *r = my_ap_create_request(c); -+#endif -+ -+ r->headers_in = apr_table_clone(r->pool, req->headers); -+ - ap_run_pre_read_request(r, c); - - /* Time to populate r with the data we have. */ -@@ -272,6 +291,9 @@ - if (r->method_number == M_GET && r->method[0] == 'H') { - r->header_only = 1; - } -+ r->the_request = apr_psprintf(r->pool, "%s %s HTTP/2.0", -+ req->method, req->path ? req->path : ""); -+ r->headers_in = apr_table_clone(r->pool, req->headers); - - rpath = (req->path ? req->path : ""); - ap_parse_uri(r, rpath); -@@ -288,7 +310,9 @@ - */ - r->hostname = NULL; - ap_update_vhost_from_headers(r); -- -+ r->protocol = "HTTP/2.0"; -+ r->proto_num = HTTP_VERSION(2, 0); -+ - /* we may have switched to another server */ - r->per_dir_config = r->server->lookup_defaults; - -@@ -337,3 +361,4 @@ - } - - -+ ---- a/modules/http2/h2_request.h -+++ b/modules/http2/h2_request.h -@@ -24,7 +24,8 @@ - - apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool, - const char *name, size_t nlen, -- const char *value, size_t vlen); -+ const char *value, size_t vlen, -+ size_t max_field_len, int *pwas_added); - - apr_status_t h2_request_add_trailer(h2_request *req, apr_pool_t *pool, - const char *name, size_t nlen, ---- a/modules/http2/h2_session.c -+++ b/modules/http2/h2_session.c -@@ -106,7 +106,7 @@ - - static void cleanup_unprocessed_streams(h2_session *session) - { -- h2_mplx_stream_do(session->mplx, rst_unprocessed_stream, session); -+ h2_mplx_m_stream_do(session->mplx, rst_unprocessed_stream, session); - } - - static h2_stream *h2_session_open_stream(h2_session *session, int stream_id, -@@ -385,14 +385,19 @@ - break; - case NGHTTP2_RST_STREAM: - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03067) -- "h2_stream(%ld-%d): RST_STREAM by client, errror=%d", -+ "h2_stream(%ld-%d): RST_STREAM by client, error=%d", - session->id, (int)frame->hd.stream_id, - (int)frame->rst_stream.error_code); - stream = h2_session_stream_get(session, frame->hd.stream_id); - if (stream && stream->initiated_on) { -+ /* A stream reset on a request we sent it. Normal, when the -+ * client does not want it. */ - ++session->pushes_reset; - } - else { -+ /* A stream reset on a request it sent us. Could happen in a browser -+ * when the user navigates away or cancels loading - maybe. */ -+ h2_mplx_m_client_rst(session->mplx, frame->hd.stream_id); - ++session->streams_reset; - } - break; -@@ -462,7 +467,7 @@ - } - - static int h2_session_continue_data(h2_session *session) { -- if (h2_mplx_has_master_events(session->mplx)) { -+ if (h2_mplx_m_has_master_events(session->mplx)) { - return 0; - } - if (h2_conn_io_needs_flush(&session->io)) { -@@ -495,9 +500,7 @@ - return NGHTTP2_ERR_WOULDBLOCK; - } - -- if (frame->data.padlen > H2_MAX_PADLEN) { -- return NGHTTP2_ERR_PROTO; -- } -+ ap_assert(frame->data.padlen <= (H2_MAX_PADLEN+1)); - padlen = (unsigned char)frame->data.padlen; - - stream = h2_session_stream_get(session, stream_id); -@@ -513,8 +516,9 @@ - H2_STRM_MSG(stream, "send_data_cb for %ld bytes"), - (long)length); - -- status = h2_conn_io_write(&session->io, (const char *)framehd, 9); -+ status = h2_conn_io_write(&session->io, (const char *)framehd, H2_FRAME_HDR_LEN); - if (padlen && status == APR_SUCCESS) { -+ --padlen; - status = h2_conn_io_write(&session->io, (const char *)&padlen, 1); - } - -@@ -622,6 +626,39 @@ - } - #endif - -+static ssize_t select_padding_cb(nghttp2_session *ngh2, -+ const nghttp2_frame *frame, -+ size_t max_payloadlen, void *user_data) -+{ -+ h2_session *session = user_data; -+ ssize_t frame_len = frame->hd.length + H2_FRAME_HDR_LEN; /* the total length without padding */ -+ ssize_t padded_len = frame_len; -+ -+ /* Determine # of padding bytes to append to frame. Unless session->padding_always -+ * the number my be capped by the ui.write_size that currently applies. -+ */ -+ if (session->padding_max) { -+ int n = ap_random_pick(0, session->padding_max); -+ padded_len = H2MIN(max_payloadlen + H2_FRAME_HDR_LEN, frame_len + n); -+ } -+ -+ if (padded_len != frame_len) { -+ if (!session->padding_always && session->io.write_size -+ && (padded_len > session->io.write_size) -+ && (frame_len <= session->io.write_size)) { -+ padded_len = session->io.write_size; -+ } -+ if (APLOGctrace2(session->c)) { -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c, -+ "select padding from [%d, %d]: %d (frame length: 0x%04x, write size: %d)", -+ (int)frame_len, (int)max_payloadlen+H2_FRAME_HDR_LEN, -+ (int)(padded_len - frame_len), (int)padded_len, (int)session->io.write_size); -+ } -+ return padded_len - H2_FRAME_HDR_LEN; -+ } -+ return frame->hd.length; -+} -+ - #define NGH2_SET_CALLBACK(callbacks, name, fn)\ - nghttp2_session_callbacks_set_##name##_callback(callbacks, fn) - -@@ -647,6 +684,7 @@ - #ifdef H2_NG2_INVALID_HEADER_CB - NGH2_SET_CALLBACK(*pcb, on_invalid_header, on_invalid_header_cb); - #endif -+ NGH2_SET_CALLBACK(*pcb, select_padding, select_padding_cb); - return APR_SUCCESS; - } - -@@ -691,7 +729,7 @@ - * Remove all streams greater than this number without submitting - * a RST_STREAM frame, since that should be clear from the GOAWAY - * we send. */ -- session->local.accepted_max = h2_mplx_shutdown(session->mplx); -+ session->local.accepted_max = h2_mplx_m_shutdown(session->mplx); - session->local.error = error; - } - else { -@@ -741,7 +779,7 @@ - } - - transit(session, trigger, H2_SESSION_ST_CLEANUP); -- h2_mplx_release_and_join(session->mplx, session->iowait); -+ h2_mplx_m_release_and_join(session->mplx, session->iowait); - session->mplx = NULL; - - ap_assert(session->ngh2); -@@ -757,13 +795,12 @@ - { - conn_rec *c = data; - h2_session *session; -- h2_ctx *ctx = h2_ctx_get(c, 0); - -- if (ctx && (session = h2_ctx_session_get(ctx))) { -+ if ((session = h2_ctx_get_session(c))) { - /* if the session is still there, now is the last chance - * to perform cleanup. Normally, cleanup should have happened - * earlier in the connection pre_close. Main reason is that -- * any ongoing requests on slave connections might still access -+ * any ongoing requests on secondary connections might still access - * data which has, at this time, already been freed. An example - * is mod_ssl that uses request hooks. */ - ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, -@@ -775,11 +812,8 @@ - return APR_SUCCESS; - } - --static apr_status_t h2_session_create_int(h2_session **psession, -- conn_rec *c, -- request_rec *r, -- h2_ctx *ctx, -- h2_workers *workers) -+apr_status_t h2_session_create(h2_session **psession, conn_rec *c, request_rec *r, -+ server_rec *s, h2_workers *workers) - { - nghttp2_session_callbacks *callbacks = NULL; - nghttp2_option *options = NULL; -@@ -820,19 +854,16 @@ - session->id = c->id; - session->c = c; - session->r = r; -- session->s = h2_ctx_server_get(ctx); -+ session->s = s; - session->pool = pool; -- session->config = h2_config_sget(session->s); - session->workers = workers; - - session->state = H2_SESSION_ST_INIT; - session->local.accepting = 1; - session->remote.accepting = 1; - -- session->max_stream_count = h2_config_geti(session->config, -- H2_CONF_MAX_STREAMS); -- session->max_stream_mem = h2_config_geti(session->config, -- H2_CONF_STREAM_MAX_MEM); -+ session->max_stream_count = h2_config_sgeti(s, H2_CONF_MAX_STREAMS); -+ session->max_stream_mem = h2_config_sgeti(s, H2_CONF_STREAM_MAX_MEM); - - status = apr_thread_cond_create(&session->iowait, session->pool); - if (status != APR_SUCCESS) { -@@ -862,14 +893,18 @@ - session->monitor->on_state_event = on_stream_state_event; - session->monitor->on_event = on_stream_event; - -- session->mplx = h2_mplx_create(c, session->pool, session->config, -- workers); -+ session->mplx = h2_mplx_m_create(c, s, session->pool, workers); - - /* connection input filter that feeds the session */ - session->cin = h2_filter_cin_create(session); - ap_add_input_filter("H2_IN", session->cin, r, c); - -- h2_conn_io_init(&session->io, c, session->config); -+ h2_conn_io_init(&session->io, c, s); -+ session->padding_max = h2_config_sgeti(s, H2_CONF_PADDING_BITS); -+ if (session->padding_max) { -+ session->padding_max = (0x01 << session->padding_max) - 1; -+ } -+ session->padding_always = h2_config_sgeti(s, H2_CONF_PADDING_ALWAYS); - session->bbtmp = apr_brigade_create(session->pool, c->bucket_alloc); - - status = init_callbacks(c, &callbacks); -@@ -888,8 +923,7 @@ - apr_pool_destroy(pool); - return status; - } -- nghttp2_option_set_peer_max_concurrent_streams( -- options, (uint32_t)session->max_stream_count); -+ nghttp2_option_set_peer_max_concurrent_streams(options, (uint32_t)session->max_stream_count); - /* We need to handle window updates ourself, otherwise we - * get flooded by nghttp2. */ - nghttp2_option_set_no_auto_window_update(options, 1); -@@ -907,7 +941,7 @@ - return APR_ENOMEM; - } - -- n = h2_config_geti(session->config, H2_CONF_PUSH_DIARY_SIZE); -+ n = h2_config_sgeti(s, H2_CONF_PUSH_DIARY_SIZE); - session->push_diary = h2_push_diary_create(session->pool, n); - - if (APLOGcdebug(c)) { -@@ -924,22 +958,11 @@ - (int)session->push_diary->N); - } - -- apr_pool_pre_cleanup_register(pool, c, session_pool_cleanup); -+ apr_pool_pre_cleanup_register(pool, c, session_pool_cleanup); -+ - return APR_SUCCESS; - } - --apr_status_t h2_session_create(h2_session **psession, -- conn_rec *c, h2_ctx *ctx, h2_workers *workers) --{ -- return h2_session_create_int(psession, c, NULL, ctx, workers); --} -- --apr_status_t h2_session_rcreate(h2_session **psession, -- request_rec *r, h2_ctx *ctx, h2_workers *workers) --{ -- return h2_session_create_int(psession, r->connection, r, ctx, workers); --} -- - static apr_status_t h2_session_start(h2_session *session, int *rv) - { - apr_status_t status = APR_SUCCESS; -@@ -1004,7 +1027,7 @@ - settings[slen].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; - settings[slen].value = (uint32_t)session->max_stream_count; - ++slen; -- win_size = h2_config_geti(session->config, H2_CONF_WIN_SIZE); -+ win_size = h2_config_sgeti(session->s, H2_CONF_WIN_SIZE); - if (win_size != H2_INITIAL_WINDOW_SIZE) { - settings[slen].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; - settings[slen].value = win_size; -@@ -1156,7 +1179,7 @@ - stream = h2_session_open_stream(session, nid, is->id); - if (!stream) { - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, -- H2_STRM_LOG(APLOGNO(03077), stream, -+ H2_STRM_LOG(APLOGNO(03077), is, - "failed to create stream obj %d"), nid); - /* kill the push_promise */ - nghttp2_submit_rst_stream(session->ngh2, NGHTTP2_FLAG_NONE, nid, -@@ -1262,7 +1285,7 @@ - - rv = nghttp2_session_change_stream_priority(session->ngh2, stream->id, &ps); - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, -- ""H2_STRM_LOG(APLOGNO(03203), stream, -+ H2_STRM_LOG(APLOGNO(03203), stream, - "PUSH %s, weight=%d, depends=%d, returned=%d"), - ptype, ps.weight, ps.stream_id, rv); - status = (rv < 0)? APR_EGENERAL : APR_SUCCESS; -@@ -1280,7 +1303,7 @@ - { - /* iff we can and they can and want */ - return (session->remote.accepting /* remote GOAWAY received */ -- && h2_config_geti(session->config, H2_CONF_PUSH) -+ && h2_config_sgeti(session->s, H2_CONF_PUSH) - && nghttp2_session_get_remote_settings(session->ngh2, - NGHTTP2_SETTINGS_ENABLE_PUSH)); - } -@@ -1324,6 +1347,7 @@ - int eos) - { - apr_status_t status = APR_SUCCESS; -+ const char *s; - int rv = 0; - - ap_assert(session); -@@ -1391,8 +1415,12 @@ - && (headers->status < 400) - && (headers->status != 304) - && h2_session_push_enabled(session)) { -- -- h2_stream_submit_pushes(stream, headers); -+ /* PUSH is possible and enabled on server, unless the request -+ * denies it, submit resources to push */ -+ s = apr_table_get(headers->notes, H2_PUSH_MODE_NOTE); -+ if (!s || strcmp(s, "0")) { -+ h2_stream_submit_pushes(stream, headers); -+ } - } - - if (!stream->pref_priority) { -@@ -1414,7 +1442,7 @@ - } - - if (headers->status == 103 -- && !h2_config_geti(session->config, H2_CONF_EARLY_HINTS)) { -+ && !h2_config_sgeti(session->s, H2_CONF_EARLY_HINTS)) { - /* suppress sending this to the client, it might have triggered - * pushes and served its purpose nevertheless */ - rv = 0; -@@ -1524,7 +1552,7 @@ - if (stream) { - ap_assert(!stream->scheduled); - if (h2_stream_prep_processing(stream) == APR_SUCCESS) { -- h2_mplx_process(session->mplx, stream, stream_pri_cmp, session); -+ h2_mplx_m_process(session->mplx, stream, stream_pri_cmp, session); - } - else { - h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR); -@@ -1680,7 +1708,7 @@ - * that already served requests - not fair. */ - session->idle_sync_until = apr_time_now() + apr_time_from_sec(1); - s = "timeout"; -- timeout = H2MAX(session->s->timeout, session->s->keep_alive_timeout); -+ timeout = session->s->timeout; - update_child_status(session, SERVER_BUSY_READ, "idle"); - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c, - H2_SSSN_LOG("", session, "enter idle, timeout = %d sec"), -@@ -1688,8 +1716,8 @@ - } - else if (session->open_streams) { - s = "timeout"; -- timeout = session->s->keep_alive_timeout; -- update_child_status(session, SERVER_BUSY_KEEPALIVE, "idle"); -+ timeout = session->s->timeout; -+ update_child_status(session, SERVER_BUSY_READ, "idle"); - } - else { - /* normal keepalive setup */ -@@ -1796,7 +1824,7 @@ - session->open_streams); - h2_conn_io_flush(&session->io); - if (session->open_streams > 0) { -- if (h2_mplx_awaits_data(session->mplx)) { -+ if (h2_mplx_m_awaits_data(session->mplx)) { - /* waiting for at least one stream to produce data */ - transit(session, "no io", H2_SESSION_ST_WAIT); - } -@@ -1954,7 +1982,8 @@ - ev_stream_closed(session, stream); - break; - case H2_SS_CLEANUP: -- h2_mplx_stream_cleanup(session->mplx, stream); -+ nghttp2_session_set_stream_user_data(session->ngh2, stream->id, NULL); -+ h2_mplx_m_stream_cleanup(session->mplx, stream); - break; - default: - break; -@@ -2044,7 +2073,7 @@ - static apr_status_t dispatch_master(h2_session *session) { - apr_status_t status; - -- status = h2_mplx_dispatch_master_events(session->mplx, -+ status = h2_mplx_m_dispatch_master_events(session->mplx, - on_stream_resume, session); - if (status == APR_EAGAIN) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, session->c, -@@ -2089,7 +2118,7 @@ - switch (session->state) { - case H2_SESSION_ST_INIT: - ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c); -- if (!h2_is_acceptable_connection(c, 1)) { -+ if (!h2_is_acceptable_connection(c, session->r, 1)) { - update_child_status(session, SERVER_BUSY_READ, - "inadequate security"); - h2_session_shutdown(session, -@@ -2112,7 +2141,7 @@ - break; - - case H2_SESSION_ST_IDLE: -- if (session->idle_until && (apr_time_now() + session->idle_delay) > session->idle_until) { -+ if (session->idle_until && (now + session->idle_delay) > session->idle_until) { - ap_log_cerror( APLOG_MARK, APLOG_TRACE1, status, c, - H2_SSSN_MSG(session, "idle, timeout reached, closing")); - if (session->idle_delay) { -@@ -2146,6 +2175,14 @@ - session->have_read = 1; - } - else if (APR_STATUS_IS_EAGAIN(status) || APR_STATUS_IS_TIMEUP(status)) { -+ status = h2_mplx_m_idle(session->mplx); -+ if (status == APR_EAGAIN) { -+ break; -+ } -+ else if (status != APR_SUCCESS) { -+ dispatch_event(session, H2_SESSION_EV_CONN_ERROR, -+ H2_ERR_ENHANCE_YOUR_CALM, "less is more"); -+ } - status = APR_EAGAIN; - goto out; - } -@@ -2168,7 +2205,7 @@ - /* We wait in smaller increments, using a 1 second timeout. - * That gives us the chance to check for MPMQ_STOPPING often. - */ -- status = h2_mplx_idle(session->mplx); -+ status = h2_mplx_m_idle(session->mplx); - if (status == APR_EAGAIN) { - break; - } -@@ -2282,7 +2319,7 @@ - "h2_session: wait for data, %ld micros", - (long)session->wait_us); - } -- status = h2_mplx_out_trywait(session->mplx, session->wait_us, -+ status = h2_mplx_m_out_trywait(session->mplx, session->wait_us, - session->iowait); - if (status == APR_SUCCESS) { - session->wait_us = 0; -@@ -2319,7 +2356,7 @@ - dispatch_event(session, H2_SESSION_EV_NGH2_DONE, 0, NULL); - } - if (session->reprioritize) { -- h2_mplx_reprioritize(session->mplx, stream_pri_cmp, session); -+ h2_mplx_m_reprioritize(session->mplx, stream_pri_cmp, session); - session->reprioritize = 0; - } - } ---- a/modules/http2/h2_session.h -+++ b/modules/http2/h2_session.h -@@ -80,12 +80,13 @@ - request_rec *r; /* the request that started this in case - * of 'h2c', NULL otherwise */ - server_rec *s; /* server/vhost we're starting on */ -- const struct h2_config *config; /* Relevant config for this session */ - apr_pool_t *pool; /* pool to use in session */ - struct h2_mplx *mplx; /* multiplexer for stream data */ - struct h2_workers *workers; /* for executing stream tasks */ - struct h2_filter_cin *cin; /* connection input filter context */ - h2_conn_io io; /* io on httpd conn filters */ -+ int padding_max; /* max number of padding bytes */ -+ int padding_always; /* padding has precedence over I/O optimizations */ - struct nghttp2_session *ngh2; /* the nghttp2 session (internal use) */ - - h2_session_state state; /* state session is in */ -@@ -131,7 +132,7 @@ - const char *last_status_msg; /* the one already reported */ - - struct h2_iqueue *in_pending; /* all streams with input pending */ -- struct h2_iqueue *in_process; /* all streams ready for processing on slave */ -+ struct h2_iqueue *in_process; /* all streams ready for processing on a secondary */ - - } h2_session; - -@@ -142,27 +143,15 @@ - * The session will apply the configured parameter. - * @param psession pointer receiving the created session on success or NULL - * @param c the connection to work on -+ * @param r optional request when protocol was upgraded - * @param cfg the module config to apply - * @param workers the worker pool to use - * @return the created session - */ - apr_status_t h2_session_create(h2_session **psession, -- conn_rec *c, struct h2_ctx *ctx, -+ conn_rec *c, request_rec *r, server_rec *, - struct h2_workers *workers); - --/** -- * Create a new h2_session for the given request. -- * The session will apply the configured parameter. -- * @param psession pointer receiving the created session on success or NULL -- * @param r the request that was upgraded -- * @param cfg the module config to apply -- * @param workers the worker pool to use -- * @return the created session -- */ --apr_status_t h2_session_rcreate(h2_session **psession, -- request_rec *r, struct h2_ctx *ctx, -- struct h2_workers *workers); -- - void h2_session_event(h2_session *session, h2_session_event_t ev, - int err, const char *msg); - ---- a/modules/http2/h2_stream.c -+++ b/modules/http2/h2_stream.c -@@ -365,9 +365,8 @@ - static void set_policy_for(h2_stream *stream, h2_request *r) - { - int enabled = h2_session_push_enabled(stream->session); -- stream->push_policy = h2_push_policy_determine(r->headers, stream->pool, -- enabled); -- r->serialize = h2_config_geti(stream->session->config, H2_CONF_SER_HEADERS); -+ stream->push_policy = h2_push_policy_determine(r->headers, stream->pool, enabled); -+ r->serialize = h2_config_sgeti(stream->session->s, H2_CONF_SER_HEADERS); - } - - apr_status_t h2_stream_send_frame(h2_stream *stream, int ftype, int flags, size_t frame_len) -@@ -398,13 +397,8 @@ - /* start pushed stream */ - ap_assert(stream->request == NULL); - ap_assert(stream->rtmp != NULL); -- status = h2_request_end_headers(stream->rtmp, stream->pool, 1, 0); -- if (status != APR_SUCCESS) { -- return status; -- } -- set_policy_for(stream, stream->rtmp); -- stream->request = stream->rtmp; -- stream->rtmp = NULL; -+ status = h2_stream_end_headers(stream, 1, 0); -+ if (status != APR_SUCCESS) goto leave; - break; - - default: -@@ -416,6 +410,7 @@ - if (status == APR_SUCCESS && eos) { - status = transit(stream, on_event(stream, H2_SEV_CLOSED_L)); - } -+leave: - return status; - } - -@@ -451,18 +446,13 @@ - ap_assert(stream->request == NULL); - if (stream->rtmp == NULL) { - /* This can only happen, if the stream has received no header -- * name/value pairs at all. The lastest nghttp2 version have become -+ * name/value pairs at all. The latest nghttp2 version have become - * pretty good at detecting this early. In any case, we have - * to abort the connection here, since this is clearly a protocol error */ - return APR_EINVAL; - } -- status = h2_request_end_headers(stream->rtmp, stream->pool, eos, frame_len); -- if (status != APR_SUCCESS) { -- return status; -- } -- set_policy_for(stream, stream->rtmp); -- stream->request = stream->rtmp; -- stream->rtmp = NULL; -+ status = h2_stream_end_headers(stream, eos, frame_len); -+ if (status != APR_SUCCESS) goto leave; - } - break; - -@@ -473,6 +463,7 @@ - if (status == APR_SUCCESS && eos) { - status = transit(stream, on_event(stream, H2_SEV_CLOSED_R)); - } -+leave: - return status; - } - -@@ -663,11 +654,14 @@ - - static apr_status_t add_trailer(h2_stream *stream, - const char *name, size_t nlen, -- const char *value, size_t vlen) -+ const char *value, size_t vlen, -+ size_t max_field_len, int *pwas_added) - { - conn_rec *c = stream->session->c; - char *hname, *hvalue; -+ const char *existing; - -+ *pwas_added = 0; - if (nlen == 0 || name[0] == ':') { - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EINVAL, c, - H2_STRM_LOG(APLOGNO(03060), stream, -@@ -681,9 +675,18 @@ - stream->trailers = apr_table_make(stream->pool, 5); - } - hname = apr_pstrndup(stream->pool, name, nlen); -- hvalue = apr_pstrndup(stream->pool, value, vlen); - h2_util_camel_case_header(hname, nlen); -+ existing = apr_table_get(stream->trailers, hname); -+ if (max_field_len -+ && ((existing? strlen(existing)+2 : 0) + vlen + nlen + 2 > max_field_len)) { -+ /* "key: (oldval, )?nval" is too long */ -+ return APR_EINVAL; -+ } -+ if (!existing) *pwas_added = 1; -+ hvalue = apr_pstrndup(stream->pool, value, vlen); - apr_table_mergen(stream->trailers, hname, hvalue); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, -+ H2_STRM_MSG(stream, "added trailer '%s: %s'"), hname, hvalue); - - return APR_SUCCESS; - } -@@ -693,44 +696,31 @@ - const char *value, size_t vlen) - { - h2_session *session = stream->session; -- int error = 0; -- apr_status_t status; -+ int error = 0, was_added = 0; -+ apr_status_t status = APR_SUCCESS; - - if (stream->has_response) { - return APR_EINVAL; - } -- ++stream->request_headers_added; -+ - if (name[0] == ':') { - if ((vlen) > session->s->limit_req_line) { - /* pseudo header: approximation of request line size check */ -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c, -- H2_STRM_MSG(stream, "pseudo %s too long"), name); -+ if (!h2_stream_is_ready(stream)) { -+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c, -+ H2_STRM_LOG(APLOGNO(10178), stream, -+ "Request pseudo header exceeds " -+ "LimitRequestFieldSize: %s"), name); -+ } - error = HTTP_REQUEST_URI_TOO_LARGE; -+ goto cleanup; - } - } -- else if ((nlen + 2 + vlen) > session->s->limit_req_fieldsize) { -- /* header too long */ -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c, -- H2_STRM_MSG(stream, "header %s too long"), name); -- error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE; -- } -- -- if (stream->request_headers_added > session->s->limit_req_fields + 4) { -- /* too many header lines, include 4 pseudo headers */ -- if (stream->request_headers_added -- > session->s->limit_req_fields + 4 + 100) { -- /* yeah, right */ -- h2_stream_rst(stream, H2_ERR_ENHANCE_YOUR_CALM); -- return APR_ECONNRESET; -- } -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c, -- H2_STRM_MSG(stream, "too many header lines")); -- error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE; -- } - -- if (error) { -- set_error_response(stream, error); -- return APR_EINVAL; -+ if (session->s->limit_req_fields > 0 -+ && stream->request_headers_added > session->s->limit_req_fields) { -+ /* already over limit, count this attempt, but do not take it in */ -+ ++stream->request_headers_added; - } - else if (H2_SS_IDLE == stream->state) { - if (!stream->rtmp) { -@@ -738,16 +728,55 @@ - NULL, NULL, NULL, NULL, NULL, 0); - } - status = h2_request_add_header(stream->rtmp, stream->pool, -- name, nlen, value, vlen); -+ name, nlen, value, vlen, -+ session->s->limit_req_fieldsize, &was_added); -+ if (was_added) ++stream->request_headers_added; - } - else if (H2_SS_OPEN == stream->state) { -- status = add_trailer(stream, name, nlen, value, vlen); -+ status = add_trailer(stream, name, nlen, value, vlen, -+ session->s->limit_req_fieldsize, &was_added); -+ if (was_added) ++stream->request_headers_added; - } - else { - status = APR_EINVAL; -+ goto cleanup; -+ } -+ -+ if (APR_EINVAL == status) { -+ /* header too long */ -+ if (!h2_stream_is_ready(stream)) { -+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c, -+ H2_STRM_LOG(APLOGNO(10180), stream,"Request header exceeds " -+ "LimitRequestFieldSize: %.*s"), -+ (int)H2MIN(nlen, 80), name); -+ } -+ error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE; -+ goto cleanup; -+ } -+ -+ if (session->s->limit_req_fields > 0 -+ && stream->request_headers_added > session->s->limit_req_fields) { -+ /* too many header lines */ -+ if (stream->request_headers_added > session->s->limit_req_fields + 100) { -+ /* yeah, right, this request is way over the limit, say goodbye */ -+ h2_stream_rst(stream, H2_ERR_ENHANCE_YOUR_CALM); -+ return APR_ECONNRESET; -+ } -+ if (!h2_stream_is_ready(stream)) { -+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c, -+ H2_STRM_LOG(APLOGNO(10181), stream, "Number of request headers " -+ "exceeds LimitRequestFields")); -+ } -+ error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE; -+ goto cleanup; - } - -- if (status != APR_SUCCESS) { -+cleanup: -+ if (error) { -+ set_error_response(stream, error); -+ return APR_EINVAL; -+ } -+ else if (status != APR_SUCCESS) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c, - H2_STRM_MSG(stream, "header %s not accepted"), name); - h2_stream_dispatch(stream, H2_SEV_CANCELLED); -@@ -755,6 +784,49 @@ - return status; - } - -+typedef struct { -+ apr_size_t maxlen; -+ const char *failed_key; -+} val_len_check_ctx; -+ -+static int table_check_val_len(void *baton, const char *key, const char *value) -+{ -+ val_len_check_ctx *ctx = baton; -+ -+ if (strlen(value) <= ctx->maxlen) return 1; -+ ctx->failed_key = key; -+ return 0; -+} -+ -+apr_status_t h2_stream_end_headers(h2_stream *stream, int eos, size_t raw_bytes) -+{ -+ apr_status_t status; -+ val_len_check_ctx ctx; -+ -+ status = h2_request_end_headers(stream->rtmp, stream->pool, eos, raw_bytes); -+ if (APR_SUCCESS == status) { -+ set_policy_for(stream, stream->rtmp); -+ stream->request = stream->rtmp; -+ stream->rtmp = NULL; -+ -+ ctx.maxlen = stream->session->s->limit_req_fieldsize; -+ ctx.failed_key = NULL; -+ apr_table_do(table_check_val_len, &ctx, stream->request->headers, NULL); -+ if (ctx.failed_key) { -+ if (!h2_stream_is_ready(stream)) { -+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c, -+ H2_STRM_LOG(APLOGNO(10230), stream,"Request header exceeds " -+ "LimitRequestFieldSize: %.*s"), -+ (int)H2MIN(strlen(ctx.failed_key), 80), ctx.failed_key); -+ } -+ set_error_response(stream, HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE); -+ /* keep on returning APR_SUCCESS, so that we send a HTTP response and -+ * do not RST the stream. */ -+ } -+ } -+ return status; -+} -+ - static apr_bucket *get_first_headers_bucket(apr_bucket_brigade *bb) - { - if (bb) { -@@ -855,7 +927,7 @@ - * is requested. But we can reduce the size in case the master - * connection operates in smaller chunks. (TSL warmup) */ - if (stream->session->io.write_size > 0) { -- max_chunk = stream->session->io.write_size - 9; /* header bits */ -+ max_chunk = stream->session->io.write_size - H2_FRAME_HDR_LEN; - } - requested = (*plen > 0)? H2MIN(*plen, max_chunk) : max_chunk; - -@@ -864,7 +936,7 @@ - - if (status == APR_EAGAIN) { - /* TODO: ugly, someone needs to retrieve the response first */ -- h2_mplx_keep_active(stream->session->mplx, stream); -+ h2_mplx_m_keep_active(stream->session->mplx, stream); - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, - H2_STRM_MSG(stream, "prep, response eagain")); - return status; -@@ -987,7 +1059,7 @@ - const char *ctype = apr_table_get(response->headers, "content-type"); - if (ctype) { - /* FIXME: Not good enough, config needs to come from request->server */ -- return h2_config_get_priority(stream->session->config, ctype); -+ return h2_cconfig_get_priority(stream->session->c, ctype); - } - } - return NULL; ---- a/modules/http2/h2_stream.h -+++ b/modules/http2/h2_stream.h -@@ -198,6 +198,10 @@ - apr_status_t h2_stream_add_header(h2_stream *stream, - const char *name, size_t nlen, - const char *value, size_t vlen); -+ -+/* End the construction of request headers */ -+apr_status_t h2_stream_end_headers(h2_stream *stream, int eos, size_t raw_bytes); -+ - - apr_status_t h2_stream_send_frame(h2_stream *stream, int frame_type, int flags, size_t frame_len); - apr_status_t h2_stream_recv_frame(h2_stream *stream, int frame_type, int flags, size_t frame_len); ---- a/modules/http2/h2_switch.c -+++ b/modules/http2/h2_switch.c -@@ -55,7 +55,6 @@ - int is_tls = h2_h2_is_tls(c); - const char **protos = is_tls? h2_tls_protos : h2_clear_protos; - -- (void)s; - if (!h2_mpm_supported()) { - return DECLINED; - } -@@ -68,7 +67,7 @@ - return DECLINED; - } - -- if (!h2_is_acceptable_connection(c, 0)) { -+ if (!h2_is_acceptable_connection(c, r, 0)) { - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03084) - "protocol propose: connection requirements not met"); - return DECLINED; -@@ -81,7 +80,7 @@ - */ - const char *p; - -- if (!h2_allows_h2_upgrade(c)) { -+ if (!h2_allows_h2_upgrade(r)) { - return DECLINED; - } - -@@ -150,7 +149,7 @@ - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, - "switching protocol to '%s'", protocol); - h2_ctx_protocol_set(ctx, protocol); -- h2_ctx_server_set(ctx, s); -+ h2_ctx_server_update(ctx, s); - - if (r != NULL) { - apr_status_t status; -@@ -160,12 +159,11 @@ - * right away. - */ - ap_remove_input_filter_byhandle(r->input_filters, "http_in"); -- ap_remove_input_filter_byhandle(r->input_filters, "reqtimeout"); - ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER"); - - /* Ok, start an h2_conn on this one. */ -- h2_ctx_server_set(ctx, r->server); -- status = h2_conn_setup(ctx, r->connection, r); -+ status = h2_conn_setup(c, r, s); -+ - if (status != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(03088) - "session setup"); -@@ -173,7 +171,7 @@ - return !OK; - } - -- h2_conn_run(ctx, c); -+ h2_conn_run(c); - } - return OK; - } ---- a/modules/http2/h2_task.c -+++ b/modules/http2/h2_task.c -@@ -86,7 +86,7 @@ - task->request->authority, - task->request->path); - task->output.opened = 1; -- return h2_mplx_out_open(task->mplx, task->stream_id, task->output.beam); -+ return h2_mplx_t_out_open(task->mplx, task->stream_id, task->output.beam); - } - - static apr_status_t send_out(h2_task *task, apr_bucket_brigade* bb, int block) -@@ -97,7 +97,7 @@ - apr_brigade_length(bb, 0, &written); - H2_TASK_OUT_LOG(APLOG_TRACE2, task, bb, "h2_task send_out"); - h2_beam_log(task->output.beam, task->c, APLOG_TRACE2, "send_out(before)"); -- /* engines send unblocking */ -+ - status = h2_beam_send(task->output.beam, bb, - block? APR_BLOCK_READ : APR_NONBLOCK_READ); - h2_beam_log(task->output.beam, task->c, APLOG_TRACE2, "send_out(after)"); -@@ -126,33 +126,16 @@ - * request_rec out filter chain) into the h2_mplx for further sending - * on the master connection. - */ --static apr_status_t slave_out(h2_task *task, ap_filter_t* f, -- apr_bucket_brigade* bb) -+static apr_status_t secondary_out(h2_task *task, ap_filter_t* f, -+ apr_bucket_brigade* bb) - { - apr_bucket *b; - apr_status_t rv = APR_SUCCESS; - int flush = 0, blocking; - -- if (task->frozen) { -- h2_util_bb_log(task->c, task->stream_id, APLOG_TRACE2, -- "frozen task output write, ignored", bb); -- while (!APR_BRIGADE_EMPTY(bb)) { -- b = APR_BRIGADE_FIRST(bb); -- if (AP_BUCKET_IS_EOR(b)) { -- APR_BUCKET_REMOVE(b); -- task->eor = b; -- } -- else { -- apr_bucket_delete(b); -- } -- } -- return APR_SUCCESS; -- } -- - send: -- /* we send block once we opened the output, so someone is there -- * reading it *and* the task is not assigned to a h2_req_engine */ -- blocking = (!task->assigned && task->output.opened); -+ /* we send block once we opened the output, so someone is there reading it */ -+ blocking = task->output.opened; - for (b = APR_BRIGADE_FIRST(bb); - b != APR_BRIGADE_SENTINEL(bb); - b = APR_BUCKET_NEXT(b)) { -@@ -192,7 +175,7 @@ - if (APR_SUCCESS == rv) { - /* could not write all, buffer the rest */ - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, task->c, APLOGNO(03405) -- "h2_slave_out(%s): saving brigade", task->id); -+ "h2_secondary_out(%s): saving brigade", task->id); - ap_assert(NULL); - rv = ap_save_brigade(f, &task->output.bb, &bb, task->pool); - flush = 1; -@@ -206,7 +189,7 @@ - } - out: - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, task->c, -- "h2_slave_out(%s): slave_out leave", task->id); -+ "h2_secondary_out(%s): secondary_out leave", task->id); - return rv; - } - -@@ -219,14 +202,14 @@ - } - - /******************************************************************************* -- * task slave connection filters -+ * task secondary connection filters - ******************************************************************************/ - --static apr_status_t h2_filter_slave_in(ap_filter_t* f, -- apr_bucket_brigade* bb, -- ap_input_mode_t mode, -- apr_read_type_e block, -- apr_off_t readbytes) -+static apr_status_t h2_filter_secondary_in(ap_filter_t* f, -+ apr_bucket_brigade* bb, -+ ap_input_mode_t mode, -+ apr_read_type_e block, -+ apr_off_t readbytes) - { - h2_task *task; - apr_status_t status = APR_SUCCESS; -@@ -236,12 +219,12 @@ - apr_size_t rmax = ((readbytes <= APR_SIZE_MAX)? - (apr_size_t)readbytes : APR_SIZE_MAX); - -- task = h2_ctx_cget_task(f->c); -+ task = h2_ctx_get_task(f->c); - ap_assert(task); - - if (trace1) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c, -- "h2_slave_in(%s): read, mode=%d, block=%d, readbytes=%ld", -+ "h2_secondary_in(%s): read, mode=%d, block=%d, readbytes=%ld", - task->id, mode, block, (long)readbytes); - } - -@@ -271,7 +254,7 @@ - /* Get more input data for our request. */ - if (trace1) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c, -- "h2_slave_in(%s): get more data from mplx, block=%d, " -+ "h2_secondary_in(%s): get more data from mplx, block=%d, " - "readbytes=%ld", task->id, block, (long)readbytes); - } - if (task->input.beam) { -@@ -284,7 +267,7 @@ - - if (trace1) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, f->c, -- "h2_slave_in(%s): read returned", task->id); -+ "h2_secondary_in(%s): read returned", task->id); - } - if (APR_STATUS_IS_EAGAIN(status) - && (mode == AP_MODE_GETLINE || block == APR_BLOCK_READ)) { -@@ -310,11 +293,9 @@ - } - } - -- /* Nothing there, no more data to get. Return APR_EAGAIN on -- * speculative reads, this is ap_check_pipeline()'s trick to -- * see if the connection needs closing. */ -+ /* Nothing there, no more data to get. Return. */ - if (status == APR_EOF && APR_BRIGADE_EMPTY(task->input.bb)) { -- return (mode == AP_MODE_SPECULATIVE)? APR_EAGAIN : APR_EOF; -+ return status; - } - - if (trace1) { -@@ -325,7 +306,7 @@ - if (APR_BRIGADE_EMPTY(task->input.bb)) { - if (trace1) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c, -- "h2_slave_in(%s): no data", task->id); -+ "h2_secondary_in(%s): no data", task->id); - } - return (block == APR_NONBLOCK_READ)? APR_EAGAIN : APR_EOF; - } -@@ -353,7 +334,7 @@ - buffer[len] = 0; - if (trace1) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c, -- "h2_slave_in(%s): getline: %s", -+ "h2_secondary_in(%s): getline: %s", - task->id, buffer); - } - } -@@ -363,7 +344,7 @@ - * to support it. Seems to work. */ - ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOTIMPL, f->c, - APLOGNO(03472) -- "h2_slave_in(%s), unsupported READ mode %d", -+ "h2_secondary_in(%s), unsupported READ mode %d", - task->id, mode); - status = APR_ENOTIMPL; - } -@@ -371,19 +352,19 @@ - if (trace1) { - apr_brigade_length(bb, 0, &bblen); - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c, -- "h2_slave_in(%s): %ld data bytes", task->id, (long)bblen); -+ "h2_secondary_in(%s): %ld data bytes", task->id, (long)bblen); - } - return status; - } - --static apr_status_t h2_filter_slave_output(ap_filter_t* filter, -- apr_bucket_brigade* brigade) -+static apr_status_t h2_filter_secondary_output(ap_filter_t* filter, -+ apr_bucket_brigade* brigade) - { -- h2_task *task = h2_ctx_cget_task(filter->c); -+ h2_task *task = h2_ctx_get_task(filter->c); - apr_status_t status; - - ap_assert(task); -- status = slave_out(task, filter, brigade); -+ status = secondary_out(task, filter, brigade); - if (status != APR_SUCCESS) { - h2_task_rst(task, H2_ERR_INTERNAL_ERROR); - } -@@ -392,14 +373,14 @@ - - static apr_status_t h2_filter_parse_h1(ap_filter_t* f, apr_bucket_brigade* bb) - { -- h2_task *task = h2_ctx_cget_task(f->c); -+ h2_task *task = h2_ctx_get_task(f->c); - apr_status_t status; - - ap_assert(task); - /* There are cases where we need to parse a serialized http/1.1 - * response. One example is a 100-continue answer in serialized mode - * or via a mod_proxy setup */ -- while (bb && !task->output.sent_response) { -+ while (bb && !task->c->aborted && !task->output.sent_response) { - status = h2_from_h1_parse_response(task, f, bb); - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, f->c, - "h2_task(%s): parsed response", task->id); -@@ -425,8 +406,15 @@ - || !strcmp("OPTIONS", task->request->method)); - } - -+int h2_task_has_started(h2_task *task) -+{ -+ return task && task->started_at != 0; -+} -+ - void h2_task_redo(h2_task *task) - { -+ task->started_at = 0; -+ task->worker_done = 0; - task->rst_error = 0; - } - -@@ -468,9 +456,9 @@ - ap_hook_process_connection(h2_task_process_conn, - NULL, NULL, APR_HOOK_FIRST); - -- ap_register_input_filter("H2_SLAVE_IN", h2_filter_slave_in, -+ ap_register_input_filter("H2_SECONDARY_IN", h2_filter_secondary_in, - NULL, AP_FTYPE_NETWORK); -- ap_register_output_filter("H2_SLAVE_OUT", h2_filter_slave_output, -+ ap_register_output_filter("H2_SECONDARY_OUT", h2_filter_secondary_output, - NULL, AP_FTYPE_NETWORK); - ap_register_output_filter("H2_PARSE_H1", h2_filter_parse_h1, - NULL, AP_FTYPE_NETWORK); -@@ -502,17 +490,17 @@ - - ctx = h2_ctx_get(c, 0); - (void)arg; -- if (h2_ctx_is_task(ctx)) { -+ if (ctx->task) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, -- "h2_slave(%s), pre_connection, adding filters", c->log_id); -- ap_add_input_filter("H2_SLAVE_IN", NULL, NULL, c); -+ "h2_secondary(%s), pre_connection, adding filters", c->log_id); -+ ap_add_input_filter("H2_SECONDARY_IN", NULL, NULL, c); - ap_add_output_filter("H2_PARSE_H1", NULL, NULL, c); -- ap_add_output_filter("H2_SLAVE_OUT", NULL, NULL, c); -+ ap_add_output_filter("H2_SECONDARY_OUT", NULL, NULL, c); - } - return OK; - } - --h2_task *h2_task_create(conn_rec *slave, int stream_id, -+h2_task *h2_task_create(conn_rec *secondary, int stream_id, - const h2_request *req, h2_mplx *m, - h2_bucket_beam *input, - apr_interval_time_t timeout, -@@ -521,17 +509,18 @@ - apr_pool_t *pool; - h2_task *task; - -- ap_assert(slave); -+ ap_assert(secondary); - ap_assert(req); - -- apr_pool_create(&pool, slave->pool); -+ apr_pool_create(&pool, secondary->pool); -+ apr_pool_tag(pool, "h2_task"); - task = apr_pcalloc(pool, sizeof(h2_task)); - if (task == NULL) { - return NULL; - } - task->id = "000"; - task->stream_id = stream_id; -- task->c = slave; -+ task->c = secondary; - task->mplx = m; - task->pool = pool; - task->request = req; -@@ -564,41 +553,40 @@ - ap_assert(task); - c = task->c; - task->worker_started = 1; -- task->started_at = apr_time_now(); - - if (c->master) { -- /* Each conn_rec->id is supposed to be unique at a point in time. Since -+ /* See the discussion at <https://github.com/icing/mod_h2/issues/195> -+ * -+ * Each conn_rec->id is supposed to be unique at a point in time. Since - * some modules (and maybe external code) uses this id as an identifier -- * for the request_rec they handle, it needs to be unique for slave -+ * for the request_rec they handle, it needs to be unique for secondary - * connections also. -- * The connection id is generated by the MPM and most MPMs use the formula -- * id := (child_num * max_threads) + thread_num -- * which means that there is a maximum id of about -- * idmax := max_child_count * max_threads -- * If we assume 2024 child processes with 2048 threads max, we get -- * idmax ~= 2024 * 2048 = 2 ** 22 -- * On 32 bit systems, we have not much space left, but on 64 bit systems -- * (and higher?) we can use the upper 32 bits without fear of collision. -- * 32 bits is just what we need, since a connection can only handle so -- * many streams. -+ * -+ * The MPM module assigns the connection ids and mod_unique_id is using -+ * that one to generate identifier for requests. While the implementation -+ * works for HTTP/1.x, the parallel execution of several requests per -+ * connection will generate duplicate identifiers on load. -+ * -+ * The original implementation for secondary connection identifiers used -+ * to shift the master connection id up and assign the stream id to the -+ * lower bits. This was cramped on 32 bit systems, but on 64bit there was -+ * enough space. -+ * -+ * As issue 195 showed, mod_unique_id only uses the lower 32 bit of the -+ * connection id, even on 64bit systems. Therefore collisions in request ids. -+ * -+ * The way master connection ids are generated, there is some space "at the -+ * top" of the lower 32 bits on allmost all systems. If you have a setup -+ * with 64k threads per child and 255 child processes, you live on the edge. -+ * -+ * The new implementation shifts 8 bits and XORs in the worker -+ * id. This will experience collisions with > 256 h2 workers and heavy -+ * load still. There seems to be no way to solve this in all possible -+ * configurations by mod_h2 alone. - */ -- int slave_id, free_bits; -- -+ task->c->id = (c->master->id << 8)^worker_id; - task->id = apr_psprintf(task->pool, "%ld-%d", c->master->id, - task->stream_id); -- if (sizeof(unsigned long) >= 8) { -- free_bits = 32; -- slave_id = task->stream_id; -- } -- else { -- /* Assume we have a more limited number of threads/processes -- * and h2 workers on a 32-bit system. Use the worker instead -- * of the stream id. */ -- free_bits = 8; -- slave_id = worker_id; -- } -- task->c->id = (c->master->id << free_bits)^slave_id; -- c->keepalive = AP_CONN_KEEPALIVE; - } - - h2_beam_create(&task->output.beam, c->pool, task->stream_id, "output", -@@ -613,7 +601,7 @@ - h2_ctx_create_for(c, task); - apr_table_setn(c->notes, H2_TASK_ID_NOTE, task->id); - -- h2_slave_run_pre_connection(c, ap_get_conn_socket(c)); -+ h2_secondary_run_pre_connection(c, ap_get_conn_socket(c)); - - task->input.bb = apr_brigade_create(task->pool, c->bucket_alloc); - if (task->request->serialize) { -@@ -633,18 +621,9 @@ - task->c->current_thread = thread; - ap_run_process_connection(c); - -- if (task->frozen) { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -- "h2_task(%s): process_conn returned frozen task", -- task->id); -- /* cleanup delayed */ -- return APR_EAGAIN; -- } -- else { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -- "h2_task(%s): processing done", task->id); -- return output_finish(task); -- } -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -+ "h2_task(%s): processing done", task->id); -+ return output_finish(task); - } - - static apr_status_t h2_task_process_request(h2_task *task, conn_rec *c) -@@ -682,14 +661,8 @@ - - ap_process_request(r); - -- if (task->frozen) { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -- "h2_task(%s): process_request frozen", task->id); -- } -- else { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -- "h2_task(%s): process_request done", task->id); -- } -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -+ "h2_task(%s): process_request done", task->id); - - /* After the call to ap_process_request, the - * request pool may have been deleted. We set -@@ -724,7 +697,7 @@ - } - - ctx = h2_ctx_get(c, 0); -- if (h2_ctx_is_task(ctx)) { -+ if (ctx->task) { - if (!ctx->task->request->serialize) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, - "h2_h2, processing request directly"); -@@ -736,33 +709,8 @@ - } - else { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -- "slave_conn(%ld): has no task", c->id); -+ "secondary_conn(%ld): has no task", c->id); - } - return DECLINED; - } - --apr_status_t h2_task_freeze(h2_task *task) --{ -- if (!task->frozen) { -- task->frozen = 1; -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, task->c, APLOGNO(03406) -- "h2_task(%s), frozen", task->id); -- } -- return APR_SUCCESS; --} -- --apr_status_t h2_task_thaw(h2_task *task) --{ -- if (task->frozen) { -- task->frozen = 0; -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, task->c, APLOGNO(03407) -- "h2_task(%s), thawed", task->id); -- } -- task->thawed = 1; -- return APR_SUCCESS; --} -- --int h2_task_has_thawed(h2_task *task) --{ -- return task->thawed; --} ---- a/modules/http2/h2_task.h -+++ b/modules/http2/h2_task.h -@@ -35,14 +35,13 @@ - * - * Finally, to keep certain connection level filters, such as ourselves and - * especially mod_ssl ones, from messing with our data, we need a filter -- * of our own to disble those. -+ * of our own to disable those. - */ - - struct h2_bucket_beam; - struct h2_conn; - struct h2_mplx; - struct h2_task; --struct h2_req_engine; - struct h2_request; - struct h2_response_parser; - struct h2_stream; -@@ -80,20 +79,18 @@ - struct h2_mplx *mplx; - - unsigned int filters_set : 1; -- unsigned int frozen : 1; -- unsigned int thawed : 1; - unsigned int worker_started : 1; /* h2_worker started processing */ -- unsigned int worker_done : 1; /* h2_worker finished */ -+ unsigned int redo : 1; /* was throttled, should be restarted later */ -+ -+ int worker_done; /* h2_worker finished */ -+ int done_done; /* task_done has been handled */ - - apr_time_t started_at; /* when processing started */ - apr_time_t done_at; /* when processing was done */ - apr_bucket *eor; -- -- struct h2_req_engine *engine; /* engine hosted by this task */ -- struct h2_req_engine *assigned; /* engine that task has been assigned to */ - }; - --h2_task *h2_task_create(conn_rec *slave, int stream_id, -+h2_task *h2_task_create(conn_rec *secondary, int stream_id, - const h2_request *req, struct h2_mplx *m, - struct h2_bucket_beam *input, - apr_interval_time_t timeout, -@@ -105,6 +102,7 @@ - - void h2_task_redo(h2_task *task); - int h2_task_can_redo(h2_task *task); -+int h2_task_has_started(h2_task *task); - - /** - * Reset the task with the given error code, resets all input/output. -@@ -120,8 +118,4 @@ - extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_in) *h2_task_logio_add_bytes_in; - extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *h2_task_logio_add_bytes_out; - --apr_status_t h2_task_freeze(h2_task *task); --apr_status_t h2_task_thaw(h2_task *task); --int h2_task_has_thawed(h2_task *task); -- - #endif /* defined(__mod_h2__h2_task__) */ ---- a/modules/http2/h2_util.c -+++ b/modules/http2/h2_util.c -@@ -638,15 +638,6 @@ - apr_status_t rv; - if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { - fifo->aborted = 1; -- apr_thread_mutex_unlock(fifo->lock); -- } -- return rv; --} -- --apr_status_t h2_fifo_interrupt(h2_fifo *fifo) --{ -- apr_status_t rv; -- if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { - apr_thread_cond_broadcast(fifo->not_empty); - apr_thread_cond_broadcast(fifo->not_full); - apr_thread_mutex_unlock(fifo->lock); -@@ -710,10 +701,6 @@ - { - apr_status_t rv; - -- if (fifo->aborted) { -- return APR_EOF; -- } -- - if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { - rv = fifo_push_int(fifo, elem, block); - apr_thread_mutex_unlock(fifo->lock); -@@ -754,10 +741,6 @@ - { - apr_status_t rv; - -- if (fifo->aborted) { -- return APR_EOF; -- } -- - if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { - rv = pull_head(fifo, pelem, block); - apr_thread_mutex_unlock(fifo->lock); -@@ -946,15 +929,6 @@ - apr_status_t rv; - if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { - fifo->aborted = 1; -- apr_thread_mutex_unlock(fifo->lock); -- } -- return rv; --} -- --apr_status_t h2_ififo_interrupt(h2_ififo *fifo) --{ -- apr_status_t rv; -- if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { - apr_thread_cond_broadcast(fifo->not_empty); - apr_thread_cond_broadcast(fifo->not_full); - apr_thread_mutex_unlock(fifo->lock); -@@ -1018,10 +992,6 @@ - { - apr_status_t rv; - -- if (fifo->aborted) { -- return APR_EOF; -- } -- - if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { - rv = ififo_push_int(fifo, id, block); - apr_thread_mutex_unlock(fifo->lock); -@@ -1062,10 +1032,6 @@ - { - apr_status_t rv; - -- if (fifo->aborted) { -- return APR_EOF; -- } -- - if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { - rv = ipull_head(fifo, pi, block); - apr_thread_mutex_unlock(fifo->lock); -@@ -1088,10 +1054,6 @@ - apr_status_t rv; - int id; - -- if (fifo->aborted) { -- return APR_EOF; -- } -- - if (APR_SUCCESS == (rv = apr_thread_mutex_lock(fifo->lock))) { - if (APR_SUCCESS == (rv = ipull_head(fifo, &id, block))) { - switch (fn(id, ctx)) { -@@ -1117,39 +1079,40 @@ - return ififo_peek(fifo, fn, ctx, 0); - } - --apr_status_t h2_ififo_remove(h2_ififo *fifo, int id) -+static apr_status_t ififo_remove(h2_ififo *fifo, int id) - { -- apr_status_t rv; -+ int rc, i; - - if (fifo->aborted) { - return APR_EOF; - } - -- if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { -- int i, rc; -- int e; -- -- rc = 0; -- for (i = 0; i < fifo->count; ++i) { -- e = fifo->elems[inth_index(fifo, i)]; -- if (e == id) { -- ++rc; -- } -- else if (rc) { -- fifo->elems[inth_index(fifo, i-rc)] = e; -- } -- } -- if (rc) { -- fifo->count -= rc; -- if (fifo->count + rc == fifo->nelems) { -- apr_thread_cond_broadcast(fifo->not_full); -- } -- rv = APR_SUCCESS; -+ rc = 0; -+ for (i = 0; i < fifo->count; ++i) { -+ int e = fifo->elems[inth_index(fifo, i)]; -+ if (e == id) { -+ ++rc; - } -- else { -- rv = APR_EAGAIN; -+ else if (rc) { -+ fifo->elems[inth_index(fifo, i-rc)] = e; - } -- -+ } -+ if (!rc) { -+ return APR_EAGAIN; -+ } -+ fifo->count -= rc; -+ if (fifo->count + rc == fifo->nelems) { -+ apr_thread_cond_broadcast(fifo->not_full); -+ } -+ return APR_SUCCESS; -+} -+ -+apr_status_t h2_ififo_remove(h2_ififo *fifo, int id) -+{ -+ apr_status_t rv; -+ -+ if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) { -+ rv = ififo_remove(fifo, id); - apr_thread_mutex_unlock(fifo->lock); - } - return rv; -@@ -1373,7 +1336,7 @@ - return status; - } - else if (blen == 0) { -- /* brigade without data, does it have an EOS bucket somwhere? */ -+ /* brigade without data, does it have an EOS bucket somewhere? */ - *plen = 0; - *peos = h2_util_has_eos(bb, -1); - } -@@ -1840,22 +1803,29 @@ - } - - apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool, -- const char *name, size_t nlen, -- const char *value, size_t vlen) -+ const char *name, size_t nlen, -+ const char *value, size_t vlen, -+ size_t max_field_len, int *pwas_added) - { - char *hname, *hvalue; -+ const char *existing; - -+ *pwas_added = 0; - if (h2_req_ignore_header(name, nlen)) { - return APR_SUCCESS; - } - else if (H2_HD_MATCH_LIT("cookie", name, nlen)) { -- const char *existing = apr_table_get(headers, "cookie"); -+ existing = apr_table_get(headers, "cookie"); - if (existing) { - char *nval; - - /* Cookie header come separately in HTTP/2, but need - * to be merged by "; " (instead of default ", ") - */ -+ if (max_field_len && strlen(existing) + vlen + nlen + 4 > max_field_len) { -+ /* "key: oldval, nval" is too long */ -+ return APR_EINVAL; -+ } - hvalue = apr_pstrndup(pool, value, vlen); - nval = apr_psprintf(pool, "%s; %s", existing, hvalue); - apr_table_setn(headers, "Cookie", nval); -@@ -1869,8 +1839,16 @@ - } - - hname = apr_pstrndup(pool, name, nlen); -- hvalue = apr_pstrndup(pool, value, vlen); - h2_util_camel_case_header(hname, nlen); -+ existing = apr_table_get(headers, hname); -+ if (max_field_len) { -+ if ((existing? strlen(existing)+2 : 0) + vlen + nlen + 2 > max_field_len) { -+ /* "key: (oldval, )?nval" is too long */ -+ return APR_EINVAL; -+ } -+ } -+ if (!existing) *pwas_added = 1; -+ hvalue = apr_pstrndup(pool, value, vlen); - apr_table_mergen(headers, hname, hvalue); - - return APR_SUCCESS; -@@ -1960,7 +1938,8 @@ - case NGHTTP2_GOAWAY: { - size_t len = (frame->goaway.opaque_data_len < s_len)? - frame->goaway.opaque_data_len : s_len-1; -- memcpy(scratch, frame->goaway.opaque_data, len); -+ if (len) -+ memcpy(scratch, frame->goaway.opaque_data, len); - scratch[len] = '\0'; - return apr_snprintf(buffer, maxlen, "GOAWAY[error=%d, reason='%s', " - "last_stream=%d]", frame->goaway.error_code, ---- a/modules/http2/h2_util.h -+++ b/modules/http2/h2_util.h -@@ -209,7 +209,6 @@ - apr_status_t h2_fifo_set_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity); - - apr_status_t h2_fifo_term(h2_fifo *fifo); --apr_status_t h2_fifo_interrupt(h2_fifo *fifo); - - int h2_fifo_count(h2_fifo *fifo); - -@@ -229,7 +228,7 @@ - - typedef enum { - H2_FIFO_OP_PULL, /* pull the element from the queue, ie discard it */ -- H2_FIFO_OP_REPUSH, /* pull and immediatley re-push it */ -+ H2_FIFO_OP_REPUSH, /* pull and immediately re-push it */ - } h2_fifo_op_t; - - typedef h2_fifo_op_t h2_fifo_peek_fn(void *head, void *ctx); -@@ -280,7 +279,6 @@ - apr_status_t h2_ififo_set_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity); - - apr_status_t h2_ififo_term(h2_ififo *fifo); --apr_status_t h2_ififo_interrupt(h2_ififo *fifo); - - int h2_ififo_count(h2_ififo *fifo); - -@@ -412,9 +410,14 @@ - apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p, - const struct h2_request *req); - -+/** -+ * Add a HTTP/2 header and return the table key if it really was added -+ * and not ignored. -+ */ - apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool, - const char *name, size_t nlen, -- const char *value, size_t vlen); -+ const char *value, size_t vlen, -+ size_t max_field_len, int *pwas_added); - - /******************************************************************************* - * h2_request helpers ---- a/modules/http2/h2_version.h -+++ b/modules/http2/h2_version.h -@@ -27,7 +27,7 @@ - * @macro - * Version number of the http2 module as c string - */ --#define MOD_HTTP2_VERSION "1.11.4" -+#define MOD_HTTP2_VERSION "1.15.14" - - /** - * @macro -@@ -35,7 +35,6 @@ - * release. This is a 24 bit number with 8 bits for major number, 8 bits - * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. - */ --#define MOD_HTTP2_VERSION_NUM 0x010b04 -- -+#define MOD_HTTP2_VERSION_NUM 0x010f0e - - #endif /* mod_h2_h2_version_h */ ---- a/modules/http2/h2_workers.c -+++ b/modules/http2/h2_workers.c -@@ -155,7 +155,7 @@ - { - apr_status_t rv; - -- rv = h2_mplx_pop_task(m, &slot->task); -+ rv = h2_mplx_s_pop_task(m, &slot->task); - if (slot->task) { - /* Ok, we got something to give back to the worker for execution. - * If we still have idle workers, we let the worker be sticky, -@@ -234,10 +234,10 @@ - * mplx the opportunity to give us back a new task right away. - */ - if (!slot->aborted && (--slot->sticks > 0)) { -- h2_mplx_task_done(slot->task->mplx, slot->task, &slot->task); -+ h2_mplx_s_task_done(slot->task->mplx, slot->task, &slot->task); - } - else { -- h2_mplx_task_done(slot->task->mplx, slot->task, NULL); -+ h2_mplx_s_task_done(slot->task->mplx, slot->task, NULL); - slot->task = NULL; - } - } -@@ -269,7 +269,6 @@ - } - - h2_fifo_term(workers->mplxs); -- h2_fifo_interrupt(workers->mplxs); - - cleanup_zombies(workers); - } ---- a/modules/http2/mod_http2.c -+++ b/modules/http2/mod_http2.c -@@ -172,27 +172,6 @@ - conn_rec *, request_rec *, char *name); - static int http2_is_h2(conn_rec *); - --static apr_status_t http2_req_engine_push(const char *ngn_type, -- request_rec *r, -- http2_req_engine_init *einit) --{ -- return h2_mplx_req_engine_push(ngn_type, r, einit); --} -- --static apr_status_t http2_req_engine_pull(h2_req_engine *ngn, -- apr_read_type_e block, -- int capacity, -- request_rec **pr) --{ -- return h2_mplx_req_engine_pull(ngn, block, capacity, pr); --} -- --static void http2_req_engine_done(h2_req_engine *ngn, conn_rec *r_conn, -- apr_status_t status) --{ -- h2_mplx_req_engine_done(ngn, r_conn, status); --} -- - static void http2_get_num_workers(server_rec *s, int *minw, int *maxw) - { - h2_get_num_workers(s, minw, maxw); -@@ -220,9 +199,6 @@ - - APR_REGISTER_OPTIONAL_FN(http2_is_h2); - APR_REGISTER_OPTIONAL_FN(http2_var_lookup); -- APR_REGISTER_OPTIONAL_FN(http2_req_engine_push); -- APR_REGISTER_OPTIONAL_FN(http2_req_engine_pull); -- APR_REGISTER_OPTIONAL_FN(http2_req_engine_done); - APR_REGISTER_OPTIONAL_FN(http2_get_num_workers); - - ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks"); -@@ -260,9 +236,8 @@ - { - if (ctx) { - if (r) { -- h2_task *task = h2_ctx_get_task(ctx); -- if (task) { -- h2_stream *stream = h2_mplx_stream_get(task->mplx, task->stream_id); -+ if (ctx->task) { -+ h2_stream *stream = h2_mplx_t_stream_get(ctx->task->mplx, ctx->task); - if (stream && stream->push_policy != H2_PUSH_NONE) { - return "on"; - } -@@ -273,8 +248,7 @@ - } - } - else if (s) { -- const h2_config *cfg = h2_config_sget(s); -- if (cfg && h2_config_geti(cfg, H2_CONF_PUSH)) { -+ if (h2_config_geti(r, s, H2_CONF_PUSH)) { - return "on"; - } - } -@@ -285,8 +259,7 @@ - conn_rec *c, request_rec *r, h2_ctx *ctx) - { - if (ctx) { -- h2_task *task = h2_ctx_get_task(ctx); -- if (task && !H2_STREAM_CLIENT_INITIATED(task->stream_id)) { -+ if (ctx->task && !H2_STREAM_CLIENT_INITIATED(ctx->task->stream_id)) { - return "PUSHED"; - } - } -@@ -297,9 +270,8 @@ - conn_rec *c, request_rec *r, h2_ctx *ctx) - { - if (ctx) { -- h2_task *task = h2_ctx_get_task(ctx); -- if (task && !H2_STREAM_CLIENT_INITIATED(task->stream_id)) { -- h2_stream *stream = h2_mplx_stream_get(task->mplx, task->stream_id); -+ if (ctx->task && !H2_STREAM_CLIENT_INITIATED(ctx->task->stream_id)) { -+ h2_stream *stream = h2_mplx_t_stream_get(ctx->task->mplx, ctx->task); - if (stream) { - return apr_itoa(p, stream->initiated_on); - } -@@ -312,9 +284,8 @@ - conn_rec *c, request_rec *r, h2_ctx *ctx) - { - if (ctx) { -- h2_task *task = h2_ctx_get_task(ctx); -- if (task) { -- return task->id; -+ if (ctx->task) { -+ return ctx->task->id; - } - } - return ""; -@@ -366,7 +337,7 @@ - for (i = 0; i < H2_ALEN(H2_VARS); ++i) { - h2_var_def *vdef = &H2_VARS[i]; - if (!strcmp(vdef->name, name)) { -- h2_ctx *ctx = (r? h2_ctx_rget(r) : -+ h2_ctx *ctx = (r? h2_ctx_get(c, 0) : - h2_ctx_get(c->master? c->master : c, 0)); - return (char *)vdef->lookup(p, s, c, r, ctx); - } -@@ -377,7 +348,7 @@ - static int h2_h2_fixups(request_rec *r) - { - if (r->connection->master) { -- h2_ctx *ctx = h2_ctx_rget(r); -+ h2_ctx *ctx = h2_ctx_get(r->connection, 0); - int i; - - for (i = 0; ctx && i < H2_ALEN(H2_VARS); ++i) { ---- a/modules/http2/mod_http2.dep -+++ b/modules/http2/mod_http2.dep -@@ -694,7 +694,6 @@ - ".\h2_ctx.h"\ - ".\h2_h2.h"\ - ".\h2_mplx.h"\ -- ".\h2_ngn_shed.h"\ - ".\h2_private.h"\ - ".\h2_request.h"\ - ".\h2_stream.h"\ -@@ -754,7 +753,6 @@ - ".\h2_ctx.h"\ - ".\h2_h2.h"\ - ".\h2_mplx.h"\ -- ".\h2_ngn_shed.h"\ - ".\h2_private.h"\ - ".\h2_request.h"\ - ".\h2_task.h"\ ---- a/modules/http2/mod_http2.dsp -+++ b/modules/http2/mod_http2.dsp -@@ -145,10 +145,6 @@ - # End Source File - # Begin Source File - --SOURCE=./h2_ngn_shed.c --# End Source File --# Begin Source File -- - SOURCE=./h2_push.c - # End Source File - # Begin Source File ---- a/modules/http2/mod_http2.h -+++ b/modules/http2/mod_http2.h -@@ -30,22 +30,20 @@ - - - /******************************************************************************* -- * HTTP/2 request engines -+ * START HTTP/2 request engines (DEPRECATED) - ******************************************************************************/ -+ -+/* The following functions were introduced for the experimental mod_proxy_http2 -+ * support, but have been abandoned since. -+ * They are still declared here for backward compatibility, in case someone -+ * tries to build an old mod_proxy_http2 against it, but will disappear -+ * completely sometime in the future. -+ */ - - struct apr_thread_cond_t; -- - typedef struct h2_req_engine h2_req_engine; -- - typedef void http2_output_consumed(void *ctx, conn_rec *c, apr_off_t consumed); - --/** -- * Initialize a h2_req_engine. The structure will be passed in but -- * only the name and master are set. The function should initialize -- * all fields. -- * @param engine the allocated, partially filled structure -- * @param r the first request to process, or NULL -- */ - typedef apr_status_t http2_req_engine_init(h2_req_engine *engine, - const char *id, - const char *type, -@@ -55,35 +53,11 @@ - http2_output_consumed **pconsumed, - void **pbaton); - --/** -- * Push a request to an engine with the specified name for further processing. -- * If no such engine is available, einit is not NULL, einit is called -- * with a new engine record and the caller is responsible for running the -- * new engine instance. -- * @param engine_type the type of the engine to add the request to -- * @param r the request to push to an engine for processing -- * @param einit an optional initialization callback for a new engine -- * of the requested type, should no instance be available. -- * By passing a non-NULL callback, the caller is willing -- * to init and run a new engine itself. -- * @return APR_SUCCESS iff slave was successfully added to an engine -- */ - APR_DECLARE_OPTIONAL_FN(apr_status_t, - http2_req_engine_push, (const char *engine_type, - request_rec *r, - http2_req_engine_init *einit)); - --/** -- * Get a new request for processing in this engine. -- * @param engine the engine which is done processing the slave -- * @param block if call should block waiting for request to come -- * @param capacity how many parallel requests are acceptable -- * @param pr the request that needs processing or NULL -- * @return APR_SUCCESS if new request was assigned -- * APR_EAGAIN if no new request is available -- * APR_EOF if engine may shut down, as no more request will be scheduled -- * APR_ECONNABORTED if the engine needs to shut down immediately -- */ - APR_DECLARE_OPTIONAL_FN(apr_status_t, - http2_req_engine_pull, (h2_req_engine *engine, - apr_read_type_e block, -@@ -98,4 +72,8 @@ - http2_get_num_workers, (server_rec *s, - int *minw, int *max)); - -+/******************************************************************************* -+ * END HTTP/2 request engines (DEPRECATED) -+ ******************************************************************************/ -+ - #endif ---- a/modules/http2/mod_http2.mak -+++ b/modules/http2/mod_http2.mak -@@ -61,7 +61,6 @@ - -@erase "$(INTDIR)\h2_h2.obj" - -@erase "$(INTDIR)\h2_headers.obj" - -@erase "$(INTDIR)\h2_mplx.obj" -- -@erase "$(INTDIR)\h2_ngn_shed.obj" - -@erase "$(INTDIR)\h2_push.obj" - -@erase "$(INTDIR)\h2_request.obj" - -@erase "$(INTDIR)\h2_session.obj" -@@ -138,7 +137,6 @@ - "$(INTDIR)\h2_h2.obj" \ - "$(INTDIR)\h2_headers.obj" \ - "$(INTDIR)\h2_mplx.obj" \ -- "$(INTDIR)\h2_ngn_shed.obj" \ - "$(INTDIR)\h2_push.obj" \ - "$(INTDIR)\h2_request.obj" \ - "$(INTDIR)\h2_session.obj" \ -@@ -207,7 +205,6 @@ - -@erase "$(INTDIR)\h2_h2.obj" - -@erase "$(INTDIR)\h2_headers.obj" - -@erase "$(INTDIR)\h2_mplx.obj" -- -@erase "$(INTDIR)\h2_ngn_shed.obj" - -@erase "$(INTDIR)\h2_push.obj" - -@erase "$(INTDIR)\h2_request.obj" - -@erase "$(INTDIR)\h2_session.obj" -@@ -284,7 +281,6 @@ - "$(INTDIR)\h2_h2.obj" \ - "$(INTDIR)\h2_headers.obj" \ - "$(INTDIR)\h2_mplx.obj" \ -- "$(INTDIR)\h2_ngn_shed.obj" \ - "$(INTDIR)\h2_push.obj" \ - "$(INTDIR)\h2_request.obj" \ - "$(INTDIR)\h2_session.obj" \ -@@ -469,11 +465,6 @@ - "$(INTDIR)\h2_mplx.obj" : $(SOURCE) "$(INTDIR)" - - --SOURCE=./h2_ngn_shed.c -- --"$(INTDIR)\h2_ngn_shed.obj" : $(SOURCE) "$(INTDIR)" -- -- - SOURCE=./h2_push.c - - "$(INTDIR)\h2_push.obj" : $(SOURCE) "$(INTDIR)" ---- a/modules/http2/mod_proxy_http2.c -+++ b/modules/http2/mod_proxy_http2.c -@@ -16,13 +16,14 @@ - - #include <nghttp2/nghttp2.h> - -+#include <ap_mmn.h> - #include <httpd.h> - #include <mod_proxy.h> - #include "mod_http2.h" - - - #include "mod_proxy_http2.h" --#include "h2_request.h" -+#include "h2.h" - #include "h2_proxy_util.h" - #include "h2_version.h" - #include "h2_proxy_session.h" -@@ -46,19 +47,12 @@ - - /* Optional functions from mod_http2 */ - static int (*is_h2)(conn_rec *c); --static apr_status_t (*req_engine_push)(const char *name, request_rec *r, -- http2_req_engine_init *einit); --static apr_status_t (*req_engine_pull)(h2_req_engine *engine, -- apr_read_type_e block, -- int capacity, -- request_rec **pr); --static void (*req_engine_done)(h2_req_engine *engine, conn_rec *r_conn, -- apr_status_t status); -- -+ - typedef struct h2_proxy_ctx { -+ const char *id; -+ conn_rec *master; - conn_rec *owner; - apr_pool_t *pool; -- request_rec *rbase; - server_rec *server; - const char *proxy_func; - char server_portstr[32]; -@@ -66,19 +60,15 @@ - proxy_worker *worker; - proxy_server_conf *conf; - -- h2_req_engine *engine; -- const char *engine_id; -- const char *engine_type; -- apr_pool_t *engine_pool; - apr_size_t req_buffer_size; -- h2_proxy_fifo *requests; - int capacity; - -- unsigned standalone : 1; - unsigned is_ssl : 1; -- unsigned flushall : 1; - -- apr_status_t r_status; /* status of our first request work */ -+ request_rec *r; /* the request processed in this ctx */ -+ apr_status_t r_status; /* status of request work */ -+ int r_done; /* request was processed, not necessarily successfully */ -+ int r_may_retry; /* request may be retried */ - h2_proxy_session *session; /* current http2 session against backend */ - } h2_proxy_ctx; - -@@ -104,16 +94,6 @@ - MOD_HTTP2_VERSION, ngh2? ngh2->version_str : "unknown"); - - is_h2 = APR_RETRIEVE_OPTIONAL_FN(http2_is_h2); -- req_engine_push = APR_RETRIEVE_OPTIONAL_FN(http2_req_engine_push); -- req_engine_pull = APR_RETRIEVE_OPTIONAL_FN(http2_req_engine_pull); -- req_engine_done = APR_RETRIEVE_OPTIONAL_FN(http2_req_engine_done); -- -- /* we need all of them */ -- if (!req_engine_push || !req_engine_pull || !req_engine_done) { -- req_engine_push = NULL; -- req_engine_pull = NULL; -- req_engine_done = NULL; -- } - - return status; - } -@@ -204,45 +184,6 @@ - return OK; - } - --static void out_consumed(void *baton, conn_rec *c, apr_off_t bytes) --{ -- h2_proxy_ctx *ctx = baton; -- -- if (ctx->session) { -- h2_proxy_session_update_window(ctx->session, c, bytes); -- } --} -- --static apr_status_t proxy_engine_init(h2_req_engine *engine, -- const char *id, -- const char *type, -- apr_pool_t *pool, -- apr_size_t req_buffer_size, -- request_rec *r, -- http2_output_consumed **pconsumed, -- void **pctx) --{ -- h2_proxy_ctx *ctx = ap_get_module_config(r->connection->conn_config, -- &proxy_http2_module); -- if (!ctx) { -- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03368) -- "h2_proxy_session, engine init, no ctx found"); -- return APR_ENOTIMPL; -- } -- -- ctx->pool = pool; -- ctx->engine = engine; -- ctx->engine_id = id; -- ctx->engine_type = type; -- ctx->engine_pool = pool; -- ctx->req_buffer_size = req_buffer_size; -- ctx->capacity = H2MIN(100, h2_proxy_fifo_capacity(ctx->requests)); -- -- *pconsumed = out_consumed; -- *pctx = ctx; -- return APR_SUCCESS; --} -- - static apr_status_t add_request(h2_proxy_session *session, request_rec *r) - { - h2_proxy_ctx *ctx = session->user_data; -@@ -252,7 +193,7 @@ - url = apr_table_get(r->notes, H2_PROXY_REQ_URL_NOTE); - apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu", - ctx->p_conn->connection->local_addr->port)); -- status = h2_proxy_session_submit(session, url, r, ctx->standalone); -+ status = h2_proxy_session_submit(session, url, r, 1); - if (status != APR_SUCCESS) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, status, r->connection, APLOGNO(03351) - "pass request body failed to %pI (%s) from %s (%s)", -@@ -266,43 +207,15 @@ - static void request_done(h2_proxy_ctx *ctx, request_rec *r, - apr_status_t status, int touched) - { -- const char *task_id = apr_table_get(r->connection->notes, H2_TASK_ID_NOTE); -- -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, r->connection, -- "h2_proxy_session(%s): request done %s, touched=%d", -- ctx->engine_id, task_id, touched); -- if (status != APR_SUCCESS) { -- if (!touched) { -- /* untouched request, need rescheduling */ -- status = h2_proxy_fifo_push(ctx->requests, r); -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, r->connection, -- APLOGNO(03369) -- "h2_proxy_session(%s): rescheduled request %s", -- ctx->engine_id, task_id); -- return; -- } -- else { -- const char *uri; -- uri = apr_uri_unparse(r->pool, &r->parsed_uri, 0); -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, r->connection, -- APLOGNO(03471) "h2_proxy_session(%s): request %s -> %s " -- "not complete, cannot repeat", -- ctx->engine_id, task_id, uri); -- } -- } -- -- if (r == ctx->rbase) { -+ if (r == ctx->r) { -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, r->connection, -+ "h2_proxy_session(%s): request done, touched=%d", -+ ctx->id, touched); -+ ctx->r_done = 1; -+ if (touched) ctx->r_may_retry = 0; - ctx->r_status = ((status == APR_SUCCESS)? APR_SUCCESS - : HTTP_SERVICE_UNAVAILABLE); - } -- -- if (req_engine_done && ctx->engine) { -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, r->connection, -- APLOGNO(03370) -- "h2_proxy_session(%s): finished request %s", -- ctx->engine_id, task_id); -- req_engine_done(ctx->engine, r->connection, status); -- } - } - - static void session_req_done(h2_proxy_session *session, request_rec *r, -@@ -311,43 +224,15 @@ - request_done(session->user_data, r, status, touched); - } - --static apr_status_t next_request(h2_proxy_ctx *ctx, int before_leave) --{ -- if (h2_proxy_fifo_count(ctx->requests) > 0) { -- return APR_SUCCESS; -- } -- else if (req_engine_pull && ctx->engine) { -- apr_status_t status; -- request_rec *r = NULL; -- -- status = req_engine_pull(ctx->engine, before_leave? -- APR_BLOCK_READ: APR_NONBLOCK_READ, -- ctx->capacity, &r); -- if (status == APR_SUCCESS && r) { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, ctx->owner, -- "h2_proxy_engine(%s): pulled request (%s) %s", -- ctx->engine_id, -- before_leave? "before leave" : "regular", -- r->the_request); -- h2_proxy_fifo_push(ctx->requests, r); -- } -- return APR_STATUS_IS_EAGAIN(status)? APR_SUCCESS : status; -- } -- return APR_EOF; --} -- --static apr_status_t proxy_engine_run(h2_proxy_ctx *ctx) { -+static apr_status_t ctx_run(h2_proxy_ctx *ctx) { - apr_status_t status = OK; - int h2_front; -- request_rec *r; - - /* Step Four: Send the Request in a new HTTP/2 stream and - * loop until we got the response or encounter errors. - */ -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->owner, -- "eng(%s): setup session", ctx->engine_id); - h2_front = is_h2? is_h2(ctx->owner) : 0; -- ctx->session = h2_proxy_session_setup(ctx->engine_id, ctx->p_conn, ctx->conf, -+ ctx->session = h2_proxy_session_setup(ctx->id, ctx->p_conn, ctx->conf, - h2_front, 30, - h2_proxy_log2((int)ctx->req_buffer_size), - session_req_done); -@@ -358,105 +243,45 @@ - } - - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->owner, APLOGNO(03373) -- "eng(%s): run session %s", ctx->engine_id, ctx->session->id); -+ "eng(%s): run session %s", ctx->id, ctx->session->id); - ctx->session->user_data = ctx; - -- while (!ctx->owner->aborted) { -- if (APR_SUCCESS == h2_proxy_fifo_try_pull(ctx->requests, (void**)&r)) { -- add_request(ctx->session, r); -- } -- -+ ctx->r_done = 0; -+ add_request(ctx->session, ctx->r); -+ -+ while (!ctx->master->aborted && !ctx->r_done) { -+ - status = h2_proxy_session_process(ctx->session); -- -- if (status == APR_SUCCESS) { -- apr_status_t s2; -- /* ongoing processing, call again */ -- if (ctx->session->remote_max_concurrent > 0 -- && ctx->session->remote_max_concurrent != ctx->capacity) { -- ctx->capacity = H2MIN((int)ctx->session->remote_max_concurrent, -- h2_proxy_fifo_capacity(ctx->requests)); -- } -- s2 = next_request(ctx, 0); -- if (s2 == APR_ECONNABORTED) { -- /* master connection gone */ -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, s2, ctx->owner, -- APLOGNO(03374) "eng(%s): pull request", -- ctx->engine_id); -- /* give notice that we're leaving and cancel all ongoing -- * streams. */ -- next_request(ctx, 1); -- h2_proxy_session_cancel_all(ctx->session); -- h2_proxy_session_process(ctx->session); -- status = ctx->r_status = APR_SUCCESS; -- break; -- } -- if ((h2_proxy_fifo_count(ctx->requests) == 0) -- && h2_proxy_ihash_empty(ctx->session->streams)) { -- break; -- } -- } -- else { -- /* end of processing, maybe error */ -+ if (status != APR_SUCCESS) { -+ /* Encountered an error during session processing */ - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, - APLOGNO(03375) "eng(%s): end of session %s", -- ctx->engine_id, ctx->session->id); -- /* -- * Any open stream of that session needs to -+ ctx->id, ctx->session->id); -+ /* Any open stream of that session needs to - * a) be reopened on the new session iff safe to do so - * b) reported as done (failed) otherwise - */ - h2_proxy_session_cleanup(ctx->session, session_req_done); -- break; -+ goto out; - } - } - -- ctx->session->user_data = NULL; -- ctx->session = NULL; -- -- return status; --} -- --static apr_status_t push_request_somewhere(h2_proxy_ctx *ctx, request_rec *r) --{ -- conn_rec *c = ctx->owner; -- const char *engine_type, *hostname; -- -- hostname = (ctx->p_conn->ssl_hostname? -- ctx->p_conn->ssl_hostname : ctx->p_conn->hostname); -- engine_type = apr_psprintf(ctx->pool, "proxy_http2 %s%s", hostname, -- ctx->server_portstr); -- -- if (c->master && req_engine_push && r && is_h2 && is_h2(c)) { -- /* If we are have req_engine capabilities, push the handling of this -- * request (e.g. slave connection) to a proxy_http2 engine which -- * uses the same backend. We may be called to create an engine -- * ourself. */ -- if (req_engine_push(engine_type, r, proxy_engine_init) == APR_SUCCESS) { -- if (ctx->engine == NULL) { -- /* request has been assigned to an engine in another thread */ -- return SUSPENDED; -- } -+out: -+ if (ctx->master->aborted) { -+ /* master connection gone */ -+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, -+ APLOGNO(03374) "eng(%s): master connection gone", ctx->id); -+ /* cancel all ongoing requests */ -+ h2_proxy_session_cancel_all(ctx->session); -+ h2_proxy_session_process(ctx->session); -+ if (!ctx->master->aborted) { -+ status = ctx->r_status = APR_SUCCESS; - } - } - -- if (!ctx->engine) { -- /* No engine was available or has been initialized, handle this -- * request just by ourself. */ -- ctx->engine_id = apr_psprintf(ctx->pool, "eng-proxy-%ld", c->id); -- ctx->engine_type = engine_type; -- ctx->engine_pool = ctx->pool; -- ctx->req_buffer_size = (32*1024); -- ctx->standalone = 1; -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -- "h2_proxy_http2(%ld): setup standalone engine for type %s", -- c->id, engine_type); -- } -- else { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, -- "H2: hosting engine %s", ctx->engine_id); -- } -- -- return h2_proxy_fifo_push(ctx->requests, r); -+ ctx->session->user_data = NULL; -+ ctx->session = NULL; -+ return status; - } - - static int proxy_http2_handler(request_rec *r, -@@ -466,7 +291,7 @@ - const char *proxyname, - apr_port_t proxyport) - { -- const char *proxy_func; -+ const char *proxy_func, *task_id; - char *locurl = url, *u; - apr_size_t slen; - int is_ssl = 0; -@@ -498,29 +323,35 @@ - default: - return DECLINED; - } -+ -+ task_id = apr_table_get(r->connection->notes, H2_TASK_ID_NOTE); - - ctx = apr_pcalloc(r->pool, sizeof(*ctx)); -- ctx->owner = r->connection; -- ctx->pool = r->pool; -- ctx->rbase = r; -- ctx->server = r->server; -+ ctx->master = r->connection->master? r->connection->master : r->connection; -+ ctx->id = task_id? task_id : apr_psprintf(r->pool, "%ld", (long)ctx->master->id); -+ ctx->owner = r->connection; -+ ctx->pool = r->pool; -+ ctx->server = r->server; - ctx->proxy_func = proxy_func; -- ctx->is_ssl = is_ssl; -- ctx->worker = worker; -- ctx->conf = conf; -- ctx->flushall = apr_table_get(r->subprocess_env, "proxy-flushall")? 1 : 0; -- ctx->r_status = HTTP_SERVICE_UNAVAILABLE; -- -- h2_proxy_fifo_set_create(&ctx->requests, ctx->pool, 100); -+ ctx->is_ssl = is_ssl; -+ ctx->worker = worker; -+ ctx->conf = conf; -+ ctx->req_buffer_size = (32*1024); -+ ctx->r = r; -+ ctx->r_status = status = HTTP_SERVICE_UNAVAILABLE; -+ ctx->r_done = 0; -+ ctx->r_may_retry = 1; - - ap_set_module_config(ctx->owner->conn_config, &proxy_http2_module, ctx); - - /* scheme says, this is for us. */ -- apr_table_setn(ctx->rbase->notes, H2_PROXY_REQ_URL_NOTE, url); -- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->rbase, -+ apr_table_setn(ctx->r->notes, H2_PROXY_REQ_URL_NOTE, url); -+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->r, - "H2: serving URL %s", url); - - run_connect: -+ if (ctx->master->aborted) goto cleanup; -+ - /* Get a proxy_conn_rec from the worker, might be a new one, might - * be one still open from another request, or it might fail if the - * worker is stopped or in error. */ -@@ -530,25 +361,11 @@ - } - - ctx->p_conn->is_ssl = ctx->is_ssl; -- if (ctx->is_ssl && ctx->p_conn->connection) { -- /* If there are some metadata on the connection (e.g. TLS alert), -- * let mod_ssl detect them, and create a new connection below. -- */ -- apr_bucket_brigade *tmp_bb; -- tmp_bb = apr_brigade_create(ctx->rbase->pool, -- ctx->rbase->connection->bucket_alloc); -- status = ap_get_brigade(ctx->p_conn->connection->input_filters, tmp_bb, -- AP_MODE_SPECULATIVE, APR_NONBLOCK_READ, 1); -- if (status != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(status)) { -- ctx->p_conn->close = 1; -- } -- apr_brigade_cleanup(tmp_bb); -- } - - /* Step One: Determine the URL to connect to (might be a proxy), - * initialize the backend accordingly and determine the server - * port string we can expect in responses. */ -- if ((status = ap_proxy_determine_connection(ctx->pool, ctx->rbase, conf, worker, -+ if ((status = ap_proxy_determine_connection(ctx->pool, ctx->r, conf, worker, - ctx->p_conn, &uri, &locurl, - proxyname, proxyport, - ctx->server_portstr, -@@ -556,17 +373,6 @@ - goto cleanup; - } - -- /* If we are not already hosting an engine, try to push the request -- * to an already existing engine or host a new engine here. */ -- if (r && !ctx->engine) { -- ctx->r_status = push_request_somewhere(ctx, r); -- r = NULL; -- if (ctx->r_status == SUSPENDED) { -- /* request was pushed to another thread, leave processing here */ -- goto cleanup; -- } -- } -- - /* Step Two: Make the Connection (or check that an already existing - * socket is still usable). On success, we have a socket connected to - * backend->hostname. */ -@@ -575,70 +381,56 @@ - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->owner, APLOGNO(03352) - "H2: failed to make connection to backend: %s", - ctx->p_conn->hostname); -- goto reconnect; -+ goto cleanup; - } - - /* Step Three: Create conn_rec for the socket we have open now. */ -- if (!ctx->p_conn->connection) { -- status = ap_proxy_connection_create_ex(ctx->proxy_func, -- ctx->p_conn, ctx->rbase); -- if (status != OK) { -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, APLOGNO(03353) -- "setup new connection: is_ssl=%d %s %s %s", -- ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname, -- locurl, ctx->p_conn->hostname); -- goto reconnect; -- } -- -- if (!ctx->p_conn->data) { -- /* New conection: set a note on the connection what CN is -- * requested and what protocol we want */ -- if (ctx->p_conn->ssl_hostname) { -- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, ctx->owner, -- "set SNI to %s for (%s)", -- ctx->p_conn->ssl_hostname, -- ctx->p_conn->hostname); -- apr_table_setn(ctx->p_conn->connection->notes, -- "proxy-request-hostname", ctx->p_conn->ssl_hostname); -- } -- if (ctx->is_ssl) { -- apr_table_setn(ctx->p_conn->connection->notes, -- "proxy-request-alpn-protos", "h2"); -- } -- } -+ status = ap_proxy_connection_create_ex(ctx->proxy_func, ctx->p_conn, ctx->r); -+ if (status != OK) { -+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, APLOGNO(03353) -+ "setup new connection: is_ssl=%d %s %s %s", -+ ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname, -+ locurl, ctx->p_conn->hostname); -+ ctx->r_status = status; -+ goto cleanup; - } -- --run_session: -- status = proxy_engine_run(ctx); -- if (status == APR_SUCCESS) { -- /* session and connection still ok */ -- if (next_request(ctx, 1) == APR_SUCCESS) { -- /* more requests, run again */ -- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->owner, APLOGNO(03376) -- "run_session, again"); -- goto run_session; -+ -+ if (!ctx->p_conn->data && ctx->is_ssl) { -+ /* New SSL connection: set a note on the connection about what -+ * protocol we want. -+ */ -+ apr_table_setn(ctx->p_conn->connection->notes, -+ "proxy-request-alpn-protos", "h2"); -+ if (ctx->p_conn->ssl_hostname) { -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->owner, -+ "set SNI to %s for (%s)", -+ ctx->p_conn->ssl_hostname, -+ ctx->p_conn->hostname); -+ apr_table_setn(ctx->p_conn->connection->notes, -+ "proxy-request-hostname", ctx->p_conn->ssl_hostname); - } -- /* done */ -- ctx->engine = NULL; - } - --reconnect: -- if (next_request(ctx, 1) == APR_SUCCESS) { -- /* Still more to do, tear down old conn and start over */ -+ if (ctx->master->aborted) goto cleanup; -+ status = ctx_run(ctx); -+ -+ if (ctx->r_status != APR_SUCCESS && ctx->r_may_retry && !ctx->master->aborted) { -+ /* Not successfully processed, but may retry, tear down old conn and start over */ - if (ctx->p_conn) { - ctx->p_conn->close = 1; -- /*only in trunk so far */ -- /*proxy_run_detach_backend(r, ctx->p_conn);*/ -+#if AP_MODULE_MAGIC_AT_LEAST(20140207, 2) -+ proxy_run_detach_backend(r, ctx->p_conn); -+#endif - ap_proxy_release_connection(ctx->proxy_func, ctx->p_conn, ctx->server); - ctx->p_conn = NULL; - } - ++reconnects; -- if (reconnects < 5 && !ctx->owner->aborted) { -+ if (reconnects < 5) { - goto run_connect; - } - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->owner, APLOGNO(10023) -- "giving up after %d reconnects, %d requests todo", -- reconnects, h2_proxy_fifo_count(ctx->requests)); -+ "giving up after %d reconnects, request-done=%d", -+ reconnects, ctx->r_done); - } - - cleanup: -@@ -647,17 +439,13 @@ - /* close socket when errors happened or session shut down (EOF) */ - ctx->p_conn->close = 1; - } -- /*only in trunk so far */ -- /*proxy_run_detach_backend(ctx->rbase, ctx->p_conn);*/ -+#if AP_MODULE_MAGIC_AT_LEAST(20140207, 2) -+ proxy_run_detach_backend(ctx->r, ctx->p_conn); -+#endif - ap_proxy_release_connection(ctx->proxy_func, ctx->p_conn, ctx->server); - ctx->p_conn = NULL; - } - -- /* Any requests will still have need to fail */ -- while (APR_SUCCESS == h2_proxy_fifo_try_pull(ctx->requests, (void**)&r)) { -- request_done(ctx, r, HTTP_SERVICE_UNAVAILABLE, 1); -- } -- - ap_set_module_config(ctx->owner->conn_config, &proxy_http2_module, NULL); - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, - APLOGNO(03377) "leaving handler"); diff --git a/debian/patches/reproducible_builds.diff b/debian/patches/reproducible_builds.diff index 36f71e2..8f48922 100644 --- a/debian/patches/reproducible_builds.diff +++ b/debian/patches/reproducible_builds.diff @@ -18,7 +18,7 @@ Last-Update: 2015-08-11 -#endif +static const char server_built[] = BUILD_DATETIME; - AP_DECLARE(const char *) ap_get_server_built() + AP_DECLARE(const char *) ap_get_server_built(void) { --- a/server/Makefile.in +++ b/server/Makefile.in diff --git a/debian/patches/series b/debian/patches/series index 839511c..49ae838 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -4,60 +4,7 @@ suexec-CVE-2007-1742.patch customize_apxs.patch build_suexec-custom.patch reproducible_builds.diff +fix-macro.patch # This patch is applied manually #suexec-custom.patch -spelling-errors.patch - -CVE-2019-0196.patch -CVE-2019-0211.patch -CVE-2019-0215.patch -CVE-2019-0217.patch -CVE-2019-0220-1.patch -CVE-2019-0220-2.patch -CVE-2019-0220-3.patch -CVE-2019-0197.patch -CVE-2019-10092.patch -CVE-2019-10097.patch -CVE-2019-10098.patch -import-http2-module-from-2.4.46.patch -CVE-2020-11984.patch -CVE-2020-1927.patch -CVE-2020-1934.patch -CVE-2021-31618.patch -CVE-2021-30641.patch -CVE-2021-26691.patch -CVE-2021-26690.patch -CVE-2020-35452.patch -CVE-2021-34798.patch -CVE-2021-36160.patch -CVE-2021-39275.patch -CVE-2021-40438.patch -CVE-2021-44224-1.patch -CVE-2021-44224-2.patch -CVE-2021-44790.patch -CVE-2021-36160-2.patch -CVE-2022-22719.patch -CVE-2022-22720.patch -CVE-2022-22721.patch -CVE-2022-23943-1.patch -CVE-2022-23943-2.patch -CVE-2022-26377.patch -CVE-2022-28614.patch -CVE-2022-28615.patch -CVE-2022-29404.patch -CVE-2022-30522.patch -CVE-2022-30556.patch -CVE-2022-31813.patch -CVE-2006-20001.patch -CVE-2022-36760.patch -CVE-2022-37436.patch -CVE-2021-33193.patch -0052-CVE-2023-27522-HTTP-Response-Smuggling-mod_proxy_uws.patch -0053-CVE-2023-25690-1.patch -0054-CVE-2023-25690-2.patch -0055-CVE-2023-25690-Regression-1.patch -0056-CVE-2023-25690-Regression-2.patch -0057-CVE-2023-25690-Regression-3.patch - - diff --git a/debian/patches/spelling-errors.patch b/debian/patches/spelling-errors.patch deleted file mode 100644 index d42ec00..0000000 --- a/debian/patches/spelling-errors.patch +++ /dev/null @@ -1,196 +0,0 @@ -Description: spelling errors -Author: Xavier Guimard <yadd@debian.org> -Forwarded: https://bz.apache.org/bugzilla/show_bug.cgi?id=62960 -Last-Update: 2018-11-28 - ---- a/LICENSE -+++ b/LICENSE -@@ -516,7 +516,7 @@ - This program may be used and copied freely providing this copyright notice - is not removed. - --This software is provided "as is" and any express or implied waranties, -+This software is provided "as is" and any express or implied warranties, - including but not limited to, the implied warranties of merchantability and - fitness for a particular purpose are disclaimed. In no event shall - Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, ---- a/docs/man/httxt2dbm.1 -+++ b/docs/man/httxt2dbm.1 -@@ -50,7 +50,7 @@ - Specify the DBM type to be used for the output\&. If not specified, will use the APR Default\&. Available types are: \fBGDBM\fR for GDBM files, \fBSDBM\fR for SDBM files, \fBDB\fR for berkeley DB files, \fBNDBM\fR for NDBM files, \fBdefault\fR for the default DBM type\&. - .TP - \fB-i \fISOURCE_TXT\fR\fR --Input file from which the dbm is to be created\&. The file should be formated with one record per line, of the form: \fBkey value\fR\&. See the documentation for RewriteMap for further details of this file's format and meaning\&. -+Input file from which the dbm is to be created\&. The file should be formatted with one record per line, of the form: \fBkey value\fR\&. See the documentation for RewriteMap for further details of this file's format and meaning\&. - .TP - \fB-o \fIOUTPUT_DBM\fR\fR - Name of the output dbm files\&. ---- a/docs/manual/howto/htaccess.html.ja.utf8 -+++ b/docs/manual/howto/htaccess.html.ja.utf8 -@@ -247,7 +247,7 @@ - - <p>As discussed in the documentation on <a href="../sections.html">Configuration Sections</a>, - <code>.htaccess</code> files can override the <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> sections for -- the corresponding directory, but will be overriden by other types -+ the corresponding directory, but will be overridden by other types - of configuration sections from the main configuration files. This - fact can be used to enforce certain configurations, even in the - presence of a liberal <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> setting. For example, to -@@ -414,4 +414,4 @@ - prettyPrint(); - } - //--><!]]></script> --</body></html> -\ No newline at end of file -+</body></html> ---- a/docs/manual/mod/core.html.es -+++ b/docs/manual/mod/core.html.es -@@ -1211,7 +1211,7 @@ - error rather than masking it. More information is available in - Microsoft Knowledge Base article <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q294807">Q294807</a>.</p> - -- <p>Although most error messages can be overriden, there are certain -+ <p>Although most error messages can be overridden, there are certain - circumstances where the internal messages are used regardless of the - setting of <code class="directive"><a href="#errordocument">ErrorDocument</a></code>. In - particular, if a malformed request is detected, normal request processing -@@ -4524,4 +4524,4 @@ - prettyPrint(); - } - //--><!]]></script> --</body></html> -\ No newline at end of file -+</body></html> ---- a/docs/manual/programs/httxt2dbm.html.en -+++ b/docs/manual/programs/httxt2dbm.html.en -@@ -66,7 +66,7 @@ - </dd> - - <dt><code>-i <var>SOURCE_TXT</var></code></dt> -- <dd>Input file from which the dbm is to be created. The file should be formated -+ <dd>Input file from which the dbm is to be created. The file should be formatted - with one record per line, of the form: <code>key value</code>. - See the documentation for <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> for - further details of this file's format and meaning. -@@ -111,4 +111,4 @@ - prettyPrint(); - } - //--><!]]></script> --</body></html> -\ No newline at end of file -+</body></html> ---- a/modules/http/http_request.c -+++ b/modules/http/http_request.c -@@ -376,7 +376,7 @@ - - /* The EOR bucket has either been handled by an output filter (eg. - * deleted or moved to a buffered_bb => no more in bb), or an error -- * occured before that (eg. c->aborted => still in bb) and we ought -+ * occurred before that (eg. c->aborted => still in bb) and we ought - * to destroy it now. So cleanup any remaining bucket along with - * the orphan request (if any). - */ -@@ -779,7 +779,7 @@ - - AP_INTERNAL_REDIRECT(r->uri, new_uri); - -- /* ap_die was already called, if an error occured */ -+ /* ap_die was already called, if an error occurred */ - if (!new) { - return; - } -@@ -803,7 +803,7 @@ - int access_status; - request_rec *new = internal_internal_redirect(new_uri, r); - -- /* ap_die was already called, if an error occured */ -+ /* ap_die was already called, if an error occurred */ - if (!new) { - return; - } ---- a/modules/http2/h2_config.c -+++ b/modules/http2/h2_config.c -@@ -419,7 +419,7 @@ - else if (!strcasecmp("BEFORE", sdependency)) { - dependency = H2_DEPENDANT_BEFORE; - if (sweight) { -- return "dependecy 'Before' does not allow a weight"; -+ return "dependency 'Before' does not allow a weight"; - } - } - else if (!strcasecmp("INTERLEAVED", sdependency)) { ---- a/modules/http2/h2_ngn_shed.c -+++ b/modules/http2/h2_ngn_shed.c -@@ -281,7 +281,7 @@ - if (H2_REQ_ENTRIES_EMPTY(&ngn->entries)) { - if (want_shutdown) { - ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, shed->c, -- "h2_ngn_shed(%ld): emtpy queue, shutdown engine %s", -+ "h2_ngn_shed(%ld): empty queue, shutdown engine %s", - shed->c->id, ngn->id); - ngn->shutdown = 1; - } ---- a/modules/mappers/mod_imagemap.c -+++ b/modules/mappers/mod_imagemap.c -@@ -858,7 +858,7 @@ - /* There's not much else we can do ... we've already sent the headers - * to the client. - */ -- ap_rputs("\n\n[an internal server error occured]\n", r); -+ ap_rputs("\n\n[an internal server error occurred]\n", r); - menu_footer(r); - return OK; - } ---- a/modules/md/md_acme_authz.c -+++ b/modules/md/md_acme_authz.c -@@ -239,7 +239,7 @@ - - if (md_log_is_level(p, log_level)) { - md_log_perror(MD_LOG_MARK, log_level, rv, p, "ACME server authz: %s for %s at %s. " -- "Exact repsonse was: %s", err? err : "", authz->domain, authz->location, -+ "Exact response was: %s", err? err : "", authz->domain, authz->location, - json? md_json_writep(json, p, MD_JSON_FMT_COMPACT) : "not available"); - } - ---- a/modules/metadata/mod_remoteip.c -+++ b/modules/metadata/mod_remoteip.c -@@ -393,7 +393,7 @@ - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, new, APLOGNO(03491) - "RemoteIPProxyProtocol: previous setting for %s:%hu from virtual " -- "host {%s:%hu in %s} is being overriden by virtual host " -+ "host {%s:%hu in %s} is being overridden by virtual host " - "{%s:%hu in %s}; new setting is '%s'", - buf, prev->addr->port, prev->source->server_hostname, - prev->source->addrs->host_port, prev->source->defn_name, ---- a/modules/ssl/mod_ssl.c -+++ b/modules/ssl/mod_ssl.c -@@ -94,7 +94,7 @@ - "Enable FIPS-140 mode " - "(`on', `off')") - SSL_CMD_ALL(CipherSuite, TAKE12, -- "Colon-delimited list of permitted SSL Ciphers, optional preceeded " -+ "Colon-delimited list of permitted SSL Ciphers, optional preceded " - "by protocol identifier ('XXX:...:XXX' - see manual)") - SSL_CMD_SRV(CertificateFile, TAKE1, - "SSL Server Certificate file " -@@ -187,7 +187,7 @@ - "('[+-][" SSL_PROTOCOLS "] ...' - see manual)") - SSL_CMD_PXY(ProxyCipherSuite, TAKE12, - "SSL Proxy: colon-delimited list of permitted SSL ciphers " -- ", optionally preceeded by protocol specifier ('XXX:...:XXX' - see manual)") -+ ", optionally preceded by protocol specifier ('XXX:...:XXX' - see manual)") - SSL_CMD_PXY(ProxyVerify, TAKE1, - "SSL Proxy: whether to verify the remote certificate " - "('on' or 'off')") ---- a/support/ab.c -+++ b/support/ab.c -@@ -18,7 +18,7 @@ - ** This program is based on ZeusBench V1.0 written by Adam Twiss - ** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/ - ** -- ** This software is provided "as is" and any express or implied waranties, -+ ** This software is provided "as is" and any express or implied warranties, - ** including but not limited to, the implied warranties of merchantability and - ** fitness for a particular purpose are disclaimed. In no event shall - ** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, diff --git a/debian/patches/suexec-CVE-2007-1742.patch b/debian/patches/suexec-CVE-2007-1742.patch index a348cbc..159c2c9 100644 --- a/debian/patches/suexec-CVE-2007-1742.patch +++ b/debian/patches/suexec-CVE-2007-1742.patch @@ -14,7 +14,7 @@ Bug: https://issues.apache.org/bugzilla/show_bug.cgi?id=44752 #include <stdio.h> #include <stdarg.h> -@@ -281,11 +282,12 @@ +@@ -279,11 +280,12 @@ char *actual_gname; /* actual group name */ char *cmd; /* command to be executed */ char cwd[AP_MAXPATH]; /* current working directory */ diff --git a/debian/patches/suexec-custom.patch b/debian/patches/suexec-custom.patch index 9c7a732..37b761d 100644 --- a/debian/patches/suexec-custom.patch +++ b/debian/patches/suexec-custom.patch @@ -2,8 +2,6 @@ Description: the actual patch to make suexec-custom read a config file Forwarded: not-needed Author: Stefan Fritsch <sf@debian.org> Last-Update: 2018-07-17 -diff --git a/support/suexec-custom.c b/support/suexec-custom.c -index f3811a97..30bb644b 100644 --- a/support/suexec-custom.c +++ b/support/suexec-custom.c @@ -29,6 +29,7 @@ @@ -22,7 +20,7 @@ index f3811a97..30bb644b 100644 #if APR_HAVE_UNISTD_H #include <unistd.h> #endif -@@ -222,6 +224,26 @@ static void log_no_err(const char *fmt,...) +@@ -222,6 +224,26 @@ return; } @@ -48,8 +46,8 @@ index f3811a97..30bb644b 100644 + static void clean_env(void) { - char pathbuf[512]; -@@ -288,6 +310,11 @@ int main(int argc, char *argv[]) + char **cleanenv; +@@ -286,6 +308,11 @@ struct stat dir_info; /* directory info holder */ struct stat prg_info; /* program info holder */ int cwdh; /* handle to cwd */ @@ -61,7 +59,7 @@ index f3811a97..30bb644b 100644 /* * Start with a "clean" environment -@@ -317,15 +344,10 @@ int main(int argc, char *argv[]) +@@ -315,15 +342,10 @@ || (! strcmp(AP_HTTPD_USER, pw->pw_name))) #endif /* _OSD_POSIX */ ) { @@ -78,17 +76,17 @@ index f3811a97..30bb644b 100644 #if defined(AP_LOG_SYSLOG) fprintf(stderr, " -D AP_LOG_SYSLOG\n"); #elif defined(AP_LOG_EXEC) -@@ -339,9 +361,6 @@ int main(int argc, char *argv[]) - #endif +@@ -338,9 +360,6 @@ #ifdef AP_UID_MIN fprintf(stderr, " -D AP_UID_MIN=%d\n", AP_UID_MIN); --#endif + #endif -#ifdef AP_USERDIR_SUFFIX - fprintf(stderr, " -D AP_USERDIR_SUFFIX=\"%s\"\n", AP_USERDIR_SUFFIX); - #endif +-#endif exit(0); } -@@ -357,23 +376,6 @@ int main(int argc, char *argv[]) + /* +@@ -355,23 +374,6 @@ target_gname = argv[2]; cmd = argv[3]; @@ -112,11 +110,10 @@ index f3811a97..30bb644b 100644 /* * Check for a leading '/' (absolute path) in the command to be executed, -@@ -397,6 +399,59 @@ int main(int argc, char *argv[]) - userdir = 1; +@@ -396,6 +398,59 @@ } -+ /* + /* + * Check to see if the user running this program + * is the user allowed to do so as defined in + * SUEXEC_CONFIG_DIR/username @@ -169,10 +166,11 @@ index f3811a97..30bb644b 100644 + } + } + - /* ++ /* * Error out if the target username is invalid. */ -@@ -538,7 +593,7 @@ int main(int argc, char *argv[]) + if (strspn(target_uname, "1234567890") != strlen(target_uname)) { +@@ -538,7 +593,7 @@ if (userdir) { if (((chdir(target_homedir)) != 0) || @@ -181,7 +179,7 @@ index f3811a97..30bb644b 100644 ((getcwd(dwd, AP_MAXPATH)) == NULL) || ((fchdir(cwdh)) != 0)) { log_err("cannot get docroot information (%s)\n", target_homedir); -@@ -546,7 +601,7 @@ int main(int argc, char *argv[]) +@@ -546,7 +601,7 @@ } } else { diff --git a/debian/perl-framework/Apache-Test/Changes b/debian/perl-framework/Apache-Test/Changes index d9202ff..ec0c6ef 100644 --- a/debian/perl-framework/Apache-Test/Changes +++ b/debian/perl-framework/Apache-Test/Changes @@ -6,7 +6,51 @@ Changes - Apache::Test change logfile =over 3 -=item 1.41-dev +=item 1.44-dev + +=item 1.43 Nov 7 2021 + +Our implementation of "which" should not search +for a program in the elements of PATH when program +already contains a path. [rjung] + +Fix hash generation when the openssl command +was overwritten with the environment variable +"APACHE_TEST_OPENSSL_CMD". [rjung] + +Add new config option limitrequestline needed +when the local directory paths are long. [rjung] + +=item 1.42 Aug 28 2019 + +Fix loading apache_test_config.pm for recent perls in which '.' is +no longer in @INC by default. [Steve Hay] + +=item 1.41 Jul 11 2019 + +Set DefaultStateDir for > 2.5.1 and add -t_state to override. [jorton] + +Inherit config via IncludeOptional as well as Include. [jorton] + +Increase size of MinSpare, MaxSpare and MaxClients to improve httpd test +framework runs with worker and preform MPMs. [rjung] + +Changed the openssl version detection to work with other *SSL libraries. +[icing] + +Switch test framework from using Net::SSL for +raw TLS sockets to IO::Socket::SSL. [rjung] + +Fix mod_ssl tests under OpenSSL 1.1.1 / TLSv1.3. [jorton] + +Add cwd to generated lib path in TEST script since Perl >=5.26 don't +do that any more. [jorton] + +Override loglevel to trace8 if running in 2.4. [covener] + +Allow an empty PREFIX. [sf] + +Add need_min_apache_fix(). [covener] =item 1.40 Sep 6 2016 @@ -585,7 +629,7 @@ not required between runs. [Geoffrey Young] Apache::TestSmoke imrovements: [Stas] o the command line option -iterations=N should always be respected - (previously it was internally overridden for order!='random'). + (previously it was internally overriden for order!='random'). o since IPC::Run3 broke the Ctrl-C handler, we started to loose any intermediate results, should the run be aborted. So for now, try to always store those results in the temp file: @@ -1111,7 +1155,7 @@ filename and the line number the function was called from. If the with the name of the subroutine the function was called from. [Stas] add support for a new env var APACHE_TEST_TRACE_LEVEL, used to -override the tracing level. It propogates the overridden (either by env +override the tracing level. It propogates the overriden (either by env var APACHE_TEST_TRACE_LEVEL or -trace option) value to the server-side, so we can use Apache::TestTrace in mod_perl handlers, and be able enable/disable tracing from the commmand line. This way we diff --git a/debian/perl-framework/Apache-Test/Makefile.PL b/debian/perl-framework/Apache-Test/Makefile.PL index 713b136..2cfec1a 100644 --- a/debian/perl-framework/Apache-Test/Makefile.PL +++ b/debian/perl-framework/Apache-Test/Makefile.PL @@ -46,17 +46,6 @@ finddepth(sub { push @scripts, "$File::Find::dir/$1"; }, '.'); -my $has_mp; -eval { require mod_perl2 }; -if ($@) { - eval { require mod_perl }; - if (!$@) { - $has_mp = 1; - } -} else { - $has_mp = 2; -} - for (@scripts) { Apache::TestMM::generate_script($_); } @@ -74,6 +63,11 @@ my %prereq = ( 'Cwd' => '2.06', ); +# Apache::TestServer uses Win32::Process on Windows. +if ($^O =~ /MSWin32/i) { + $prereq{'Win32::Process'} = '0' +} + # Apache-Test/META.yml is excluded from mp2 distro to make PAUSE # indexer happy, but then perl Makefile.PL complains about a missing # META.yml, so autogenerate it if it wasn't in the distro diff --git a/debian/perl-framework/Apache-Test/RELEASE b/debian/perl-framework/Apache-Test/RELEASE index fa10838..0ec2b46 100644 --- a/debian/perl-framework/Apache-Test/RELEASE +++ b/debian/perl-framework/Apache-Test/RELEASE @@ -15,7 +15,7 @@ Instructions for Apache-Test Release Manager tags, so keep that in mind. b. commit Changes - % svn ci -m "1.41 rc1" Changes + % svn ci -m "1.44 rc1" Changes c. nuke any preinstalled Apache-Test libs and run 'make test' @@ -37,7 +37,7 @@ Instructions for Apache-Test Release Manager (or maybe longer to give most people a chance to catch up). no need to tag this package - Subject: [RELEASE CANDIDATE] Apache-Test-1.41 RC\d+ + Subject: [RELEASE CANDIDATE] Apache-Test-1.44 RC\d+ a. if problems are detected during stage 2, repeat stages 1 and 2. @@ -54,7 +54,7 @@ Instructions for Apache-Test Release Manager % make -n tag c. commit Changes - % svn ci -m "1.41 release" Changes + % svn ci -m "1.44 release" Changes d. tag % make tag @@ -73,9 +73,8 @@ Instructions for Apache-Test Release Manager o test-dev/perl.apache.org o dev/perl.apache.org o modperl/perl.apache.org - o announce/apache.org - Subject: [ANNOUNCE] Apache-Test-1.41 + Subject: [ANNOUNCE] Apache-Test-1.44 include: - MD5 sig (as it comes from CPAN upload announce). @@ -88,11 +87,11 @@ Instructions for Apache-Test Release Manager b. edit ./Changes: - start a new item with incremented version + '-dev' - =item 1.42-dev + =item 1.45-dev c. bump up version numbers in this file to make it easier to do the next release. % perl -pi.bak -e 's/(\d+)\.(\d+)/join(".", $1, $2+1)/eg' RELEASE d. commit Changes - % svn ci -m "start 1.41-dev cycle" Changes RELEASE lib/Apache/Test.pm + % svn ci -m "start 1.44-dev cycle" Changes RELEASE lib/Apache/Test.pm diff --git a/debian/perl-framework/Apache-Test/lib/Apache/Test.pm b/debian/perl-framework/Apache-Test/lib/Apache/Test.pm index e748c83..b18de11 100644 --- a/debian/perl-framework/Apache-Test/lib/Apache/Test.pm +++ b/debian/perl-framework/Apache-Test/lib/Apache/Test.pm @@ -37,7 +37,7 @@ BEGIN { use vars qw(@ISA @EXPORT %EXPORT_TAGS $VERSION %SubTests @SkipReasons); -$VERSION = '1.41'; +$VERSION = '1.44'; my @need = qw(need_lwp need_http11 need_cgi need_access need_auth need_module need_apache need_min_apache_version need_min_apache_fix diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestCommon.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestCommon.pm index e65d1d3..9722bc2 100644 --- a/debian/perl-framework/Apache-Test/lib/Apache/TestCommon.pm +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestCommon.pm @@ -53,7 +53,7 @@ sub run_write_test { $received += length $chunk; }); - ok t_cmp($length, $received, 'bytes in body'); + ok t_cmp($received, $length, 'bytes in body'); } } } diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestConfig.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestConfig.pm index ad0b02c..274f1a0 100644 --- a/debian/perl-framework/Apache-Test/lib/Apache/TestConfig.pm +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestConfig.pm @@ -59,41 +59,44 @@ use Apache::TestRun (); use vars qw(%Usage); %Usage = ( - top_dir => 'top-level directory (default is $PWD)', - t_dir => 'the t/ test directory (default is $top_dir/t)', - t_conf => 'the conf/ test directory (default is $t_dir/conf)', - t_logs => 'the logs/ test directory (default is $t_dir/logs)', - t_pid_file => 'location of the pid file (default is $t_logs/httpd.pid)', - t_conf_file => 'test httpd.conf file (default is $t_conf/httpd.conf)', - src_dir => 'source directory to look for mod_foos.so', - serverroot => 'ServerRoot (default is $t_dir)', - documentroot => 'DocumentRoot (default is $ServerRoot/htdocs', - port => 'Port [port_number|select] (default ' . DEFAULT_PORT . ')', - servername => 'ServerName (default is localhost)', - user => 'User to run test server as (default is $USER)', - group => 'Group to run test server as (default is $GROUP)', - bindir => 'Apache bin/ dir (default is apxs -q BINDIR)', - sbindir => 'Apache sbin/ dir (default is apxs -q SBINDIR)', - httpd => 'server to use for testing (default is $bindir/httpd)', - target => 'name of server binary (default is apxs -q TARGET)', - apxs => 'location of apxs (default is from Apache2::BuildConfig)', - startup_timeout => 'seconds to wait for the server to start (default is 60)', - httpd_conf => 'inherit config from this file (default is apxs derived)', - httpd_conf_extra=> 'inherit additional config from this file', - minclients => 'minimum number of concurrent clients (default is 1)', - maxclients => 'maximum number of concurrent clients (default is minclients+1)', - perlpod => 'location of perl pod documents (for testing downloads)', - proxyssl_url => 'url for testing ProxyPass / https (default is localhost)', - sslca => 'location of SSL CA (default is $t_conf/ssl/ca)', - sslcaorg => 'SSL CA organization to use for tests (default is asf)', - sslproto => 'SSL/TLS protocol version(s) to test', - libmodperl => 'path to mod_perl\'s .so (full or relative to LIBEXECDIR)', - defines => 'values to add as -D defines (for example, "VAR1 VAR2")', + top_dir => 'top-level directory (default is $PWD)', + t_dir => 'the t/ test directory (default is $top_dir/t)', + t_conf => 'the conf/ test directory (default is $t_dir/conf)', + t_logs => 'the logs/ test directory (default is $t_dir/logs)', + t_state => 'the state/ test directory (default is $t_dir/state)', + t_pid_file => 'location of the pid file (default is $t_logs/httpd.pid)', + t_conf_file => 'test httpd.conf file (default is $t_conf/httpd.conf)', + src_dir => 'source directory to look for mod_foos.so', + serverroot => 'ServerRoot (default is $t_dir)', + documentroot => 'DocumentRoot (default is $ServerRoot/htdocs', + port => 'Port [port_number|select] (default ' . DEFAULT_PORT . ')', + servername => 'ServerName (default is localhost)', + user => 'User to run test server as (default is $USER)', + group => 'Group to run test server as (default is $GROUP)', + bindir => 'Apache bin/ dir (default is apxs -q BINDIR)', + sbindir => 'Apache sbin/ dir (default is apxs -q SBINDIR)', + httpd => 'server to use for testing (default is $bindir/httpd)', + target => 'name of server binary (default is apxs -q TARGET)', + apxs => 'location of apxs (default is from Apache2::BuildConfig)', + startup_timeout => 'seconds to wait for the server to start (default is 60)', + httpd_conf => 'inherit config from this file (default is apxs derived)', + httpd_conf_extra => 'inherit additional config from this file', + minclients => 'minimum number of concurrent clients (default is 1)', + maxclients => 'maximum number of concurrent clients (default is minclients+1)', + threadsperchild => 'number of threads per child when using threaded MPMs (default is 10)', + limitrequestline => 'global LimitRequestLine setting (default is 128)', + perlpod => 'location of perl pod documents (for testing downloads)', + proxyssl_url => 'url for testing ProxyPass / https (default is localhost)', + sslca => 'location of SSL CA (default is $t_conf/ssl/ca)', + sslcaorg => 'SSL CA organization to use for tests (default is asf)', + sslproto => 'SSL/TLS protocol version(s) to test', + libmodperl => 'path to mod_perl\'s .so (full or relative to LIBEXECDIR)', + defines => 'values to add as -D defines (for example, "VAR1 VAR2")', (map { $_ . '_module_name', "$_ module name"} qw(cgi ssl thread access auth php)), ); my %filepath_conf_opts = map { $_ => 1 } - qw(top_dir t_dir t_conf t_logs t_pid_file t_conf_file src_dir serverroot + qw(top_dir t_dir t_conf t_logs t_state t_pid_file t_conf_file src_dir serverroot documentroot bindir sbindir httpd apxs httpd_conf httpd_conf_extra perlpod sslca libmodperl); @@ -298,9 +301,7 @@ sub new { $vars->{sslca} ||= catfile $vars->{t_conf}, 'ssl', 'ca'; $vars->{sslcaorg} ||= 'asf'; - if (!defined($vars->{sslproto})) { - require Apache::TestSSLCA; - + if (!defined($vars->{sslproto}) and eval { require Apache::TestSSLCA; 1; }) { $vars->{sslproto} = Apache::TestSSLCA::sslproto(); } else { @@ -308,6 +309,7 @@ sub new { } $vars->{t_logs} ||= catfile $vars->{serverroot}, 'logs'; + $vars->{t_state} ||= catfile $vars->{serverroot}, 'state'; $vars->{t_conf_file} ||= catfile $vars->{t_conf}, 'httpd.conf'; $vars->{t_pid_file} ||= catfile $vars->{t_logs}, 'httpd.pid'; @@ -326,6 +328,7 @@ sub new { $vars->{group} ||= $self->default_group; $vars->{serveradmin} ||= $self->default_serveradmin; + $vars->{threadsperchild} ||= 10; $vars->{minclients} ||= 1; $vars->{maxclients_preset} = $vars->{maxclients} || 0; # if maxclients wasn't explicitly passed try to @@ -338,13 +341,36 @@ sub new { $vars->{maxclients_preset} < $vars->{minclients}) { $vars->{minclients} = $vars->{maxclients_preset}; } + if ($vars->{minclients} < 2) { + $vars->{maxspare} = 2; + } else { + $vars->{maxspare} = $vars->{minclients}; + } + if ($vars->{maxclients} < $vars->{maxspare} + 1) { + $vars->{maxclients} = $vars->{maxspare} + 1; + } + + # for threaded mpms MinClients and MaxClients must be a + # multiple of ThreadsPerChild + { + use integer; + $vars->{minclientsthreadedmpm} = ($vars->{minclients} + $vars->{threadsperchild} - 1) / + $vars->{threadsperchild} * $vars->{threadsperchild}; + $vars->{maxclientsthreadedmpm} = ($vars->{maxclients} + $vars->{threadsperchild} - 1) / + $vars->{threadsperchild} * $vars->{threadsperchild}; + $vars->{maxsparethreadedmpm} = ($vars->{maxspare} + $vars->{threadsperchild} - 1) / + $vars->{threadsperchild} * $vars->{threadsperchild}; + $vars->{startserversthreadedmpm} = $vars->{minclientsthreadedmpm} / $vars->{threadsperchild}; + } + if ($vars->{maxsparethreadedmpm} < 2 * $vars->{threadsperchild}) { + $vars->{maxsparethreadedmpm} = 2 * $vars->{threadsperchild}; + } + if ($vars->{maxclientsthreadedmpm} < $vars->{maxsparethreadedmpm} + $vars->{threadsperchild}) { + $vars->{maxclientsthreadedmpm} = $vars->{maxsparethreadedmpm} + $vars->{threadsperchild}; + } - # for threaded mpms MaxClients must be a multiple of - # ThreadsPerChild (i.e. maxclients % minclients == 0) - # so unless -maxclients was explicitly specified use a double of - # minclients - $vars->{maxclientsthreadedmpm} = - $vars->{maxclients_preset} || $vars->{minclients} * 2; + $vars->{limitrequestline} ||= 128; + $vars->{limitrequestlinex2} = 2 * $vars->{limitrequestline}; $vars->{proxy} ||= 'off'; $vars->{proxyssl_url} ||= ''; @@ -524,6 +550,15 @@ sub configure_proxy { unless ($vars->{maxclients_preset}) { $vars->{minclients}++; $vars->{maxclients}++; + $vars->{maxspare}++; + $vars->{startserversthreadedmpm} ++; + $vars->{minclientsthreadedmpm} += $vars->{threadsperchild}; + $vars->{maxclientsthreadedmpm} += $vars->{threadsperchild}; + $vars->{maxsparethreadedmpm} += $vars->{threadsperchild}; + #In addition allow for some backend processes + #in keep-alive state. For threaded MPMs we + #already should be fine. + $vars->{maxclients} += 3; } $vars->{proxy} = $self->{vhosts}->{'mod_proxy'}->{hostport}; return $vars->{proxy}; @@ -1409,6 +1444,15 @@ sub check_vars { unless ($vars->{maxclients_preset}) { $vars->{minclients}++; $vars->{maxclients}++; + $vars->{maxspare}++; + $vars->{startserversthreadedmpm} ++; + $vars->{minclientsthreadedmpm} += $vars->{threadsperchild}; + $vars->{maxclientsthreadedmpm} += $vars->{threadsperchild}; + $vars->{maxsparethreadedmpm} += $vars->{threadsperchild}; + #In addition allow for some backend processes + #in keep-alive state. For threaded MPMs we + #already should be fine. + $vars->{maxclients} += 3; } } } @@ -1571,6 +1615,7 @@ sub generate_httpd_conf { $self->generate_index_html; $self->gendir($vars->{t_logs}); + $self->gendir($vars->{t_state}); $self->gendir($vars->{t_conf}); my @very_last_postamble = (); @@ -1737,6 +1782,11 @@ sub which { return undef unless $program; + # No need to search PATH components + # if $program already contains a path + return $program if !OSX and !WINFU and + $program =~ /\// and -f $program and -x $program; + my @dirs = File::Spec->path(); require Config; @@ -2166,6 +2216,11 @@ LogLevel debug DefaultRunTimeDir "@t_logs@" LogLevel trace8 </IfVersion> +<IfVersion > 2.4.34> +<IfDirective DefaultStateDir> + DefaultStateDir "@t_state@" +</IfDirective> +</IfVersion> </IfModule> <IfModule mod_log_config.c> @@ -2194,10 +2249,10 @@ HostnameLookups Off LockFile @t_logs@/accept.lock </IfVersion> </IfModule> - StartServers 1 - MinSpareThreads @MinClients@ - MaxSpareThreads @MinClients@ - ThreadsPerChild @MinClients@ + StartServers @StartServersThreadedMPM@ + MinSpareThreads @ThreadsPerChild@ + MaxSpareThreads @MaxSpareThreadedMPM@ + ThreadsPerChild @ThreadsPerChild@ MaxClients @MaxClientsThreadedMPM@ MaxRequestsPerChild 0 </IfModule> @@ -2210,8 +2265,8 @@ HostnameLookups Off </IfModule> NumServers 1 StartThreads @MinClients@ - MinSpareThreads @MinClients@ - MaxSpareThreads @MinClients@ + MinSpareThreads 1 + MaxSpareThreads @MaxSpare@ MaxThreadsPerChild @MaxClients@ MaxRequestsPerChild 0 </IfModule> @@ -2223,8 +2278,8 @@ HostnameLookups Off </IfVersion> </IfModule> StartServers @MinClients@ - MinSpareServers @MinClients@ - MaxSpareServers @MinClients@ + MinSpareServers 1 + MaxSpareServers @MaxSpare@ MaxClients @MaxClients@ MaxRequestsPerChild 0 </IfModule> @@ -2232,8 +2287,8 @@ HostnameLookups Off <IfDefine APACHE1> LockFile @t_logs@/accept.lock StartServers @MinClients@ - MinSpareServers @MinClients@ - MaxSpareServers @MinClients@ + MinSpareServers 1 + MaxSpareServers @MaxSpare@ MaxClients @MaxClients@ MaxRequestsPerChild 0 </IfDefine> diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParse.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParse.pm index fa26f34..60e12e3 100644 --- a/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParse.pm +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestConfigParse.pm @@ -342,7 +342,7 @@ sub inherit_config_file_or_directory { (my $directive, $_) = split /\s+/, $_, 2; - if ($directive eq "Include") { + if ($directive eq "Include" or $directive eq "IncludeOptional") { foreach my $include (glob($self->server_file_rel2abs($_))) { $self->inherit_config_file_or_directory($include); } diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestRun.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestRun.pm index f398eb5..515f69a 100644 --- a/debian/perl-framework/Apache-Test/lib/Apache/TestRun.pm +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestRun.pm @@ -776,7 +776,7 @@ sub detect_relocation { return unless -e $config_file; my %inc = %INC; - eval { require "$config_file" }; + eval { require "./$config_file" }; %INC = %inc; # be stealth warn($@), return if $@; diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestRunPHP.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestRunPHP.pm index df01bc4..d2965ba 100644 --- a/debian/perl-framework/Apache-Test/lib/Apache/TestRunPHP.pm +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestRunPHP.pm @@ -234,7 +234,7 @@ what this means, but it isn't important to understand the gory details. instead, it is sufficient to understand that when C<Apache::Test> calls C<bar.php> it feeds the results directly to C<Test::Harness>, a module that comes with every Perl installation, and C<Test::Harness> expects -what it receives to be formatted in a very specific way. by itself, all +what it receives to be formated in a very specific way. by itself, all of this is pretty useless, so C<Apache::Test> provides PHP testers with something much better. here is a much better example: diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestSSLCA.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestSSLCA.pm index 3f1a24a..ca37f16 100644 --- a/debian/perl-framework/Apache-Test/lib/Apache/TestSSLCA.pm +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestSSLCA.pm @@ -23,7 +23,7 @@ use DirHandle (); use File::Path (); use File::Copy 'cp'; use File::Basename; -use Net::SSLeay; +use File::Spec::Functions qw(devnull); use Apache::TestConfig (); use Apache::TestTrace; @@ -73,6 +73,7 @@ if (Apache::Test::normalize_vstring($version) < my $sslproto = "all"; +eval { require Net::SSLeay; }; if (Apache::Test::normalize_vstring($version) >= Apache::Test::normalize_vstring("1.1.1") && !defined(&Net::SSLeay::CTX_set_post_handshake_auth)) { @@ -293,8 +294,20 @@ nsComment = This Is A Comment 1.3.6.1.4.1.18060.12.0 = DER:0c064c656d6f6e73 subjectAltName = email:\$mail$san_msupn +[ client_ext ] +extendedKeyUsage = clientAuth + [ server_ext ] subjectAltName = DNS:\$CN$san_dnssrv +extendedKeyUsage = serverAuth +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +[ ca_ext ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = critical,CA:true + EOF return $file; @@ -325,7 +338,7 @@ sub new_ca { join ':', dn_oneline('client_snakeoil'), $basic_auth_password); - openssl req => "-new -x509 -keyout $cakey -out $cacert $days", + openssl req => "-new -x509 -extensions ca_ext -keyout $cakey -out $cacert $days", config('ca'); export_cert('ca'); #useful for importing into IE @@ -366,7 +379,8 @@ sub sign_cert { my $name = shift; my $exts = ''; - $exts = ' -extensions client_ok_ext' if $name =~ /client_ok/; + $exts = ' -extensions client_ext' if $name =~ /client/; + $exts .= ' -extensions client_ok_ext' if $name =~ /client_ok/; $exts = ' -extensions server_ext' if $name =~ /server/; @@ -422,7 +436,7 @@ sub hash_certs { for my $file ($dh->read) { next unless $file =~ /\.cr[tl]$/; - chomp(my $hash = `openssl $type -noout -hash < $file`); + chomp(my $hash = `$openssl $type -noout -hash < $file`); next unless $hash; my $symlink = "$hash.r$n"; $n++; @@ -572,9 +586,10 @@ sub gendir { } sub version { - my $version = qx($openssl version); - return $1 if $version =~ /^OpenSSL (\S+) /; - return 0; + my $devnull = devnull(); + my $version = qx($openssl version 2>$devnull); + return $1 if $version =~ /^\S+SSL (\S+)/; + die "FATAL: unable to determine openssl version via `$openssl version` from: $version"; } sub dgst { diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestTrace.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestTrace.pm index 19c5b29..00426ea 100644 --- a/debian/perl-framework/Apache-Test/lib/Apache/TestTrace.pm +++ b/debian/perl-framework/Apache-Test/lib/Apache/TestTrace.pm @@ -126,9 +126,9 @@ sub nc_trace { } sub trace_level { - # overridden by user/-trace + # overriden by user/-trace (defined $Level && $levels{$Level}) || - # or overridden by env var + # or overriden by env var (exists $ENV{APACHE_TEST_TRACE_LEVEL} && $levels{$ENV{APACHE_TEST_TRACE_LEVEL}}) || # or default diff --git a/debian/perl-framework/Makefile.PL b/debian/perl-framework/Makefile.PL index 86e0355..ece2205 100644 --- a/debian/perl-framework/Makefile.PL +++ b/debian/perl-framework/Makefile.PL @@ -22,6 +22,26 @@ finddepth(sub { Apache::TestMM::filter_args(); +# Temporary workaround to allow passing +# arguments to "perl Makefile.PL" +# that should go to t/TEST but are not yet +# supported in an Apache::Test release. +# Code borrowed from Apache::TestMM::filter_args(). +my %local_args = ( + limitrequestline => 'Value for LimitRequestLine', + limitrequestlinex2 => 'Twice the value for LimitRequestLine', +); +my($argv, $args_vars) = Apache::TestConfig::filter_args(\@ARGV, \%local_args); +@ARGV = @$argv; +# Merge given vars with default values +my %local_vars = ( + limitrequestline => '128', + limitrequestlinex2 => '256', +); +map {$local_vars{$_} = $args_vars->{$_}} keys %$args_vars; + +push(@Apache::TestMM::Argv, %local_vars); + for my $script (@scripts) { Apache::TestMM::generate_script($script); } diff --git a/debian/perl-framework/NOTICE b/debian/perl-framework/NOTICE index 9038837..b823d44 100644 --- a/debian/perl-framework/NOTICE +++ b/debian/perl-framework/NOTICE @@ -1,5 +1,5 @@ Apache HTTP Server Test Framework -Copyright 2018 The Apache Software Foundation. +Copyright 2020 The Apache Software Foundation. This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/debian/perl-framework/README b/debian/perl-framework/README index 24d2ab6..639d684 100644 --- a/debian/perl-framework/README +++ b/debian/perl-framework/README @@ -29,18 +29,16 @@ http://svn.apache.org/viewvc/perl/modperl/docs/trunk/src/docs/general/testing/te To run the tests for all Apache web server modules, some additional CPAN modules will be required. If the tests don't work, make sure that you have up to date versions of each of these perl modules: -- HTTP::DAV (DAV tests) -- DateTime (mod_include tests) -- Time::HiRes -- Protocol::HTTP2::Client and AnyEvent (mod_http2 tests) -- Test -- Test::Harness -- Crypt::SSLeay -- Net::SSLeay -- IO::Socket::SSL -- IO::Socket::IP -- IO::Select -- LWP::Protocol::https + +``` +cpan App::cpanminus +cpanm Bundle::ApacheTest \ + HTTP::DAV DateTime Time::HiRes \ + Test::Harness Crypt::SSLeay Net::SSLeay IO::Socket::SSL \ + IO::Socket::IP IO::Select LWP::Protocol::https AnyEvent \ + AnyEvent::WebSocket::Client LWP::Protocol::AnyEvent::http FCGI +``` + Quick Start ----------- diff --git a/debian/perl-framework/STATUS b/debian/perl-framework/STATUS index f1fb35d..9975ca7 100644 --- a/debian/perl-framework/STATUS +++ b/debian/perl-framework/STATUS @@ -1,5 +1,5 @@ httpd-test/perl-framework STATUS: -*-text-*- -Last modified at [$Date: 2018-10-10 16:23:46 +0200 (Wed, 10 Oct 2018) $] +Last modified at [$Date: 2018-10-10 18:23:46 +0400 (Wed, 10 Oct 2018) $] Stuff to do: * finish the t/TEST exit code issue (ORed with 0x2C if diff --git a/debian/perl-framework/c-modules/echo_post/mod_echo_post.c b/debian/perl-framework/c-modules/echo_post/mod_echo_post.c index 0461735..ebda4d5 100644 --- a/debian/perl-framework/c-modules/echo_post/mod_echo_post.c +++ b/debian/perl-framework/c-modules/echo_post/mod_echo_post.c @@ -66,7 +66,7 @@ static int echo_post_handler(request_rec *r) "[mod_echo_post] read %ld bytes (wanted %d, remaining=%ld)", nrd, sizeof(buff), r->remaining); #else - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "[mod_echo_post] read %ld bytes (wanted %" APR_SIZE_T_FMT ", remaining=%" APR_OFF_T_FMT ")", nrd, sizeof(buff), r->remaining); diff --git a/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c b/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c index 07a9fce..99bc95a 100644 --- a/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c +++ b/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c @@ -38,10 +38,10 @@ static int test_pass_brigade_handler(request_rec *r) httpd_test_split_qs_numbers(r, &buff_size, &remaining, NULL); - fprintf(stderr, "[mod_test_pass_brigade] " - "going to echo %" APR_SIZE_T_FMT " bytes with " - "buffer size=%" APR_SIZE_T_FMT "\n", - remaining, buff_size); + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "going to echo %" APR_SIZE_T_FMT " bytes with " + "buffer size=%" APR_SIZE_T_FMT "", + remaining, buff_size); buff = malloc(buff_size); memset(buff, 'a', buff_size); @@ -50,35 +50,51 @@ static int test_pass_brigade_handler(request_rec *r) while (total < remaining) { int left = (remaining - total); int len = left <= buff_size ? left : buff_size; - apr_bucket *bucket = apr_bucket_heap_create(buff, len, NULL, - c->bucket_alloc); + apr_bucket *bucket = apr_bucket_transient_create(buff, len, + c->bucket_alloc); apr_status_t status; apr_brigade_cleanup(bb); APR_BRIGADE_INSERT_TAIL(bb, bucket); + if (len + total == remaining) { + bucket = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + +#if 0 + /* ###### A FLUSH should not be strictly necessary here + * but inserting one apears to work around intermittent + * failures when running t/apache/pass_brigade.t under + * worker. */ + bucket = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); +#endif + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "[mod_test_pass_brigade] sending EOS"); + } status = ap_pass_brigade(r->output_filters->next, bb); if (status != APR_SUCCESS) { apr_brigade_destroy(bb); - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, - status, r->server, - "[mod_test_pass_brigade] ap_pass_brigade failed"); + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "[mod_test_pass_brigade] ap_pass_brigade failed"); free(buff); return HTTP_INTERNAL_SERVER_ERROR; } total += len; - fprintf(stderr, "[mod_test_pass_brigade] wrote %d of %d bytes\n", - len, len); + ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, + "[mod_test_pass_brigade] wrote %d of %d bytes", + len, len); } apr_brigade_destroy(bb); - fprintf(stderr, - "[mod_test_pass_brigade] done writing %" APR_SIZE_T_FMT - " of %" APR_SIZE_T_FMT " bytes\n", - total, remaining); + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "[mod_test_pass_brigade] done writing %" APR_SIZE_T_FMT + " of %" APR_SIZE_T_FMT " bytes", + total, remaining); free(buff); return OK; diff --git a/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c b/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c index 5675edd..64f1542 100644 --- a/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c +++ b/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c @@ -36,8 +36,9 @@ static int test_rwrite_handler(request_rec *r) httpd_test_split_qs_numbers(r, &buff_size, &remaining, NULL); - fprintf(stderr, "[mod_test_rwrite] going to echo %" APR_SIZE_T_FMT " bytes\n", - remaining); + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "[mod_test_rwrite] going to echo %" APR_SIZE_T_FMT " bytes", + remaining); buff = malloc(buff_size); memset(buff, 'a', buff_size); @@ -48,14 +49,14 @@ static int test_rwrite_handler(request_rec *r) long nrd = ap_rwrite(buff, len, r); total += nrd; - fprintf(stderr, "[mod_test_rwrite] wrote %ld of %d bytes\n", - nrd, len); + ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, + "[mod_test_rwrite] wrote %ld of %d bytes", nrd, len); } - - fprintf(stderr, - "[mod_test_rwrite] done writing %" APR_SIZE_T_FMT - " of %" APR_SIZE_T_FMT " bytes\n", - total, remaining); + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "[mod_test_rwrite] done writing %" APR_SIZE_T_FMT + " of %" APR_SIZE_T_FMT " bytes", + total, remaining); free(buff); return OK; diff --git a/debian/perl-framework/c-modules/test_session/mod_test_session.c b/debian/perl-framework/c-modules/test_session/mod_test_session.c index c9e0ea2..4099cbe 100644 --- a/debian/perl-framework/c-modules/test_session/mod_test_session.c +++ b/debian/perl-framework/c-modules/test_session/mod_test_session.c @@ -34,7 +34,7 @@ SessionMaxAge 100 </Location> <IfModule mod_version.c> - <IfVersion >= 2.5.0> + <IfVersion >= 2.4.41> <Location /sessiontest/on/expire/cache> SessionExpiryUpdateInterval 50 </Location> diff --git a/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c b/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c index a7177a1..c9bc762 100644 --- a/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c +++ b/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c @@ -114,7 +114,7 @@ static int test_ssl_ext_lookup(request_rec *r) static int test_ssl_var_lookup(request_rec *r) { - char *value; + const char *value; if (strcmp(r->handler, "test-ssl-var-lookup")) { return DECLINED; diff --git a/debian/perl-framework/scripts/httpd-sub.ldif b/debian/perl-framework/scripts/httpd-sub.ldif new file mode 100644 index 0000000..7908cb6 --- /dev/null +++ b/debian/perl-framework/scripts/httpd-sub.ldif @@ -0,0 +1,15 @@ +dn: cn=httpd,dc=example,dc=com +objectClass: applicationProcess +objectClass: simpleSecurityObject +cn: httpd +description: Service Account for httpd +userPassword: mod_authnz_ldap + +dn: ou=dept,dc=example,dc=com +ou: dept +objectClass: organizationalUnit + +# Group +dn: cn=Subgroup,ou=dept,dc=example,dc=com +objectClass: groupOfUniqueNames +uniqueMember: uid=beta,dc=example,dc=com diff --git a/debian/perl-framework/scripts/httpd.ldif b/debian/perl-framework/scripts/httpd.ldif new file mode 100644 index 0000000..b9211ee --- /dev/null +++ b/debian/perl-framework/scripts/httpd.ldif @@ -0,0 +1,56 @@ +dn: cn=httpd,dc=example,dc=com +objectClass: applicationProcess +objectClass: simpleSecurityObject +cn: httpd +description: Service Account for httpd +userPassword: mod_authnz_ldap + +dn: uid=alpha,dc=example,dc=com +objectClass: inetOrgPerson +cn: Alpha Person +givenName: Alpha +sn: Person +uid: alpha +roomnumber: 42 +userPassword: Alpha + +dn: uid=beta,dc=example,dc=com +objectClass: inetOrgPerson +cn: Beta Person +givenName: Beta +sn: Person +uid: beta +roomnumber: 41 +userPassword: Beta + +dn: uid=gamma,dc=example,dc=com +objectClass: inetOrgPerson +cn: Gamma Person +givenName: Gamma +sn: Person +uid: gamma +roomnumber: 101 +userPassword: Gamma + +dn: uid=delta,dc=example,dc=com +objectClass: inetOrgPerson +cn: Delta Person +givenName: Delta +sn: Person +uid: delta +roomnumber: 43 +userPassword: Delta + +# Group +dn: cn=Group One, dc=example,dc=com +objectClass: groupOfUniqueNames +uniqueMember: uid=alpha,dc=example,dc=com +uniqueMember: uid=beta,dc=example,dc=com +uniqueMember: uid=delta,dc=example,dc=com + +# Referral +dn: ou=dept,dc=example,dc=com +objectClass: referral +objectClass: extensibleObject +ou: dept +ref: ldap://localhost:8390/ou=dept,dc=example,dc=com diff --git a/debian/perl-framework/scripts/ldap-init.sh b/debian/perl-framework/scripts/ldap-init.sh new file mode 100755 index 0000000..148a9d0 --- /dev/null +++ b/debian/perl-framework/scripts/ldap-init.sh @@ -0,0 +1,28 @@ +#!/bin/bash -ex +DOCKER=${DOCKER:-`which docker 2>/dev/null || which podman 2>/dev/null`} +cid1=`${DOCKER} run -d -p 8389:389 httpd_ldap` +cid2=`${DOCKER} run -d -p 8390:389 httpd_ldap` +sleep 5 + +# For the CentOS slapd configuration, load some default schema: +if ${DOCKER} exec -i $cid1 test -f /etc/centos-release; then + ${DOCKER} exec -i $cid1 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// < scripts/slapd-config.ldif + ${DOCKER} exec -i $cid2 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// < scripts/slapd-config.ldif + + for sc in cosine inetorgperson nis; do + fn=/etc/openldap/schema/${sc}.ldif + ${DOCKER} exec -i $cid1 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// -f ${fn} + ${DOCKER} exec -i $cid2 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// -f ${fn} + done + + ldapadd -x -H ldap://localhost:8390 -D cn=admin,dc=example,dc=com -w travis < scripts/suffix.ldif + ldapadd -x -H ldap://localhost:8389 -D cn=admin,dc=example,dc=com -w travis < scripts/suffix.ldif +fi + +# Disable anonymous bind; must be done as an authenticated local user +# hence via ldapadd -Y EXTERNAL within the container. +${DOCKER} exec -i $cid1 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// < scripts/non-anon.ldif +${DOCKER} exec -i $cid2 /usr/bin/ldapadd -Y EXTERNAL -H ldapi:// < scripts/non-anon.ldif + +ldapadd -x -H ldap://localhost:8389 -D cn=admin,dc=example,dc=com -w travis < scripts/httpd.ldif +ldapadd -x -H ldap://localhost:8390 -D cn=admin,dc=example,dc=com -w travis < scripts/httpd-sub.ldif diff --git a/debian/perl-framework/scripts/memcached-init.sh b/debian/perl-framework/scripts/memcached-init.sh new file mode 100755 index 0000000..f90f055 --- /dev/null +++ b/debian/perl-framework/scripts/memcached-init.sh @@ -0,0 +1,8 @@ +#!/bin/bash -ex +DOCKER=${DOCKER:-`which docker 2>/dev/null || which podman 2>/dev/null`} +${DOCKER} build -t httpd_memcached - <<EOF +FROM quay.io/centos/centos:stream8 +RUN yum install -y memcached +CMD /usr/bin/memcached -u memcached -v +EOF +${DOCKER} run -d -p 11211:11211 httpd_memcached diff --git a/debian/perl-framework/scripts/non-anon.ldif b/debian/perl-framework/scripts/non-anon.ldif new file mode 100644 index 0000000..535312c --- /dev/null +++ b/debian/perl-framework/scripts/non-anon.ldif @@ -0,0 +1,14 @@ +dn: cn=config +changetype: modify +add: olcDisallows +olcDisallows: bind_anon + +dn: cn=config +changetype: modify +add: olcRequires +olcRequires: authc + +dn: olcDatabase={-1}frontend,cn=config +changetype: modify +add: olcRequires +olcRequires: authc diff --git a/debian/perl-framework/scripts/redis-init.sh b/debian/perl-framework/scripts/redis-init.sh new file mode 100755 index 0000000..f950138 --- /dev/null +++ b/debian/perl-framework/scripts/redis-init.sh @@ -0,0 +1,8 @@ +#!/bin/bash -ex +DOCKER=${DOCKER:-`which docker 2>/dev/null || which podman 2>/dev/null`} +${DOCKER} build -t httpd_redis - <<EOF +FROM quay.io/centos/centos:stream8 +RUN yum install -y redis +CMD /usr/bin/redis-server +EOF +${DOCKER} run -d -p 6379:6379 httpd_redis diff --git a/debian/perl-framework/scripts/slapd-config.ldif b/debian/perl-framework/scripts/slapd-config.ldif new file mode 100644 index 0000000..fa9763e --- /dev/null +++ b/debian/perl-framework/scripts/slapd-config.ldif @@ -0,0 +1,10 @@ +dn: olcDatabase={2}hdb,cn=config +changetype: modify +replace: olcSuffix +olcSuffix: dc=example,dc=com +- +replace: olcRootDN +olcRootDN: cn=admin,dc=example,dc=com +- +add: olcRootPW +olcRootPW: travis diff --git a/debian/perl-framework/scripts/suffix.ldif b/debian/perl-framework/scripts/suffix.ldif new file mode 100644 index 0000000..bf5cbdb --- /dev/null +++ b/debian/perl-framework/scripts/suffix.ldif @@ -0,0 +1,5 @@ +dn: dc=example,dc=com +objectClass: organization +objectClass: dcObject +dc: example +o: Example Organization diff --git a/debian/perl-framework/t/ab/base.t b/debian/perl-framework/t/ab/base.t index 722c714..fe565f6 100644 --- a/debian/perl-framework/t/ab/base.t +++ b/debian/perl-framework/t/ab/base.t @@ -29,14 +29,14 @@ sub run_and_gather_output { my $ab_path = catfile $vars->{bindir}, "ab"; my $http_url = Apache::TestRequest::module2url("core", {scheme => 'http', path => '/'}); -my $http_results = run_and_gather_output("$ab_path -B 127.0.0.1 -q -n 10 $http_url"); -ok ($http_results->{status} == 0); -ok (scalar(@{$http_results->{stderr}}) == 0); +my $http_results = run_and_gather_output("ASAN_OPTIONS='detect_leaks=0' $ab_path -B 127.0.0.1 -q -n 10 $http_url"); +ok $http_results->{status}, 0; +ok scalar(@{$http_results->{stderr}}), 0; if ($vars->{ssl_module_name}) { my $https_url = Apache::TestRequest::module2url($vars->{ssl_module_name}, {scheme => 'https', path => '/'}); - my $https_results = run_and_gather_output("$ab_path -B 127.0.0.1 -q -n 10 $https_url"); - ok ($https_results->{status} == 0); + my $https_results = run_and_gather_output("ASAN_OPTIONS='detect_leaks=0' $ab_path -B 127.0.0.1 -q -n 10 $https_url"); + ok $https_results->{status}, 0; ok (scalar(@{$https_results->{stderr}}), 0, "https had stderr output:" . Dumper $https_results->{stderr}); diff --git a/debian/perl-framework/t/apache/expr.t b/debian/perl-framework/t/apache/expr.t index 58c4a57..7d62bc0 100644 --- a/debian/perl-framework/t/apache/expr.t +++ b/debian/perl-framework/t/apache/expr.t @@ -268,6 +268,8 @@ if (have_min_apache_version("2.5")) { [ "'email:<redacted2>' -in split s/$SAN_split/\$1/, $SAN_list_one" => 0 ], [ "'IP Address:%{REMOTE_ADDR}' -in split/, /, join $SAN_list_one" => 1 ], + [ "replace(%{REQUEST_METHOD}, 'E', 'O') == 'GOT'" => 1], + [ "replace(%{REQUEST_METHOD}, 'E', 'O') == 'GET'" => 0], )); } diff --git a/debian/perl-framework/t/apache/expr_string.t b/debian/perl-framework/t/apache/expr_string.t index a9115ee..4682d4a 100644 --- a/debian/perl-framework/t/apache/expr_string.t +++ b/debian/perl-framework/t/apache/expr_string.t @@ -3,10 +3,12 @@ use warnings FATAL => 'all'; use Apache::Test; use Apache::TestRequest; -use Apache::TestUtil qw(t_write_file t_start_error_log_watch t_finish_error_log_watch); +use Apache::TestUtil qw(t_write_file t_start_error_log_watch t_finish_error_log_watch t_cmp); use File::Spec; +use Time::HiRes qw(usleep); + # test ap_expr Apache::TestRequest::user_agent(keep_alive => 1); @@ -62,6 +64,8 @@ foreach my $t (@test_cases) { 'SomeHeader' => 'SomeValue', 'User-Agent' => 'SomeAgent', 'Referer' => 'SomeReferer'); + ### Sleep here, attempt to avoid intermittent failures. + usleep(250000); my @loglines = t_finish_error_log_watch(); my @evalerrors = grep {/(?:internal evaluation error|flex scanner jammed)/i @@ -97,8 +101,7 @@ foreach my $t (@test_cases) { [ ]\(log_transaction) # trailing hook info (LogLevel debug and higher) }x ) { my $result = $1; - print "Got '$result', expected '$expect'\n"; - ok($result eq $expect); + ok t_cmp($result, $expect, "log message @msg didn't match"); } else { print "Can't extract expr result from log message:\n@msg\n"; diff --git a/debian/perl-framework/t/apache/hostcheck.t b/debian/perl-framework/t/apache/hostcheck.t index a295af7..62bb38d 100644 --- a/debian/perl-framework/t/apache/hostcheck.t +++ b/debian/perl-framework/t/apache/hostcheck.t @@ -21,7 +21,7 @@ my @test_cases = ( [ "GET / HTTP/1.1\r\nHost: nvh-strict\r\n\r\n" => 200, 200, "NVH matches"], [ "GET / HTTP/1.1\r\nHost: nvh-strict:1\r\n\r\n" => 200, 200, "NVH matches port ignored"], ); -plan tests => scalar(@test_cases) * 2, need_min_apache_version('2.5.1'); +plan tests => scalar(@test_cases) * 2, need_min_apache_version('2.4.49'); foreach my $vhosts ((["default" => 1], ["core" => 2])) { @@ -41,11 +41,10 @@ foreach my $vhosts ((["default" => 1], ["core" => 2])) { next; } + print "# SENDING to " . peer($sock) . "\n# $req\n"; $sock->print($req); $sock->shutdown(1); - sleep(0.1); $req = escape($req); - print "# SENDING to " . peer($sock) . "\n# $req\n"; my $response_data = ""; my $buf; diff --git a/debian/perl-framework/t/apache/leaks.t b/debian/perl-framework/t/apache/leaks.t index 99ce600..bb7b329 100644 --- a/debian/perl-framework/t/apache/leaks.t +++ b/debian/perl-framework/t/apache/leaks.t @@ -9,61 +9,55 @@ my $url = "/memory_track"; my $init_iters = 2000; my $iters = 500; +my $active = GET_RC($url) == 200; + my $num_tests = $init_iters + $iters * 2; -plan tests => $num_tests; +plan tests => $num_tests, + need { "mod_memory_track not activated" => $active }; ### this doesn't seem sufficient to force all requests over a single ### persistent connection any more, is there a better trick? Apache::TestRequest::user_agent(keep_alive => 1); Apache::TestRequest::scheme('http'); -my $r = GET $url; +my $cid = -1; +my $mem; -if ($r->code != 200) { - # these tests will be skipped for async MPMs or with an APR not - # built with --enable-pool-debug. - skip "mod_memory_track not activated" foreach (1..$num_tests); +# initial iterations should get workers to steady-state memory use. +foreach (1..$init_iters) { + ok t_cmp(GET_RC($url), 200, "200 response"); } -else { - my $cid = -1; - my $mem; - - # initial iterations should get workers to steady-state memory use. - foreach (1..$init_iters) { - ok t_cmp(GET_RC($url), 200, "200 response"); - } - # now test whether c->pool memory is increasing for further - # requests on a given conn_rec (matched by id)... could track them - # all with a bit more effort. - foreach (1..$iters) { - $r = GET $url; +# now test whether c->pool memory is increasing for further +# requests on a given conn_rec (matched by id)... could track them +# all with a bit more effort. +foreach (1..$iters) { + my $r = GET $url; - print "# iter $_\n"; - - ok t_cmp($r->code, 200, "got response"); + print "# iter $_\n"; + + ok t_cmp($r->code, 200, "got response"); - my $content = $r->content; - chomp $content; - my ($key, $id, $bytes) = split ',', $content; + my $content = $r->content; + chomp $content; + my ($key, $id, $bytes) = split ',', $content; - print "# $key, $id, $bytes\n"; + print "# $key, $id, $bytes\n"; - if ($cid == -1) { - $cid = $id; - $mem = $bytes; - ok 1; - } - elsif ($cid != $id) { - skip "using wrong connection"; - } - elsif ($bytes > $mem) { - print "# error: pool memory increased from $mem to $bytes!\n"; - ok 0; - } - else { - ok 1; - } + if ($cid == -1) { + $cid = $id; + $mem = $bytes; + ok 1; + } + elsif ($cid != $id) { + skip "using wrong connection"; + } + elsif ($bytes > $mem) { + print "# error: pool memory increased from $mem to $bytes!\n"; + ok 0; + } + else { + ok 1; } } diff --git a/debian/perl-framework/t/apache/limits.t b/debian/perl-framework/t/apache/limits.t index 124f731..a475f82 100644 --- a/debian/perl-framework/t/apache/limits.t +++ b/debian/perl-framework/t/apache/limits.t @@ -12,7 +12,7 @@ use Apache::TestUtil; # # These values are chosen to exceed the limits in extra.conf, namely: # -# LimitRequestLine 128 +# LimitRequestLine @limitrequestline@ # LimitRequestFieldSize 1024 # LimitRequestFields 32 # <Directory @SERVERROOT@/htdocs/apache/limits> @@ -20,10 +20,12 @@ use Apache::TestUtil; # </Directory> # +my $limitrequestlinex2 = Apache::Test::config()->{vars}->{limitrequestlinex2}; + my @conditions = qw(requestline fieldsize fieldcount bodysize merged_fieldsize); my %params = ('requestline-succeed' => "/apache/limits/", - 'requestline-fail' => ("/apache/limits/" . ('a' x 256)), + 'requestline-fail' => ("/apache/limits/" . ('a' x $limitrequestlinex2)), 'fieldsize-succeed' => 'short value', 'fieldsize-fail' => ('a' x 2048), 'fieldcount-succeed' => 1, diff --git a/debian/perl-framework/t/apache/mergeslashes.t b/debian/perl-framework/t/apache/mergeslashes.t new file mode 100644 index 0000000..850fc93 --- /dev/null +++ b/debian/perl-framework/t/apache/mergeslashes.t @@ -0,0 +1,117 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use MIME::Base64; +use Data::Dumper; +use HTTP::Response; +use Socket; + +# undef: HTTPD should drop connection without error message + +my @test_cases = ( + # request, status code global, status code 'mergeslashes off' VH, msg + [ "GET /authz_core/a/b/c/index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "exact match"], + [ "GET //authz_core/a/b/c/index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "merged even at front"], + [ "GET ///authz_core/a/b/c/index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "merged even at front"], + [ "GET /authz_core/a/b/c//index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "c// should be merged"], + [ "GET /authz_core/a//b/c/index.html HTTP/1.1\r\nHost: merge-default\r\nConnection: close\r\n\r\n" => 403, "a// should be merged"], + [ "GET /authz_core/a//b/c/index.html HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n" => 403, "a// matches locationmatch"], + [ "GET /authz_core/a/b/c//index.html HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n" => 200, "c// doesn't match locationmatch"], + [ "GET /authz_core/a/b/d/index.html HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n" => 403, "baseline failed", need_min_apache_version('2.4.47')], + [ "GET /authz_core/a/b//d/index.html HTTP/1.1\r\nHost: merge-disabled\r\nConnection: close\r\n\r\n" => 403, "b//d not merged for Location with OFF",need_min_apache_version('2.4.47')], +); + +plan tests => scalar(@test_cases), need_min_apache_version('2.4.39'); + + + foreach my $t (@test_cases) { + my $req = $t->[0]; + my $expect = $t->[1]; + my $desc = $t->[2]; + my $cond = $t->[3]; + my $decoded; + + if (defined($cond) && !$cond) { + skip("n/a"); + } + + my $sock = Apache::TestRequest::vhost_socket("core"); + if (!$sock) { + print "# failed to connect\n"; + ok(0); + next; + } + + $sock->print($req); + sleep(0.1); + $req = escape($req); + print "# SENDING to " . peer($sock) . "\n# $req\n"; + + my $response_data = ""; + my $buf; + while ($sock->read($buf, 10000) > 0) { + $response_data .= $buf; + } + my $response = HTTP::Response->parse($response_data); + if ($decoded) { + $response_data =~ s/<title>.*/.../s; + my $out = escape($response_data); + $out =~ s{\\n}{\\n\n# }g; + print "# RESPONSE:\n# $out\n"; + } + if (! defined $response) { + die "HTTP::Response->parse failed"; + } + my $rc = $response->code; + if (! defined $rc) { + if (! defined $expect) { + print "# expecting dropped connection and HTTPD dropped connection\n"; + ok(1); + } + else { + print "# expecting $expect, but HTTPD dropped the connection\n"; + ok(0); + } + } + elsif ($expect > 100) { + print "# expected $expect, got " . $response->code . " for $desc\n"; + ok ($response->code, $expect, $desc ); + } + elsif ($expect == 90) { + print "# expecting headerless HTTP/0.9 body, got response\n"; + ok (1); + } + elsif ($expect) { + print "# expecting success, got ", $rc, ": $desc\n"; + ok ($rc >= 200 && $rc < 400); + } + else { + print "# expecting error, got ", $rc, ": $desc\n"; + ok ($rc >= 400); + } + } + +sub escape +{ + my $in = shift; + $in =~ s{\\}{\\\\}g; + $in =~ s{\r}{\\r}g; + $in =~ s{\n}{\\n}g; + $in =~ s{\t}{\\t}g; + $in =~ s{([\x00-\x1f])}{sprintf("\\x%02x", ord($1))}ge; + return $in; +} + +sub peer +{ + my $sock = shift; + my $hersockaddr = getpeername($sock); + return "<disconnected>" if !$hersockaddr; + my ($port, $iaddr) = sockaddr_in($hersockaddr); + my $herhostname = gethostbyaddr($iaddr, AF_INET); + my $herstraddr = inet_ntoa($iaddr); + return "$herstraddr:$port"; +} diff --git a/debian/perl-framework/t/apache/pr64339.t b/debian/perl-framework/t/apache/pr64339.t new file mode 100644 index 0000000..00097e6 --- /dev/null +++ b/debian/perl-framework/t/apache/pr64339.t @@ -0,0 +1,46 @@ + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; + +my @testcases = ( + # Backend sends Content-Type: application/xml; charset=utf-8 + ['/doc.xml', "application/xml; charset=utf-8", "fóó\n" ], + + # Backend sends Content-Type: application/foo+xml; charset=utf-8 + ['/doc.fooxml', "application/foo+xml; charset=utf-8", "fóó\n" ], + + # Backend sends Content-Type: application/notreallyxml (no charset) + # This should NOT be transformed or have a charset added. + ['/doc.notxml', "application/notreallyxml", "f\xf3\xf3\n" ], + + # Sent with charset=ISO-8859-1 - should be transformed to utf-8 + ['/doc.isohtml', "text/html;charset=utf-8", "<html><body><p>fóó\n</p></body></html>" ], +); + +# mod_xml2enc on trunk behaves quite differently to the 2.4.x version +# after r1785780, and does NOT transform the response body. Unclear if +# this is a regression, so restricting this test to 2.4.x (for now). + +if (have_min_apache_version('2.5.0')) { + print "1..0 # skip: Test only valid for 2.4.x"; + exit 0; +} + +if (not have_min_apache_version('2.4.59')) { + print "1..0 # skip: Test not valid before 2.4.59"; + exit 0; +} + +plan tests => (3*scalar @testcases), need [qw(xml2enc alias proxy_html proxy)]; + +foreach my $t (@testcases) { + my $r = GET("/modules/xml2enc/front".$t->[0]); + + ok t_cmp($r->code, 200, "fetching ".$t->[0]); + ok t_cmp($r->header('Content-Type'), $t->[1], "content-type header test for ".$t->[0]); + ok t_cmp($r->content, $t->[2], "content test for ".$t->[0]); +} diff --git a/debian/perl-framework/t/apache/teclchunk.t b/debian/perl-framework/t/apache/teclchunk.t new file mode 100644 index 0000000..b804368 --- /dev/null +++ b/debian/perl-framework/t/apache/teclchunk.t @@ -0,0 +1,57 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestUtil; +use Apache::TestCommon (); +use Apache::TestRequest (); + +my $module = 'default'; + +if (!have_min_apache_version('2.5.0')) { + print "1..0 # skip: Not supported yet"; + exit 0; +} + +plan tests => 4, ['echo_post_chunk']; + +my $sock = Apache::TestRequest::vhost_socket($module); +ok $sock; + +Apache::TestRequest::socket_trace($sock); +$sock->print("POST /echo_post_chunk HTTP/1.1\r\n"); +$sock->print("Host: localhost\r\n"); +$sock->print("Content-Length: 77\r\n"); +$sock->print("Transfer-Encoding: chunked\r\n"); +$sock->print("\r\n"); +$sock->print("0\r\n"); +$sock->print("X-Chunk-Trailer: $$\r\n"); +$sock->print("\r\n"); +$sock->print("GET /i_do_not_exist_in_your_wildest_imagination HTTP/1.1\r\n"); +$sock->print("Host: localhost\r\n"); + +# Read the status line +chomp(my $response = Apache::TestRequest::getline($sock) || ''); +$response =~ s/\s$//; +ok t_cmp($response, "HTTP/1.1 200 OK", "response codes"); + +# Read the rest +do { + chomp($response = Apache::TestRequest::getline($sock)); + $response =~ s/\s$//; +} +while ($response ne ""); + +# Do the next request... that MUST fail. +$sock->print("\r\n"); +$sock->print("\r\n"); + +# read the trailer (pid) +$response = Apache::TestRequest::getline($sock); +chomp($response) if (defined($response)); +ok t_cmp($response, "$$", "trailer (pid)"); + +# Make sure we have not received a 404. +chomp($response = Apache::TestRequest::getline($sock) || 'NO'); +$response =~ s/\s$//; +ok t_cmp($response, "NO", "no response"); diff --git a/debian/perl-framework/t/conf/core.conf.in b/debian/perl-framework/t/conf/core.conf.in index 10e411f..c82f375 100644 --- a/debian/perl-framework/t/conf/core.conf.in +++ b/debian/perl-framework/t/conf/core.conf.in @@ -2,10 +2,11 @@ # will be converted to a set of NVH'es on the same dynamic port, so they # are collected here. +MaxMemFree 1 <VirtualHost strict-default:core> ServerName default-strict - <IfVersion >= 2.5.1> + <IfVersion >= 2.4.49> # StrictHostCheck can only be configure globally or in a "default" vhost StrictHostCheck ON </IfVersion> @@ -15,3 +16,40 @@ ServerAlias nvh-strict-alias # Implicitly StrictHostCheck ON from default VH above </VirtualHost> + +# MergeSlashes +<IfVersion >= 2.4.39> + <VirtualHost merge-default:core> + ServerName merge-default + <Directory @DocumentRoot@/authz_core/> + require all granted + </Directory> + <LocationMatch ^/authz_core/a/b/c/index.html> + require all denied + </LocationMatch> + </virtualHost> + <VirtualHost merge-disabled:core> + ServerName merge-disabled + MergeSlashes OFF + <Directory @DocumentRoot@/authz_core/> + require all granted + </Directory> + <LocationMatch ^/authz_core/a/b/c/index.html> + require all denied + </LocationMatch> + <LocationMatch ^/authz_core/a//b/c/index.html> + require all denied + </LocationMatch> + <Location /authz_core/a/b/d> + require all denied + </Location> + <ifModule rewrite_module> + <Location /CVE-2020-1927/> + RewriteEngine ON + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L] + </Location> + </ifModule> + </virtualHost> +</IfVersion> + diff --git a/debian/perl-framework/t/conf/extra.conf.in b/debian/perl-framework/t/conf/extra.conf.in index abb699f..2719985 100644 --- a/debian/perl-framework/t/conf/extra.conf.in +++ b/debian/perl-framework/t/conf/extra.conf.in @@ -97,6 +97,7 @@ AddLanguage fr .fr AddLanguage de .de AddLanguage fu .fu + AddLanguage zh-TW .zh-TW AddHandler type-map .var </IfModule> @@ -111,22 +112,27 @@ <Directory @SERVERROOT@/htdocs/modules/negotiation/en> Options +MultiViews - LanguagePriority en fr de fu + LanguagePriority en fr de fu zh-TW </Directory> <Directory @SERVERROOT@/htdocs/modules/negotiation/de> Options +MultiViews - LanguagePriority de en fr fu + LanguagePriority de en fr fu zh-TW </Directory> <Directory @SERVERROOT@/htdocs/modules/negotiation/fr> Options +MultiViews - LanguagePriority fr en de fu + LanguagePriority fr en de fu zh-TW </Directory> <Directory @SERVERROOT@/htdocs/modules/negotiation/fu> Options +MultiViews - LanguagePriority fu fr en de + LanguagePriority fu fr en de zh-TW + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/negotiation/zh-TW> + Options +MultiViews + LanguagePriority zh-TW fr fu en de </Directory> <IfDefine APACHE2> @@ -248,7 +254,7 @@ ### Proxy pass-through to env.pl RewriteRule ^/modules/rewrite/proxy2/(.*)$ http://@SERVERNAME@:@PORT@/modules/cgi/$1 [L,P] - + ### Pass-through conditional on QUERY_STRING RewriteCond %{QUERY_STRING} horse=trigger RewriteRule ^/modules/rewrite/proxy3/(.*)$ http://@SERVERNAME@:@PORT@/modules/cgi/$1 [L,P] @@ -256,6 +262,42 @@ ### Redirect, server context RewriteRule ^/modules/rewrite/redirect.html$ http://@SERVERNAME@:@PORT@/foobar.html [L,R=301] + RewriteRule ^/modules/rewrite/cookie/$ - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly] + RewriteRule ^/modules/rewrite/cookie/0 - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:0] + RewriteRule ^/modules/rewrite/cookie/false - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:false] + RewriteRule ^/modules/rewrite/cookie/lax - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:lax] + RewriteRule ^/modules/rewrite/cookie/none - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:none] + RewriteRule ^/modules/rewrite/cookie/foo - [CO=NAME3:VAL:localhost:86400:/0:secure:httponly:foo] + + RewriteRule ^/modules/rewrite/escaping/local/(.*) /?$1 + RewriteRule ^/modules/rewrite/escaping/local_b/(.*) /?$1 [B] + RewriteRule ^/modules/rewrite/escaping/local_b_justslash/(.*) /?$1 [B=/] + + RewriteRule ^/modules/rewrite/escaping/qsd-like/(.*) /$1? [R] + RewriteRule ^/modules/rewrite/escaping/qsd-like-plus-qsa/(.*) /$1? [R,QSA] + RewriteRule ^/modules/rewrite/escaping/qsd-like-plus-qsa-qsl/(.*) /$1? [R,QSA,QSL] + + <IfVersion >= 2.4.57> + RewriteRule ^/modules/rewrite/escaping/local_bctls/(.*) /?$1 [BCTLS] + RewriteRule ^/modules/rewrite/escaping/local_bctls_andslash/(.*) /?$1 [B=/,BCTLS] + RewriteRule ^/modules/rewrite/escaping/local_bctls_nospace/(.*) /?$1 "[BCTLS,BNE= ?]" + RewriteRule ^/modules/rewrite/escaping/local_b_noslash/(.*) /?$1 [B,BNE=/] + </IfVersion> + RewriteRule ^/modules/rewrite/escaping/redir/(.*) http://@SERVERNAME@:@PORT@/?$1 [R] + RewriteRule ^/modules/rewrite/escaping/redir_ne/(.*) http://@SERVERNAME@:@PORT@/?$1 [R,NE] + RewriteRule ^/modules/rewrite/escaping/proxy/(.*) http://@SERVERNAME@:@PORT@/?$1 [P] + RewriteRule ^/modules/rewrite/escaping/proxy_ne/(.*) http://@SERVERNAME@:@PORT@/?$1 [P,NE] + <LocationMatch ^/modules/rewrite/escaping/fixups/> + RewriteRule local/(.*) /?$1 + RewriteRule redir/(.*) http://@SERVERNAME@:@PORT@/?$1 [R] + RewriteRule redir_ne/(.*) http://@SERVERNAME@:@PORT@/?$1 [R,NE] + RewriteRule proxy/(.*) http://@SERVERNAME@:@PORT@/?$1 [P] + RewriteRule proxy_ne/(.*) http://@SERVERNAME@:@PORT@/?$1 [P,NE] + </LocationMatch> + + <Location /modules/rewrite/escaping> + Header always set rewritten-query "expr=%{QUERY_STRING}" + </Location> <VirtualHost cve_2011_3368_rewrite> DocumentRoot @SERVERROOT@/htdocs/modules/proxy RewriteEngine On @@ -266,10 +308,10 @@ <IfVersion >= 2.4> <Location /modules/rewrite/pr60478-rewrite-loop> # This pair of RewriteRules will loop but should eventually 500 once we - # reach LimitRequestLine * 2 bytes. (In this case, 128 * 2 = 256.) + # reach LimitRequestLine * 2 bytes. (In this case, @limitrequestline@ * 2 = @limitrequestlinex2@.) RewriteRule ^(.*)X(.*)$ $1x$2 # Don't run the test machine out of memory on failure, just stop the loop - RewriteCond expr "util_strlen(%{REQUEST_FILENAME}) -lt 257" + RewriteCond expr "util_strlen(%{REQUEST_FILENAME}) -le @limitrequestlinex2@" RewriteRule X - [N] </Location> </IfVersion> @@ -283,6 +325,8 @@ ProxyPass /reverse/notproxy/ ! ProxyPass /reverse/ http://@SERVERNAME@:@PORT@/ ProxyPassReverse /reverse/ http://@SERVERNAME@:@PORT@/ + ProxyPassMatch ^/reverse-match/(.*)$ http://@SERVERNAME@:@PORT@/$1 + ProxyPassMatch ^/reverse-slash(/.*)?$ http://@SERVERNAME@:@PORT@$1 ProxyPassReverseCookieDomain local remote ProxyPassReverseCookiePath /local /remote <IfVersion >= 2.4.7> @@ -334,12 +378,7 @@ AddHandler cgi-script .sh AddHandler cgi-script .pl ScriptLog @SERVERROOT@/logs/mod_cgi.log - <IfModule mod_cgi.c> - ScriptLogLength 40960 - </IfModule> - <IfModule !mod_cgi.c> - ScriptLogLength 8192 - </IfModule> + ScriptLogLength 40960 ScriptLogBuffer 256 <Directory @SERVERROOT@/htdocs/modules/cgi> @@ -417,6 +456,24 @@ </IfDefine> </IfModule> + +<IfVersion >= 2.5.1> + <Location /redirect_relative/default> + Redirect /out-default + </Location> + <Location /redirect_relative/on> + RedirectRelative ON + Redirect /out-on + </Location> + <Location /redirect_relative/off> + RedirectRelative OFF + Redirect /out-off + </Location> + <Location /redirect_relative/off/fail> + Redirect fail-to-construct-url + </Location> +</IfVersion> + Alias /manual @inherit_documentroot@/manual <Location /manual> Order deny,allow @@ -465,6 +522,14 @@ Alias /manual @inherit_documentroot@/manual <IfModule mod_dir.c> <Directory @SERVERROOT@/htdocs/modules/dir/htaccess> + DirectorySlash OFF + </Directory> + <IfVersion >= 2.5.1> + <Directory @SERVERROOT@/htdocs/modules/dir/htaccess/sub> + DirectorySlash NotFound + </Directory> + </IfVersion> + <Directory @SERVERROOT@/htdocs/modules/dir/htaccess> AllowOverride Indexes </Directory> </IfModule> @@ -506,7 +571,9 @@ Alias /manual @inherit_documentroot@/manual ## <IfModule mod_dav.c> - DAVLockDB @SERVERROOT@/logs/davlock.db + <IfVersion < 2.5.1> + DAVLockDB @SERVERROOT@/logs/davlock.db + </IfVersion> <Directory @SERVERROOT@/htdocs/modules/dav> DAV On @@ -532,7 +599,7 @@ Alias /manual @inherit_documentroot@/manual ## LimitRequest* directive testing ## -LimitRequestLine 128 +LimitRequestLine @limitrequestline@ LimitRequestFieldSize 1024 LimitRequestFields 32 <Directory @SERVERROOT@/htdocs/apache/limits> @@ -739,6 +806,46 @@ LimitRequestFields 32 </IfModule> </IfDefine> +## +## Configuration for t/modules/ldap.t. +## +<IfDefine LDAP> + Alias /modules/ldap/simple @DocumentRoot@ + Alias /modules/ldap/group @DocumentRoot@ + Alias /modules/ldap/refer @DocumentRoot@ + + # Simple user lookup + <Location /modules/ldap/simple> + AuthLDAPURL "ldap://localhost:8389/dc=example,dc=com?uid" + AuthLDAPBindDN "cn=httpd,dc=example,dc=com" + AuthLDAPBindPassword mod_authnz_ldap + AuthType Basic + AuthName ldap-simple@httpd.apache.org + AuthBasicProvider ldap + Require valid-user + </Location> + # Static group configuration + <Location /modules/ldap/group> + AuthLDAPURL "ldap://localhost:8389/dc=example,dc=com?uid" + AuthLDAPBindDN "cn=httpd,dc=example,dc=com" + AuthLDAPBindPassword mod_authnz_ldap + AuthType Basic + AuthName ldap-group@httpd.apache.org + AuthBasicProvider ldap + Require ldap-group cn=Group One,dc=example,dc=com + </Location> + # Referral configuration -- the second user is only found if + # httpd follows the referral. + <Location /modules/ldap/refer> + AuthLDAPURL "ldap://localhost:8389/dc=example,dc=com?uid" + AuthLDAPBindDN "cn=httpd,dc=example,dc=com" + AuthLDAPBindPassword mod_authnz_ldap + AuthType Basic + AuthName ldap-refer@httpd.apache.org + AuthBasicProvider ldap + Require ldap-group cn=Subgroup,ou=dept,dc=example,dc=com + </Location> +</IfDefine> ## ## ErrorDocument handling @@ -828,16 +935,27 @@ LimitRequestFields 32 <Directory @SERVERROOT@/htdocs/modules/filter/bytype> <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE application/xml + AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css </IfModule> <IfModule mod_case_filter.c> AddOutputFilterByType CASEFILTER application/xml + AddOutputFilterByType CASEFILTER text/xml AddOutputFilterByType CASEFILTER text/plain </IfModule> </Directory> </IfModule> ## +## mod_dumpio configuration +## +<IfModule mod_dumpio.c> + DumpIOInput on + DumpIOOutput on + LogLevel dumpio:trace7 +</IfModule> + +## ## LogLevel configuration ## <IfDefine APACHE2> @@ -1061,6 +1179,14 @@ LimitRequestFields 32 LuaHookTranslateName @SERVERROOT@/htdocs/modules/lua/translate.lua translate_name2 # default: LuaInherit parent-first </Location> + + # Filtering tests + LuaOutputFilter LUA_OUTPUT @SERVERROOT@/htdocs/modules/lua/filters.lua output_filter + Alias /modules/lua/filtered @DocumentRoot@ + <Location /modules/lua/filtered/> + SetOutputFilter LUA_OUTPUT + </Location> + </IfModule> # @@ -1255,9 +1381,22 @@ LimitRequestFields 32 <Directory @SERVERROOT@/htdocs/modules/allowmethods> Options +Indexes </Directory> + <IfVersion >= 2.5.1> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/NoPost> + AllowMethods -POST + </Directory> + </IfVersion> <Directory @SERVERROOT@/htdocs/modules/allowmethods/Get> AllowMethods GET </Directory> + <IfVersion >= 2.5.1> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/Get/post> + AllowMethods +POST + </Directory> + <Directory @SERVERROOT@/htdocs/modules/allowmethods/Get/none> + AllowMethods -GET + </Directory> + </IfVersion> <Directory @SERVERROOT@/htdocs/modules/allowmethods/Head> AllowMethods HEAD </Directory> @@ -1318,3 +1457,85 @@ LimitRequestFields 32 CheckCaseOnly on </Directory> </IfModule> + +<IfModule mod_actions.c> + ScriptAlias /cgi_mod_actions @SERVERROOT@/htdocs/modules/cgi + <Location /mod_actions> + SetHandler my-handler + Action my-handler "/cgi_mod_actions/perl_echo.pl" virtual + </Location> + + <Directory @SERVERROOT@/htdocs/modules/actions/action> + AddHandler my-file-type1 .xyz1 + Action my-file-type1 "/cgi_mod_actions/perl_echo.pl" + AddHandler my-file-type2 .xyz2 + Action my-file-type2 "/cgi_mod_actions/perl_echo.pl" virtual + </Directory> + + <Directory @SERVERROOT@/htdocs/modules/actions/script> + Script GET "/cgi_mod_actions/perl_echo.pl" + Script POST "/cgi_mod_actions/perl_post.pl" + </Directory> +</IfModule> + +<IfModule mod_heartbeat.c> + <IfModule mod_heartmonitor.c> + HeartbeatListen 239.0.0.1:27999 + HeartbeatAddress 239.0.0.1:27999 + </IfModule> +</IfModule> + +# +# t/modules/sed.t test config +# +<IfModule mod_sed.c> + AliasMatch /apache/sed/[^/]+/(.*) @DocumentRoot@/$1 + + <Location /apache/sed-echo> + SetHandler echo_post + SetInputFilter sed + </Location> + + <Location /apache/sed/> + AddOutputFilter sed .html + </Location> + + <Location /apache/sed/out-foo> + OutputSed "s/foo/bar/g" + </Location> + <Location /apache/sed-echo/input> + InputSed "s/foo/bar/g" + </Location> + <Location /apache/sed-echo/out-foo-grow> + SetOutputFilter sed + OutputSed "s/foo/barbarbarbar/g" + </Location> +</IfModule> + +# +# t/apache/pr64339.t test configuration +# +<IfModule mod_xml2enc.c> + <IfModule mod_proxy_html.c> + <IfModule mod_proxy.c> + Alias /modules/xml2enc/back @SERVERROOT@/htdocs/modules/xml2enc + Alias /modules/xml2enc/back/iso @SERVERROOT@/htdocs/modules/xml2enc + <Location /modules/xml2enc/back> + AddType application/foo+xml fooxml + AddType application/notreallyxml notxml + AddType application/xml xml + AddType text/html isohtml + AddCharset ISO-8859-1 .isohtml + AddCharset UTF-8 .xml + AddCharset UTF-8 .fooxml + </Location> + <Location /modules/xml2enc/front> + ProxyHTMLEnable on + # mod_proxy_html needs some configuration. + ProxyHTMLURLMap / /blah + ProxyHTMLLinks a href + ProxyPass http://@SERVERNAME@:@PORT@/modules/xml2enc/back + </Location> + </IfModule> + </IfModule> +</IfModule> diff --git a/debian/perl-framework/t/conf/http2.conf.in b/debian/perl-framework/t/conf/http2.conf.in deleted file mode 100644 index 2e6ca67..0000000 --- a/debian/perl-framework/t/conf/http2.conf.in +++ /dev/null @@ -1,105 +0,0 @@ -## -## mod_http2 test config -## - -<IfDefine APACHE2> - <IfModule http2_module> - - LogLevel http2:debug - - <VirtualHost h2c> - Protocols h2c http/1.1 - - <IfModule @CGI_MODULE@> - <Directory @SERVERROOT@/htdocs/modules/h2> - Options +ExecCGI - AddHandler cgi-script .pl - - </Directory> - </IfModule> - - <Location /modules/h2/hello.pl> - </Location> - <IfModule mod_rewrite.c> - RewriteEngine on - RewriteRule ^/modules/h2/latest.tar.gz$ /modules/h2/xxx-1.0.2a.tar.gz [R=302,NC] - </IfModule> - - </VirtualHost> - - <IfModule @ssl_module@> - - <VirtualHost @SERVERNAME@:h2> - Protocols h2 http/1.1 - H2Direct on - - SSLEngine on - SSLCACertificateFile @SSLCA@/asf/certs/ca.crt - SSLCACertificatePath @ServerRoot@/conf/ssl - SSLCARevocationFile @SSLCA@/asf/crl/ca-bundle.crl - SSLCARevocationCheck chain - - # taken from https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations - # - SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK - SSLProtocol All -SSLv2 -SSLv3 - SSLOptions +StdEnvVars - - <IfVersion >= 2.4.18> - # need this off as long as we ran on old openssl - H2ModernTLSOnly off - </IfVersion> - - <IfModule @CGI_MODULE@> - <Directory @SERVERROOT@/htdocs/modules/h2> - Options +ExecCGI - AddHandler cgi-script .pl - </Directory> - </IfModule> - - <Location /modules/h2/hello.pl> - </Location> - <IfModule mod_rewrite.c> - RewriteEngine on - RewriteRule ^/modules/h2/latest.tar.gz$ /modules/h2/xxx-1.0.2a.tar.gz [R=302,NC] - </IfModule> - - </VirtualHost> - - <VirtualHost noh2.example.org:h2> - Protocols http/1.1 - H2Direct off - </VirtualHost> - - <VirtualHost test.example.org:h2> - Protocols h2 http/1.1 - H2Direct on - - SSLEngine on - SSLCACertificateFile @SSLCA@/asf/certs/ca.crt - SSLCACertificatePath @ServerRoot@/conf/ssl - SSLCARevocationFile @SSLCA@/asf/crl/ca-bundle.crl - SSLCARevocationCheck chain - - # taken from https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations - # - SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK - SSLProtocol All -SSLv2 -SSLv3 - SSLOptions +StdEnvVars - - </VirtualHost> - - <VirtualHost test2.example.org:h2> - Protocols http/1.1 h2 - H2Direct on - </VirtualHost> - - <VirtualHost test-ser.example.org:h2> - </VirtualHost> - - </ifModule> - - </IfModule> - -</IfDefine> - diff --git a/debian/perl-framework/t/conf/include.conf.in b/debian/perl-framework/t/conf/include.conf.in index 7e686b9..349f565 100644 --- a/debian/perl-framework/t/conf/include.conf.in +++ b/debian/perl-framework/t/conf/include.conf.in @@ -46,6 +46,11 @@ Options Includes </Directory> + <Directory @SERVERROOT@/htdocs/modules/include/mod_request> + Options Includes + KeptBodySize 32 + </Directory> + <IfDefine APACHE2> <IfModule mod_bucketeer.c> <Directory @SERVERROOT@/htdocs/modules/include/bucketeer> diff --git a/debian/perl-framework/t/conf/proxy.conf.in b/debian/perl-framework/t/conf/proxy.conf.in index 5f740cd..a199ca8 100644 --- a/debian/perl-framework/t/conf/proxy.conf.in +++ b/debian/perl-framework/t/conf/proxy.conf.in @@ -6,6 +6,11 @@ ProxyRequests On </VirtualHost> + <IfVersion >= 2.4.49> + # Test the mapping. + ProxyPass /mapping http://@SERVERNAME@:@PORT@/servlet mapping=servlet + </IfVersion> + </IfModule> <IfModule mod_proxy_hcheck.c> @@ -24,51 +29,51 @@ </VirtualHost> <VirtualHost proxy_http_balancer> + + <IfModule mod_lbmethod_byrequests.c> <Proxy balancer://foo1> BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL2_PORT@ loadfactor=1 </Proxy> + ProxySet balancer://foo1 lbmethod=byrequests + <Location /baltest1> + ProxyPass balancer://foo1/ + </Location> + </IfModule> + <IfModule mod_lbmethod_bytraffic.c> <Proxy balancer://foo2> BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL2_PORT@ loadfactor=1 </Proxy> + ProxySet balancer://foo2 lbmethod=bytraffic + <Location /baltest2> + ProxyPass balancer://foo2/ + </Location> + </IfModule> + <IfModule mod_lbmethod_bybusyness.c> <Proxy balancer://foo3> BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL2_PORT@ loadfactor=1 </Proxy> + ProxySet balancer://foo3 lbmethod=bybusyness + <Location /baltest3> + ProxyPass balancer://foo3/ + </Location> + </IfModule> + <IfModule mod_lbmethod_heartbeat.c> <Proxy balancer://foo4> BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL2_PORT@ loadfactor=1 </Proxy> - - ProxySet balancer://foo1 lbmethod=byrequests - ProxySet balancer://foo2 lbmethod=bytraffic - ProxySet balancer://foo3 lbmethod=bybusyness - <IfVersion >= 2.3.0> - ProxySet balancer://foo4 lbmethod=heartbeat - </IfVersion> - - <Location /baltest1> - ProxyPass balancer://foo1/ - </Location> - - <Location /baltest2> - ProxyPass balancer://foo2/ - </Location> - - <Location /baltest3> - ProxyPass balancer://foo3/ + ProxySet balancer://foo4 lbmethod=heartbeat + <Location /baltest4> + # TODO heartbeat needs additional configuration to have it work + ProxyPass balancer://foo4/ </Location> - - <IfVersion >= 2.3.0> - <Location /baltest4> - # TODO heartbeat needs additional configuration to have it work - ProxyPass balancer://foo4/ - </Location> - </IfVersion> + </IfModule> ## PR 45434 tests <Proxy balancer://pr45434> @@ -78,6 +83,22 @@ ProxyPass /pr45434 balancer://pr45434/alias ProxyPassReverse /pr45434 balancer://pr45434/alias + <Proxy balancer://failover> + BalancerMember http://@SERVERNAME@:@NextAvailablePort@ loadfactor=1 retry=1ms + BalancerMember http://@SERVERNAME@:@PROXY_HTTP_BAL1_PORT@ loadfactor=1 status=H + </Proxy> + ProxyPassMatch ^/baltest_echo_post balancer://failover/echo_post + + ## Test "dynamic balancer + <Proxy balancer://dynproxy> + ProxySet growth=10 + </Proxy> + <Location /balancer-manager> + SetHandler balancer-manager + Allow from all + </Location> + ProxyPass /dynproxy balancer://dynproxy/ + </VirtualHost> </IfModule> @@ -161,6 +182,9 @@ </VirtualHost> + + ProxyPass /proxy/wsoc ws://@SERVERNAME@:@PORT@/modules/lua/websockets.lua + </IfModule> <IfModule mod_rewrite.c> diff --git a/debian/perl-framework/t/conf/ssl/proxyssl.conf.in b/debian/perl-framework/t/conf/ssl/proxyssl.conf.in index dc18fdf..161385b 100644 --- a/debian/perl-framework/t/conf/ssl/proxyssl.conf.in +++ b/debian/perl-framework/t/conf/ssl/proxyssl.conf.in @@ -51,6 +51,66 @@ ProxyPass / https://@proxyssl_url@/ ProxyPassReverse / https://@proxyssl_url@/ + + ProxyPass /proxy/wsoc wss://localhost:@proxy_https_https_port@/modules/lua/websockets.lua + </VirtualHost> + + #here we can test http <-> https using SSLProxyMachine* inside <Proxy> + <VirtualHost proxy_http_https_proxy_section> + #these are not on by default in the 1.x based mod_ssl + <IfDefine APACHE2> + SSLProxyEngine On + + SSLProxyProtocol All + SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL + + SSLProxyCACertificateFile @SSLCA@/asf/certs/ca.crt + SSLProxyCACertificatePath @ServerRoot@/conf/ssl + SSLProxyCARevocationFile @SSLCA@/asf/crl/ca-bundle.crl + <IfVersion >= 2.3.15> + SSLProxyCARevocationCheck chain + </IfVersion> + SSLProxyVerify on + SSLProxyVerifyDepth 10 + </IfDefine> + + + ProxyPass / https://@proxyssl_url@/ + ProxyPassReverse / https://@proxyssl_url@/ + <IfDefine APACHE2> + <Proxy https://@proxyssl_url@> + SSLProxyMachineCertificateFile @SSLCA@/asf/proxy/client_ok.pem + #SSLProxyMachineCertificatePath @SSLCA@/asf/proxy + </Proxy> + </IfDefine> + </VirtualHost> + + + #here we can test https <-> https using SSLProxyMachine* inside <Proxy> + <VirtualHost proxy_https_https_proxy_section> + SSLEngine on + + #these are not on by default in the 1.x based mod_ssl + <IfDefine APACHE2> + SSLProxyEngine On + SSLProxyCACertificateFile @SSLCA@/asf/certs/ca.crt + SSLProxyVerify on + SSLProxyCARevocationPath @SSLCA@/asf/crl + <IfVersion >= 2.3.15> + SSLProxyCARevocationCheck chain + </IfVersion> + </IfDefine> + + + ProxyPass / https://@proxyssl_url@/ + ProxyPassReverse / https://@proxyssl_url@/ + <IfDefine APACHE2> + <Proxy https://@proxyssl_url@> + # ensure that client_ok.pem is picked first: + SSLProxyMachineCertificateFile @SSLCA@/asf/proxy/client_ok.pem + SSLProxyMachineCertificatePath @SSLCA@/asf/proxy + </Proxy> + </IfDefine> </VirtualHost> #here we can test https <-> http @@ -60,7 +120,6 @@ ProxyPass / http://@servername@:@port@/ ProxyPassReverse / http://@servername@:@port@/ </VirtualHost> - </IfModule> </IfModule> diff --git a/debian/perl-framework/t/conf/ssl/ssl.conf.in b/debian/perl-framework/t/conf/ssl/ssl.conf.in index f796b34..6fadf33 100644 --- a/debian/perl-framework/t/conf/ssl/ssl.conf.in +++ b/debian/perl-framework/t/conf/ssl/ssl.conf.in @@ -5,11 +5,12 @@ AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl - SSLSessionCache none - #XXX: would be nice to test these - #SSLSessionCache shm:@ServerRoot@/logs/ssl_scache(512000) - #SSLSessionCache dbm:@ServerRoot@/logs/ssl_scache - #SSLSessionCacheTimeout 300 + <IfDefine TEST_SSL_SESSCACHE> + SSLSessionCache ${SSL_SESSCACHE} + </IfDefine> + <IfDefine !TEST_SSL_SESSCACHE> + SSLSessionCache none + </IfDefine> <IfVersion < 2.3.4> #SSLMutex file:@ServerRoot@/logs/ssl_mutex @@ -87,6 +88,15 @@ SSLVerifyDepth 10 </Location> + # t/ssl/pha.t + <Location /require/small> + SSLVerifyClient require + SSLVerifyDepth 10 + + SSLRenegBufferSize 10 + </Location> + Alias /require/small @DocumentRoot@/modules/cgi + #t/ssl/require.t Alias /require/asf @DocumentRoot@ Alias /require/snakeoil @DocumentRoot@ diff --git a/debian/perl-framework/t/filter/case.t b/debian/perl-framework/t/filter/case.t index 8037789..9bd6915 100644 --- a/debian/perl-framework/t/filter/case.t +++ b/debian/perl-framework/t/filter/case.t @@ -9,7 +9,7 @@ my %urls = ( mod_php4 => '/php/hello.php', mod_cgi => '/modules/cgi/perl.pl', mod_test_rwrite => '/test_rwrite', - mod_alias => '/getfiles-perl-pod/perlsub.pod', + mod_alias => '/getfiles-perl-pod/perlsub.pod', # requires perl-doc on Ubuntu ); my @filter = ('X-AddOutputFilter' => 'CaseFilter'); #mod_client_add_filter @@ -29,6 +29,7 @@ for my $module (sort keys %urls) { print "# testing $module with $urls{$module}\n"; print "# expected 200\n"; print "# received ".$r->code."\n"; + print "# body: ".$r->content."\n"; verify($r); } diff --git a/debian/perl-framework/t/htdocs/modules/h2/files/empty.txt b/debian/perl-framework/t/htdocs/modules/actions/action/dummy.txt index e69de29..e69de29 100644 --- a/debian/perl-framework/t/htdocs/modules/h2/files/empty.txt +++ b/debian/perl-framework/t/htdocs/modules/actions/action/dummy.txt diff --git a/debian/perl-framework/t/htdocs/modules/actions/script/dummy.txt b/debian/perl-framework/t/htdocs/modules/actions/script/dummy.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/actions/script/dummy.txt diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Get/none/.empty b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/none/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/none/.empty diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Get/post/foo.txt b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/post/foo.txt new file mode 100644 index 0000000..5716ca5 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Get/post/foo.txt @@ -0,0 +1 @@ +bar diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/NoPost/.empty b/debian/perl-framework/t/htdocs/modules/allowmethods/NoPost/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/NoPost/.empty diff --git a/debian/perl-framework/t/htdocs/modules/allowmethods/Post/reset/.empty b/debian/perl-framework/t/htdocs/modules/allowmethods/Post/reset/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/allowmethods/Post/reset/.empty diff --git a/debian/perl-framework/t/htdocs/modules/cgi/perl_post.pl.PL b/debian/perl-framework/t/htdocs/modules/cgi/perl_post.pl.PL new file mode 100755 index 0000000..e19d204 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/cgi/perl_post.pl.PL @@ -0,0 +1,23 @@ +local ($buffer, @pairs, $pair, $name, $value); + +print "Content-type: text/plain\n\n"; + +$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; +print "$ENV{'REQUEST_METHOD'}\n"; + +# Read in text +if ($ENV{'REQUEST_METHOD'} eq "POST") { + read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); +} else { + $buffer = $ENV{'QUERY_STRING'}; +} + +# Split information into name/value pairs +@pairs = split(/&/, $buffer); +foreach $pair (@pairs) { + ($name, $value) = split(/=/, $pair); + $value =~ tr/+/ /; + $value =~ s/%(..)/pack("C", hex($1))/eg; + + print "$name: $value\n"; +} diff --git a/debian/perl-framework/t/htdocs/modules/dir/htaccess/sub1/index.html b/debian/perl-framework/t/htdocs/modules/dir/htaccess/sub1/index.html new file mode 100644 index 0000000..be1a204 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/dir/htaccess/sub1/index.html @@ -0,0 +1 @@ +dir index diff --git a/debian/perl-framework/t/htdocs/modules/h2/001.html b/debian/perl-framework/t/htdocs/modules/h2/001.html deleted file mode 100755 index 184952d..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/001.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE HTML>
- <html>
- <head>
- <title>HTML/2.0 Test File: 001</title>
- </head>
- <body>
- <p><h1>HTML/2.0 Test File: 001</h1></p>
- <p>This file only contains a simple HTML structure with plain text.</p>
- </body>
-</html>
diff --git a/debian/perl-framework/t/htdocs/modules/h2/002.jpg b/debian/perl-framework/t/htdocs/modules/h2/002.jpg Binary files differdeleted file mode 100755 index 3feefb0..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/002.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/003.html b/debian/perl-framework/t/htdocs/modules/h2/003.html deleted file mode 100755 index d5b08c5..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/003.html +++ /dev/null @@ -1,11 +0,0 @@ -<!DOCTYPE HTML>
- <html>
- <head>
- <title>HTML/2.0 Test File: 003</title>
- </head>
- <body>
- <p><h1>HTML/2.0 Test File: 003</h1></p>
- <p>This is a text HTML file with a big image:</p>
- <p><img src="003/003_img.jpg" alt="GSMA Logo" style="width:269px;height:249px"></p>
- </body>
-</html>
diff --git a/debian/perl-framework/t/htdocs/modules/h2/003/003_img.jpg b/debian/perl-framework/t/htdocs/modules/h2/003/003_img.jpg Binary files differdeleted file mode 100755 index 3feefb0..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/003/003_img.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004.html b/debian/perl-framework/t/htdocs/modules/h2/004.html deleted file mode 100755 index 768cb82..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004.html +++ /dev/null @@ -1,23 +0,0 @@ -<html>
- <head>
- <title>HTML/2.0 Test File: 004</title>
- </head>
- <body>
- <p><h1>HTML/2.0 Test File: 004</h1>
- This file contains plain text with a bunch of images.<br>
- <img src="004/gophertiles_142.jpg" height="32" width="32"><img src="004/gophertiles_084.jpg" height="32" width="32"><img src="004/gophertiles_052.jpg" height="32" width="32"><img src="004/gophertiles_077.jpg" height="32" width="32"><img src="004/gophertiles_030.jpg" height="32" width="32"><img src="004/gophertiles_027.jpg" height="32" width="32"><img src="004/gophertiles_039.jpg" height="32" width="32"><img src="004/gophertiles_025.jpg" height="32" width="32"><img src="004/gophertiles_017.jpg" height="32" width="32"><img src="004/gophertiles_179.jpg" height="32" width="32"><img src="004/gophertiles_032.jpg" height="32" width="32"><img src="004/gophertiles_161.jpg" height="32" width="32"><img src="004/gophertiles_088.jpg" height="32" width="32"><img src="004/gophertiles_022.jpg" height="32" width="32"><img src="004/gophertiles_146.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_102.jpg" height="32" width="32"><img src="004/gophertiles_009.jpg" height="32" width="32"><img src="004/gophertiles_132.jpg" height="32" width="32"><img src="004/gophertiles_137.jpg" height="32" width="32"><img src="004/gophertiles_055.jpg" height="32" width="32"><img src="004/gophertiles_036.jpg" height="32" width="32"><img src="004/gophertiles_127.jpg" height="32" width="32"><img src="004/gophertiles_145.jpg" height="32" width="32"><img src="004/gophertiles_147.jpg" height="32" width="32"><img src="004/gophertiles_153.jpg" height="32" width="32"><img src="004/gophertiles_105.jpg" height="32" width="32"><img src="004/gophertiles_103.jpg" height="32" width="32"><img src="004/gophertiles_033.jpg" height="32" width="32"><img src="004/gophertiles_054.jpg" height="32" width="32"><img src="004/gophertiles_015.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_016.jpg" height="32" width="32"><img src="004/gophertiles_072.jpg" height="32" width="32"><img src="004/gophertiles_115.jpg" height="32" width="32"><img src="004/gophertiles_108.jpg" height="32" width="32"><img src="004/gophertiles_148.jpg" height="32" width="32"><img src="004/gophertiles_070.jpg" height="32" width="32"><img src="004/gophertiles_083.jpg" height="32" width="32"><img src="004/gophertiles_118.jpg" height="32" width="32"><img src="004/gophertiles_053.jpg" height="32" width="32"><img src="004/gophertiles_021.jpg" height="32" width="32"><img src="004/gophertiles_059.jpg" height="32" width="32"><img src="004/gophertiles_130.jpg" height="32" width="32"><img src="004/gophertiles_163.jpg" height="32" width="32"><img src="004/gophertiles_098.jpg" height="32" width="32"><img src="004/gophertiles_064.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_018.jpg" height="32" width="32"><img src="004/gophertiles_058.jpg" height="32" width="32"><img src="004/gophertiles_167.jpg" height="32" width="32"><img src="004/gophertiles_082.jpg" height="32" width="32"><img src="004/gophertiles_056.jpg" height="32" width="32"><img src="004/gophertiles_180.jpg" height="32" width="32"><img src="004/gophertiles_046.jpg" height="32" width="32"><img src="004/gophertiles_093.jpg" height="32" width="32"><img src="004/gophertiles_106.jpg" height="32" width="32"><img src="004/gophertiles_065.jpg" height="32" width="32"><img src="004/gophertiles_175.jpg" height="32" width="32"><img src="004/gophertiles_139.jpg" height="32" width="32"><img src="004/gophertiles_101.jpg" height="32" width="32"><img src="004/gophertiles_099.jpg" height="32" width="32"><img src="004/gophertiles_051.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_140.jpg" height="32" width="32"><img src="004/gophertiles_134.jpg" height="32" width="32"><img src="004/gophertiles_149.jpg" height="32" width="32"><img src="004/gophertiles_049.jpg" height="32" width="32"><img src="004/gophertiles_095.jpg" height="32" width="32"><img src="004/gophertiles_075.jpg" height="32" width="32"><img src="004/gophertiles_066.jpg" height="32" width="32"><img src="004/gophertiles_090.jpg" height="32" width="32"><img src="004/gophertiles_035.jpg" height="32" width="32"><img src="004/gophertiles_114.jpg" height="32" width="32"><img src="004/gophertiles_160.jpg" height="32" width="32"><img src="004/gophertiles_079.jpg" height="32" width="32"><img src="004/gophertiles_062.jpg" height="32" width="32"><img src="004/gophertiles_096.jpg" height="32" width="32"><img src="004/gophertiles_100.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_104.jpg" height="32" width="32"><img src="004/gophertiles_057.jpg" height="32" width="32"><img src="004/gophertiles_037.jpg" height="32" width="32"><img src="004/gophertiles_086.jpg" height="32" width="32"><img src="004/gophertiles_168.jpg" height="32" width="32"><img src="004/gophertiles_138.jpg" height="32" width="32"><img src="004/gophertiles_045.jpg" height="32" width="32"><img src="004/gophertiles_141.jpg" height="32" width="32"><img src="004/gophertiles_029.jpg" height="32" width="32"><img src="004/gophertiles_165.jpg" height="32" width="32"><img src="004/gophertiles_110.jpg" height="32" width="32"><img src="004/gophertiles_063.jpg" height="32" width="32"><img src="004/gophertiles_158.jpg" height="32" width="32"><img src="004/gophertiles_122.jpg" height="32" width="32"><img src="004/gophertiles_068.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_170.jpg" height="32" width="32"><img src="004/gophertiles_120.jpg" height="32" width="32"><img src="004/gophertiles_117.jpg" height="32" width="32"><img src="004/gophertiles_031.jpg" height="32" width="32"><img src="004/gophertiles_113.jpg" height="32" width="32"><img src="004/gophertiles_074.jpg" height="32" width="32"><img src="004/gophertiles_129.jpg" height="32" width="32"><img src="004/gophertiles_019.jpg" height="32" width="32"><img src="004/gophertiles_060.jpg" height="32" width="32"><img src="004/gophertiles_109.jpg" height="32" width="32"><img src="004/gophertiles_080.jpg" height="32" width="32"><img src="004/gophertiles_097.jpg" height="32" width="32"><img src="004/gophertiles_116.jpg" height="32" width="32"><img src="004/gophertiles_085.jpg" height="32" width="32"><img src="004/gophertiles_050.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_151.jpg" height="32" width="32"><img src="004/gophertiles_094.jpg" height="32" width="32"><img src="004/gophertiles_067.jpg" height="32" width="32"><img src="004/gophertiles_128.jpg" height="32" width="32"><img src="004/gophertiles_034.jpg" height="32" width="32"><img src="004/gophertiles_135.jpg" height="32" width="32"><img src="004/gophertiles_012.jpg" height="32" width="32"><img src="004/gophertiles_010.jpg" height="32" width="32"><img src="004/gophertiles_152.jpg" height="32" width="32"><img src="004/gophertiles_171.jpg" height="32" width="32"><img src="004/gophertiles_087.jpg" height="32" width="32"><img src="004/gophertiles_126.jpg" height="32" width="32"><img src="004/gophertiles_048.jpg" height="32" width="32"><img src="004/gophertiles_023.jpg" height="32" width="32"><img src="004/gophertiles_078.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_071.jpg" height="32" width="32"><img src="004/gophertiles_131.jpg" height="32" width="32"><img src="004/gophertiles_073.jpg" height="32" width="32"><img src="004/gophertiles_143.jpg" height="32" width="32"><img src="004/gophertiles_173.jpg" height="32" width="32"><img src="004/gophertiles_154.jpg" height="32" width="32"><img src="004/gophertiles_061.jpg" height="32" width="32"><img src="004/gophertiles_178.jpg" height="32" width="32"><img src="004/gophertiles_013.jpg" height="32" width="32"><img src="004/gophertiles_028.jpg" height="32" width="32"><img src="004/gophertiles_157.jpg" height="32" width="32"><img src="004/gophertiles_038.jpg" height="32" width="32"><img src="004/gophertiles_069.jpg" height="32" width="32"><img src="004/gophertiles_174.jpg" height="32" width="32"><img src="004/gophertiles_076.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_155.jpg" height="32" width="32"><img src="004/gophertiles_107.jpg" height="32" width="32"><img src="004/gophertiles_136.jpg" height="32" width="32"><img src="004/gophertiles_144.jpg" height="32" width="32"><img src="004/gophertiles_091.jpg" height="32" width="32"><img src="004/gophertiles_024.jpg" height="32" width="32"><img src="004/gophertiles_014.jpg" height="32" width="32"><img src="004/gophertiles_159.jpg" height="32" width="32"><img src="004/gophertiles_011.jpg" height="32" width="32"><img src="004/gophertiles_176.jpg" height="32" width="32"><img src="004/gophertiles_162.jpg" height="32" width="32"><img src="004/gophertiles_156.jpg" height="32" width="32"><img src="004/gophertiles_081.jpg" height="32" width="32"><img src="004/gophertiles_119.jpg" height="32" width="32"><img src="004/gophertiles_026.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_133.jpg" height="32" width="32"><img src="004/gophertiles_020.jpg" height="32" width="32"><img src="004/gophertiles_044.jpg" height="32" width="32"><img src="004/gophertiles_125.jpg" height="32" width="32"><img src="004/gophertiles_150.jpg" height="32" width="32"><img src="004/gophertiles_172.jpg" height="32" width="32"><img src="004/gophertiles_002.jpg" height="32" width="32"><img src="004/gophertiles_169.jpg" height="32" width="32"><img src="004/gophertiles_007.jpg" height="32" width="32"><img src="004/gophertiles_008.jpg" height="32" width="32"><img src="004/gophertiles_042.jpg" height="32" width="32"><img src="004/gophertiles_041.jpg" height="32" width="32"><img src="004/gophertiles_166.jpg" height="32" width="32"><img src="004/gophertiles_005.jpg" height="32" width="32"><img src="004/gophertiles_089.jpg" height="32" width="32"><br>
- <img src="004/gophertiles_177.jpg" height="32" width="32"><img src="004/gophertiles_092.jpg" height="32" width="32"><img src="004/gophertiles_043.jpg" height="32" width="32"><img src="004/gophertiles_111.jpg" height="32" width="32"><img src="004/gophertiles_047.jpg" height="32" width="32"><img src="004/gophertiles.jpg" height="32" width="32"><img src="004/gophertiles_006.jpg" height="32" width="32"><img src="004/gophertiles_121.jpg" height="32" width="32"><img src="004/gophertiles_004.jpg" height="32" width="32"><img src="004/gophertiles_124.jpg" height="32" width="32"><img src="004/gophertiles_123.jpg" height="32" width="32"><img src="004/gophertiles_112.jpg" height="32" width="32"><img src="004/gophertiles_040.jpg" height="32" width="32"><img src="004/gophertiles_164.jpg" height="32" width="32"><img src="004/gophertiles_003.jpg" height="32" width="32"><br>
- <hr>This page is developed using this template:<a href="https://http2.golang.org/">HTTP/2 demo server</a>
- </p>
- </body>
-</html>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles.jpg Binary files differdeleted file mode 100755 index e45ac3b..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_002.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_002.jpg Binary files differdeleted file mode 100755 index 91121de..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_002.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_003.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_003.jpg Binary files differdeleted file mode 100755 index a26648f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_003.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_004.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_004.jpg Binary files differdeleted file mode 100755 index 1d2db98..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_004.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_005.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_005.jpg Binary files differdeleted file mode 100755 index 05a298c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_005.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_006.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_006.jpg Binary files differdeleted file mode 100755 index 54a4920..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_006.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_007.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_007.jpg Binary files differdeleted file mode 100755 index 526f850..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_007.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_008.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_008.jpg Binary files differdeleted file mode 100755 index 35f5a2f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_008.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_009.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_009.jpg Binary files differdeleted file mode 100755 index 96ec2b8..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_009.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_010.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_010.jpg Binary files differdeleted file mode 100755 index 95a9509..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_010.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_011.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_011.jpg Binary files differdeleted file mode 100755 index 65701ed..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_011.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_012.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_012.jpg Binary files differdeleted file mode 100755 index 6242fa6..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_012.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_013.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_013.jpg Binary files differdeleted file mode 100755 index 8096ab2..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_013.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_014.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_014.jpg Binary files differdeleted file mode 100755 index e027312..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_014.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_015.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_015.jpg Binary files differdeleted file mode 100755 index a27076d..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_015.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_016.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_016.jpg Binary files differdeleted file mode 100755 index 04b20db..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_016.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_017.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_017.jpg Binary files differdeleted file mode 100755 index 9b6e44b..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_017.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_018.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_018.jpg Binary files differdeleted file mode 100755 index 209b6fd..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_018.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_019.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_019.jpg Binary files differdeleted file mode 100755 index 3bc23a3..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_019.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_020.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_020.jpg Binary files differdeleted file mode 100755 index ba04297..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_020.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_021.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_021.jpg Binary files differdeleted file mode 100755 index f5a422f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_021.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_022.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_022.jpg Binary files differdeleted file mode 100755 index cb49051..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_022.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_023.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_023.jpg Binary files differdeleted file mode 100755 index 7e83a7e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_023.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_024.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_024.jpg Binary files differdeleted file mode 100755 index 87c711b..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_024.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_025.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_025.jpg Binary files differdeleted file mode 100755 index c42eb3c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_025.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_026.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_026.jpg Binary files differdeleted file mode 100755 index 29f9da6..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_026.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_027.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_027.jpg Binary files differdeleted file mode 100755 index 6ceccde..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_027.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_028.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_028.jpg Binary files differdeleted file mode 100755 index 6e3cb34..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_028.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_029.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_029.jpg Binary files differdeleted file mode 100755 index dac302b..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_029.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_030.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_030.jpg Binary files differdeleted file mode 100755 index 4299071..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_030.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_031.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_031.jpg Binary files differdeleted file mode 100755 index 739924f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_031.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_032.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_032.jpg Binary files differdeleted file mode 100755 index 4685513..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_032.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_033.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_033.jpg Binary files differdeleted file mode 100755 index 26ea0e1..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_033.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_034.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_034.jpg Binary files differdeleted file mode 100755 index f02930e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_034.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_035.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_035.jpg Binary files differdeleted file mode 100755 index 8b6bde8..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_035.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_036.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_036.jpg Binary files differdeleted file mode 100755 index 23ac1c0..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_036.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_037.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_037.jpg Binary files differdeleted file mode 100755 index 6de6681..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_037.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_038.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_038.jpg Binary files differdeleted file mode 100755 index aea11a3..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_038.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_039.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_039.jpg Binary files differdeleted file mode 100755 index bb54d13..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_039.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_040.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_040.jpg Binary files differdeleted file mode 100755 index 91591af..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_040.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_041.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_041.jpg Binary files differdeleted file mode 100755 index 96b13dd..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_041.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_042.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_042.jpg Binary files differdeleted file mode 100755 index 0ef80f1..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_042.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_043.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_043.jpg Binary files differdeleted file mode 100755 index c3828a7..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_043.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_044.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_044.jpg Binary files differdeleted file mode 100755 index 036ec10..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_044.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_045.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_045.jpg Binary files differdeleted file mode 100755 index 03f5413..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_045.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_046.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_046.jpg Binary files differdeleted file mode 100755 index 8353e24..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_046.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_047.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_047.jpg Binary files differdeleted file mode 100755 index 86e4d88..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_047.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_048.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_048.jpg Binary files differdeleted file mode 100755 index 8f308ed..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_048.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_049.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_049.jpg Binary files differdeleted file mode 100755 index bf22844..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_049.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_050.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_050.jpg Binary files differdeleted file mode 100755 index 65addde..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_050.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_051.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_051.jpg Binary files differdeleted file mode 100755 index aabb52b..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_051.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_052.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_052.jpg Binary files differdeleted file mode 100755 index 3d4bad8..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_052.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_053.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_053.jpg Binary files differdeleted file mode 100755 index d30c4d0..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_053.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_054.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_054.jpg Binary files differdeleted file mode 100755 index c27a34c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_054.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_055.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_055.jpg Binary files differdeleted file mode 100755 index bac6e3f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_055.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_056.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_056.jpg Binary files differdeleted file mode 100755 index 246624e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_056.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_057.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_057.jpg Binary files differdeleted file mode 100755 index 0122037..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_057.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_058.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_058.jpg Binary files differdeleted file mode 100755 index 71f602f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_058.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_059.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_059.jpg Binary files differdeleted file mode 100755 index 78b0dd1..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_059.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_060.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_060.jpg Binary files differdeleted file mode 100755 index b2c699c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_060.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_061.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_061.jpg Binary files differdeleted file mode 100755 index 082fe53..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_061.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_062.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_062.jpg Binary files differdeleted file mode 100755 index 9b3bd8a..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_062.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_063.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_063.jpg Binary files differdeleted file mode 100755 index 34bbfc5..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_063.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_064.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_064.jpg Binary files differdeleted file mode 100755 index ac0ddc7..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_064.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_065.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_065.jpg Binary files differdeleted file mode 100755 index f85dce5..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_065.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_066.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_066.jpg Binary files differdeleted file mode 100755 index 616dd5c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_066.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_067.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_067.jpg Binary files differdeleted file mode 100755 index bbbaecf..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_067.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_068.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_068.jpg Binary files differdeleted file mode 100755 index d0b6a18..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_068.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_069.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_069.jpg Binary files differdeleted file mode 100755 index 27e1abc..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_069.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_070.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_070.jpg Binary files differdeleted file mode 100755 index de1a15e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_070.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_071.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_071.jpg Binary files differdeleted file mode 100755 index 40912e3..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_071.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_072.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_072.jpg Binary files differdeleted file mode 100755 index ef01d06..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_072.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_073.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_073.jpg Binary files differdeleted file mode 100755 index 3298be7..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_073.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_074.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_074.jpg Binary files differdeleted file mode 100755 index 28fb75c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_074.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_075.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_075.jpg Binary files differdeleted file mode 100755 index 1f70c5e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_075.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_076.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_076.jpg Binary files differdeleted file mode 100755 index d929f53..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_076.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_077.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_077.jpg Binary files differdeleted file mode 100755 index 49c8ca1..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_077.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_078.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_078.jpg Binary files differdeleted file mode 100755 index a21dd87..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_078.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_079.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_079.jpg Binary files differdeleted file mode 100755 index bfbd4c2..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_079.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_080.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_080.jpg Binary files differdeleted file mode 100755 index 6ff068c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_080.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_081.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_081.jpg Binary files differdeleted file mode 100755 index dd615c7..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_081.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_082.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_082.jpg Binary files differdeleted file mode 100755 index 0c28382..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_082.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_083.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_083.jpg Binary files differdeleted file mode 100755 index 5512c16..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_083.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_084.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_084.jpg Binary files differdeleted file mode 100755 index d08ac7b..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_084.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_085.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_085.jpg Binary files differdeleted file mode 100755 index c098f72..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_085.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_086.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_086.jpg Binary files differdeleted file mode 100755 index 203e41d..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_086.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_087.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_087.jpg Binary files differdeleted file mode 100755 index b664135..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_087.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_088.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_088.jpg Binary files differdeleted file mode 100755 index e211d21..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_088.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_089.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_089.jpg Binary files differdeleted file mode 100755 index 00c4730..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_089.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_090.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_090.jpg Binary files differdeleted file mode 100755 index 7203f10..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_090.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_091.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_091.jpg Binary files differdeleted file mode 100755 index f57baa9..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_091.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_092.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_092.jpg Binary files differdeleted file mode 100755 index cba16c6..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_092.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_093.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_093.jpg Binary files differdeleted file mode 100755 index 6d4c1a5..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_093.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_094.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_094.jpg Binary files differdeleted file mode 100755 index a5f6a2a..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_094.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_095.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_095.jpg Binary files differdeleted file mode 100755 index d213fe5..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_095.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_096.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_096.jpg Binary files differdeleted file mode 100755 index 0fd51eb..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_096.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_097.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_097.jpg Binary files differdeleted file mode 100755 index 2b706cc..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_097.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_098.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_098.jpg Binary files differdeleted file mode 100755 index 7861f2a..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_098.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_099.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_099.jpg Binary files differdeleted file mode 100755 index be10042..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_099.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_100.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_100.jpg Binary files differdeleted file mode 100755 index 8687873..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_100.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_101.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_101.jpg Binary files differdeleted file mode 100755 index fe4b56a..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_101.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_102.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_102.jpg Binary files differdeleted file mode 100755 index d888f6c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_102.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_103.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_103.jpg Binary files differdeleted file mode 100755 index 4ebf13d..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_103.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_104.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_104.jpg Binary files differdeleted file mode 100755 index b4dc051..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_104.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_105.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_105.jpg Binary files differdeleted file mode 100755 index 4f3c5a1..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_105.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_106.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_106.jpg Binary files differdeleted file mode 100755 index 51d6742..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_106.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_107.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_107.jpg Binary files differdeleted file mode 100755 index ef986b7..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_107.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_108.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_108.jpg Binary files differdeleted file mode 100755 index 8901141..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_108.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_109.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_109.jpg Binary files differdeleted file mode 100755 index a946a2b..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_109.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_110.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_110.jpg Binary files differdeleted file mode 100755 index 35d542c..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_110.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_111.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_111.jpg Binary files differdeleted file mode 100755 index 0ec9641..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_111.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_112.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_112.jpg Binary files differdeleted file mode 100755 index 530739a..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_112.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_113.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_113.jpg Binary files differdeleted file mode 100755 index 0537d7f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_113.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_114.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_114.jpg Binary files differdeleted file mode 100755 index 9ecb936..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_114.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_115.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_115.jpg Binary files differdeleted file mode 100755 index 221e6f4..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_115.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_116.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_116.jpg Binary files differdeleted file mode 100755 index 0de1084..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_116.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_117.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_117.jpg Binary files differdeleted file mode 100755 index 8ebd1ea..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_117.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_118.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_118.jpg Binary files differdeleted file mode 100755 index 246d055..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_118.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_119.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_119.jpg Binary files differdeleted file mode 100755 index 8d92e15..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_119.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_120.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_120.jpg Binary files differdeleted file mode 100755 index 8ebef73..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_120.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_121.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_121.jpg Binary files differdeleted file mode 100755 index e7a3772..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_121.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_122.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_122.jpg Binary files differdeleted file mode 100755 index 6a57fc8..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_122.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_123.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_123.jpg Binary files differdeleted file mode 100755 index b941523..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_123.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_124.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_124.jpg Binary files differdeleted file mode 100755 index 9dddf38..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_124.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_125.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_125.jpg Binary files differdeleted file mode 100755 index d2e479e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_125.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_126.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_126.jpg Binary files differdeleted file mode 100755 index 32fc518..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_126.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_127.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_127.jpg Binary files differdeleted file mode 100755 index c5f71cc..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_127.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_128.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_128.jpg Binary files differdeleted file mode 100755 index d899e3d..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_128.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_129.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_129.jpg Binary files differdeleted file mode 100755 index 3508872..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_129.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_130.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_130.jpg Binary files differdeleted file mode 100755 index b26d716..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_130.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_131.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_131.jpg Binary files differdeleted file mode 100755 index 56a27d4..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_131.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_132.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_132.jpg Binary files differdeleted file mode 100755 index b34a2f0..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_132.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_133.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_133.jpg Binary files differdeleted file mode 100755 index b5dc4da..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_133.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_134.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_134.jpg Binary files differdeleted file mode 100755 index 24d6866..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_134.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_135.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_135.jpg Binary files differdeleted file mode 100755 index f0c27c8..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_135.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_136.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_136.jpg Binary files differdeleted file mode 100755 index d3b3b28..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_136.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_137.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_137.jpg Binary files differdeleted file mode 100755 index 7e78d35..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_137.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_138.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_138.jpg Binary files differdeleted file mode 100755 index 5a0024e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_138.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_139.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_139.jpg Binary files differdeleted file mode 100755 index e0e16bc..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_139.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_140.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_140.jpg Binary files differdeleted file mode 100755 index b9c54c4..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_140.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_141.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_141.jpg Binary files differdeleted file mode 100755 index f62eada..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_141.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_142.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_142.jpg Binary files differdeleted file mode 100755 index 6085722..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_142.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_143.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_143.jpg Binary files differdeleted file mode 100755 index f533fe5..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_143.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_144.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_144.jpg Binary files differdeleted file mode 100755 index bcc5602..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_144.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_145.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_145.jpg Binary files differdeleted file mode 100755 index 3b9402e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_145.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_146.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_146.jpg Binary files differdeleted file mode 100755 index f2f049b..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_146.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_147.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_147.jpg Binary files differdeleted file mode 100755 index 06fc738..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_147.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_148.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_148.jpg Binary files differdeleted file mode 100755 index e094d96..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_148.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_149.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_149.jpg Binary files differdeleted file mode 100755 index 26ab8d7..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_149.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_150.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_150.jpg Binary files differdeleted file mode 100755 index 02ca417..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_150.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_151.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_151.jpg Binary files differdeleted file mode 100755 index 78fe841..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_151.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_152.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_152.jpg Binary files differdeleted file mode 100755 index 9cfa47a..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_152.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_153.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_153.jpg Binary files differdeleted file mode 100755 index 0a67731..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_153.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_154.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_154.jpg Binary files differdeleted file mode 100755 index 9a38955..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_154.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_155.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_155.jpg Binary files differdeleted file mode 100755 index 5a10b47..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_155.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_156.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_156.jpg Binary files differdeleted file mode 100755 index 809d5f9..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_156.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_157.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_157.jpg Binary files differdeleted file mode 100755 index 8c852e2..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_157.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_158.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_158.jpg Binary files differdeleted file mode 100755 index 5ef80f7..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_158.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_159.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_159.jpg Binary files differdeleted file mode 100755 index 2fe485f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_159.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_160.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_160.jpg Binary files differdeleted file mode 100755 index 072cfc6..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_160.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_161.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_161.jpg Binary files differdeleted file mode 100755 index cd66e83..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_161.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_162.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_162.jpg Binary files differdeleted file mode 100755 index 6af87e8..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_162.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_163.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_163.jpg Binary files differdeleted file mode 100755 index 1a903c3..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_163.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_164.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_164.jpg Binary files differdeleted file mode 100755 index 71694cf..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_164.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_165.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_165.jpg Binary files differdeleted file mode 100755 index 084c64a..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_165.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_166.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_166.jpg Binary files differdeleted file mode 100755 index 6554740..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_166.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_167.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_167.jpg Binary files differdeleted file mode 100755 index ef2d248..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_167.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_168.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_168.jpg Binary files differdeleted file mode 100755 index fda5636..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_168.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_169.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_169.jpg Binary files differdeleted file mode 100755 index 7b53b20..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_169.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_170.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_170.jpg Binary files differdeleted file mode 100755 index 271c69d..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_170.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_171.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_171.jpg Binary files differdeleted file mode 100755 index a52ac34..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_171.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_172.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_172.jpg Binary files differdeleted file mode 100755 index 7438a7e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_172.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_173.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_173.jpg Binary files differdeleted file mode 100755 index d91d538..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_173.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_174.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_174.jpg Binary files differdeleted file mode 100755 index 3901ca5..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_174.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_175.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_175.jpg Binary files differdeleted file mode 100755 index 106900d..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_175.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_176.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_176.jpg Binary files differdeleted file mode 100755 index c4a54bf..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_176.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_177.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_177.jpg Binary files differdeleted file mode 100755 index d214f26..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_177.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_178.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_178.jpg Binary files differdeleted file mode 100755 index be6cb55..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_178.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_179.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_179.jpg Binary files differdeleted file mode 100755 index 516faa1..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_179.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_180.jpg b/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_180.jpg Binary files differdeleted file mode 100755 index 67bf870..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/004/gophertiles_180.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/006.html b/debian/perl-framework/t/htdocs/modules/h2/006.html deleted file mode 100755 index 6b73025..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/006.html +++ /dev/null @@ -1,23 +0,0 @@ -<!DOCTYPE HTML>
- <html>
- <head>
- <title>HTML/2.0 Test File: 006</title>
- <link rel="stylesheet" type="text/css" href="006/006.css">
- <script type="text/javascript" src="006/006.js"></script>
- </head>
- <body>
- <h1>HTML/2.0 Test File: 006</h1>
- <div class="listTitle">This page contains:
- <ul class="listElements">
- <li>HTML
- <li>CSS
- <li>JavaScript
- </ul>
- </div>
- <div class="listTitle">
- <script type="text/javascript">
- mainJavascript();
- </script>
- </div>
- </body>
-</html>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/006/006.css b/debian/perl-framework/t/htdocs/modules/h2/006/006.css deleted file mode 100755 index de6aa5f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/006/006.css +++ /dev/null @@ -1,21 +0,0 @@ -@CHARSET "ISO-8859-1";
-body{
- background:HoneyDew;
-}
-p{
-color:#0000FF;
-text-align:left;
-}
-
-h1{
-color:#FF0000;
-text-align:center;
-}
-
-.listTitle{
- font-size:large;
-}
-
-.listElements{
- color:#3366FF
-}
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/006/006.js b/debian/perl-framework/t/htdocs/modules/h2/006/006.js deleted file mode 100755 index b450067..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/006/006.js +++ /dev/null @@ -1,31 +0,0 @@ -/**
- * JavaScript Functions File
- */
-function returnDate()
-{
- var currentDate;
- currentDate=new Date();
- var dateString=(currentDate.getMonth()+1)+'/'+currentDate.getDate()+'/'+currentDate.getFullYear();
- return dateString;
-}
-
-function returnHour()
-{
- var currentDate;
- currentDate=new Date();
- var hourString=currentDate.getHours()+':'+currentDate.getMinutes()+':'+currentDate.getSeconds();
- return hourString;
-}
-
-function javaScriptMessage(){
- return 'This section is generated under JavaScript:<br>';
-}
-
-function mainJavascript(){
- document.write(javaScriptMessage())
- document.write('<ul class="listElements">');
- document.write('<li>Current date (dd/mm/yyyy): ' + returnDate());
- document.write('<br>');
- document.write('<li>Current time (hh:mm:ss): '+returnHour());
- document.write('</ul>');
-}
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/007.html b/debian/perl-framework/t/htdocs/modules/h2/007.html deleted file mode 100755 index 4db93e4..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/007.html +++ /dev/null @@ -1,21 +0,0 @@ -<!DOCTYPE html>
-<html>
-<head>
-<meta charset="ISO-8859-1">
-<title>HTML/2.0 Test File: 007</title>
-</head>
-<body>
- <h1>HTML/2.0 Test File: 007</h1>
- <div><p>This page is used to send data from the client to the server:</p>
- <FORM ACTION="007/007.py" METHOD="post" ENCTYPE="multipart/form-data">
- <input type="hidden" name="pageName" value="007.html">
- Name:<input type="text" name="pName" value="Write your name here." size="30" maxlength="30"><br>
- Age:<input type="text" name="pAge" value="00" size="2" maxlength="2"><br>
- Gender: Male<input type="radio" name="pGender" VALUE="Male">
- Female<input type="radio" name="pGender" VALUE="Female"><br>
- <input type="submit" name="userForm" value="Send">
- <input type="reset" value="Clear">
- </FORM>
- </div>
-</body>
-</html>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/007/007.py b/debian/perl-framework/t/htdocs/modules/h2/007/007.py deleted file mode 100755 index 02b5466..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/007/007.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -import cgi, sys -import cgitb; cgitb.enable() - -print "Content-Type: text/html;charset=UTF-8" -print - -print """\ - <!DOCTYPE html><html><head> - <title>HTML/2.0 Test File: 007 (received data)</title></head> - <body><h1>HTML/2.0 Test File: 007</h1>""" - -# alternative output: parsed form params <-> plain POST body -parseContent = True # <-> False - -if parseContent: - print '<h2>Data processed:</h2><ul>' - form = cgi.FieldStorage() - for name in form: - print '<li>', name, ': ', form[name].value, '</li>' - print '</ul>' -else: - print '<h2>POST data output:</h2><div><pre>' - data = sys.stdin.read() - print data - print '</pre></div>' - -print '</body></html>'
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/009.py b/debian/perl-framework/t/htdocs/modules/h2/009.py deleted file mode 100755 index 8fd9095..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/009.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -import cgi, sys, time -import cgitb; cgitb.enable() - -print "Content-Type: text/html;charset=UTF-8" -print - -print """\ - <!DOCTYPE html><html><head> - <title>HTML/2.0 Test File: 009 (server time)</title></head> - <body><h1>HTML/2.0 Test File: 009</h1> - <p>60 seconds of server time, one by one.</p>""" - -for i in range(60): - s = time.strftime("%Y-%m-%d %H:%M:%S") - print "<div>", s, "</div>" - sys.stdout.flush() - time.sleep(1) - -print "<p>done.</p></body></html>"
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/hello.pl b/debian/perl-framework/t/htdocs/modules/h2/hello.pl deleted file mode 100755 index 688b102..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/hello.pl +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env perl - -use Env; - -print "Content-Type: text/html\n"; -print "\n"; - -#my $ssl_protocol = $ENV{'SSL_TLS_SNI'}; -print <<EOF -<html><body> -<h2>Hello World!</h2> -</body></html> -EOF diff --git a/debian/perl-framework/t/htdocs/modules/h2/index.html b/debian/perl-framework/t/htdocs/modules/h2/index.html deleted file mode 100644 index aa11d4f..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/index.html +++ /dev/null @@ -1,45 +0,0 @@ -<html> - <head> - <title>mod_h2 test site</title> - </head> - <body> - <h1>mod_h2 test site</h1> - <p></p> - <h2>served directly</h2> - <ul> - <li><a href="001.html">01: html</a></li> - <li><a href="002.jpg">02: image</a></li> - <li><a href="003.html">03: html+image</a></li> - <li><a href="004.html">04: tiled image</a></li> - <li><a href="005.txt">05: large text</a></li> - <li><a href="006.html">06: html/js/css</a></li> - <li><a href="007.html">07: form submit</a></li> - <li><a href="upload.py">08: upload</a></li> - <li><a href="009.py">09: small chunks</a></li> - </ul> - <h2>mod_proxyied</h2> - <ul> - <li><a href="proxy/001.html">01: html</a></li> - <li><a href="proxy/002.jpg">02: image</a></li> - <li><a href="proxy/003.html">03: html+image</a></li> - <li><a href="proxy/004.html">04: tiled image</a></li> - <li><a href="proxy/005.txt">05: large text</a></li> - <li><a href="proxy/006.html">06: html/js/css</a></li> - <li><a href="proxy/007.html">07: form submit</a></li> - <li><a href="proxy/upload.py">08: upload</a></li> - <li><a href="proxy/009.py">09: small chunks</a></li> - </ul> - <h2>mod_rewritten</h2> - <ul> - <li><a href="rewrite/001.html">01: html</a></li> - <li><a href="rewrite/002.jpg">02: image</a></li> - <li><a href="rewrite/003.html">03: html+image</a></li> - <li><a href="rewrite/004.html">04: tiled image</a></li> - <li><a href="rewrite/005.txt">05: large text</a></li> - <li><a href="rewrite/006.html">06: html/js/css</a></li> - <li><a href="rewrite/007.html">07: form submit</a></li> - <li><a href="rewrite/upload.py">08: upload</a></li> - <li><a href="rewrite/009.py">09: small chunks</a></li> - </ul> - </body> -</html>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/index.jpg b/debian/perl-framework/t/htdocs/modules/h2/index.jpg Binary files differdeleted file mode 100755 index 246624e..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/index.jpg +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/h2/info.php b/debian/perl-framework/t/htdocs/modules/h2/info.php deleted file mode 100644 index 640e4f2..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/info.php +++ /dev/null @@ -1,3 +0,0 @@ -<?php - phpinfo(); -?>
\ No newline at end of file diff --git a/debian/perl-framework/t/htdocs/modules/h2/necho.pl b/debian/perl-framework/t/htdocs/modules/h2/necho.pl deleted file mode 100755 index bc9b6c0..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/necho.pl +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env perl - -use Env; - -my $query = $ENV{QUERY_STRING}; - -if ($query) { - $query =~ /count=([0-9]+)/; - my $count = $1; - $query =~ /text=([^&]+)/; - my $text = $1; - - print "Status: 200\n"; - print "Content-Type: text/plain\n"; - print "\n"; - foreach my $i (1..$count) { - print $text; - } -} -else { - print "Status: 400 Parameter Missing\n"; - print "Content-Type: text/plain\n"; - print "\n"; - print <<EOF; -<html><body> -<p>No query was specified.</p> -</body></html> -EOF -} diff --git a/debian/perl-framework/t/htdocs/modules/h2/upload.pl b/debian/perl-framework/t/htdocs/modules/h2/upload.pl deleted file mode 100755 index 71880f1..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/upload.pl +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python -import cgi, os -import cgitb; cgitb.enable() - -status = '200 Ok' - -try: # Windows needs stdio set for binary mode. - import msvcrt - msvcrt.setmode (0, os.O_BINARY) # stdin = 0 - msvcrt.setmode (1, os.O_BINARY) # stdout = 1 -except ImportError: - pass - -form = cgi.FieldStorage() - -# Test if the file was uploaded -if 'file' in form: - # A nested FieldStorage instance holds the file - fileitem = form['file'] - - # strip leading path from file name to avoid directory traversal attacks - fn = os.path.basename(fileitem.filename) - open('./files/' + fn, 'wb').write(fileitem.file.read()) - message = 'The file "' + fn + '" was uploaded successfully' - -elif 'remove' in form: - remove = form['remove'].value - try: - fn = os.path.basename(remove) - os.remove('./files/' + fn) - message = 'The file "' + fn + '" was removed successfully' - except OSError, e: - message = 'Error removing ' + fn + ': ' + e.strerror - status = '404 File Not Found' -else: - message = '''\ - Upload File<form method="POST" enctype="multipart/form-data"> - <input type="file" name="file"> - <button type="submit">Upload</button></form> - ''' - -print "Status: %s" % (status,) -print """\ - Content-Type: text/html\n - <html><body> - <p>%s</p> - </body></html>""" % (message,) diff --git a/debian/perl-framework/t/htdocs/modules/h2/upload.py b/debian/perl-framework/t/htdocs/modules/h2/upload.py deleted file mode 100755 index 71880f1..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/upload.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python -import cgi, os -import cgitb; cgitb.enable() - -status = '200 Ok' - -try: # Windows needs stdio set for binary mode. - import msvcrt - msvcrt.setmode (0, os.O_BINARY) # stdin = 0 - msvcrt.setmode (1, os.O_BINARY) # stdout = 1 -except ImportError: - pass - -form = cgi.FieldStorage() - -# Test if the file was uploaded -if 'file' in form: - # A nested FieldStorage instance holds the file - fileitem = form['file'] - - # strip leading path from file name to avoid directory traversal attacks - fn = os.path.basename(fileitem.filename) - open('./files/' + fn, 'wb').write(fileitem.file.read()) - message = 'The file "' + fn + '" was uploaded successfully' - -elif 'remove' in form: - remove = form['remove'].value - try: - fn = os.path.basename(remove) - os.remove('./files/' + fn) - message = 'The file "' + fn + '" was removed successfully' - except OSError, e: - message = 'Error removing ' + fn + ': ' + e.strerror - status = '404 File Not Found' -else: - message = '''\ - Upload File<form method="POST" enctype="multipart/form-data"> - <input type="file" name="file"> - <button type="submit">Upload</button></form> - ''' - -print "Status: %s" % (status,) -print """\ - Content-Type: text/html\n - <html><body> - <p>%s</p> - </body></html>""" % (message,) diff --git a/debian/perl-framework/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz b/debian/perl-framework/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz Binary files differdeleted file mode 100644 index f025d43..0000000 --- a/debian/perl-framework/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz +++ /dev/null diff --git a/debian/perl-framework/t/htdocs/modules/include/comment.shtml b/debian/perl-framework/t/htdocs/modules/include/comment.shtml new file mode 100755 index 0000000..b278735 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/comment.shtml @@ -0,0 +1,5 @@ +No +<!--#comment blah blah blah ... --> +comment +<!--#comment blah blah blah ... --> +here diff --git a/debian/perl-framework/t/htdocs/modules/include/mod_request/echo.shtml b/debian/perl-framework/t/htdocs/modules/include/mod_request/echo.shtml new file mode 100755 index 0000000..b211acf --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/mod_request/echo.shtml @@ -0,0 +1 @@ +<!--#echo var="DOCUMENT_NAME" --> diff --git a/debian/perl-framework/t/htdocs/modules/include/mod_request/post.shtml b/debian/perl-framework/t/htdocs/modules/include/mod_request/post.shtml new file mode 100755 index 0000000..a6721e3 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/include/mod_request/post.shtml @@ -0,0 +1 @@ +<!--#include virtual="/modules/cgi/perl_post.pl?$QUERY_STRING"--> diff --git a/debian/perl-framework/t/htdocs/modules/lua/filters.lua b/debian/perl-framework/t/htdocs/modules/lua/filters.lua new file mode 100644 index 0000000..4236ecc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/filters.lua @@ -0,0 +1,16 @@ +--[[ + Example output filter that escapes all HTML entities in the output +]]-- +function output_filter(r) + coroutine.yield("prefix\n") + while bucket do -- For each bucket, do... + if string.len(bucket) > 0 then + local output = "bucket:" .. bucket .. "\n" + coroutine.yield(output) -- Send converted data down the chain + else + coroutine.yield("") -- Send converted data down the chain + end + end + coroutine.yield("suffix\n") + -- No more buckets available. +end diff --git a/debian/perl-framework/t/htdocs/modules/lua/websockets.lua b/debian/perl-framework/t/htdocs/modules/lua/websockets.lua new file mode 100644 index 0000000..6e6d5ba --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/lua/websockets.lua @@ -0,0 +1,18 @@ +function handle(r) +if r:wsupgrade() then -- if we can upgrade: + while true do + local line, isFinal = r:wsread() + local len = string.len(line); + r:debug(string.format("writing line of len %d: %s", len, line)) + if len >= 1024 then + r:debug("writing line ending in '" .. string.sub(line, -127, -1) .. "'") + end + r:wswrite(line) + if line == "quit" then + r:wsclose() -- goodbye! + break + end + + end +end +end diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/map.var index 6b6abcf..1069a10 100644 --- a/debian/perl-framework/t/htdocs/modules/negotiation/de/two/map.var +++ b/debian/perl-framework/t/htdocs/modules/negotiation/de/two/map.var @@ -15,3 +15,7 @@ Content-Language: fr URI: index.fu.html Content-Type: text/html Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/map.var index 6b6abcf..1069a10 100644 --- a/debian/perl-framework/t/htdocs/modules/negotiation/en/two/map.var +++ b/debian/perl-framework/t/htdocs/modules/negotiation/en/two/map.var @@ -15,3 +15,7 @@ Content-Language: fr URI: index.fu.html Content-Type: text/html Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/map.var index 6b6abcf..1069a10 100644 --- a/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/map.var +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fr/two/map.var @@ -15,3 +15,7 @@ Content-Language: fr URI: index.fu.html Content-Type: text/html Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/map.var index 6b6abcf..1069a10 100644 --- a/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/map.var +++ b/debian/perl-framework/t/htdocs/modules/negotiation/fu/two/map.var @@ -15,3 +15,7 @@ Content-Language: fr URI: index.fu.html Content-Type: text/html Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.de new file mode 100755 index 0000000..555bd83 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.de @@ -0,0 +1 @@ +index.html.de.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.en new file mode 100755 index 0000000..b0d750c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.en @@ -0,0 +1 @@ +index.html.en.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fr new file mode 100755 index 0000000..3a8b0bd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fr @@ -0,0 +1 @@ +index.html.fr.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fu new file mode 100755 index 0000000..c0b85df --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.fu @@ -0,0 +1 @@ +index.html.fu.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.zh-TW new file mode 100755 index 0000000..453658e --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/compressed/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW.gz diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.de b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.de new file mode 100755 index 0000000..1d9a5e8 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.de @@ -0,0 +1 @@ +index.html.de diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.en b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.en new file mode 100755 index 0000000..d288e3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.en @@ -0,0 +1 @@ +index.html.en diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fr b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fr new file mode 100755 index 0000000..e739edd --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fr @@ -0,0 +1 @@ +index.html.fr diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fu b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fu new file mode 100755 index 0000000..c0b6f1f --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.fu @@ -0,0 +1 @@ +index.html.fu diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.zh-TW b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.zh-TW new file mode 100755 index 0000000..f653cbe --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/index.html.zh-TW @@ -0,0 +1 @@ +index.html.zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.de.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.de.html new file mode 100755 index 0000000..075f6bc --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.de.html @@ -0,0 +1 @@ +index.de.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.en.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.en.html new file mode 100755 index 0000000..35c0623 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.en.html @@ -0,0 +1 @@ +index.en.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fr.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fr.html new file mode 100755 index 0000000..8c756a7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fr.html @@ -0,0 +1 @@ +index.fr.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fu.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fu.html new file mode 100755 index 0000000..72eb5ef --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.fu.html @@ -0,0 +1 @@ +index.fu.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.zh-TW.html b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.zh-TW.html new file mode 100755 index 0000000..f4f6298 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/index.zh-TW.html @@ -0,0 +1 @@ +index.zh-TW.html diff --git a/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/map.var b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/map.var new file mode 100755 index 0000000..1069a10 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/negotiation/zh-TW/two/map.var @@ -0,0 +1,21 @@ +URI: index.html + +URI: index.en.html +Content-Type: text/html +Content-Language: en + +URI: index.de.html +Content-Type: text/html +Content-Language: de + +URI: index.fr.html +Content-Type: text/html +Content-Language: fr + +URI: index.fu.html +Content-Type: text/html +Content-Language: fu + +URI: index.zh-TW.html +Content-Type: text/html +Content-Language: zh-TW diff --git a/debian/perl-framework/t/htdocs/modules/substitute/.empty b/debian/perl-framework/t/htdocs/modules/substitute/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/substitute/.empty diff --git a/debian/perl-framework/t/htdocs/modules/xml2enc/doc.fooxml b/debian/perl-framework/t/htdocs/modules/xml2enc/doc.fooxml new file mode 100644 index 0000000..612ba3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/xml2enc/doc.fooxml @@ -0,0 +1 @@ +fóó diff --git a/debian/perl-framework/t/htdocs/modules/xml2enc/doc.isohtml b/debian/perl-framework/t/htdocs/modules/xml2enc/doc.isohtml new file mode 100644 index 0000000..9a07943 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/xml2enc/doc.isohtml @@ -0,0 +1 @@ +fóó diff --git a/debian/perl-framework/t/htdocs/modules/xml2enc/doc.notxml b/debian/perl-framework/t/htdocs/modules/xml2enc/doc.notxml new file mode 100644 index 0000000..9a07943 --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/xml2enc/doc.notxml @@ -0,0 +1 @@ +fóó diff --git a/debian/perl-framework/t/htdocs/modules/xml2enc/doc.xml b/debian/perl-framework/t/htdocs/modules/xml2enc/doc.xml new file mode 100644 index 0000000..612ba3c --- /dev/null +++ b/debian/perl-framework/t/htdocs/modules/xml2enc/doc.xml @@ -0,0 +1 @@ +fóó diff --git a/debian/perl-framework/t/htdocs/servlet/mapping.html b/debian/perl-framework/t/htdocs/servlet/mapping.html new file mode 100644 index 0000000..f0b7bc7 --- /dev/null +++ b/debian/perl-framework/t/htdocs/servlet/mapping.html @@ -0,0 +1 @@ +hello servlet diff --git a/debian/perl-framework/t/modules/actions.t b/debian/perl-framework/t/modules/actions.t new file mode 100644 index 0000000..337d4d8 --- /dev/null +++ b/debian/perl-framework/t/modules/actions.t @@ -0,0 +1,59 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +## +## mod_action tests +## +my @tests_action = ( + [ "mod_actions/", 200, "nada"], # Handler for this location + + [ "modules/actions/action/test.xyz", 404], # No handler for .xyz + [ "modules/actions/action/test.xyz1", 404], # Handler for .xyz1, but not virtual + [ "modules/actions/action/test.xyz22", 404], # No Handler for .xyz2x (but one for .xyz2) + + [ "modules/actions/action/test.xyz2", 200, "nada"], # Handler for .xyz2, and virtual +); + +my @tests_script = ( + [ "modules/actions/script/test.x", 404], + [ "modules/actions/script/test.x?foo=bar", 200, "foo=bar"], +); + +my $r; + +plan tests => scalar @tests_action*2 + scalar @tests_script*(2+2+1), need_module('mod_actions'); + +foreach my $test (@tests_action) { + $r = GET($test->[0]); + ok t_cmp($r->code, $test->[1]); + if ($test->[1] == 200) { + ok t_cmp($r->content, $test->[2]); + } + else { + skip "RC=404, no need to check content", 1; + } +} + +foreach my $test (@tests_script) { + $r = GET($test->[0]); + ok t_cmp($r->code, $test->[1]); + if ($test->[1] == 200) { + ok t_cmp($r->content, $test->[2]); + } + else { + skip "RC=404, no need to check content", 1; + } + + $r = POST($test->[0], content => "foo2=bar2"); + ok t_cmp($r->code, 200); + ok t_cmp($r->content, "POST\nfoo2: bar2\n"); + + # Method not allowed + $r = PUT($test->[0], content => "foo2=bar2"); + ok t_cmp($r->code, 405); +} + diff --git a/debian/perl-framework/t/modules/alias.t b/debian/perl-framework/t/modules/alias.t index a605966..957fccc 100644 --- a/debian/perl-framework/t/modules/alias.t +++ b/debian/perl-framework/t/modules/alias.t @@ -35,6 +35,14 @@ my %rm_rc = ( f => '403' ); + +my %relative_redirects = ( + "/redirect_relative/default" => "^http", # URL should be absolute + "/redirect_relative/on" => "^/out-on", # URL should be relative + "/redirect_relative/off" => "^http", # URL should be absolute + "/redirect_relative/off/fail" => undef, # 500 due to invalid URL +); + #XXX: find something that'll on other platforms (/bin/sh aint it) my $script_tests = WINFU ? 0 : 4 + have_min_apache_version("2.4.19"); @@ -44,6 +52,10 @@ my $tests = 12 + have_min_apache_version("2.4.19") * 10 + (keys %rm_rc) * (1 + have_min_apache_version("2.4.19")) * 10 + $script_tests; +if (have_min_apache_version("2.5.1")) { + $tests += (keys %relative_redirects)*2; +} + #LWP required to follow redirects plan tests => $tests, need need_module('alias'), need_lwp; @@ -207,3 +219,22 @@ ok t_cmp((GET_RC "/aliascgi-nada"), ## clean up ## t_rmtree("$vars->{t_logs}/mod_cgi.log"); + + +if (have_min_apache_version("2.5.1")) { + my ($path, $regex); + while (($path, $regex) = each (%relative_redirects)) { + local $Apache::TestRequest::RedirectOK = 0; + my $r; + $r = GET($path); + if (defined($regex)) { + ok t_cmp($r->code, "302"); + ok t_cmp($r->header("Location"), qr/$regex/, "failure on $path"); + } + else { + ok t_cmp($r->code, "500"); + ok t_cmp($r->header("Location"), undef, "failure on $path"); + } + } +} + diff --git a/debian/perl-framework/t/modules/allowmethods.t b/debian/perl-framework/t/modules/allowmethods.t index 6e2e815..d012554 100644 --- a/debian/perl-framework/t/modules/allowmethods.t +++ b/debian/perl-framework/t/modules/allowmethods.t @@ -9,6 +9,7 @@ my $r; my $get = "Get"; my $head = "Head"; my $post = "Post"; +my $options = "Options"; ## ## mod_allowmethods test @@ -25,11 +26,26 @@ my @test_cases = ( [ $post, $post, 200 ], ); +my @new_test_cases = ( + [ $get, $post . '/reset', 200 ], + [ $post, $get . '/post', 200 ], + [ $get, $get . '/post', 200 ], + [ $options, $get . '/post', 405 ], + [ $get, $get . '/none', 405 ], + [ $get, "NoPost", 200 ], + [ $post, "NoPost", 405 ], + [ $options, "NoPost" , 200 ], +); + +if (have_min_apache_version('2.5.1')) { + push(@test_cases, @new_test_cases); +} + plan tests => (scalar @test_cases), have_module 'allowmethods'; foreach my $case (@test_cases) { my ($fct, $allowed, $rc) = @{$case}; - + if ($fct eq $get) { $r = GET('/modules/allowmethods/' . $allowed . '/'); } @@ -39,7 +55,10 @@ foreach my $case (@test_cases) { elsif ($fct eq $post) { $r = POST('/modules/allowmethods/' . $allowed . '/foo.txt'); } + elsif ($fct eq $options) { + $r = OPTIONS('/modules/allowmethods/' . $allowed . '/'); + } - ok t_cmp($r->code, $rc, $fct . " - When " . $allowed . " is allowed."); + ok t_cmp($r->code, $rc, "$fct request to /$allowed responds $rc"); } - + diff --git a/debian/perl-framework/t/modules/autoindex.t b/debian/perl-framework/t/modules/autoindex.t index acd9656..76c9af4 100644 --- a/debian/perl-framework/t/modules/autoindex.t +++ b/debian/perl-framework/t/modules/autoindex.t @@ -122,8 +122,17 @@ foreach my $fancy (0,1) { sub ai_test ($$$$) { my ($htconf,$c,$o,$t_uri) = @_; - my $html_head = <<HEAD; -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> + my $html_head; + + if (have_min_apache_version('2.5.1')) { + $html_head = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'; + } + else { + $html_head = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'; + } + + $html_head .= <<HEAD; + <html> <head> <title>Index of $uri_prefix</title> diff --git a/debian/perl-framework/t/modules/brotli.t b/debian/perl-framework/t/modules/brotli.t index fcbed74..0f9dc13 100644 --- a/debian/perl-framework/t/modules/brotli.t +++ b/debian/perl-framework/t/modules/brotli.t @@ -5,49 +5,86 @@ use Apache::Test; use Apache::TestUtil; use Apache::TestRequest; -plan tests => 10, need_module 'brotli', need_module 'alias'; +my @qvalue = ( + [ '' , 1], + [ ' ' , 1], + [ ';' , 1], + [';q=' , 1], + [';q=0' , 0], + [';q=0.' , 0], + [';q=0.0' , 0], + [';q=0.00' , 0], + [';q=0.000' , 0], + [';q=0.0000' , 1], # invalid qvalue format +); + +plan tests => (6 * scalar @qvalue) + 4, need_module 'brotli', need_module 'alias'; my $r; -# GET request against the location with Brotli. -$r = GET("/only_brotli/index.html", "Accept-Encoding" => "br"); -ok t_cmp($r->code, 200); -ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); -if (!defined($r->header("Content-Length"))) { - t_debug "Content-Length was expected"; - ok 0; -} -if (!defined($r->header("ETag"))) { - t_debug "ETag field was expected"; - ok 0; -} +foreach my $q (@qvalue) { + # GET request against the location with Brotli. + print "qvalue: " . $q->[0] . "\n"; + $r = GET("/only_brotli/index.html", "Accept-Encoding" => "br" . $q->[0]); + ok t_cmp($r->code, 200); + if ($q->[1] == 1) { + ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); + } + else { + ok t_cmp($r->header("Content-Encoding"), undef, "response without Content-Encoding is OK"); + } + + if (!defined($r->header("Content-Length"))) { + t_debug "Content-Length was expected"; + ok 0; + } + if (!defined($r->header("ETag"))) { + t_debug "ETag field was expected"; + ok 0; + } -# GET request for a zero-length file. -$r = GET("/only_brotli/zero.txt", "Accept-Encoding" => "br"); -ok t_cmp($r->code, 200); -ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); -if (!defined($r->header("Content-Length"))) { - t_debug "Content-Length was expected"; - ok 0; -} -if (!defined($r->header("ETag"))) { - t_debug "ETag field was expected"; - ok 0; -} + # GET request for a zero-length file. + print "qvalue: " . $q->[0] . "\n"; + $r = GET("/only_brotli/zero.txt", "Accept-Encoding" => "br" . $q->[0]); + ok t_cmp($r->code, 200); + if ($q->[1] == 1) { + ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); + } + else { + ok t_cmp($r->header("Content-Encoding"), undef, "response without Content-Encoding is OK"); + } -# HEAD request against the location with Brotli. -$r = HEAD("/only_brotli/index.html", "Accept-Encoding" => "br"); -ok t_cmp($r->code, 200); -ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); -if (!defined($r->header("Content-Length"))) { - t_debug "Content-Length was expected"; - ok 0; -} -if (!defined($r->header("ETag"))) { - t_debug "ETag field was expected"; - ok 0; + if (!defined($r->header("Content-Length"))) { + t_debug "Content-Length was expected"; + ok 0; + } + if (!defined($r->header("ETag"))) { + t_debug "ETag field was expected"; + ok 0; + } + + # HEAD request against the location with Brotli. + print "qvalue: " . $q->[0] . "\n"; + $r = HEAD("/only_brotli/index.html", "Accept-Encoding" => "br" . $q->[0]); + ok t_cmp($r->code, 200); + if ($q->[1] == 1) { + ok t_cmp($r->header("Content-Encoding"), "br", "response Content-Encoding is OK"); + } + else { + ok t_cmp($r->header("Content-Encoding"), undef, "response without Content-Encoding is OK"); + } + + if (!defined($r->header("Content-Length"))) { + t_debug "Content-Length was expected"; + ok 0; + } + if (!defined($r->header("ETag"))) { + t_debug "ETag field was expected"; + ok 0; + } } + if (have_module('deflate')) { # GET request against the location with fallback to deflate (test that # Brotli is chosen due to the order in SetOutputFilter). diff --git a/debian/perl-framework/t/modules/cgi.t b/debian/perl-framework/t/modules/cgi.t index d191d8d..9b6edc2 100644 --- a/debian/perl-framework/t/modules/cgi.t +++ b/debian/perl-framework/t/modules/cgi.t @@ -9,10 +9,7 @@ use File::stat; my $have_apache_2 = have_apache 2; my $have_apache_2050 = have_min_apache_version "2.0.50"; -my $script_log_length = 8192; -if (have_module 'mod_cgi') { - $script_log_length = 40960; -} +my $script_log_length = 40960; ## mod_cgi test ## @@ -21,12 +18,7 @@ if (have_module 'mod_cgi') { ## AddHandler cgi-script .sh ## AddHandler cgi-script .pl ## ScriptLog logs/mod_cgi.log -## <IfModule mod_cgi.c> -## ScriptLogLength 40960 -## </IfModule mod_cgi> -## <IfModule !mod_cgi.c> -## ScriptLogLength 8192 -## </IfModule mod_cgi> +## ScriptLogLength 40960 ## ScriptLogBuffer 256 ## <Directory @SERVERROOT@/htdocs/modules/cgi> ## Options +ExecCGI @@ -191,9 +183,8 @@ foreach my $length (@post_content) { $actual = POST_RC "$path/bogus-perl.pl", content => "$content"x$length; print "# posted content (length $length) to bogus-perl.pl\n"; - print "# got return code of: $actual, expecting: $expected\n"; ## should get rc 500 - ok ($actual eq $expected); + ok t_cmp($actual, $expected, "POST to $path/bogus-perl.pl [content: $content x $length]"); if (-e $cgi_log) { ## cgi log should be bigger. @@ -206,7 +197,7 @@ foreach my $length (@post_content) { ## should not fall in here at this point, ## but just in case... print "# verifying log did not increase in size...\n"; - ok ($$stat[7] eq $log_size); + ok t_cmp($$stat[7], $log_size, "log size should not have increased"); } $log_size = $$stat[7]; diff --git a/debian/perl-framework/t/modules/deflate.t b/debian/perl-framework/t/modules/deflate.t index c107b14..3b368ce 100644 --- a/debian/perl-framework/t/modules/deflate.t +++ b/debian/perl-framework/t/modules/deflate.t @@ -21,7 +21,7 @@ my @server_bucketeer_uri = ("/modules/deflate/bucketeer/P.txt", ); my $cgi_tests = 3; -my $tests_per_uri = 3; +my $tests_per_uri = 4; my $tests = $tests_per_uri * (@server_deflate_uris + @server_bucketeer_uri) + $cgi_tests; my $vars = Apache::Test::vars(); my $module = 'default'; @@ -33,6 +33,9 @@ print "testing $module\n"; my @deflate_headers; push @deflate_headers, "Accept-Encoding" => "gzip"; +my @deflate_headers_q0; +push @deflate_headers_q0, "Accept-Encoding" => "gzip;q=0"; + my @inflate_headers; push @inflate_headers, "Content-Encoding" => "gzip"; @@ -47,11 +50,13 @@ for my $server_deflate_uri (@server_deflate_uris) { my $original_str = GET_BODY($server_deflate_uri); my $deflated_str = GET_BODY($server_deflate_uri, @deflate_headers); + my $deflated_str_q0 = GET_BODY($server_deflate_uri, @deflate_headers_q0); my $inflated_str = POST_BODY($server_inflate_uri, @inflate_headers, content => $deflated_str); ok $original_str eq $inflated_str; + ok $original_str eq $deflated_str_q0; my $resp = POST($server_inflate_uri, @inflate_headers, content => "foo123456789012346"); if (have_min_apache_version("2.5")) { diff --git a/debian/perl-framework/t/modules/dir.t b/debian/perl-framework/t/modules/dir.t index 1b93423..51e632e 100644 --- a/debian/perl-framework/t/modules/dir.t +++ b/debian/perl-framework/t/modules/dir.t @@ -20,7 +20,7 @@ sub my_chomp { $actual =~ s/[\r\n]+$//s; } -plan tests => @bad_index * @index * 5 + @bad_index + 5, need_module 'dir'; +plan tests => @bad_index * @index * 5 + @bad_index + 5 + 3, need_module 'dir'; foreach my $bad_index (@bad_index) { @@ -91,6 +91,21 @@ $actual = GET_BODY $url; my_chomp(); ok ($actual eq $expected); +# DirectorySlash stuff +my $res = GET "/modules/dir", redirect_ok => 0; +ok ($res->code == 301); +$res = GET "/modules/dir/htaccess", redirect_ok => 0; +ok ($res->code == 403); + +if (!have_min_apache_version('2.5.1')) { + skip("missing DirectorySlash NotFound"); +} +else { + $res = GET "/modules/dir/htaccess/sub", redirect_ok => 0; + ok ($res->code == 404); +} + + sub write_htaccess { my $string = shift; diff --git a/debian/perl-framework/t/modules/headers.t b/debian/perl-framework/t/modules/headers.t index 3504a33..4892b95 100644 --- a/debian/perl-framework/t/modules/headers.t +++ b/debian/perl-framework/t/modules/headers.t @@ -2,6 +2,7 @@ use strict; use warnings FATAL => 'all'; use Apache::Test; +use Apache::TestUtil; use Apache::TestRequest; ## @@ -11,11 +12,138 @@ use Apache::TestRequest; my $htdocs = Apache::Test::vars('documentroot'); my $htaccess = "$htdocs/modules/headers/htaccess/.htaccess"; my @header_types = ('set', 'append', 'add', 'unset'); - + +my @testcases = ( + ## htaccess + ## Header to set in the request + ## Expected result + + # echo + [ + "Header echo Test-Header\nHeader echo ^Aaa\$\nHeader echo ^Aa\$", + [ 'Test-Header' => 'value', 'Aaa' => 'b' , 'Aa' => 'bb' ], + [ 'Test-Header' => 'value', 'Aaa' => 'b' , 'Aa' => 'bb' ], + ], + [ + "Header echo Test-Header\nHeader echo XXX\nHeader echo ^Aa\$", + [ 'Test-Header' => 'foo', 'aaa' => 'b', 'aa' => 'bb' ], + [ 'Test-Header' => 'foo', 'aa' => 'bb' ], + ], + [ + "Header echo Test-Header.*", # regex + [ 'Test-Header' => 'foo', 'Test-Header1' => 'value1', 'Test-Header2' => 'value2' ], + [ 'Test-Header' => 'foo', 'Test-Header1' => 'value1', 'Test-Header2' => 'value2' ], + ], + # edit + [ + "Header echo Test-Header\nHeader edit Test-Header foo bar", # sizeof(foo) = sizeof(bar) + [ 'Test-Header' => 'foofoo' ], + [ 'Test-Header' => 'barfoo' ], + ], + [ + "Header echo Test-Header\nHeader edit Test-Header foo2 bar", # sizeof(foo2) > sizeof(bar) + [ 'Test-Header' => 'foo2foo2' ], + [ 'Test-Header' => 'barfoo2' ], + ], + [ + "Header echo Test-Header\nHeader edit Test-Header foo bar2", # sizeof(foo) < sizeof(bar2) + [ 'Test-Header' => 'foofoo' ], + [ 'Test-Header' => 'bar2foo' ], + ], + # edit* + [ + "Header echo Test-Header\nHeader edit* Test-Header foo bar", # sizeof(foo) = sizeof(bar) + [ 'Test-Header' => 'foofoo' ], + [ 'Test-Header' => 'barbar' ], + ], + [ + "Header echo Test-Header\nHeader edit* Test-Header foo2 bar", # sizeof(foo2) > sizeof(bar) + [ 'Test-Header' => 'foo2foo2' ], + [ 'Test-Header' => 'barbar' ], + ], + [ + "Header echo Test-Header\nHeader edit* Test-Header foo bar2", # sizeof(foo) < sizeof(bar2) + [ 'Test-Header' => 'foofoo' ], + [ 'Test-Header' => 'bar2bar2' ], + ], + # merge + [ + "Header merge Test-Header foo", # missing header + [ ], + [ 'Test-Header' => 'foo' ], + ], + [ + "Header echo Test-Header\nHeader merge Test-Header foo", # already existing, same value + [ 'Test-Header' => 'foo' ], + [ 'Test-Header' => 'foo' ], + ], + [ + "Header echo Test-Header\nHeader merge Test-Header foo", # already existing, same value, but with "" + [ 'Test-Header' => '"foo"' ], + [ 'Test-Header' => '"foo", foo' ], + ], + [ + "Header echo Test-Header\nHeader merge Test-Header bar", # already existing, different value + [ 'Test-Header' => 'foo' ], + [ 'Test-Header' => 'foo, bar' ], + ], + # setifempty + [ + "Header echo Test-Header\nHeader setifempty Test-Header bar", # already existing + [ 'Test-Header' => 'foo' ], + [ 'Test-Header' => 'foo' ], + ], + [ + "Header echo Test-Header\nHeader setifempty Test-Header2 bar", # missing header + [ 'Test-Header' => 'foo' ], + [ 'Test-Header' => 'foo', 'Test-Header2' => 'bar' ], + ], + # env= + [ + "SetEnv MY_ENV\nHeader set Test-Header foo env=MY_ENV", # env defined + [ ], + [ 'Test-Header' => 'foo' ], + ], + [ + "Header set Test-Header foo env=!MY_ENV", # env NOT defined + [ ], + [ 'Test-Header' => 'foo' ], + ], + # expr= + [ + "Header set Test-Header foo \"expr=%{REQUEST_URI} =~ m#htaccess#\"", # expr + [ ], + [ 'Test-Header' => 'foo' ], + ], +); +if (have_min_apache_version('2.5.1')) { + push(@testcases, + ( + # edit* + [ + "Header echo Test-Header\nHeader edit* Test-Header (?<=a)(ba) cd", # lookbehind + [ 'Test-Header' => 'ababa' ], + [ 'Test-Header' => 'acdcd' ], + ], + [ + "Header echo Test-Header\nHeader edit* Test-Header ^ foo", # empty match (no infinite loop!) + [ 'Test-Header' => 'bar' ], + [ 'Test-Header' => 'foobar' ], + ], + [ + "Header echo Test-Header\nHeader edit* Test-Header ^(.*)\$ \$1;httpOnly;secure", # empty header/match (no infinite loop!) + [ 'Test-Header' => '' ], + [ 'Test-Header' => ';httpOnly;secure' ], + ], + ) + ); +} + plan tests => - @header_types**4 + @header_types**3 + @header_types**2 + @header_types**1, + @header_types**4 + @header_types**3 + @header_types**2 + @header_types**1 + scalar @testcases * 2, have_module 'headers'; +# Test various configurations foreach my $header1 (@header_types) { ok test_header($header1); @@ -37,6 +165,13 @@ foreach my $header1 (@header_types) { } +# Test some other Header directives, including regex +my $ua = LWP::UserAgent->new(); +my $hostport = Apache::TestRequest::hostport(); +foreach my $t (@testcases) { + test_header2($t); +} + ## clean up ## unlink $htaccess; @@ -157,3 +292,42 @@ sub test_header { } } + +sub test_header2 { + my @test = @_; + my $h = HTTP::Headers->new; + + print "\n\n\n"; + for (my $i = 0; $i < scalar @{$test[0][1]}; $i += 2) { + print "Header sent n°" . $i/2 . ":\n"; + print " header: " . $test[0][1][$i] . "\n"; + print " value: " . $test[0][1][$i+1] . "\n"; + $h->header($test[0][1][$i] => $test[0][1][$i+1]); + } + + open (HT, ">$htaccess"); + print HT $test[0][0]; + close(HT); + + ## + my $r = HTTP::Request->new('GET', "http://$hostport/modules/headers/htaccess/", $h); + my $res = $ua->request($r); + ok t_cmp($res->code, 200, "Checking return code is '200'"); + + my $isok = 1; + for (my $i = 0; $i < scalar @{$test[0][2]}; $i += 2) { + print "\n"; + print "Header received n°" . $i/2 . ":\n"; + print " header: " . $test[0][2][$i] . "\n"; + print " expected: " . $test[0][2][$i+1] . "\n"; + if ($res->header($test[0][2][$i])) { + print " received: " . $res->header($test[0][2][$i]) . "\n"; + } else { + print " received: <undefined>\n"; + } + $isok = $isok && $res->header($test[0][2][$i]) && $test[0][2][$i+1] eq $res->header($test[0][2][$i]); + } + print "\nResponse received is:\n" . $res->as_string; + + ok $isok; +} diff --git a/debian/perl-framework/t/modules/heartbeat.t b/debian/perl-framework/t/modules/heartbeat.t new file mode 100644 index 0000000..d9f6f18 --- /dev/null +++ b/debian/perl-framework/t/modules/heartbeat.t @@ -0,0 +1,30 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil qw/t_start_error_log_watch t_finish_error_log_watch/; + +my $r; +my $line; +my $count = 0; +my $nb_seconds = 5; +# Because of timing, we may see less than what could be expected +my $nb_expected = $nb_seconds - 2; + +plan tests => 1, sub { need_module('mod_heartbeat', 'mod_heartmonitor') && !need_apache_mpm('prefork') }; + +# Give some time to the heart to beat a few times +t_start_error_log_watch(); +sleep($nb_seconds); +my @loglines = t_finish_error_log_watch(); + +# Heartbeat sent by mod_heartbeat and received by mod_heartmonitor are logged with DEBUG AH02086 message +foreach $line (@loglines) { + if ($line =~ "AH02086") { + $count++; + } +} + +print "Expecting at least " . $nb_expected . " heartbeat ; Seen: " . $count . "\n"; +ok($count >= $nb_expected); diff --git a/debian/perl-framework/t/modules/http2.t b/debian/perl-framework/t/modules/http2.t deleted file mode 100644 index d58f52f..0000000 --- a/debian/perl-framework/t/modules/http2.t +++ /dev/null @@ -1,528 +0,0 @@ -use strict; -use warnings FATAL => 'all'; - -use Net::SSLeay; -use Apache::Test; -use Apache::TestRequest; -use Apache::TestUtil; -use Apache::TestConfig (); - -my $tls_version_suite = 4; -my $num_suite = 24; -my $vhost_suite = 4; - -my $total_tests = 2 * $num_suite + $vhost_suite + $tls_version_suite; - -Net::SSLeay::initialize(); - -my $sni_available = Net::SSLeay::OPENSSL_VERSION_NUMBER() >= 0x01000000; -my $alpn_available = $sni_available && exists &Net::SSLeay::CTX_set_alpn_protos; - -plan tests => $total_tests, need 'Protocol::HTTP2::Client', - need_module 'http2', need_min_apache_version('2.4.17'); - -# Check support for TLSv1_2 and later - -my $tls_modern = 1; - -Apache::TestRequest::set_ca_cert(); -my $sock = Apache::TestRequest::vhost_socket('h2'); -ok ($sock && $sock->connected); - -my $req = "GET / HTTP/1.1\r\n". - "Host: " . Apache::TestRequest::hostport() . "\r\n". - "\r\n"; - -ok $sock->print($req); - -my $line = Apache::TestRequest::getline($sock) || ''; - -ok t_cmp($line, qr{^HTTP/1\.. 200}, "read first response-line"); - -my $tls_version = $sock->get_sslversion(); - -ok t_cmp($tls_version, qr{^(SSL|TLSv\d(_\d)?$)}, "TLS version in use"); - -if ($tls_version =~ /^(SSL|TLSv1(|_0|_1)$)/) { - print STDOUT "Disabling TLS tests due to TLS version $tls_version\n"; - $tls_modern = 0; -} - -Apache::TestRequest::module("http2"); - -my $config = Apache::Test::config(); -my $host = $config->{vhosts}->{h2c}->{servername}; -my $port = $config->{vhosts}->{h2c}->{port}; - -my $shost = $config->{vhosts}->{h2}->{servername}; -my $sport = $config->{vhosts}->{h2}->{port}; -my $serverdir = $config->{vars}->{t_dir}; -my $htdocs = $serverdir . "/htdocs"; - -require Protocol::HTTP2::Client; -use AnyEvent; -use AnyEvent::Socket; -use AnyEvent::Handle; -use Net::SSLeay; -use AnyEvent::TLS; -use Carp qw( croak ); - -no warnings 'redefine'; -no strict 'refs'; -{ - my $old_ref = \&{ 'AnyEvent::TLS::new' }; - *{ 'AnyEvent::TLS::new' } = sub { - my ( $class, %param ) = @_; - - my $self = $old_ref->( $class, %param ); - - $self->{host_name} = $param{host_name} - if exists $param{host_name}; - - $self; - }; -} - -{ - my $old_ref = \&{ 'AnyEvent::TLS::_get_session' }; - *{ 'AnyEvent::TLS::_get_session' } = sub($$;$$) { - my ($self, $mode, $ref, $cn) = @_; - - my $session = $old_ref->( @_ ); - - if ( $mode eq 'connect' ) { - if ( $self->{host_name} ) { - print 'setting host_name to ' . $self->{host_name}; - Net::SSLeay::set_tlsext_host_name( $session, $self->{host_name} ); - } - } - - $session; - }; -} - - -sub connect_and_do { - my %args = ( - @_ - ); - my $scheme = $args{ctx}->{scheme}; - my $host = $args{ctx}->{host}; - my $port = $args{ctx}->{port}; - my $client = $args{ctx}->{client}; - my $host_name = $args{ctx}->{host_name}; - my $w = AnyEvent->condvar; - - tcp_connect $host, $port, sub { - my ($fh) = @_ or do { - print "connection failed: $!\n"; - $w->send; - return; - }; - - my $tls; - my $tls_ctx; - if ($scheme eq 'https') { - $tls = "connect"; - eval { - # ALPN (Net-SSLeay > 1.55, openssl >= 1.0.1) - if ( $alpn_available ) { - $tls_ctx = AnyEvent::TLS->new( method => "TLSv1_2", - host_name => $host_name ); - Net::SSLeay::CTX_set_alpn_protos( $tls_ctx->ctx, ['h2'] ); - } - else { - $tls_ctx = AnyEvent::TLS->new( host_name => $host_name ); - } - }; - if ($@) { - print "Some problem with SSL CTX: $@\n"; - $w->send; - return; - } - } - - my $handle; - $handle = AnyEvent::Handle->new( - fh => $fh, - tls => $tls, - tls_ctx => $tls_ctx, - autocork => 1, - on_error => sub { - $_[0]->destroy; - print "connection error\n"; - $w->send; - }, - on_eof => sub { - $handle->destroy; - $w->send; - } - ); - - # First write preface to peer - while ( my $frame = $client->next_frame ) { - $handle->push_write($frame); - } - - $handle->on_read(sub { - my $handle = shift; - - $client->feed( $handle->{rbuf} ); - $handle->{rbuf} = undef; - - while ( my $frame = $client->next_frame ) { - $handle->push_write($frame); - } - - # Terminate connection if all done - $handle->push_shutdown if $client->shutdown; - }); - }; - $w->recv; - -} - -################################################################################ -# -# Add a request to the client, will be started whenever a STREAM to -# the server is available. -# -sub add_request { - my ($scheme, $client, $host, $port); - my %args = ( - method => 'GET', - headers => [], - rc => 200, - on_done => sub { - my %args = ( @_ ); - my $ctx = $args{ctx}; - my $req = $args{request}; - my $resp = $args{response}; - my $hr = $resp->{headers}; - my %headers = @$hr; - ok t_cmp($headers{':status'}, $req->{rc}, - "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}"); - }, - @_ - ); - $client = $args{ctx}->{client}; - $scheme = $args{ctx}->{scheme}; - $host = $args{ctx}->{host}; - $port = $args{ctx}->{port}; - - $client->request( - ':scheme' => $scheme, - ':authority' => $args{authority} || $host . ':' . $port, - ':path' => $args{path}, - ':method' => $args{method}, - headers => $args{headers}, - on_done => sub { - my ($headers, $data) = @_; - $args{on_done}( - ctx => $args{ctx}, - request => \%args, - response => { headers => \@$headers, data => $data } - ); - } - ); -} - -################################################################################ -# -# Add a list of request that will be processed in order. Only when the previous -# request is done, will a new one be started. -# -sub add_sequential { - my ($scheme, $client, $host, $port); - my %args = ( @_ ); - my $ctx = $args{ctx}; - my $requests = $args{requests}; - - $client = $args{ctx}->{client}; - $scheme = $args{ctx}->{scheme}; - $host = $args{ctx}->{host}; - $port = $args{ctx}->{port}; - - my $request = shift @$requests; - - if ($request) { - my %r = ( - method => 'GET', - headers => [], - rc => 200, - on_done => sub { - my %args = ( @_ ); - my $ctx = $args{ctx}; - my $req = $args{request}; - my $resp = $args{response}; - my $hr = $resp->{headers}; - my %headers = @$hr; - ok t_cmp($headers{':status'}, $req->{rc}, - "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}"); - }, - %$request - ); - - print "test case: $r{descr}: $r{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$r{path}\n"; - $client->request( - ':scheme' => $scheme, - ':authority' => $r{authority} || $host . ':' . $port, - ':path' => $r{path}, - ':method' => $r{method}, - headers => $r{headers}, - on_done => sub { - my ($headers, $data) = @_; - $r{on_done}( - ctx => ${ctx}, - request => \%r, - response => { headers => \@$headers, data => $data } - ); - add_sequential( - ctx => $ctx, - requests => $requests - ); - } - ); - } -} - -sub cmp_content_length { - my %args = ( @_ ); - my $ctx = $args{ctx}; - my $req = $args{request}; - my $resp = $args{response}; - my $hr = $resp->{headers}; - my %headers = @$hr; - ok t_cmp($headers{':status'}, $req->{rc}, "response status"); - ok t_cmp(length $resp->{data}, $req->{content_length}, "content-length"); -} - -sub cmp_content { - my %args = ( @_ ); - my $ctx = $args{ctx}; - my $req = $args{request}; - my $resp = $args{response}; - my $hr = $resp->{headers}; - my %headers = @$hr; - ok t_cmp($headers{':status'}, $req->{rc}, "response status"); - ok t_cmp($resp->{data}, $req->{content}, "content comparision"); -} - -sub cmp_file_response { - my %args = ( @_ ); - my $ctx = $args{ctx}; - my $req = $args{request}; - my $resp = $args{response}; - my $hr = $resp->{headers}; - my %headers = @$hr; - ok t_cmp($headers{':status'}, $req->{rc}, "response status"); - open(FILE, "<$htdocs$req->{path}") or die "cannot open $req->{path}"; - undef $/; - my $content = <FILE>; - close(FILE); - ok t_is_equal($resp->{data}, $content); -} - -sub check_redir { - my %args = ( @_ ); - my $ctx = $args{ctx}; - my $req = $args{request}; - my $resp = $args{response}; - my $hr = $resp->{headers}; - my %headers = @$hr; - ok t_cmp($headers{':status'}, 302, "response status"); - ok t_cmp( - $headers{location}, - "$ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{redir_path}", - "location header" - ); -} - -################################################################################ -# -# Perform common tests to h2c + h2 hosts -# -sub do_common { - my %args = ( - scheme => 'http', - host => 'localhost', - port => 80, - @_ - ); - my $true_tls = ($args{scheme} eq 'https' and $sni_available); - - $args{client} = Protocol::HTTP2::Client->new( upgrade => 0 ); - - my $r = [ - { - descr => 'TC0001, expecting 200', - path => '/' - }, - { - descr => 'TC0002, expecting 404', - rc => 404, - path => '/not_here' - }, - { - descr => 'TC0005, cmp index.html file', - path => '/modules/h2/index.html', - on_done => \&cmp_file_response - }, - { - descr => 'TC0006, cmp image file', - path => '/modules/h2/003/003_img.jpg', - on_done => \&cmp_file_response - }, - ]; - - if (have_module 'mod_rewrite') { - push @$r, { - descr => 'TC0007, rewrite handling', - path => '/modules/h2/latest.tar.gz', - redir_path => "/modules/h2/xxx-1.0.2a.tar.gz", - on_done => \&check_redir - } - } - else { - skip "skipping test as mod_rewrite not available" foreach(1..2); - } - - if (have_cgi) { - # my $sni_host = $true_tls? 'localhost' : ''; - my $content = <<EOF; -<html><body> -<h2>Hello World!</h2> -</body></html> -EOF - - push @$r, { - descr => 'TC0008, hello.pl with ssl vars', - path => '/modules/h2/hello.pl', - content => $content, - on_done => \&cmp_content, - }; - - $content = <<EOF; -<html><body> -<p>No query was specified.</p> -</body></html> -EOF - push @$r, { - descr => 'TC0009, necho.pl without arguments', - path => '/modules/h2/necho.pl', - content => $content, - rc => 400, - on_done => \&cmp_content, - }; - push @$r, { - descr => 'TC0010, necho.pl 2x10', - path => '/modules/h2/necho.pl?count=2&text=0123456789', - content => "01234567890123456789", - on_done => \&cmp_content, - }; - push @$r, { - descr => 'TC0011, necho.pl 10x10', - path => '/modules/h2/necho.pl?count=10&text=0123456789', - content_length => 100, - on_done => \&cmp_content_length, - }; - push @$r, { - descr => 'TC0012, necho.pl 100x10', - path => '/modules/h2/necho.pl?count=100&text=0123456789', - content_length => 1000, - on_done => \&cmp_content_length, - }; - push @$r, { - descr => 'TC0013, necho.pl 1000x10', - path => '/modules/h2/necho.pl?count=1000&text=0123456789', - content_length => 10000, - on_done => \&cmp_content_length, - }; - push @$r, { - descr => 'TC0014, necho.pl 10000x10', - path => '/modules/h2/necho.pl?count=10000&text=0123456789', - content_length => 100000, - on_done => \&cmp_content_length, - }; - push @$r, { - descr => 'TC0015, necho.pl 100000x10', - path => '/modules/h2/necho.pl?count=100000&text=0123456789', - content_length => 1000000, - on_done => \&cmp_content_length, - }; - } - else { - skip "skipping test as mod_cgi not available" foreach(1..1); - } - - add_sequential( - ctx => \%args, - requests => $r - ); - connect_and_do( ctx => \%args ); -} - -################################################################################ -# -# Perform tests for virtual host setups, requires a client with SNI+ALPN -# -sub do_vhosts { - my %args = ( - scheme => 'http', - host => 'localhost', - port => 80, - @_ - ); - $args{client} = Protocol::HTTP2::Client->new( upgrade => 0 ); - - my $r = [ - { - descr => 'VHOST000, expecting 200', - path => '/' - }, - { - descr => 'VHOST001, expect 404 or 421 (using Host:)', - rc => 404, - path => '/misdirected', - header => [ 'host' => 'noh2.example.org' . $args{port} ] - }, - { - descr => 'VHOST002, expect 421 (using :authority)', - rc => 421, - path => '/misdirected', - authority => 'noh2.example.org:' . $args{port} - }, - { - descr => 'VHOST003, expect 421 ', - rc => (have_min_apache_version('2.4.18')? 404 : 421), - path => '/misdirected', - authority => 'test.example.org:' . $args{port} - }, - ]; - - add_sequential( - ctx => \%args, - requests => $r - ); - connect_and_do( ctx => \%args ); -} - -################################################################################ -# -# Bring it on -# -do_common( 'scheme' => 'http', 'host' => $host, 'port' => $port ); -if ($tls_modern) { - do_common( 'scheme' => 'https', 'host' => $shost, 'port' => $sport ); -} else { - skip "skipping test as TLS version '$tls_version' is not supported" foreach(1..$num_suite); -} -if ($sni_available) { - if ($tls_modern) { - do_vhosts( 'scheme' => 'https', 'host' => $shost, 'port' => $sport, host_name => "$shost:${sport}" ); - } else { - skip "skipping test as TLS version '$tls_version' is not supported" foreach(1..$vhost_suite); - } -} else { - skip "skipping test as SNI not available" foreach(1..$vhost_suite); -} diff --git a/debian/perl-framework/t/modules/include.t b/debian/perl-framework/t/modules/include.t index 64b2fdc..9ff2411 100644 --- a/debian/perl-framework/t/modules/include.t +++ b/debian/perl-framework/t/modules/include.t @@ -28,6 +28,7 @@ my $htdocs = Apache::Test::vars('documentroot'); my %test = ( "echo.shtml" => "echo.shtml", "set.shtml" => "set works", +"comment.shtml" => "No comment here", "include1.shtml" => "inc-two.shtml body include.shtml body", "include2.shtml" => "inc-two.shtml body include.shtml body", "include3.shtml" => "inc-two.shtml body inc-one.shtml body ". @@ -96,6 +97,10 @@ my %test = ( "virtualq.shtml?foo=bar" => "foo=bar pass inc-two.shtml body foo=bar", # PR#12655 "inc-nego.shtml" => "index.html.en", # requires mod_negotiation +"mod_request/echo.shtml"=> "echo.shtml", +"mod_request/post.shtml?foo=bar&foo2=bar2" + => "GET foo: bar foo2: bar2", +"mod_request/post.shtml"=> "POST foo: bar foo2: bar2", # will be twice, only the first one succeed ); my %ap_expr_test = ( @@ -227,15 +232,16 @@ unless ($have_apache_2) { push @todo, (scalar keys %tests) + 1; } -# in addition to %tests, there are 1 fsize and 1 flastmod test, +# in addition to %tests, there are 1 mod_request expected failure, +# 1 fsize and 1 flastmod test, # 1 GET test, 2 query string tests, 14 XBitHack tests and 14 # tests that use mod_bucketeer to construct brigades for mod_include -my $tests = (scalar keys %tests) + @patterns + 1 + 1 + 1 + 2 + 14 + 14; +my $tests = (scalar keys %tests) + 1 + @patterns + 1 + 1 + 1 + 2 + 14 + 14; plan tests => $tests, todo => \@todo, - need need_lwp, need_module 'include'; + need 'DateTime', need_lwp, need_module 'include'; foreach $doc (sort keys %tests) { # do as much from %test as we can @@ -267,6 +273,35 @@ foreach $doc (sort keys %tests) { skip "Skipping 'exec cgi' test; no cgi module.", 1; } } + elsif ($doc =~ m/mod_request.*\?/) { + # param in the url ==> use GET + if (have_cgi) { + ok t_cmp(super_chomp(GET_BODY "$dir$doc"), + $tests{$doc}, + "GET $dir$doc" + ); + } + else { + skip "Skipping 'exec cgi' test; no cgi module.", 1; + } + } + elsif ($doc =~ m/mod_request/) { + # no param in the url ==> use POST with a content + if (have_cgi) { + ok t_cmp(super_chomp(POST_BODY "$dir$doc", content => "foo=bar&foo2=bar2"), + $tests{$doc}, + "POST $dir$doc" + ); + if ($doc =~ m/mod_request.*post/) { + # KeptBodySize is 32 + my $r = POST("$dir$doc", content => "foo=bar&foo2=bar2&foo3=bar3&foo4=bar4"); + ok t_cmp($r->code, 413, "sizeof(body) > KeptBodySize"); + } + } + else { + skip "Skipping 'exec cgi' test; no cgi module.", 2; + } + } else { ok t_cmp(super_chomp(GET_BODY "$dir$doc"), $tests{$doc}, @@ -311,6 +346,10 @@ unless(eval "require POSIX") { else { # use DateTime and avoid the system locale messing things up use DateTime; + # Only for checking, whether system strftime supports %s + use POSIX; + my $strftime_gnu = (POSIX::strftime("%s", gmtime()) eq '%s' ? 0 : 1); + my $result = super_chomp(GET_BODY "${dir}file.shtml"); $result = single_space($result); @@ -325,8 +364,8 @@ else { my $expected = join ' ' => $dt->strftime("%A, %B %e, %G"), $dt->strftime("%A, %B %e, %G"), - $dt->strftime("%s"), - $dt->strftime("%s"); + $strftime_gnu ? $dt->strftime("%s") : '%s', + $strftime_gnu ? $dt->strftime("%s") : '%s'; # trim output $expected = single_space($expected); diff --git a/debian/perl-framework/t/modules/info.t b/debian/perl-framework/t/modules/info.t index cbc4d6e..21cee4e 100644 --- a/debian/perl-framework/t/modules/info.t +++ b/debian/perl-framework/t/modules/info.t @@ -31,7 +31,7 @@ foreach (split /\n/, $info) { foreach (sort keys %$mods) { ($mods->{$_} && !$config->should_skip_module($_)) or next; - if ($_ =~ /^mod_mpm_(eventopt|event|prefork|worker)\.c$/) { + if ($_ =~ /^mod_mpm_(eventopt|event|motorz|prefork|worker)\.c$/) { push(@expected,"$1.c"); } elsif ($_ eq 'mod_mpm_simple.c') { push(@expected,'simple_api.c'); diff --git a/debian/perl-framework/t/modules/ldap.t b/debian/perl-framework/t/modules/ldap.t new file mode 100644 index 0000000..d3bb8e9 --- /dev/null +++ b/debian/perl-framework/t/modules/ldap.t @@ -0,0 +1,52 @@ +use strict; +use warnings FATAL => 'all'; + +# +# To run tests for mod_authnz_ldap: +# +# a) run an LDAP server with root DN of dc=example,dc=com on localhost port 8389 +# b) populate the directory with the LDIF from scripts/httpd.ldif +# c) configure & run the test suite passing "--defines LDAP" to ./t/TEST +# + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig; + +my $defs = Apache::Test->vars('defines'); +my $ldap_defined = $defs =~ /LDAP/; + +# URL -> username, password, expected-status +my @cases = ( + ['/modules/ldap/simple/' => '', '', 401], + ['/modules/ldap/simple/' => 'alpha', 'badpass', 401], + ['/modules/ldap/simple/' => 'alpha', 'Alpha', 200], + ['/modules/ldap/simple/' => 'gamma', 'Gamma', 200], + ['/modules/ldap/group/' => 'gamma', 'Gamma', 401], + ['/modules/ldap/group/' => 'delta', 'Delta', 200], + ['/modules/ldap/refer/' => 'alpha', 'Alpha', 401], + ['/modules/ldap/refer/' => 'beta', 'Beta', 200], +); + +plan tests => scalar @cases, + need need_module('authnz_ldap'), { "LDAP testing not configured" => $ldap_defined }; + +foreach my $t (@cases) { + my $url = $t->[0]; + my $username = $t->[1]; + my $password = $t->[2]; + my $response; + my $creds; + + if ($username) { + $response = GET $url, username => $username, password => $password; + $creds = "$username/$password"; + } + else { + $response = GET $url; + $creds = "no credentials"; + } + + ok t_cmp($response->code, $t->[3], "test for $url with $creds"); +} diff --git a/debian/perl-framework/t/modules/lua.t b/debian/perl-framework/t/modules/lua.t index 9eb5b4f..9e6836d 100644 --- a/debian/perl-framework/t/modules/lua.t +++ b/debian/perl-framework/t/modules/lua.t @@ -41,6 +41,8 @@ my @ts = ( { url => "$pfx/setheaderfromparam.lua?HeaderName=foo&HeaderValue=bar", rcontent => "Header set", headers => { "foo" => "bar" } }, + { url => "$pfx/filtered/foobar.html", + rcontent => "prefix\nbucket:foobar\nsuffix\n" }, ); plan tests => 4 * scalar @ts, need 'lua'; diff --git a/debian/perl-framework/t/modules/negotiation.t b/debian/perl-framework/t/modules/negotiation.t index 0081ce0..9218aa1 100644 --- a/debian/perl-framework/t/modules/negotiation.t +++ b/debian/perl-framework/t/modules/negotiation.t @@ -7,8 +7,12 @@ use Apache::TestUtil; ## mod_negotiation test (see extra.conf.in) -my ($en, $fr, $de, $fu, $bu) = qw(en fr de fu bu); +my ($en, $fr, $de, $fu, $bu, $zh) = qw(en fr de fu bu zh-TW); + my @language = ($en, $fr, $de, $fu); +if (have_min_apache_version("2.4.38")) { + push @language, $zh; +} my @ct_tests = ( # [ Accept header, Expected response ] diff --git a/debian/perl-framework/t/modules/proxy.t b/debian/perl-framework/t/modules/proxy.t index af822cd..0a81f4f 100644 --- a/debian/perl-framework/t/modules/proxy.t +++ b/debian/perl-framework/t/modules/proxy.t @@ -7,16 +7,45 @@ use Apache::TestUtil; use Apache::TestConfig (); use Misc; -my $num_tests = 31; +my $num_tests = 46; plan tests => $num_tests, need need_module 'proxy', need_module 'setenvif'; Apache::TestRequest::module("proxy_http_reverse"); Apache::TestRequest::user_agent(requests_redirectable => 0); my $r = GET("/reverse/"); -ok t_cmp($r->code, 200, "reverse proxy to index.html"); +ok t_cmp($r->code, 200, "reverse proxy"); ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body"); +$r = GET("/reverse/index.html"); +ok t_cmp($r->code, 200, "reverse proxy to index.html"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body to index.html"); + +if (have_min_apache_version('2.4.49')) { + $r = GET("/reverse-match/"); + ok t_cmp($r->code, 200, "reverse proxy match"); + ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body match"); + + $r = GET("/reverse-match/index.html"); + ok t_cmp($r->code, 200, "reverse proxy match to index.html"); + ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body match to index.html"); +} +else { + skip "skipping reverse-match test with httpd <2.5.1" foreach (1..4); +} + +$r = GET("/reverse-slash"); +ok t_cmp($r->code, 200, "reverse proxy match no slash"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body no slash"); + +$r = GET("/reverse-slash/"); +ok t_cmp($r->code, 200, "reverse proxy match w/ slash"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body w/ slash"); + +$r = GET("/reverse-slash/index.html"); +ok t_cmp($r->code, 200, "reverse proxy match w/ slash to index.html"); +ok t_cmp($r->content, qr/^welcome to /, "reverse proxied body w/ slash to index.html"); + if (have_min_apache_version('2.4.0')) { $r = GET("/reverse/locproxy/"); ok t_cmp($r->code, 200, "reverse Location-proxy to index.html"); @@ -188,3 +217,17 @@ else { skip "skipping UDS tests with httpd < 2.4.7" foreach (1..2); } +if (have_min_apache_version('2.4.49')) { + + $r = GET("/notexisting/../mapping/mapping.html"); + ok t_cmp($r->code, 200, "proxy mapping=servlet map it to /servlet/mapping.html"); + + $r = GET("/notexisting/..;/mapping/mapping.html"); + ok t_cmp($r->code, 200, "proxy mapping=servlet map it to /servlet/mapping.html"); + + $r = GET("/mapping/mapping.html"); + ok t_cmp($r->code, 200, "proxy to /servlet/mapping.html"); +} +else { + skip "skipping tests with mapping=servlet" foreach (1..3); +} diff --git a/debian/perl-framework/t/modules/proxy_balancer.t b/debian/perl-framework/t/modules/proxy_balancer.t index a16521b..ee31507 100644 --- a/debian/perl-framework/t/modules/proxy_balancer.t +++ b/debian/perl-framework/t/modules/proxy_balancer.t @@ -6,22 +6,120 @@ use Apache::TestRequest; use Apache::TestUtil; use Apache::TestConfig (); -plan tests => 3, need 'proxy_balancer', 'proxy_http'; +my @echos = ('A'x8, 'A'x64, 'A'x2048, 'A'x4096); + +my $skipbodyfailover = !need_min_apache_version("2.4.42"); +my $referertest = 0; + +if (have_min_apache_version("2.4.41")) { + $referertest = 2; +} + +plan tests => 6+(2*scalar @echos)+$referertest, need 'proxy_balancer', 'proxy_http'; Apache::TestRequest::module("proxy_http_balancer"); Apache::TestRequest::user_agent(requests_redirectable => 0); +# Extract the nonce from response to the URL +sub GetNonce { + my $url = shift; + my $balancer = shift; + my $r; + $r = GET($url); + my $NONCE; + foreach my $query ( split( /\?b=/, $r->content ) ){ + if ($query =~ m/$balancer/) { + foreach my $var ( split( /&/, $query ) ){ + if ($var =~ m/nonce=/) { + foreach my $nonce ( split( /nonce=/, $var ) ){ + my $ind = index ($nonce, "\""); + $nonce = substr($nonce, 0, ${ind}); + if ( $nonce =~ m/^[0-9a-fA-F-]+$/ ) { + $NONCE = $nonce; + last; + } + } + last; + } + } + last; + } + } + return $NONCE; +} + +my $r; + +if (have_module('lbmethod_byrequests')) { + $r = GET("/baltest1/index.html"); + ok t_cmp($r->code, 200, "Balancer did not die"); +} else { + skip "skipping tests without mod_lbmethod_byrequests" foreach (1..1); +} + +if (have_module('lbmethod_bytraffic')) { + $r = GET("/baltest2/index.html"); + ok t_cmp($r->code, 200, "Balancer did not die"); +} else { + skip "skipping tests without mod_lbmethod_bytraffic" foreach (1..1); +} + +if (have_module('lbmethod_bybusyness')) { + $r = GET("/baltest3/index.html"); + ok t_cmp($r->code, 200, "Balancer did not die"); +} else { + skip "skipping tests without mod_lbmethod_bybusyness" foreach (1..1); +} + +if (have_module('lbmethod_heartbeat')) { + #$r = GET("/baltest4/index.html"); + #ok t_cmp($r->code, 200, "Balancer did not die"); +} else { + #skip "skipping tests without mod_lbmethod_heartbeat" foreach (1..1); +} + -my $r = GET("/baltest1/index.html"); -ok t_cmp($r->code, 200, "Balancer did not die"); -$r = GET("/baltest2/index.html"); -ok t_cmp($r->code, 200, "Balancer did not die"); +# PR63891 +foreach my $t (@echos) { + $r = POST "/baltest_echo_post", content => $t; + skip $skipbodyfailover, t_cmp($r->code, 200, "failed over"); + skip $skipbodyfailover, t_cmp($r->content, $t, "response body echoed"); +} + +# test dynamic part +$r = GET("/balancer-manager"); +ok t_cmp($r->code, 200, "Can't find balancer-manager"); + +# get the nonce and add a worker +my $result = GetNonce("/balancer-manager", "dynproxy"); -$r = GET("/baltest3/index.html"); -ok t_cmp($r->code, 200, "Balancer did not die"); +my $query = "b_lbm=byrequests&b_tmo=0&b_max=0&b_sforce=0&b_ss=&b_nwrkr=ajp%3A%2F%2F%5B0%3A0%3A0%3A0%3A0%3A0%3A0%3A1%5D%3A8080&b_wyes=1&b=dynproxy&nonce=" . $result; +my @proxy_balancer_headers; +my $vars = Apache::Test::vars(); +push @proxy_balancer_headers, "Referer" => "http://" . $vars->{servername} . ":" . $vars->{port} . "/balancer-manager"; + +# First try without the referer it should fail. +if (have_min_apache_version("2.4.41")) { + $r = POST("/balancer-manager", content => $query); + ok t_cmp($r->code, 200, "request failed"); + ok !t_cmp($r->content, qr/ajp/, "AJP worker created"); +} -if (have_min_apache_version("2.3.0")) { - # $r = GET("/baltest4/index.html"); - # ok t_cmp($r->code, 200, "Balancer did not die"); +# Try with the referer and http (byrequests) +if (have_min_apache_version("2.4.49") && have_module('lbmethod_byrequests')) { + $r = GET("/dynproxy"); + ok t_cmp($r->code, 503, "request should fail for /dynproxy"); + # create it + $query = 'b_lbm=byrequests&b_tmo=0&b_max=0&b_sforce=0&b_ss=&b_nwrkr=http%3A%2F%2F' . $vars->{servername} . '%3A' . $vars->{port} . '&b_wyes=1&b=dynproxy&nonce=' . $result; + $r = POST("/balancer-manager", content => $query, @proxy_balancer_headers); + # enable it. + $query = 'w=http%3A%2F%2F' . $vars->{servername} . '%3A' . $vars->{port} . '&b=dynproxy&w_status_D=0&nonce=' . $result; + $r = POST("/balancer-manager", content => $query, @proxy_balancer_headers); + # make a query + $r = GET("/dynproxy"); + ok t_cmp($r->code, 200, "request failed to /dynproxy"); +} else { + skip "skipping tests without lbmethod_byrequests"; + skip "skipping tests without lbmethod_byrequests"; } diff --git a/debian/perl-framework/t/modules/proxy_fcgi.t b/debian/perl-framework/t/modules/proxy_fcgi.t index 1577497..2f62580 100644 --- a/debian/perl-framework/t/modules/proxy_fcgi.t +++ b/debian/perl-framework/t/modules/proxy_fcgi.t @@ -129,8 +129,16 @@ sub run_fcgi_envvar_request $envs{$components[0]} = $components[1]; } - # Rejoin the child FCGI process. - waitpid($child, 0) unless ($fcgi_port <= 0) ; + if ($fcgi_port > 0) { + if ($r->code eq '500') { + # Unknown failure, probably the request didn't hit the FCGI child + # process, so it will hang waiting for our request + kill 'TERM', $child; + } else { + # Rejoin the child FCGI process. + waitpid($child, 0); + } + } return \%envs; } diff --git a/debian/perl-framework/t/modules/proxy_websockets.t b/debian/perl-framework/t/modules/proxy_websockets.t new file mode 100644 index 0000000..f2d6558 --- /dev/null +++ b/debian/perl-framework/t/modules/proxy_websockets.t @@ -0,0 +1,81 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +# not reliable, hangs for some people: +# my @test_cases = ( "ping0", "ping1" x 10, "ping2" x 100, "ping3" x 1024, "ping4" x 4096, "sendquit"); +my @test_cases = ( "ping0", "ping1" x 10, "ping2" x 100, "ping3" x 1024, "sendquit"); +my $total_tests = 2; + +plan tests => $total_tests, need 'AnyEvent::WebSocket::Client', + need_module('proxy_http', 'lua'), need_min_apache_version('2.4.47'); + +require AnyEvent; +require AnyEvent::WebSocket::Client; + +my $config = Apache::Test::config(); +my $hostport = Apache::TestRequest::hostport(); + +my $client = AnyEvent::WebSocket::Client->new(timeout => 5); + +my $quit_program = AnyEvent->condvar; + +my $responses = 0; +my $surprised = 0; + +$client->connect("ws://$hostport/proxy/wsoc")->cb(sub { + our $connection = eval { shift->recv }; + t_debug("wsoc connected"); + if($@) { + # handle error... + warn $@; + $quit_program->send(); + return; + } + + + # AnyEvent::WebSocket::Connection does not pass the PONG message down to the callback + # my $actualpingmsg = AnyEvent::WebSocket::Message->new(opcode => 0x09, body => "xxx"); + # $connection->send($actualpingmsg); + + foreach (@test_cases){ + $connection->send($_); + } + + $connection->on(finish => sub { + t_debug("finish"); + }); + + # recieve message from the websocket... + $connection->on(each_message => sub { + # $connection is the same connection object + # $message isa AnyEvent::WebSocket::Message + my($connection, $message) = @_; + $responses++; + t_debug("wsoc msg received: " . substr($message->body, 0, 5). " opcode " . $message->opcode); + if ("sendquit" eq $message->body) { + $connection->send('quit'); + t_debug("closing"); + $connection->close; # doesn't seem to close TCP. + $quit_program->send(); + } + elsif ($message->body =~ /^ping(\d)/) { + my $offset = $1; + if ($message->body ne $test_cases[$offset]) { + $surprised++; + } + } + else { + $surprised++; + } + }); + +}); + +$quit_program->recv; +ok t_cmp($surprised, 0); +ok t_cmp($responses, scalar(@test_cases) ); diff --git a/debian/perl-framework/t/modules/proxy_websockets_ssl.t b/debian/perl-framework/t/modules/proxy_websockets_ssl.t new file mode 100644 index 0000000..793ff48 --- /dev/null +++ b/debian/perl-framework/t/modules/proxy_websockets_ssl.t @@ -0,0 +1,86 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestConfig (); + +# my @test_cases = ( "ping0", "ping1" x 10, "ping2" x 100, "ping3" x 1024, "ping4" x 4000, "sendquit"); +my @test_cases = ( "ping0", "ping1" x 10, "ping2" x 100, "ping3" x 1024, "sendquit"); +my $total_tests = 2; + +plan tests => $total_tests, need 'AnyEvent::WebSocket::Client', + need_module('ssl', 'proxy_http', 'lua'), need_min_apache_version('2.4.47'); + +require AnyEvent; +require AnyEvent::WebSocket::Client; + +my $config = Apache::Test::config(); +#my $hostport = $config->{vhosts}->{proxy_https_https}->{hostport}; +my $hostport = $config->{vhosts}->{$config->{vars}->{ssl_module_name}}->{hostport}; +my $client = AnyEvent::WebSocket::Client->new(timeout => 5, ssl_ca_file => $config->{vars}->{sslca} . "/" . $config->{vars}->{sslcaorg} . "/certs/ca.crt"); + +my $quit_program = AnyEvent->condvar; + +my $responses = 0; +my $surprised = 0; + +t_debug("wss://$hostport/modules/lua/websockets.lua"); + +# $client->connect("wss://$hostport/proxy/wsoc")->cb(sub { +$client->connect("wss://$hostport/modules/lua/websockets.lua")->cb(sub { + our $connection = eval { shift->recv }; + t_debug("wsoc connected"); + if($@) { + # handle error... + warn $@; + $quit_program->send(); + return; + } + + + # AnyEvent::WebSocket::Connection does not pass the PONG message down to the callback + # my $actualpingmsg = AnyEvent::WebSocket::Message->new(opcode => 0x09, body => "xxx"); + # $connection->send($actualpingmsg); + + foreach (@test_cases){ + $connection->send($_); + } + + $connection->on(finish => sub { + t_debug("finish"); + $quit_program->send(); + }); + + # recieve message from the websocket... + $connection->on(each_message => sub { + # $connection is the same connection object + # $message isa AnyEvent::WebSocket::Message + my($connection, $message) = @_; + $responses++; + t_debug("wsoc msg received: " . substr($message->body, 0, 5). " opcode " . $message->opcode); + if ("sendquit" eq $message->body) { + $connection->send('quit'); + t_debug("closing"); + $connection->close; # doesn't seem to close TCP. + $quit_program->send(); + } + elsif ($message->body =~ /^ping(\d)/) { + my $offset = $1; + if ($message->body ne $test_cases[$offset]) { + t_debug("wrong data"); + $surprised++; + } + } + else { + $surprised++; + } + }); + +}); + +$quit_program->recv; +ok t_cmp($surprised, 0); +# We don't expect the 20k over SSL to work, and we won't read the "sendquit" echoed back either. +ok t_cmp($responses, scalar(@test_cases)); diff --git a/debian/perl-framework/t/modules/rewrite.t b/debian/perl-framework/t/modules/rewrite.t index f566535..4673431 100644 --- a/debian/perl-framework/t/modules/rewrite.t +++ b/debian/perl-framework/t/modules/rewrite.t @@ -15,6 +15,49 @@ my @url = qw(forbidden gone perm temp); my @todo; my $r; +my @redirects_all = ( + ["/modules/rewrite/escaping/qsd-like/foo", "/foo\$", have_min_apache_version('2.4.57')], # PR66547 + ["/modules/rewrite/escaping/qsd-like-plus-qsa/foo?preserve-me", "/foo\\?preserve-me\$", have_min_apache_version('2.5.1')], # PR66672 + ["/modules/rewrite/escaping/qsd-like-plus-qsa-qsl/foo/%3fbar/?preserve-me", "/foo/%3fbar/\\?preserve-me\$", have_min_apache_version('2.5.1')], # PR66672 + ); + +my @escapes = ( + # rewrite to local/PT is not escaped + [ "/modules/rewrite/escaping/local/foo%20bar" => 403], + # rewrite to redir escape opted out + [ "/modules/rewrite/escaping/redir_ne/foo%20bar" => 403], + # rewrite never escapes proxy targets, even though [NE] is kind or repurposed. + [ "/modules/rewrite/escaping/proxy/foo%20bar" => 403], + [ "/modules/rewrite/escaping/proxy_ne/foo%20bar" => 403], + + [ "/modules/rewrite/escaping/fixups/local/foo%20bar" => 403], + [ "/modules/rewrite/escaping/fixups/redir_ne/foo%20bar" => 403], + [ "/modules/rewrite/escaping/fixups/proxy/foo%20bar" => 403], + [ "/modules/rewrite/escaping/fixups/proxy_ne/foo%20bar" => 403], +); +if (have_min_apache_version('2.4.57')) { + push(@escapes, ( + # rewrite to redir escaped by default + [ "/modules/rewrite/escaping/redir/foo%20bar" => 302], + [ "/modules/rewrite/escaping/fixups/redir/foo%20bar" => 302], + )); +} + +my @bflags = ( + # t/conf/extra.conf.in + [ "/modules/rewrite/escaping/local_b/foo/bar/%20baz%0d" => "foo%2fbar%2f+baz%0d"], # this is why [B] sucks + [ "/modules/rewrite/escaping/local_b_justslash/foo/bar/%20baz/" => "foo%2fbar%2f baz%2f"], # test basic B=/ +); +if (have_min_apache_version('2.4.57')) { + # [BCTLS] / [BNE] + push(@bflags, ( + [ "/modules/rewrite/escaping/local_bctls/foo/bar/%20baz/%0d" => "foo/bar/+baz/%0d"], # spaces and ctls only + [ "/modules/rewrite/escaping/local_bctls_nospace/foo/bar/%20baz/%0d" => "foo/bar/ baz/%0d"], # ctls but keep space + [ "/modules/rewrite/escaping/local_bctls_andslash/foo/bar/%20baz/%0d" => "foo%2fbar%2f+baz%2f%0d"], # not realistic, but opt in to slashes + [ "/modules/rewrite/escaping/local_b_noslash/foo/bar/%20baz/%0d" => "foo/bar/+baz/%0d"], # negate something from [B] + )); +} + if (!have_min_apache_version('2.4.19')) { # PR 50447, server context push @todo, 26 @@ -26,8 +69,11 @@ if (!have_min_apache_version('2.4')) { # Specific tests for PR 58231 my $vary_header_tests = (have_min_apache_version("2.4.30") ? 9 : 0) + (have_min_apache_version("2.4.29") ? 4 : 0); +my $cookie_tests = have_min_apache_version("2.4.47") ? 6 : 0; +my @redirects = map {$_->[2] ? $_ : ()} @redirects_all; -plan tests => @map * @num + 16 + $vary_header_tests, todo => \@todo, need_module 'rewrite'; +plan tests => @map * @num + 16 + $vary_header_tests + $cookie_tests + scalar(@escapes) + scalar(@redirects) + scalar(@bflags), + todo => \@todo, need_module 'rewrite'; foreach (@map) { foreach my $n (@num) { @@ -128,6 +174,7 @@ if (have_min_apache_version('2.4')) { if (have_min_apache_version("2.4.29")) { # PR 58231: Vary:Host header (was) mistakenly added to the response + # XXX: If LWP uses http2, this can result in "Host: localhost, test1" $r = GET("/modules/rewrite/vary1.html", "Host" => "test1"); ok t_cmp($r->content, qr/VARY2/, "Correct internal redirect happened, OK"); ok t_cmp($r->header("Vary"), qr/(?!.*Host.*)/, "Vary:Host header not added, OK"); @@ -168,3 +215,46 @@ if (have_min_apache_version("2.4.30")) { ok t_cmp($r->content, qr/VARY4/, "Correct internal redirect happened, OK"); ok t_cmp($r->header("Vary"), qr/(?!.*Host.*)/, "Vary:Host header not added, OK"); } + +if (have_min_apache_version("2.4.47")) { + $r = GET("/modules/rewrite/cookie/"); + ok t_cmp($r->header("Set-Cookie"), qr/(?!.*SameSite=.*)/, "samesite not present with no arg"); + $r = GET("/modules/rewrite/cookie/0"); + ok t_cmp($r->header("Set-Cookie"), qr/(?!.*SameSite=.*)/, "samesite not present with 0"); + $r = GET("/modules/rewrite/cookie/false"); + ok t_cmp($r->header("Set-Cookie"), qr/(?!.*SameSite=.*)/, "samesite not present with false"); + $r = GET("/modules/rewrite/cookie/none"); + ok t_cmp($r->header("Set-Cookie"), qr/SameSite=none/, "samesite=none"); + $r = GET("/modules/rewrite/cookie/lax"); + ok t_cmp($r->header("Set-Cookie"), qr/SameSite=lax/, "samesite=lax"); + $r = GET("/modules/rewrite/cookie/foo"); + ok t_cmp($r->header("Set-Cookie"), qr/SameSite=foo/, "samesite=foo"); +} + + +foreach my $t (@escapes) { + my $url= $t->[0]; + my $expect = $t->[1]; + t_debug "Check $url for $expect\n"; + $r = GET($url, redirect_ok => 0); + ok t_cmp $r->code, $expect; +} +foreach my $t (@bflags) { + my $url= $t->[0]; + my $expect= $t->[1]; + t_debug "Check $url for $expect\n"; + $r = GET($url, redirect_ok => 0); + t_debug("rewritten query '" . $r->header("rewritten-query") . "'"); + ok t_cmp $r->header("rewritten-query"), $expect; +} + +foreach my $t (@redirects) { + my $url= $t->[0]; + my $expect= $t->[1]; + t_debug "Check $url for redir $expect\n"; + $r = GET($url, redirect_ok => 0); + my $loc = $r->header("location"); + t_debug " redirect is $loc"; + ok $loc =~ /$expect/; +} + diff --git a/debian/perl-framework/t/modules/sed.t b/debian/perl-framework/t/modules/sed.t new file mode 100644 index 0000000..6ab1ee1 --- /dev/null +++ b/debian/perl-framework/t/modules/sed.t @@ -0,0 +1,48 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my @ts = ( + # see t/conf/extra.conf.in + { url => "/apache/sed/out-foo/foobar.html", content => 'barbar', msg => "sed output filter", code => '200' }, + # error after status sent + { url => "/apache/sed-echo/out-foo-grow/foobar.html", content => "", msg => "sed output filter too large", code => '200', body=>"foo" x (8192*1024), resplen=>0}, + { url => "/apache/sed-echo/input", content => 'barbar', msg => "sed input filter", code => '200', body=>"foobar" }, + { url => "/apache/sed-echo/input", content => undef, msg => "sed input filter", code => '200', body=>"foo" x (1024)}, + # fixme: returns 400 default error doc for some people instead + # { url => "/apache/sed-echo/input", content => '!!!ERROR!!!', msg => "sed input filter", code => '200', skippable=>true body=>"foo" x (1024*4096)} +); + +my $tests = 2*scalar @ts; + +plan tests => $tests, need 'LWP::Protocol::AnyEvent::http', need_module('sed'); + +# Hack to allow streaming of data in/out of mod_echo +require LWP::Protocol::AnyEvent::http; + +for my $t (@ts) { + my $req; + if (defined($t->{'body'})) { + t_debug "posting body of size ". length($t->{'body'}); + $req = POST $t->{'url'}, content => $t->{'body'}; + t_debug "... posted body of size ". length($t->{'body'}); + } + else { + $req = GET $t->{'url'}; + } + t_debug "Content Length " . length $req->content; + ok t_cmp($req->code, $t->{'code'}, "status code for " . $t->{'url'}); + if (defined($t->{content})) { + my $content = $req->content; + chomp($content); + ok t_cmp($content, $t->{content}, $t->{msg}); + } + else { + ok "no body check"; + } +} + + diff --git a/debian/perl-framework/t/modules/session.t b/debian/perl-framework/t/modules/session.t index 91428fe..617239c 100644 --- a/debian/perl-framework/t/modules/session.t +++ b/debian/perl-framework/t/modules/session.t @@ -24,7 +24,7 @@ my @todo = ( ); # Until the fix for PR 57300 is backported, sessions are always saved. -if (!have_min_apache_version('2.5')) { +if (!have_min_apache_version('2.4.41')) { my @todo_backport = ( 8, 18, 38, 43, 48, 58, 63, 133 ); push(@todo, @todo_backport); } @@ -172,8 +172,8 @@ check_get 'Keep non-expired session', check_post 'Session writable after expired', '/on/expire?expiry=1', $create_session, $session, 1, 1; -# SessionExpiryUpdateInterval directive - new in 2.5 -if (have_module('version') && have_min_apache_version('2.5')) { +# SessionExpiryUpdateInterval directive - new in 2.4.41 +if (have_module('version') && have_min_apache_version('2.4.41')) { my $max_expiry = expiry_from_seconds(time() + 100); my $threshold_expiry = expiry_from_seconds(time() + 40); diff --git a/debian/perl-framework/t/modules/setenvif.t b/debian/perl-framework/t/modules/setenvif.t index 82c4bf4..cb561c2 100644 --- a/debian/perl-framework/t/modules/setenvif.t +++ b/debian/perl-framework/t/modules/setenvif.t @@ -167,10 +167,16 @@ write_htaccess("SetEnvIfExpr \"%{REQUEST_URI} =~ /\.\(sh\)tmlXXX\$/\" VAR_ONE=\$ $body = GET_BODY $page; ok t_cmp($body, "1:(none)\n2:(none)\n3:(none)\n"); -## test SetEnvIfExpr with replacement when regex is REQUIRED to NOT match ## -write_htaccess("SetEnvIfExpr \"%{REQUEST_URI} !~ /\.\(sh\)tmlXXX\$/\" VAR_ONE=\$0 VAR_TWO=\$1"); -$body = GET_BODY $page; -ok t_cmp($body, "1:\$0\n2:\$1\n3:(none)\n"); +if (need_min_apache_version("2.4.38")) { + ## test SetEnvIfExpr with replacement when regex is REQUIRED to NOT match ## + write_htaccess("SetEnvIfExpr \"%{REQUEST_URI} !~ /\.\(sh\)tmlXXX\$/\" VAR_ONE=\$0 VAR_TWO=\$1"); + $body = GET_BODY $page; + ok t_cmp($body, "1:\$0\n2:\$1\n3:(none)\n"); +} +else { + # Skip for versions without r1786235 backported + skip "skipping inverted match test with version <2.4.38" +} ## i think this should work, but it doesnt. ## leaving it commented now pending investigation. diff --git a/debian/perl-framework/t/modules/speling.t b/debian/perl-framework/t/modules/speling.t index 25eb54e..85af159 100644 --- a/debian/perl-framework/t/modules/speling.t +++ b/debian/perl-framework/t/modules/speling.t @@ -2,8 +2,8 @@ use strict; use warnings FATAL => 'all'; use Apache::Test; -use Apache::TestUtil; use Apache::TestRequest; +use Apache::TestUtil; my @testcasespaths = ( ['/modules/speling/nocase/'], @@ -17,7 +17,6 @@ my @testcases = ( ['goood.html', "insertion", 301, 404], ['godo.html', "transposition", 301, 404], ['go_d.html', "wrong character", 301, 404], - ['GOOD.html', "case", 301, 301], ['good.wrong_ext', "wrong extension", 300, 300], ['GOOD.wrong_ext', "NC wrong extension", 300, 300], @@ -26,9 +25,15 @@ my @testcases = ( ['dogo.html', "double transposition", 404, 404], ['XooX.html', "double wrong character", 404, 404], - ['several0.html', "multiple choise", 300, 404], + ['several0.html', "multiple choice", 300, 404], ); +# macOS HFS is case-insensitive but case-preserving so the below tests +# would cause misleading failures +if ($^O ne "darwin") { + push (@testcases, ['GOOD.html', "case", 301, 301]); +} + plan tests => scalar @testcasespaths * scalar @testcases * 2, need 'mod_speling'; my $r; @@ -40,6 +45,7 @@ local $Apache::TestRequest::RedirectOK = 0; foreach my $p (@testcasespaths) { foreach my $t (@testcases) { ## + #local $Apache::TestRequest::RedirectOK = 0; $r = GET($p->[0] . $t->[0]); # Checking for return code diff --git a/debian/perl-framework/t/modules/substitute.t b/debian/perl-framework/t/modules/substitute.t index cc8c153..0f111c0 100644 --- a/debian/perl-framework/t/modules/substitute.t +++ b/debian/perl-framework/t/modules/substitute.t @@ -15,6 +15,8 @@ my $B = chr(0x02); my $F = chr(0x06); my $P = chr(0x10); +my @simple_cases = (); + my @test_cases = ( [ "f${B}o${P}ofoo" => 's/foo/bar/' ], [ "f${B}o${P}ofoo" => 's/fo/fa/', 's/fao/bar/' ], @@ -40,7 +42,10 @@ if (have_min_apache_version("2.3.5")) { [ "foobar" => 's/(oo)b/\d$1/' ]; } -plan tests => scalar @test_cases, +if (have_min_apache_version("2.4.42")) { + push @simple_cases, [ "foo\nbar" => 's/foo.*/XXX$0XXX', "XXXfooXXX\nbar" ], +} +plan tests => scalar @test_cases + scalar @simple_cases, need need_lwp, need_module('mod_substitute'), need_module('mod_bucketeer'); @@ -84,6 +89,18 @@ foreach my $t (@test_cases) { ok($ok); } +foreach my $t (@simple_cases) { + my ($content, $rule, $expect) = @{$t}; + write_testfile($content); + write_htaccess($rule); + my $response = GET('/modules/substitute/test.txt'); + my $rc = $response->code; + my $got = $response->content; + my $ok = ($rc == 200) && ($got eq $expect); + print "got $rc '$got'", ($ok ? ": OK\n" : ", expected '$expect'\n"); + + ok($ok); +} exit 0; ### sub routines diff --git a/debian/perl-framework/t/modules/usertrack.t b/debian/perl-framework/t/modules/usertrack.t index 449d5b5..d9f62da 100644 --- a/debian/perl-framework/t/modules/usertrack.t +++ b/debian/perl-framework/t/modules/usertrack.t @@ -15,7 +15,7 @@ my @testcases = ( my $iters = 100; my %cookiex = (); -plan tests => (scalar (@testcases) * 2 + 2) * $iters + 1, need 'mod_usertrack'; +plan tests => (scalar (@testcases) * 2 + 2) * $iters + 1 + 3, need 'mod_usertrack'; foreach (1..$iters) { my $nb_req = 1; @@ -60,3 +60,15 @@ foreach (1..$iters) { # Check the overall number of cookies generated ok ((scalar (keys %cookiex)) == ($iters * 2)); + +# Check that opt-in flags aren't set +my $r = GET("/modules/usertrack/foo.html"); +ok t_cmp($r->code, 200, "Checking return code is '200'"); +# Checking for content +my $setcookie = $r->header('Set-Cookie'); +t_debug("$setcookie"); +ok defined $setcookie; +$setcookie =~ m/(Secure|HTTPonly|SameSite)/i; +ok t_cmp($1, undef); + + diff --git a/debian/perl-framework/t/php-fpm/log/.empty b/debian/perl-framework/t/php-fpm/log/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/log/.empty diff --git a/debian/perl-framework/t/php-fpm/pools/www/.empty b/debian/perl-framework/t/php-fpm/pools/www/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/pools/www/.empty diff --git a/debian/perl-framework/t/php-fpm/run/.empty b/debian/perl-framework/t/php-fpm/run/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/run/.empty diff --git a/debian/perl-framework/t/php-fpm/var/log/.empty b/debian/perl-framework/t/php-fpm/var/log/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/perl-framework/t/php-fpm/var/log/.empty diff --git a/debian/perl-framework/t/security/CVE-2009-3555.t b/debian/perl-framework/t/security/CVE-2009-3555.t index 636fee5..bd0c413 100644 --- a/debian/perl-framework/t/security/CVE-2009-3555.t +++ b/debian/perl-framework/t/security/CVE-2009-3555.t @@ -18,6 +18,12 @@ Apache::TestRequest::set_client_cert("client_ok"); Apache::TestRequest::module('mod_ssl'); my $sock = Apache::TestRequest::vhost_socket('mod_ssl'); + +if ($sock && $sock->connected && $sock->get_sslversion() eq "TLSv1_3") { + skip "Skipping test for TLSv1.3" foreach(1..4); + exit; +} + ok $sock && $sock->connected; diff --git a/debian/perl-framework/t/ssl/ocsp.t b/debian/perl-framework/t/ssl/ocsp.t index 9e0d776..8ec8505 100644 --- a/debian/perl-framework/t/ssl/ocsp.t +++ b/debian/perl-framework/t/ssl/ocsp.t @@ -30,24 +30,35 @@ my $r; sok { $r = GET $url, cert => undef; - my $message = $r->message() || ''; + my $message = $r->content() || ''; my $warning = $r->header('Client-Warning') || ''; + print "warning: $warning\n"; + print "message: $message"; + print "response:\n"; print $r->as_string; $r->code == 500 && $warning =~ 'Internal response' && - $message =~ /alert handshake failure|read failed/; + $message =~ /alert handshake failure|read failed|closed connection without sending any data/; }; sok { $r = GET $url, cert => 'client_ok'; + my $warning = $r->header('Client-Warning') || ''; + my $message = $r->content() || ''; + print "warning: $warning\n"; + print "message: $message"; + print "response:\n"; print $r->as_string; $r->code == 200; }; sok { $r = GET $url, cert => 'client_revoked'; - my $message = $r->message() || ''; + my $message = $r->content() || ''; my $warning = $r->header('Client-Warning') || ''; + print "warning: $warning\n"; + print "message: $message"; + print "response:\n"; print $r->as_string; $r->code == 500 && $warning =~ 'Internal response' && - $message =~ /alert certificate revoked|read failed/; + $message =~ /alert certificate revoked|read failed|closed connection without sending any data/; }; diff --git a/debian/perl-framework/t/ssl/pha.t b/debian/perl-framework/t/ssl/pha.t new file mode 100644 index 0000000..2e2a763 --- /dev/null +++ b/debian/perl-framework/t/ssl/pha.t @@ -0,0 +1,47 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use IO::Socket::SSL; + +# This is the equivalent of pr12355.t for TLSv1.3. + +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); +Apache::TestRequest::scheme('https'); +Apache::TestRequest::user_agent_keepalive(1); + +my $r = GET "/"; + +if (!$r->is_success) { + print "1..0 # skip: TLSv1.3 not supported"; + exit 0; +} + +if (!defined &IO::Socket::SSL::can_pha || !IO::Socket::SSL::can_pha()) { + print "1..0 # skip: PHA not supported by IO::Socket::SSL < 2.061"; + exit 0; +} + +plan tests => 4, need_min_apache_version("2.4.47"); + +$r = GET("/verify/", cert => undef); +ok t_cmp($r->code, 403, "access must be denied without client certificate"); + +# SSLRenegBufferSize 10 for this location which should mean a 413 +# error. +$r = POST("/require/small/perl_echo.pl", content => 'y'x101, + cert => 'client_ok'); +ok t_cmp($r->code, 413, "PHA reneg body buffer size restriction works"); + +# Reset to use a new connection. +Apache::TestRequest::user_agent(reset => 1); +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); +Apache::TestRequest::scheme('https'); + +$r = POST("/verify/modules/cgi/perl_echo.pl", content => 'x'x10000, + cert => 'client_ok'); + +ok t_cmp($r->code, 200, "PHA works with POST body"); +ok t_cmp($r->content, $r->request->content, "request body matches response"); diff --git a/debian/perl-framework/t/ssl/pr12355.t b/debian/perl-framework/t/ssl/pr12355.t index 51be00f..8444b3f 100644 --- a/debian/perl-framework/t/ssl/pr12355.t +++ b/debian/perl-framework/t/ssl/pr12355.t @@ -7,11 +7,26 @@ use Apache::TestUtil; plan tests => 10, need 'ssl', need_min_apache_version('2.0'); -Apache::TestRequest::user_agent( ssl_opts => { SSL_cipher_list => 'ALL'}); -Apache::TestRequest::user_agent_keepalive(1); +my $r; + +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); Apache::TestRequest::scheme('https'); -my $r; +$r = GET "/"; +my $tls13_works = $r->is_success; + +# Forget the above user agent settings, start fresh +Apache::TestRequest::user_agent(reset => 1); + +# If TLS 1.3 worked, downgrade to TLS 1.2, otherwise use what works. +if ($tls13_works) { + t_debug "Downgrading to TLSv12"; + Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL', SSL_version => 'TLSv12'}); +} else { + Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL'}); +} +Apache::TestRequest::user_agent_keepalive(1); +Apache::TestRequest::scheme('https'); # Send a series of POST requests with varying size request bodies. # Alternate between the location which requires a AES128-SHA ciphersuite diff --git a/debian/perl-framework/t/ssl/pr43738.t b/debian/perl-framework/t/ssl/pr43738.t index 0814a39..6bf9ccf 100644 --- a/debian/perl-framework/t/ssl/pr43738.t +++ b/debian/perl-framework/t/ssl/pr43738.t @@ -9,11 +9,26 @@ plan tests => 4, need 'ssl', need_module('actions'), need_min_apache_version('2.2.7'); -Apache::TestRequest::user_agent( ssl_opts => { SSL_cipher_list => 'ALL'}); -Apache::TestRequest::user_agent_keepalive(1); +my $r; + +Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'}); Apache::TestRequest::scheme('https'); -my $r; +$r = GET "/"; +my $tls13_works = $r->is_success; + +# Forget the above user agent settings, start fresh +Apache::TestRequest::user_agent(reset => 1); + +# If TLS 1.3 worked, downgrade to TLS 1.2, otherwise use what works. +if ($tls13_works) { + t_debug "Downgrading to TLSv12"; + Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL', SSL_version => 'TLSv12'}); +} else { + Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL'}); +} +Apache::TestRequest::user_agent_keepalive(1); +Apache::TestRequest::scheme('https'); # Variation of the PR 12355 test which breaks per PR 43738. diff --git a/debian/perl-framework/t/ssl/proxy.t b/debian/perl-framework/t/ssl/proxy.t index bbeddb6..bec84b4 100644 --- a/debian/perl-framework/t/ssl/proxy.t +++ b/debian/perl-framework/t/ssl/proxy.t @@ -7,14 +7,18 @@ use Apache::TestUtil; use Apache::TestCommon (); my %frontend = ( - proxy_http_https => 'http', - proxy_https_https => 'https', - proxy_https_http => 'https', + proxy_http_https => 'http', + proxy_https_https => 'https', + proxy_https_http => 'https', + proxy_http_https_proxy_section => 'http', + proxy_https_https_proxy_section => 'https', ); my %backend = ( - proxy_http_https => 'https', - proxy_https_https => 'https', - proxy_https_http => 'http', + proxy_http_https => 'https', + proxy_https_https => 'https', + proxy_https_http => 'http', + proxy_http_https_proxy_section => 'https', + proxy_https_https_proxy_section => 'https', ); my $num_modules = scalar keys %frontend; diff --git a/debian/perl-framework/t/ssl/varlookup.t b/debian/perl-framework/t/ssl/varlookup.t index 126d442..e00a143 100644 --- a/debian/perl-framework/t/ssl/varlookup.t +++ b/debian/perl-framework/t/ssl/varlookup.t @@ -103,6 +103,10 @@ if (not have_min_apache_version('2.4.32')) { @vars = grep(!/_RAW/, @vars); } +if (not have_min_apache_version('2.5.1')) { + @vars = grep(!/_B64CERT/, @vars); +} + plan tests => scalar (@vars), need need_lwp, need_module('test_ssl'); for my $key (@vars) { @@ -254,7 +258,8 @@ SSL_CLIENT_A_KEY 'rsaEncryption' SSL_SERVER_A_KEY qr(^[rd]saEncryption$) SSL_CLIENT_CERT qr(^-----BEGIN CERTIFICATE-----) SSL_SERVER_CERT qr(^-----BEGIN CERTIFICATE-----) -#SSL_CLIENT_CERT_CHAINn +SSL_CLIENT_B64CERT qr(^[a-zA-Z0-9+/]{64,}={0,2}$) +SSL_SERVER_B64CERT qr(^[a-zA-Z0-9+/]{64,}={0,2}$) SSL_CLIENT_VERIFY 'SUCCESS' SSL_VERSION_LIBRARY SSL_VERSION_INTERFACE diff --git a/debian/upstream/signing-key.asc b/debian/upstream/signing-key.asc index 23d1174..d129b06 100644 --- a/debian/upstream/signing-key.asc +++ b/debian/upstream/signing-key.asc @@ -1,3 +1,23 @@ +This file contains the PGP keys of various developers that work on +the Apache HTTP Server and its subprojects. + +Please don't use these keys for email unless you have asked the owner +because some keys are only used for code signing. + +Please realize that this file itself or the public key servers may be +compromised. You are encouraged to validate the authenticity of these keys in +an out-of-band manner. For information about our validation and signing +policies, please read http://httpd.apache.org/dev/verification.html. + +Apache users: pgp < KEYS +Apache developers: + (pgpk -ll <your name> && pgpk -xa <your name>) >> this file. + or + (gpg --fingerprint --list-sigs <your name> + && gpg --armor --export <your name>) >> this file. + +Apache developers: please ensure that your key is also available via the +PGP keyservers (such as pgpkeys.mit.edu). Type Bits/KeyID Date User ID pub 1024/2719AF35 1995/05/13 Ben Laurie <ben@algroup.co.uk> @@ -163,7 +183,6 @@ uid Rodent of Unusual Size (DSA) <Ken.Coar@MeepZor.Com> uid Rodent of Unusual Size (DSA) <Ken@Coar.Org> uid Rodent of Unusual Size (DSA) <coar@ACM.Org> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGPfreeware 5.0i for non-commercial use mQGiBDqJD0sRBADmh5EfoFA8VC/c7+BlG5l4+RBIcYlkvYFZcLbS2fPgkHDndrrp 5xIeYCFvnnRSVGkQbAfl4Gj62fGcyaI9QIbLAByGeqSoM+DbiEzIyR+QQNpBq+bo @@ -174,67 +193,32 @@ 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 -oLSGqJ147DJuA6/pNp9OXD1q98vj -=DZH6 +IFVudXN1YWwgU2l6ZSAoRFNBKSA8S2VuLkNvYXJAR29sdXguQ29tPohWBBMRAgAW +BQI6iQ9LBAsKBAMDFQMCAxYCAQIXgAAKCRBQjq7FMC2laP8oAJ9LlFZKQo9K+VFV +sIu44z+HGniLfwCffPkZqEjG6nSJYV50x0bjnVb8GDu0LlJvZGVudCBvZiBVbnVz +dWFsIFNpemUgKERTQSkgPGNvYXJAQXBhY2hlLk9yZz6IVgQTEQIAFgUCOsofogQL +CgQDAxUDAgMWAgECF4AACgkQUI6uxTAtpWiLEACeMAIfJy7f1UQb9P8ec1jyIm3d +MUcAn3ul4q4NJVNMta1/AEe//LTn6J42tDNSb2RlbnQgb2YgVW51c3VhbCBTaXpl +IChEU0EpIDxDb2FyQFJhbGVpZ2guSUJNLkNvbT6IVgQTEQIAFgUCOsofzQQLCgQD +AxUDAgMWAgECF4AACgkQUI6uxTAtpWgBSwCfQeEi5/Z1WNTVlu8mS4iZeQiKBHwA +n1SRRmfgoL6M1/J7e5EV3LLvhWYmtDNSb2RlbnQgb2YgVW51c3VhbCBTaXplIChE +U0EpIDxLZW4uQ29hckBNZWVwWm9yLkNvbT6IVgQTEQIAFgUCOsof5wQLCgQDAxUD +AgMWAgECF4AACgkQUI6uxTAtpWjpagCgs+JIIn5mnNMHEZtQySabyOJ2WlkAoJMU +FB11bUWQe4oUxRp71LeA5BWxtCtSb2RlbnQgb2YgVW51c3VhbCBTaXplIChEU0Ep +IDxLZW5AQ29hci5Pcmc+iFYEExECABYFAjrKH/sECwoEAwMVAwIDFgIBAheAAAoJ +EFCOrsUwLaVoubMAniazysuQ/Xw5vx/Z27Fy0E7qOUHVAJ9tQIhIqobq5OOjO+O0 +qi6TSZoKhbQrUm9kZW50IG9mIFVudXN1YWwgU2l6ZSAoRFNBKSA8Y29hckBBQ00u +T3JnPohWBBMRAgAWBQI6yiAkBAsKBAMDFQMCAxYCAQIXgAAKCRBQjq7FMC2laIlX +AKCWqXUTcphAK7wQlpLXYTIpq45cKgCfV7S+4kkw8A/Sg3/v9rzbTIFTKfW5AQ0E +OokPURAEAPb9XCxUtIXh12LmwYNk0PA9TWNJM1Mgo20rwUsZUdLHOZNuXCUfYIjH +jw951K1KqpXGCv4On/0SVXagXZs9yI+y4Emkz6qPhr9nAzHexH+ykn+ROaP0zNKt +PPgp5CQcHz9FXyz90XZuU48Tly20a9qo0v21dhVh0D4tulkS3pAHAAMFBADUgNY8 +7Tsz3ndoonHoJUFfzwlm5gOknvxE0Sk8dgYzYPrcLX9ZETpSoTWepbjfSe2F1voT +scMkV2WhKMSrdtzFrd8PjvOo8tXLkPL72vyUgw7BDFnfLvIaLtHAQu0BqfHaORhH +5ufFZLXrOXvHGaYfx/kSbFOpjK/KCrYgLzF3r4hGBBgRAgAGBQI6iQ9RAAoJEFCO +rsUwLaVoNLMAniMmvoRcOC404uCsivKbgDEzDbDZAKC0hqideOwybgOv6TafTlw9 +avfL4w== +=gsUq -----END PGP PUBLIC KEY BLOCK----- Type Bits KeyID Created Expires Algorithm Use @@ -250,7 +234,6 @@ uid Rodent of Unusual Size (DSS) <Ken@Coar.Org> uid Rodent of Unusual Size (DSS) <coar@DECUS.Org> uid Rodent of Unusual Size <coar@ACM.Org> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGPfreeware 5.0i for non-commercial use mQGiBDYpIJsRBADkH4H8YqFaBHE7lTb+DkZ12CLXq7Hk41DA/HU+KM2CrGOExK4r DO9zVa7zjMbjhskYMK9AVTPC+f+LrDk4PtTJrRrh6DKZf8loEhgChrUpSDBvlByw @@ -261,86 +244,38 @@ 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 -XgCg6ajZ164aAHwQStdF9x+Jn96GQTg= -=e95K +zZu0M1JvZGVudCBvZiBVbnVzdWFsIFNpemUgKERTUykgPEtlbi5Db2FyQE1lZXBa +b3IuQ29tPohLBBARAgALBQI3sYjvBAsDAQIACgkQ3bpkuiwxLS/jwgCgivhW0g8P +0LcgelNNzVxL4mkJlDQAoOnfabeV/fxP7rVtKSnl+GMLNAYntDNSb2RlbnQgb2Yg +VW51c3VhbCBTaXplIChEU1MpIDxDb2FyQFJhbGVpZ2guSUJNLkNvbT6ISwQQEQIA +CwUCN7GJGAQLAwECAAoJEN26ZLosMS0vkGUAoPbhp3yi/BeC6zR2mv16XARtVlAw +AKCE8kHKDREPKA/E7KpH6dHEx8BBzrQrUm9kZW50IG9mIFVudXN1YWwgU2l6ZSAo +RFNTKSA8S2VuQENvYXIuT3JnPohLBBARAgALBQI3sZ2tBAsDAQIACgkQ3bpkuiwx +LS8ingCfTd/ApQmqLhMhS7gqpaI0gnCJxDIAoOn4LWVwKIvSshj9ST4cBbLZN4Us +tC1Sb2RlbnQgb2YgVW51c3VhbCBTaXplIChEU1MpIDxjb2FyQERFQ1VTLk9yZz6I +SwQQEQIACwUCNikhawQLAwECAAoJEN26ZLosMS0vurAAoLIKrWymZ44LD56dmUSb +p0Im3HX9AKCPXngeaVD2FV9yb4xyEr3aAPb8p7QlUm9kZW50IG9mIFVudXN1YWwg +U2l6ZSA8Y29hckBBQ00uT3JnPohLBBARAgALBQI6yhqCBAsDAQIACgkQ3bpkuiwx +LS/t3ACcCjcL+TpZYClEaxwdFM4SFgha8TAAn2qAC65Jedqiwrhy3MTDaUII0pdK +uQINBDYpIJwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmP +QFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24 +rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhO +SdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18 +F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsC +RtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/wLOaRaqRbtLnVLmNqeCPnJ +Psazjr/ePco1a8eT4giB4T8slDSTtj+AyVC4CMwBZ6SmZ7l2N+VF5rBzffOTJx87 +5PZ5NG9B8pcaJgRa68O8VB8GYA9Klwmw6eoA8g2vkmNs5gYaPFf3Uyu56rblBH6s +1GO6wm/tuqdqUb3XrR5gl0ef8kOXFrzcPAMhgm8fuwvLWtsumq1s9uGT99jL3py1 +66RngIrmUSqlpwgC5LEsTVE9DTKpk4IZC9vUHMNheW6/zE8+CpxNM577fat8yyvr +qSMaKk7CmqitsokriP5TG5dTTx/vwcNhK9VQXAjQdeP9nKoreNtaTIgpttHQoaji +iD8DBRg2KSCc3bpkuiwxLS8RAt8CAKDSmRCvou1moFG3fWUxweRlndgLXgCg6ajZ +164aAHwQStdF9x+Jn96GQTg= +=WPUH -----END PGP PUBLIC KEY BLOCK----- pub 1024D/08C975E5 1999-04-14 Jim Jagielski <jim@apache.org> @@ -1663,7 +1598,6 @@ sub 4096R/DE8FC860 2013-06-28 [expires: 2018-06-27] sub 4096g/E1758474 2013-06-28 [expires: 2018-06-27] -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.9 (GNU/Linux) mQINBEf810gBEADSwwRqdmepv91pr6k18+X7Xmgr+TM7DXUSxjGEZ6zkJkK9VEBn WKIV37768nvZXFl6kxTvMfRNlwotlDHz2WA94fDOA5cTsH6AcRVx+5SNKbGBhDSz @@ -1676,470 +1610,405 @@ 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 -CAf4F0UC9mAucwHZOkjI0HulK1HliZc= -=prMe +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 +F0UC9mAucwHZOkjI0HulK1HliZc= +=KR9S -----END PGP PUBLIC KEY BLOCK----- Type bits keyID Date User ID @@ -2207,7 +2076,6 @@ Key 0xB0D5F771 fingerprint = 3DE0 24AF DA7A 4B15 B0D5 F771 -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGP 6.5.8 mQGiBDyyDL0RBAD7CpRGu7Gvtrp/J/wDKgOxLpX8xLTFTXFnncHctLYKMta6nQ1y pQpx5WhrVyE3wkVPTHbDfd+mtviD8muBLAVdtiVbpN8YxRPxg4KAY+yzpBtIEsUW @@ -2218,15 +2086,9 @@ Z3odHJcSbLEddmm3Y7ToCTpid03FO/UgonPbu/N//BNuu/WLimO6I3ZC9EYAMwWW zzhEBACv3IIwjrkJHLxJZh6NJjoXJL5/w0FgRA+C08/nZBxcBWElavk1ukpxyB2v 23P531IljA8MT8VyQktNSzfAccQuvY3gIweDEgPXxpc5c1MqNihixDtZvAtoBqyr nmKWgl1WeW26oe1eg/0XmpCSg5klaeF7EV0EV5DYUczNP5Ecv7QjQ2xpZmYgV29v -bGxleSA8andvb2xsZXlAYXBhY2hlLm9yZz6JAE4EEBECAA4FAjyyDL0ECwMBAgIZ -AQAKCRA2FSLXgqt70TzVAKCr/RJ3yVYBNdkZTW5e2PFFhHfZhgCfYBAPdm+WomzF -qHvigpnQ7KjXNuCJARwEEAEBAAYFAjyyDVAACgkQ1zqQuGu6nV2XRggAuGaGWQRp -apcTcrsPALlzUuzFOTApMePxmtaB66fKm6zdV6FpC4iSW5zaMZOZTNDOWD5541qe -Rl3JtP+lo/ZrY91gO9mmjkB5cnXQrzLP84rfL1LELgTgSJ3lcCFqgp6dJr3NI0UF -eMYcAu/OjjUQ9JNoNsxVjTvuxnslSOekQWU28CjD11/pm4n0VPlbPJosHv4wbncF -DplifohuXoQnJX7a2JbCTn0+YDvUe9+aMj6A1/qftgv4msvxqL7f8d8cZ5vwK+CC -VfcVNsFYf/EblFH9X05e4nBt/P58SnLLWxsCg6foNKpuK83SjPpTAYA2s8+AJ9CA -054a+swKXbFWDbkCDQQ8sg01EAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL +bGxleSA8andvb2xsZXlAYXBhY2hlLm9yZz6ITgQQEQIADgUCPLIMvQQLAwECAhkB +AAoJEDYVIteCq3vRPNUAoKv9EnfJVgE12RlNbl7Y8UWEd9mGAJ9gEA92b5aibMWo +e+KCmdDsqNc24LkCDQQ8sg01EAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL OCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N 286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/ RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2O @@ -2237,26 +2099,11 @@ wrsg3NXrnMe65PluraGnIovnh9KO9i4XSkIWdB3zQgTlkxhtfZ8NJHB/ihSnxtTa u8zmJ1514QJzHH6lDlCzYNhS4tPvR6deIoUwzSupi8L8DKNhS/dwlvKmKQXMpII4 PULCDT7/nFbB35GmA0E6vM4ZnmHaZNDv448OxoePR8bKy0RpdNIznKHV8MbhI5il 2IfzbiqJ0HIGtZJCaJSfIv2+qWsQf2JbY+uln+KiWwSkUI1MvqUHKKmC4/eMPVSK -xsm2vrikocYSgokARgQYEQIABgUCPLINNQAKCRA2FSLXgqt70d0RAJ4gArDns42K -44A6p/EkdHPvPRt2UACg1PdswGHhdskOJmGc6rftbDon2jyZAQ0DPLIMKAAAAQgA -zLpNBiA2pEnKa2OocaCvTSiYn1mSnXPbtqsBQdodIeq0zm8x1YizTWzhyocjIwM0 -N1i2QdFY8RQfmiqjoEOthzPCpP/3/K+BUYOpaq1Oro67DvmDnS8tOFvhQG2cDLcq -LXW1v9cDTSiRLP6cNZVyYYtlQAPoIkOVbnzBE2nHSeS5nv67XmDIvTNZJFlFHnUr -cbZ1Lcbg5blL94teRFNaVRaCVpBKGiIE3XycgWV5+MBVKRH0XOnmcyaOS0VaFIr7 -o/g0WjZ2Cn8lipjEx3KSi0cERIqZQFMfqTGC7oVuuyOrtvp6S3/9ltmtndkzJ7so -RMRnjS9eZW3XOpC4a7qdXQAFEbQjQ2xpZmYgV29vbGxleSA8andvb2xsZXlAYXBh -Y2hlLm9yZz6JARUDBRA8sgwo1zqQuGu6nV0BAaZLB/9tR1ZYc2tB4uFGqa1YJbIq -7qRYESrESkeePJvt5A1WF2n39zY7RwRECBuUhZe3GJVohac+kZ85pS6WbtihrO8I -HSuSm0HPvfkoedk21Md/zUzaaq+gKE/0eaPO1UycwZk8F8jv4uC2tKBwfbZyay5L -fQ8YcYM6XFzV0uY4oJF7x7jTaNT6iyQtsPPo6UAxNwcaZFdQ1Yz/ZFvl0vK3ssYz -h00QsYxy1TJGaqHXO26FlIBzP24xl//jbMVS88DKmltO07O1ZzZ0H8gvX5u9AYeO -S4jt7wJlJql5jQGQ781ZybGAzBma11ixK5XItq2mVaAQdJdOqMiTmJvWgE5/ymoQ -iQBGBBARAgAGBQI8shKPAAoJECFFSvDMiw9+E3cAoJCOGqlkIY3JXY7rYHqICrz8 -D7eRAKDOQjhlMF3OOD6KlGtnuBpdhpK6rw== -=gjEJ +xsm2vrikocYSgohGBBgRAgAGBQI8sg01AAoJEDYVIteCq3vR3REAniACsOezjYrj +gDqn8SR0c+89G3ZQAKDU92zAYeF2yQ4mYZzqt+1sOifaPA== +=+RAA -----END PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGP 6.5.8 mQGiBDteBSwRBADAFBGWcqz40R9Ne7jX6zyk1XMqVsab4LNZMzd67n9J/Qni34Wq 5ZMHKUUqMYgIgKjUB4J7J56XVoPEujGBxG7kb5HOi4Vt8C8jg3FF551yM2WgamVT @@ -2267,35 +2114,10 @@ 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 -=8dFY +bGxleSA8andvb2xsZXlAdmlyZ2luaWEuZWR1PohOBBARAgAOBQI7XgUsBAsDAQIC +GQEACgkQD4GqirDV93E1vgCg0sUvhCCZsIRmHJWTU/C0Liiqa6MAoKPKYZ0OFuJK +u5nu39CjRu8akNrc +=XJfp -----END PGP PUBLIC KEY BLOCK----- @@ -2304,7 +2126,6 @@ pub 1024D/751D7F27 1999-08-19 Graham Leggett <minfrin@apache.org> uid Graham Leggett <minfrin@sharp.fm> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.7 (GNU/Linux) mQGiBDe8doYRBADX8dv5WHSCk8CDrqMFs7eB3MHEIeWanX+7e43s2NTuDhxWUOOg vWFYFM0aQrGGvJ3xT/8DrI3V6KdtBK1W/h2PjWNXoD1RsmBQZUzFx3PR+I+dwv+T @@ -2317,70 +2138,23 @@ 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 -=qXzK +ZeK/fea0I0dyYWhhbSBMZWdnZXR0IDxtaW5mcmluQGFwYWNoZS5vcmc+iFcEExEC +ABcFAjyy75AFCwcKAwQDFQMCAxYCAQIXgAAKCRA0SoRNdR1/J6hlAKDswGkprIhy +XLLSbwnx+03aFOMZLACg9w8cNcNJe+nFEalcGX22VM4lW3+5Ag0EN7x2hhAIAPZC +V7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdM +ZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHO +fMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNs +OA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq +/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2J +SyIZJrqrol7DVekyCzsAAgIIAKLAVHC7Lr6Z+N3NzPbcQrPHzw83kC/9BxqXIzYN +hGhE4IGSX/M5T72DljGYE/MuuAvOpj1CCC2IdsHGV/kl2hE3ynMTd4lbzAo6/wTs +1EHCDr1Fsker6QI+PTBrxuzy6HW2ooiFpmOjgnjIUJZ6TDohBo8gdMJx/yJoMQv9 +gaaWqeP1pf5Hr1aIyoEtVfcwh6ZSN98JhWqjz2Cle47ZQsimGWNo04jYyqLq7pAF +f8F0e0ILoz+Da6qEhkFl4FwVpRJ/kg4fNI2aF7s9bep+T7+4mPFGhVM3RVEF/D4q +R1kQZl91tFk2QW3zjSiPaqLMA6eM8+yVesuX1Z7zSlDJwKeIPwMFGDe8doY0SoRN +dR1/JxECfe0AoLVVCeAIRUE+I+g2tPg0dPtQRjw9AKD4iTus3noeSP+IOpuUB143 +i9q2mQ== +=V2wv -----END PGP PUBLIC KEY BLOCK----- @@ -2420,7 +2194,6 @@ uid Roy T. Fielding <fielding@apache.org> uid Roy T. Fielding <fielding@cox.net> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.1 (Darwin) mQGiBDrKHnYRBADjqUE4qp5WS3rI51oKVZOMLPyYI8lNwf8NwJ6LwfquU/DfiCf3 K4CWKej721VMgT3zkd+PK/hGl8XpKGZIZIsPyZnvUOfPW9k+bxn3WtUiprwwVvBi @@ -2433,331 +2206,30 @@ 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 -xkA8JT6eXcJrBJhGbcY= -=KQRI +c2ddPD2Ggd8Anj0JI6lG+iLuXusECs0Ipr1XQLxLtCVSb3kgVC4gRmllbGRpbmcg +PGZpZWxkaW5nQGFwYWNoZS5vcmc+iFcEExECABcFCwcKAwQDFQMCAxYCAQIXgAUC +QY75RQAKCRBbloAQ4E+aidLAAJ0bK66qzhQiErheJkbpRHhl3JUY1gCfSMRP3RLk +eeGkY5hCx9k8VBYP0920IlJveSBULiBGaWVsZGluZyA8ZmllbGRpbmdAY294Lm5l +dD6IXwQTEQIAHwUCQY74FwIbAwcLCQgHAwIBAxUCAwMWAgECHgECF4AACgkQW5aA +EOBPmonYRwCglIthafvYgHvdYcvlQ42kkh16xq8An2KEveQwXY/rxzIfVdQOnXaP +EMbLtCNSb3kgVC4gRmllbGRpbmcgPGZpZWxkaW5nQGdiaXYuY29tPohiBBMRAgAi +AhsDBwsJCAcDAgEDFQIDAxYCAQIeAQIXgAUCQY7+GgIZAQAKCRBbloAQ4E+aiRjW +AJ4zujQgVHlJ2wn6S6/00/ldOQItzQCfcPVPscHSaqzW5aG8U2aH8P2W9/e5AQ0E +OsoeghAEAPQu2Yp56TDXBqWQYrw4C8omkFPhabgCE+acc2HcwVGMICK3xQtkRbRc +Mez/kgc4VGnHIoqlLKfNE0YYzZiL0O9blpyfkfhSzVVzwIHHVMcr7MLsBTvJL1MJ +HnVUM8Q40inaZx3R5rIHZH2IaK70pX9GPz4f/9gYXawK8CpfA4ofAAQLBACz5s0/ +vxLUvvy/iaPnvGm0staWxPFeRl3UkKKixeK02YYtiwu0GV0C2W5cWWVLYiMNk9X0 +qnvih+Bo7jCHTVCmuTgaflKtIjs6PpgfwMD+CCDDu//+EQEuKY3vmiR+p/MGE1Nc +0jEfrOG6jzRFx9fQn+tlDgB279pd5ilHsTfoKohGBBgRAgAGBQI6yh6CAAoJEFuW +gBDgT5qJxWEAnihVjTh6CI5ZtmPwOgEu4+OLCIakAJ9lO46xIoHGQDwlPp5dwmsE +mEZtxg== +=NPuq -----END PGP PUBLIC KEY BLOCK----- pub 1024/E2226795 1999/09/19 Justin R. Erenkrantz <justin@erenkrantz.com> Key fingerprint = 3C 01 6F 2B 76 46 21 BB 54 9C 66 B5 16 A9 64 95 E2 22 67 95 -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: 5.0 -Comment: PGP Key Server 0.9.4+patch2 mQGiBDflD4IRBADqhgm28jVQWqu8ogG/NvYOSySYc4MhrXFqOQrRxJOcAxdc03fR Mu7RtAa4hXpNfjOLIfxY0cc6aqKJLlOuZAUxNNFWIcuO3xSWsPrwflaBsATt+0jw @@ -2767,58 +2239,26 @@ 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 -=6s4E +8b+BFeY6Wipa4YQQWWBl2DXpkQPbn6lp4fgH7re52Ifp+S67R7QtSnVzdGluIFIu +IEVyZW5rcmFudHogPGplcmVua3JhbnR6QGFwYWNoZS5vcmc+iFcEExECABcFAju6 +tA8FCwcKAwQDFQMCAxYCAQIXgAAKCRAWqWSV4iJnldxxAJ4/ecG7zJ68UmNWURqc +bfS806TptQCgpQwEmH+4oahCGgqO1GYBu9r0uFi0LUp1c3RpbiBSLiBFcmVua3Jh +bnR6IDxqZXJlbmtyYW50ekBlYnVpbHQuY29tPohWBBMRAgAWBQI5s90oBAsKBAMD +FQMCAxYCAQIXgAAKCRAWqWSV4iJnlSTwAKD7a1IKU1qWfAgKCE2UAsTjzKlplQCg +zcXJOJkeCina5IOMFaRLmqet/+25Ag0EN+UPgxAIAPZCV7cIfwgXcqK61qlC8wXo ++VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D4 +9Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNb +no2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbz +ySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLW +hsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsA +AgIH/i4xG6zgw7Z9Gb7+zPej/pW7VNCTVkBvqoOHCuQCt+ePtSM0JaqfQH15q5sX +3q9OiRvqEG2/cVIFnlMO+eABsW9kSM2lcZ+hbgaShF0Mo2ligjxEtMqOVEqJoSX5 +/V71bFCnuLI/ijRUDEBbR/+xDDMsYikxLU9qM7aYEG1JbfZ7tmDLgL8AD3XgVvgB +HzCSgM++vyrc/QO/C2eZ3SlI94B8apjxC1MqOM90DIROnUkiof65WWuKPkLC0B3f +AkE3gYx9ei3O0QhMDy6bzFL/gSdZI5E5N/c02G/0ytO8xik+yh0IP93QgnuVx7iF +Xm/NnqFhfTuC9wngtCuob1vfIs2IRgQYEQIABgUCN+UPgwAKCRAWqWSV4iJnlZJI +AJ9ADoJugmLv0uJJsQllPv7jArhQnACgsKfYamDvXyEMgZlTMLZq9qNE1RM= +=jcXn -----END PGP PUBLIC KEY BLOCK----- pub 1024D/2CF86427 2002-02-01 Ian Holsman <ianh@apache.org> @@ -2888,87 +2328,28 @@ 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 -=SyIW +CWUm61QppZdYAz44QwPStCJBYXJvbiBCYW5uZXJ0IDxhYXJvbkBjb3ZhbGVudC5u +ZXQ+iFcEExECABcFAju5HOoFCwcKAwQDFQMCAxYCAQIXgAAKCRAhRUrwzIsPfp/Z +AKCcug8zNT2WbAXMt4PPJUzhPKch7gCglldxj1byfdKv9NJnrQLTQ6mXsma0IEFh +cm9uIEJhbm5lcnQgPGFhcm9uQGFwYWNoZS5vcmc+iFcEExECABcFAju5HSoFCwcK +AwQDFQMCAxYCAQIXgAAKCRAhRUrwzIsPfpXhAJ90H0qqJqDdP3xjq1DlhJvbn1cm +dgCgz19DfSxtDF+Y0q44duQi4+5TbjC0IUFhcm9uIEJhbm5lcnQgPGFiYW5uZXJ0 +QGt1Y2kub3JnPohXBBMRAgAXBQI7uUmvBQsHCgMEAxUDAgMWAgECF4AACgkQIUVK +8MyLD3583wCfaxQQSZMvfJ+r84L6rZftxzVOqtAAoMWki8MtCouiIv3k86jZvHy9 ++CF9uQINBDu5HBQQCACKePczRQE1gIWH6LZaCDY8pINsW6SHl4MXDnBPgnuZ9H/6 +kFr++2OXatVKlAoQ3mK0sN/py/HeGkMwKBI9lWVldPik4pgDhdmZU3B3spA+TTCB +WNpKyXGY2c7P+ougUvwQAysifhxOGAvr1R6TpBqeSdZ74ZzMPhHLSJGwOSq3BJ/u +aViRzZORbVmUFV8s1Og3UlHdvoK+blnbj6eMVyrQ/n+ULviDnPDxasWhP4an+v8c +4Gk2qsAz1XmXccn7S4pa9x/yxiXLNHHrr90Dd0h5LvvvhgcQTUFbEwwcdfzKKaiO +tuq6qA0Rki/wBBabEtLPzCgBIpUj2lUZZrySVR/7AAMFB/0a9jaU9Gc25ZygMtft +WMVIXEGG7aTqm95Q3ZebYRlpxnJJUkNyLuj09IwBuV7aXkpEBdACHNTyPwl3khms +wjxQO5tWj6JEvdijxMEHu8JtfTq43zRAc62bMq6uJshWNd1oVu7pS4JQGmJvUyZj +J+Q9iiyY92XtdSyN0QnB0BeXHyHJB7ZeHbzALkOBDKUJyK50/ACJz5JFXabvc0c0 +zwveU46rFFa2Vdqv2Tf3exL4Gix/Pd8cKfknrssXoIwmUvpESL92XUUSm7Ozy43+ +UWq2J55NSLNuqNtZyoMJWiLv3RpBn1DdGbXpuIeyDHCDMM59GnqTdrJWcVQ9WJ/9 +txxziEYEGBECAAYFAju5HBQACgkQIUVK8MyLD35AfACZAcAS375Fg+hea6FxD9qn +qpaZpjMAoLY7tAaEc1bKdJ/8Za3ZPT/GON9J +=PFvF -----END PGP PUBLIC KEY BLOCK----- pub 1024/3A4E7AC9 2000/10/11 Brad Nicholes <bnicholes@novell.com> @@ -3007,8 +2388,6 @@ sub 2048g/532D14CA 2002-04-10 sig DE885DD3 2002-04-10 Sander Striker <striker@apache.org> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.6 (GNU/Linux) -Comment: For info see http://www.gnupg.org mQGiBDy0wXgRBAD1J8+8rBKAXD3Z9n7LhdQ+gDcYIDw/sN0cZGz5kpc/1YWWaMQg ArmoNW7y+BBwNu6Cn42Nid16avSC86H1zBzOdQscDc9/WLwBCiFDCSHB98+UId25 @@ -3021,13 +2400,10 @@ op8A/ljW2BDm6VxHSBUkIJvULUbN8rxvQGnpKplv9jgiwBHoPhKZ/TX7KvXAvdPg bx8Z4EfSVJRQs7j/v/IhM8xn8tu0EEW+Fg1SHCFWV5iqe6aTZrQjU2FuZGVyIFN0 cmlrZXIgPHN0cmlrZXJAc3RyaWtlci5ubD6IVwQTEQIAFwUCPLTBeAULBwoDBAMV AwIDFgIBAheAAAoJEGY1tsDeiF3T18kAn2kAzhMXT0tOg5GvGVNi+rc+dpZcAJ4z -rKA/8TnQ88Lqq/OOwkuC/TXrHohGBBARAgAGBQI8z5oyAAoJEBapZJXiImeVyywA -n1wPiGQVC6Kwdz1XlXrFL6/yC98mAJ9MZZgOr/Kyh2mDgwqWi+Fa/bgqarQjU2Fu -ZGVyIFN0cmlrZXIgPHN0cmlrZXJAYXBhY2hlLm9yZz6IVwQTEQIAFwUCPLTB5gUL -BwoDBAMVAwIDFgIBAheAAAoJEGY1tsDeiF3TQNMAn0ear3DqKydi9oTzfBYFCidn -YhqJAJ9fvKcU27+jJCRHIPp3lQPX0C+UQIhGBBARAgAGBQI8z5o1AAoJEBapZJXi -ImeVXd0AoP+AlwMBWr5fJ9pERjvKmnnNJE5oAKCJTRBYnB/aYkt8/aqPMVtl3k1L -NrkCDQQ8tMGJEAgA2F8v1AMPGI7cv7cWuySfnd2CV7SXOZQpc3Pfv2UHgYP+1lTL +rKA/8TnQ88Lqq/OOwkuC/TXrHrQjU2FuZGVyIFN0cmlrZXIgPHN0cmlrZXJAYXBh +Y2hlLm9yZz6IVwQTEQIAFwUCPLTB5gULBwoDBAMVAwIDFgIBAheAAAoJEGY1tsDe +iF3TQNMAn0ear3DqKydi9oTzfBYFCidnYhqJAJ9fvKcU27+jJCRHIPp3lQPX0C+U +QLkCDQQ8tMGJEAgA2F8v1AMPGI7cv7cWuySfnd2CV7SXOZQpc3Pfv2UHgYP+1lTL NJoRtfwXMiNjrEwgLrpLy7F0nHnVqb6MBYv/Dhx6eO7MoejJUc2pADijCS3Qcg5n 7hCZ+pWvCjdZAfZhHB1cpSm0FVuc07jrJYTbI/qsdbUHQ4r1jcIZR/ZU4mTnFgnE bAw4NxSGJ8ikFNNfviDdb3O/XAYS27dgJcGHOHaQi54dWkJpYt5vayUHYt85pOMH @@ -3040,7 +2416,7 @@ voQte/WBoVYdVCigUIeArRqNyCsk1yGUfiBcmJFHCyhKNtYNAUwWGPv8AmTAb5yf FFVprAMbDlv2yhiTnEj7AvEC+OP1RH0Z4j0TDlpeKHoZtu3uP/gp7Mshs7ssE2mV qohGBBgRAgAGBQI8tMGJAAoJEGY1tsDeiF3TPewAnj9AmBMuS8QvsuS5hUhSWNZ/ uLN6AJ9FK1Wz3vBRoTloK5D3D3UaJ4x7Hg== -=AHY5 +=TcJw -----END PGP PUBLIC KEY BLOCK----- pub 1024D/E005C9CB 2002-08-15 Greg Stein <gstein@lyra.org> @@ -3110,7 +2486,6 @@ rev 8103A37E 2003-11-28 Andre Malo <nd@apache.org> sig 8103A37E 2002-07-18 Andre Malo <nd@apache.org> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.3 (GNU/Linux) mQGiBD020E8RBACVdPw0jDJ4jXKx8hBllu73Vmoxz8amOq6J92XH0Ch3obgHKTa/ JndsxvYFDy4onZItPXbb4TC8uJGwi717eU+w8dHvB/R972JveKgb0HMeHcrGFOvS @@ -3123,76 +2498,40 @@ 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 -=93VU +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 +=vnQ/ -----END PGP PUBLIC KEY BLOCK----- pub 1024D/75A67692 2002-09-28 Erik Abele <erik@codefaktor.de> @@ -3217,7 +2556,6 @@ sub 2048g/A680673F 2002-09-28 sig 75A67692 2002-09-28 Erik Abele <erik@codefaktor.de> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.1 (GNU/Linux) mQGiBD2WL90RBACfr70TIDSk7pcnS895qhkiBp1A3wunMVIshhmxNpjxxJAWnZ+5 wS8rvtwksMmjW7LCK8UA6Jt0avsc12qyufiR+pfhMXVtJmGQc6VPHd/mQcQS6SM0 @@ -3229,44 +2567,24 @@ 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 -=Yf4N +KigAnj3zryS/aoPAoaxMhJAh8MPDtN2GAJ9R6/wC2EYBpAK2WiJzCUFfC1Ho0LQh +RXJpayBBYmVsZSA8ZXJpa2FiZWxlQGFwYWNoZS5vcmc+iFcEExECABcFAj3gA1cF +CwcKAwQDFQMCAxYCAQIXgAAKCRAVP6DNdaZ2kqTcAJ9b6SqN/SWtyDhAjwwVxhDA +gpqYFQCgpOFZZ07RA3tLNBmPPsPVyOjhWC65Ag0EPZYv7hAIAI4cV77TdfoOfwGu +NBRQCYkSoRumKGuKAgPfRyRLm4x+hShn1hN49O1haUPfYz3E3XhABJWvvCNVTC5B +dpEeFftKCtIpcUbNrf+lfoeyrKi7YrxjghCDvP7kSxvEVCaLOi0h3nWvCmBCZtiv +doD1/z0AupqmZU6Eso+Kbp/plDKjOh23tOVKXcoIo95cu4dWEES29XVDiG/ybvUe +HN05xUIBa4+uHNoZXSWOEj3DPay+X3zo901JzC7GjHaC6zC9OB+cIiCtdcKbMd2x +XhnGn6Fx28IdtUcQyvyjlXPUVG8N+R9RmoZ6+hEZwDgc9UiR6d9Mtsw7FYNuyNAQ +o/NXgDcAAwUH/0a3TbbJDW7jUsbC/1CzfeJUsKMA5aXCICEWxRH6srwr4xg7jVc+ +gJR7InqwlrSJ+7A+WxCiBoCShWjWwLiLgSfjxoc5S+0ghllvUvQdfSW1wRf6Ac75 +nW7Nxz5t0196gLr4VWdW/RfpiUwevlG/f3P2GtRboF8x3z8miQaXrLUF0kBpoGgE +Hd/mPWCxyLUCbpn1vwFkwquYBZ02vO0KTfhrCyMd7+PcLbvUvmkYBKZeA223+S8A +mLSOdcaJrhH3W+DNr/n66oLz+1qvS9HOQz5qha7JVcxPotd3qDycWL/7jHZhLXWR +vSWYGUopm9C3jbKhifCmbhV61CDgklAiLvSIRgQYEQIABgUCPZYv7gAKCRAVP6DN +daZ2krITAJ46KBuTgt+pl1zH+xKQA6BeoXVaTgCfXYNZppSmOIwCrsggJyU+FOco +xOw= +=NIxJ -----END PGP PUBLIC KEY BLOCK----- pub 1024D/2261D073 2003-01-01 Astrid Kessler (Kess) <kess@kess-net.de> Key fingerprint = FA39 B617 B614 93FD 2835 03E7 EED1 EA39 2261 D073 @@ -3307,7 +2625,6 @@ sub 2048g/A676B84D 2003-01-01 sig 2261D073 2003-01-01 Astrid Kessler (Kess) <kess@kess-net.de> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.1 (MingW32) mQGiBD4TcBQRBADAwVM+jE6VQUNhOHL/0L+VsWC/n5tMEbINSYUj+7KFrWqlTLgc nVA9vOGlScm+STor7YaE5Uhni6WK9TfmMBrLL/qPBVVH+jh3J4AYv9IzNuqmIyV6 @@ -3320,75 +2637,32 @@ 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 -d6rncSGIlA== -=SNQD +yL3wrwCcCxDCMy8ry7JvHUnsdryCMC80s3C0KUFzdHJpZCBLZcOhbGVyIChLZXNz +KSA8a2Vzc0BhcnNub2N0cmUuZGU+iFwEExECABwFAj4TeHwCGwMECwcDAgMVAgMD +FgIBAh4BAheAAAoJEO7R6jkiYdBz1SkAoI4wGZmWj2JSeQhmmaiOjFYxNbHYAJwL +VOQoXOCn1ia4PhWQxHmTHoooBrQnQXN0cmlkIEtlw6FsZXIgKEtlc3MpIDxrZXNz +QGFwYWNoZS5vcmc+iFwEExECABwFAj4TeNYCGwMECwcDAgMVAgMDFgIBAh4BAheA +AAoJEO7R6jkiYdBzmmoAnjYKzplFGoSk3nb9BY7rprfpdupMAJ0dtGQ0Yut2Itax +M6S+3jSfZQVDB7Q7QXN0cmlkIEtlw6FsZXIgKEtlc3MpIDxhc3RyaWQua2Vzc2xl +ckBiYXllcmNyb3BzY2llbmNlLmNvbT6IXAQTEQIAHAUCPhN5CAIbAwQLBwMCAxUC +AwMWAgECHgECF4AACgkQ7tHqOSJh0HNWpgCdFdCF+lue7FLID942h8vbHS/wRxoA +nAtWhoefloXQmEkDXwzLbEZla23rtChBc3RyaWQgS2Vzc2xlciAoS2VzcykgPGtl +c3NAa2Vzcy1uZXQuZGU+iF8EExECAB8CGwMECwcDAgMVAgMDFgIBAh4BAheAAhkB +BQI+jgk/AAoJEO7R6jkiYdBzkEYAmwauRVlLQWfQQWYL2oETUR5r2LWMAJ4li2Xu +W3+Q9ieAcYVgLW5JVrIDkbkCDQQ+E3BzEAgAoNcpH15IEiWXX5dHI2H94Qnrff0X +l4j1Wdh+P/JJNDA8FrOWCMcGSR+RCDPYiZ+R1bNskmiU2fBnb/KrdVPVtGYc+Fm/ +51PeA7oxV/hyI7JudyouEm5JW4x9JzNcDXjnVWxt5OvddJX5CDU6NmELPycKArRA +xuS970htnGXf9MzhBsqjCWyiq226r1d7irnXXqL7+nC0DPOcyV1FNoralULY3qpf +7k6oxadjJ24x4Eo3GbZrse7IJzdO6ojfros9Mo0VVnnC0lRh4BHpOGNav8DENySN +cWKUqCFSG6Pp8fvz5Py5pHP81sLDewaBp3wMrtKWt613N15Kuoy8FbeTdwADBQgA +nNdV0mjGHWoOe+D4s61mm8OsawGSk5VvmxgClcO1uYO2hlCpRgpSSVwoy7Gk1BAH +8iPRR0/zTk6tR/Yqgc57BIDSD/FSfDOEMj0FkOt07DEqdAqyqF1QQlmznMV8qWXC +aVXZf4e3a1zTS233RU6ue7uF5iAvqSN1AOoh3dEk8WVlNa+Pdtao346XOK+bVDru +Jt9yRtW4AlR95Oy+FqPSSF0DzaH5MDFPCBJjZFuWAtOTpyKV7bqrREbzDiNNWHY9 +D24wk4jTvXakNPNWU2LSIt2MFvX7JUZHr39AOIuzOq7YHg6fISaeVG9bFLioCzvL +HHwO98U3dkvXZWBMDRv1F4hGBBgRAgAGBQI+E3BzAAoJEO7R6jkiYdBzo9MAniGR +GjIDno4FmOE32kgt2U5LEvIrAJ46RiKuEJ7Yf6tf9CPQd6rncSGIlA== +=VZOv -----END PGP PUBLIC KEY BLOCK----- pub 1024D/208F5064 2003-06-13 @@ -3496,8 +2770,6 @@ pub 1024D/E76CF6D0 2001-04-09 Stas Bekman <stas@stason.org> sub 2048g/01611FBE 2001-04-09 -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.4 (FreeBSD) -Comment: For info see http://www.gnupg.org mQGiBDrSKd8RBADpBhHzpCEB/tWZTNZ0B4oMSMsWBnukkYADPy7ydBUOZHw17ddL oKj8IOveqkX9Fdl7e32At1cd25kitU2nNXeQWt27C47LfDVR0iPfnVg+YE4jfDDb @@ -3510,26 +2782,20 @@ sjsr0G0yfbSIdAKK88BC/YlRR9WfYKwd8vvH9VUyroYgo8ufFYvhhBZZwP+FWw60 mvY5EWLPk5g7rwT8Fqrg5y8rVSXTsZs/baesQPqkhFLXT+g5TrQdU3RhcyBCZWtt YW4gPHN0YXNAc3Rhc29uLm9yZz6ISwQQEQIACwUCOtIp3wQLAwECAAoJEMyy60bn bPbQnXQAnj8fmeXLyodcHPASyt376IUzsar4AKC98XkNtS8gl4AfCCfOUkGNrh59 -B4icBBABAQAGBQI60Z9MAAoJEFMHR+Yj6eq1eLsD/inQzkDNOsCDEbOF9calmv/C -QkRZps0kLKEnxk9bS3SnwYZN3PbtZDNh4ImrrZ/xqBdkOds95jZm5Mo4mJUTzpX0 -gK2gEhajjeWUdQ4k0QZ7pb722DQ69PMJReNZQQkcV+rY3SaRLugeDUIzpexvcO1w -i4lKffrvJNVN0I/Yim4UiEYEEBECAAYFAjtSGwoACgkQVZHiwGZkwHhcpgCeNoZu -zqc9rVB62+Igb4pu6l65Bu8AniM2tGWqq6tFGLqvYtA7DC0mlFfhiEYEEBECAAYF -AjtXsjcACgkQyzKhB4jDpaXnwwCfSUCu5OKxMNtHZWQwv2HMt/DlgFYAnjoAbCqy -96V/aY/0rHMhPWlhd4SJuQINBDrSKd8QCAD2Qle3CH8IF3KiutapQvMF6PlTETlP -tvFuuUs4INoBp1ajFOmPQFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2 -Uk89PY3bzpnhV5JZzf24rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVy -OtQa8L9GAFgr5fSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPw -pVsYjY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnI -Byl6ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/47 -TeZ/O+z41M9MMI2/4aKBqbfIWNzcWl+71KZwPymTQO5F+WR9fSlS+qTNz+h3gi+l -bAEQ4dI2d+tUZX6q5cszNn/60ffxUbEqa3uBIkOaE+ZuoFSM4I/3IWlZqH7q2x3N -Q/oQgthLOU7c8HnCv3hHL4a1nsvVZze7zT4Rasb07+kGydlYpkoVhFEp012s0PJT -vDHG062vs0sx9HmknX6Nu1y91UQCFE7GVfkixk991s/7qHbKNW3u7FC1F0WrwMDa -Sgp27uJmn8E+tFrb8mpLqvJko2852EL9xKWGDDUqI/sRtZtuxdTcqsLBRyGJqxFy -0yA+GHeueqiS5YeEX1Z1iD8DBRg60infzLLrRuds9tARAvtZAJ9YzzyCiEYU/s9p -NVbVevC9/OkwYQCg5fViSXktQM035ki0W14ocNEpXdI= -=oamg +B7kCDQQ60infEAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTp +j0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39 +uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1Y +TknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9 +fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCb +AkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwACAgf+O03mfzvs+NTPTDCNv+Gi +gam3yFjc3Fpfu9SmcD8pk0DuRflkfX0pUvqkzc/od4IvpWwBEOHSNnfrVGV+quXL +MzZ/+tH38VGxKmt7gSJDmhPmbqBUjOCP9yFpWah+6tsdzUP6EILYSzlO3PB5wr94 +Ry+GtZ7L1Wc3u80+EWrG9O/pBsnZWKZKFYRRKdNdrNDyU7wxxtOtr7NLMfR5pJ1+ +jbtcvdVEAhROxlX5IsZPfdbP+6h2yjVt7uxQtRdFq8DA2koKdu7iZp/BPrRa2/Jq +S6ryZKNvOdhC/cSlhgw1KiP7EbWbbsXU3KrCwUchiasRctMgPhh3rnqokuWHhF9W +dYg/AwUYOtIp38yy60bnbPbQEQL7WQCfWM88gohGFP7PaTVW1XrwvfzpMGEAoOX1 +Ykl5LUDNN+ZItFteKHDRKV3S +=wDxR -----END PGP PUBLIC KEY BLOCK----- @@ -3538,7 +2804,6 @@ pub 1024D/42721F00 2004-01-17 Paul Querna <chip@force-elite.com> Key fingerprint = 39F6 691A 0ECF 0C50 E8BB 849C F788 75F6 4272 1F00 -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.4 (Darwin) mQGiBEAJtaERBACrYSun+13XY5xobkfAojSZXeYiLCGrqpRQJiRbSQCQEFIhCqTp 5Q3q5wcHFqx9da3EpF9Dl9yw7BP/R1nvWw68/eGKMusjyvjF9vVKFFCnaB0YwWuh @@ -3551,126 +2816,29 @@ S1hieaoeZ0UIt2T72Un/KUZinBYYGZAzXSFQNNqiyvy1v5WeVMjaEHOHHWLbqzX5 3ycf4o9B802MIBS6F0UGpCAEnakZzT+2GG0B/z8RTF6eHpRBv7QbUGF1bCBRdWVy bmEgPGNoaXBAY3lhbi5jb20+iF4EExECAB4FAkDwYsgCGwMGCwkIBwMCAxUCAwMW AgECHgECF4AACgkQ94h19kJyHwA1pwCfYThV8T/7hCKtGOBUgVABymqtER8An1Dq -UrHIVDhb8JkD/pXxjf1g5pVWiEYEEhECAAYFAkGjAIEACgkQB2FzsZKExFLdCwCf -bxMTetsoC3REjFbIGddDZQOICUkAoIY9m2AOUZmx21CniAK4ihNq1As8iEYEEhEC -AAYFAkG6O+IACgkQAQVmvOQTY5JrygCgiW8vzmmKQ3lbIRUpHyQ1D9vubdYAniuO -5P3M5v2glVmplF2kma3lu9SriEYEExECAAYFAkGaiAcACgkQMJF5cimLx9ADZwCf -WWqyc5FAe+exeZeuOzL+F2Zj4bMAoLVY32mEOzifj3gRU84v7Wm2HxAMiEYEExEC -AAYFAkGaug8ACgkQW5aAEOBPmomgLwCghP2fgryoG0IqPtp9NHWIuecwhqYAn1M+ -VmigV5yC/PXqZXhxCUX8YTZUiEYEExECAAYFAkGiWNwACgkQBJfVkRK/55qYPACf -SReNPV+c0HhjCPgRT9/oZLw/E0UAn3uz9WHSWqxBrmvpoAXUFlBGqYZeiEYEExEC -AAYFAkGjS4kACgkQ3bpkuiwxLS+jzwCfeziDXPZWK2KIhNEYW9XnBxfRzPsAoNXw -LWYxPgO35kBQ8KTvoJbta0HTiEYEExECAAYFAkGjS5IACgkQUI6uxTAtpWj2PgCf -buJ0M+q0RjVJFZ9FsttqXzCYr8EAn0/J280RJzAAvGARJkRztdZmkC+XiEYEExEC -AAYFAkGkL9MACgkQF2rZyNGqiWKJtgCgkf0628uDGiANtRsnVqTC2T0ZXbkAoIVp -cBe1RZIrVZ3I/d1ZM07u8Rm1iEYEExECAAYFAkGrePsACgkQzgGkfhxD2FBqPgCg -mtjV6A54A0n+cWj5QNXhNoUKLGwAn3FXjBUNPsEDliW9cWBYS6ceRF1FiJwEEwEB -AAYFAkGjTT0ACgkQms08wKmfdd2zFgQAwloFiGEZ4n+WrOMzzT9eued90SSVW42c -6JyJA+nChSaGtT50XBxXDHxWtr3rtleQn/MqnFpFdi+LMCREJzc3Og3V86M+ndj/ -6xftMyig0VW0lC8FvDu9WSso4ny3MZt2vUmOqUBH7ConCFIhjEdjS4dCuq1+RhmH -o+R7TDImU9eInAQTAQIABgUCQZmBbgAKCRAxpj2W7BQLgafeBACXLa0nkaexTqjG -EhG/kksIC3TXR6IiH4i+VcTzuMEuv+T7uDrdhZjc7jroeLWWl5XyLCASyhI6LP/3 -lrK+UdO3AnNA+PDuzVYqaC4dDMj9kdDbEzKYcrVPbKymuTVzR4l+XSgWz5kOyoDW -Nsqk6VxuK+/KdnuXdZ8K938HVBuIZYhGBBIRAgAGBQJB4sieAAoJEEzETQAR34fp -yXIAnj1YBCHiGmdN6GjkM4oTyvVRWhluAJ9yWdPGw5wrlsRtAl9WHVqnZ3iPMIhG -BBMRAgAGBQJBzqlGAAoJEME58VMjy3oqkFIAnRXkYqT6dfMckUaBZNCi+V9zi4kr -AJ9qKT38Kfs36TFRt/WxmFZLysz7D7QiUGF1bCBRdWVybmEgPGNoaXBAZm9yY2Ut -ZWxpdGUuY29tPohgBBMRAgAhAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheABQJA8Gcf -AhkBAAoJEPeIdfZCch8Au7UAlRmVWI3GpMbVSxFf1w/jj5I3S6MAnRfzZ8URA5C6 -pzb5X+WecPVrON+TiEYEEBECAAYFAkGeEXoACgkQJ0aiJIc88a3YbACgmixFO0rw -BdROgUtYIUlYBLxucQUAoOb2Ki8PKEQlMl+gpaP4qwy+3E5kiEYEEhECAAYFAkGj -AIEACgkQB2FzsZKExFI/XQCfViYZu5AcqGa3aZynBgUAd9A8ekUAn2skGwDzd3Jl -y14qCWF+qCNyyej/iEYEEhECAAYFAkG6O+EACgkQAQVmvOQTY5KaCwCfUwLt98Pq -aVgks/658RVhhlUNqLoAn2RyNQ9njp0HEc0cjeowpU5s4BumiEYEExECAAYFAkGa -iAYACgkQMJF5cimLx9AjeQCfSWiedjEzebbt7il5PXHgvJx40pwAn1bbP6iVk7yv -3nM3xKTtD1mHWzr+iEYEExECAAYFAkGaugsACgkQW5aAEOBPmomvzACfY2Jx3c5a -GKEdKJBazjboun4g97cAn3RbDFtb8MDJe5bQVQ3X/vysdAQ8iEYEExECAAYFAkGi -WNkACgkQBJfVkRK/55qh1gCfYVBinwZQBDLLWdOhFf9wYWcqEU0An0k9HWExIUFF -3uItQ+K9Z7C3NGuqiEYEExECAAYFAkGjS48ACgkQ3bpkuiwxLS9JqACgrZy8c176 -z1zxMnKVgiLZ1xjjaI4AoLeLarplmadavnMPcGhF+TXH4Q2GiEYEExECAAYFAkGj -S5gACgkQUI6uxTAtpWhjFQCeMEJH780DFHpbXWSyOvs29cYuPFgAoLmUNcUQbx0c -iinkYFD8VdeReHodiEYEExECAAYFAkGkL9IACgkQF2rZyNGqiWJ1UQCgs3YJAx0P -6pinCMhzunuIJTVBbRsAoLfF0lN2LW6Cy6mHBMIG0YB9Y0zSiEYEExECAAYFAkGr -ePUACgkQzgGkfhxD2FBueACfdLtQ1wegmW1s934n4tDQH0dfpnAAoJbdfKwLrDNC -agh6BwGF+Kd5hJKDiEYEExECAAYFAkG+MhkACgkQ6DAYSBao06uOFQCeNpMgvhNE -MqsT3UWkDBjau2vTYcgAnRp3f65Wls0+Af794qZa9TtJFnqliF4EExECAB4FAkAJ -taECGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQ94h19kJyHwD4kQCeO13BXjGC -MLvj7PxuXmav149yFccAoMb8DRP1u4pTz2aE38nKCHtO4kwGiJwEEwEBAAYFAkGj -TUIACgkQms08wKmfdd2aBgP7Bs3M4QnfAXFNf3pnWEIPhlS9JVsShwZEBe7U3saH -6vLdGUTOqxU7fT7nohhGV+XDCAHpWLBI/odavlQguZiTYQf/RHaSxdtoXUuwSpvt -NlFgYdp6ex/B2llg5Qof18LMHy1R5A9lm7M2Av+DDhi1ErYV59S59SryCU0PeREN -KoKInAQTAQIABgUCQZmBbAAKCRAxpj2W7BQLgS6bA/9Ds417wgIpgS6frkCtyKAu -otIL7JQ1Lqsbv4+CZeqi52ERxzGqryxBWx9YY58bwv+px9dOOnm33zesf4hx/IVr -nD82bnrmdA1qWqXPPfLAwYdKh98gWPnYkhH9RCrYnudCTFjNezS5+xRENQyYX1qT -UlAE+x2nffKxnLJ2845gTYhGBBIRAgAGBQJB4sihAAoJEEzETQAR34fp/cYAniEX -EYhEkx0osaS407/sVzK1CAd/AJwJW0ZL0nAyjjsqpgOM0ba3IpKxg4hGBBMRAgAG -BQJBzqlKAAoJEME58VMjy3oqDZkAn0Dulg3UtHdiI5EaABr9C5rN9lsnAJwIkeGz -T+S6kfIkuSH9/Nafyd6r97QgUGF1bCBRdWVybmEgPHBxdWVybmFAYXBhY2hlLm9y -Zz6IXgQTEQIAHgUCQPBidAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRD3iHX2 -QnIfAFiFAKCVt9mEsKqCe4o1K1HmOAT4OmdiOgCgnCr58C1CTeBYMjzgiLteqSl4 -Bx+IRgQSEQIABgUCQaMAgQAKCRAHYXOxkoTEUit6AJ9sVkHFsNXow160c1h70DYF -nMduxQCcDdNa8lNoauvnKBq6Jv7B9JBaKEWIRgQSEQIABgUCQbo74gAKCRABBWa8 -5BNjkiZQAJ45YgPe6LiBIyGPI3LFsLPPaHp62QCfc6UHkdWCgsvHg8GhjSD5wwHX -UHuIRgQTEQIABgUCQZqIBwAKCRAwkXlyKYvH0NHwAJ946lD+sO4+bWSWVG7fGtgN -f3B32wCfRTezxng6aLluB/QWspObQEpvfXiIRgQTEQIABgUCQZq6DwAKCRBbloAQ -4E+aiVMeAJ9o25E+6sOTxI4KxYfPLfHgip/QEwCeMTzPbYVlryWT2px1syjvjXkd -tEWIRgQTEQIABgUCQaJY3AAKCRAEl9WREr/nmrG8AKDGq14Su7iLDYm5Z7/4LJSU -8/MF1gCePdaPGg0vmnWonKZJApyEEuwvDJOIRgQTEQIABgUCQaNLjwAKCRDdumS6 -LDEtLzrTAJ9aq2KOnzSclCF1BBuF9tE6Ykwi7wCfWOrw/mBKr0tolIcQ5esUinIB -RkSIRgQTEQIABgUCQaNLmAAKCRBQjq7FMC2laG3NAKCkzGOfXP+ONhWD0oAvIhjN -AccyVwCeKlQjucbMdl7uEkWrf1Gya8pThu6IRgQTEQIABgUCQaQv0wAKCRAXatnI -0aqJYpemAJ9GdLeZi96/h6Jg68z2ZDeSc53g3wCeJo7A6QuCXXM/rcmfJqCEbB5A -0G2IRgQTEQIABgUCQat4+wAKCRDOAaR+HEPYUPLQAKDAMgt9qlL55JIRygMXhdiw -kJD0TQCfQlGUyCYz4I3IYVbgpWtf4uq4KDyInAQTAQEABgUCQaNNQgAKCRCazTzA -qZ913fUWA/49r5W+Y5V4RRWGWgaXd8JLAQ2yu88qZsIam35F997tRS1uqZOoEWds -6r6F9XVXwOUt2xsZSe34+jRfKWAXZdcmTyMIMTInhCcmukPCzEcRRLd3PBgIBPDM -vMgGGLKjDjjh5QZ/IpYdiVKaiY1IN92OLm6sKXh3SeXAjWlt1fK1d4icBBMBAgAG -BQJBmYFuAAoJEDGmPZbsFAuBxiQD/R9audVADYECPnTSp+YZJeB+LSDh84FGrWRm -61yKp2qGIorhhzf1zZ77QMS45Zy3hEct4Bx6/YSpieL2PPzMKhag+6LNY2W46QYN -k+d9v+ru3MMSHYoNfIqo70GOV6zad4fUMYywtYhDEalyMyPB3pP8jrmHt8m5ahws -sfJKn3fQiEYEEhECAAYFAkHiyKIACgkQTMRNABHfh+k6TQCeJk1afbGzsIN/doC0 -0HvYiHCmk7oAnRd4SefB12lqKxB7+rOETvWu5pqRiEYEExECAAYFAkHOqUoACgkQ -wTnxUyPLeirbGQCbBQL/YdNEhAR+QojUCsGLg46B89QAmQF109O9TS5Eqrn9+C5f -3bck6qbEtCBQYXVsIFF1ZXJuYSA8Y2hpcEBjb3JlbGFuZHMuY29tPoheBBMRAgAe -BQJA8GKZAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEPeIdfZCch8Ak0UAnjpl -plE4Mw3PM3j9nSHOoXrzzglPAJ42khRlgk6TMfnUTU41h1FXA51bCohGBBIRAgAG -BQJBowCBAAoJEAdhc7GShMRSXd4Anivb6tq25jFqiaoFJmqkNoi3/vdCAJ40ZK68 -cP0Q6ib2yiOWdjlmftGXXYhGBBIRAgAGBQJBujviAAoJEAEFZrzkE2OSFoAAn3Wb -daZJ0raIS5NIOQcrca8sELZdAJ9y3+9st6AXjDXSRsghu59Zg3zfQYhGBBMRAgAG -BQJBmogHAAoJEDCReXIpi8fQl3IAn24VtuU4CYAkDfSJhPRPbdwXC9oYAJ9KSvz3 -7QG2mZnimcoopCQy2g1z9YhGBBMRAgAGBQJBmroPAAoJEFuWgBDgT5qJhogAnRL0 -IF9/2Exe712BeoVWPK5eBSi2AJoDzWCbp7wr1nALbPllkqApkll2S4hGBBMRAgAG -BQJBoljcAAoJEASX1ZESv+eashwAoIwuyzeeGal/ZWkKIxBbordqIl6bAKCj4iFg -Kya4SFt/bd5ZKBzWWv16AohGBBMRAgAGBQJBo0uPAAoJEN26ZLosMS0vJroAnjeL -RzjPkxFDmABQPshdkftFzAoXAKD7qaB4eHmYqZyDZ4n4dLpukmer44hGBBMRAgAG -BQJBo0uYAAoJEFCOrsUwLaVoLuIAn2deIMzEBk9KTdIITM5cBUiPccGBAJ9PguKy -15iLmZE1EduTLoY750KnTYhGBBMRAgAGBQJBpC/TAAoJEBdq2cjRqoliyFIAn0Ar -xe90GYJrXOPsan0RbBWfrIzYAKCku4aJi4Fy9OweqRet0wzeyYzEE4hGBBMRAgAG -BQJBq3j7AAoJEM4BpH4cQ9hQD4wAoLgEBvKXRJbdgpHKAynebPFc7+xTAKDCie3Y -g9nTInyAkBR+woMlo8IP4oicBBMBAQAGBQJBo01CAAoJEJrNPMCpn3XdiXwD/1O4 -ya08P1YxIYn7owU2DFVj65++T97WO+yOvkZnPuT88anrx2lci915sXAQYZh1o4Qx -HIsterJrJB31p3iokJzQxMt6K6HMzITDdNh4mvGoNAaSNurqhIeqmk2UpuLuDe1f -gART4fCmgMxglgIlMBI6UyhP0RhzHx+qePRHxf4hiJwEEwECAAYFAkGZgW4ACgkQ -MaY9luwUC4HNuQP/cQUltjk6iJq10+NLv97/vw7+eij/z8kBwfe7przIchSoApFa -ADyVDuIMmZcSU/PbwlPRebESQrQ84q6jHqpG3ZMhvIT0EEOWmS+8Ga1FhwqXjNrY -AsNlAFa/tfUPAPTj2M7kTt3Dq4UD2xXywY9Rja3Q+khSttGqQGEq+qB6a4eIRgQS -EQIABgUCQeLIogAKCRBMxE0AEd+H6ZS7AJ94jbsCZKDncSb/JktR+O3R6XjmLQCf -W8zLP/1780h7U+SeGZRx1K2uNDqIRgQTEQIABgUCQc6pSgAKCRDBOfFTI8t6KlUH -AJwOQx8xEJeGwce+D3DtawU+uf/JdQCeIIL5AT7+oEK1IzZDN7klXB/4zii5Ag0E -QAm1shAIALfqB4jeQyzKfybVkA8PksS9yD4hmjaYIo6XaQ6GAJsgYOVcWINPzcHt -2rjQNxScSjkNApTxttpgRRVP2s8RCR9Vkn8S2t76SKm85mgmuTT3iVNjyIbtQEqQ -cpN7LDJAq2LbGIDt1fdvmhkI2gNNqnbWMsAxsJkws3r0JHsCxD8jraXKvBQ83tFT -Kqi9ZeQ1nW4dc5s1/p40OLrsq3ww23CfnP9Oxp+8rvggWyE1Rr4xb6hnYN7mSLNe -u6xlycRopG12Rkvh5QLrKNr7D/GV1j6IGTqh4aRm+z9o/1Wwxz0WkaEyN7uFbQg5 -hscBBHJBKT1Q8evrJpTEUyzA8mrBO6sAAwYH/i2ygbxLRdqgRcjgqaWCkIDwUTJ+ -c6kIQmpPH9RMMpwnbU9kcGENCjhmFVIvbcUk9xBqQgUqSq9a8zZUrwuBauNCOmVX -wruGyIXAYjlUXvxMOpTgEku6PlpKiDhmcv1Wb21dTz020ID5gpAa7s0T82VC3ciG -JmYTiQut/Dz6W1X/vKkPtQ8UEQ7LTkNOyg7ys16FpktXYq/MxAhgQ5rRLqEwIPe1 -sjClgK4Lnzh5o6ue6pa6VAd+Bwpfy9i4yh3+CEgjWjq9DyciR6x6j2de+k0hQW6k -V01gLPtduJnaPo+XWlHMonhKSlsPK10RMuVC901oLZYZSKOwMgpG5EGx2OSISQQY -EQIACQUCQAm1sgIbDAAKCRD3iHX2QnIfAJZLAKCuvcDan/KMsSsAjM/rHTf8G0AK -nQCfbbvCK0fwZcra7ofd1z1Up1+ID94= -=xYye +UrHIVDhb8JkD/pXxjf1g5pVWtCJQYXVsIFF1ZXJuYSA8Y2hpcEBmb3JjZS1lbGl0 +ZS5jb20+iGAEExECACECGwMGCwkIBwMCAxUCAwMWAgECHgECF4AFAkDwZx8CGQEA +CgkQ94h19kJyHwC7tQCVGZVYjcakxtVLEV/XD+OPkjdLowCdF/NnxREDkLqnNvlf +5Z5w9Ws435O0IFBhdWwgUXVlcm5hIDxwcXVlcm5hQGFwYWNoZS5vcmc+iF4EExEC +AB4FAkDwYnQCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQ94h19kJyHwBYhQCg +lbfZhLCqgnuKNStR5jgE+DpnYjoAoJwq+fAtQk3gWDI84Ii7XqkpeAcftCBQYXVs +IFF1ZXJuYSA8Y2hpcEBjb3JlbGFuZHMuY29tPoheBBMRAgAeBQJA8GKZAhsDBgsJ +CAcDAgMVAgMDFgIBAh4BAheAAAoJEPeIdfZCch8Ak0UAnjplplE4Mw3PM3j9nSHO +oXrzzglPAJ42khRlgk6TMfnUTU41h1FXA51bCrkCDQRACbWyEAgAt+oHiN5DLMp/ +JtWQDw+SxL3IPiGaNpgijpdpDoYAmyBg5VxYg0/Nwe3auNA3FJxKOQ0ClPG22mBF +FU/azxEJH1WSfxLa3vpIqbzmaCa5NPeJU2PIhu1ASpByk3ssMkCrYtsYgO3V92+a +GQjaA02qdtYywDGwmTCzevQkewLEPyOtpcq8FDze0VMqqL1l5DWdbh1zmzX+njQ4 +uuyrfDDbcJ+c/07Gn7yu+CBbITVGvjFvqGdg3uZIs167rGXJxGikbXZGS+HlAuso +2vsP8ZXWPogZOqHhpGb7P2j/VbDHPRaRoTI3u4VtCDmGxwEEckEpPVDx6+smlMRT +LMDyasE7qwADBgf+LbKBvEtF2qBFyOCppYKQgPBRMn5zqQhCak8f1EwynCdtT2Rw +YQ0KOGYVUi9txST3EGpCBSpKr1rzNlSvC4Fq40I6ZVfCu4bIhcBiOVRe/Ew6lOAS +S7o+WkqIOGZy/VZvbV1PPTbQgPmCkBruzRPzZULdyIYmZhOJC638PPpbVf+8qQ+1 +DxQRDstOQ07KDvKzXoWmS1dir8zECGBDmtEuoTAg97WyMKWArgufOHmjq57qlrpU +B34HCl/L2LjKHf4ISCNaOr0PJyJHrHqPZ176TSFBbqRXTWAs+124mdo+j5daUcyi +eEpKWw8rXREy5UL3TWgtlhlIo7AyCkbkQbHY5IhJBBgRAgAJBQJACbWyAhsMAAoJ +EPeIdfZCch8AlksAoK69wNqf8oyxKwCMz+sdN/wbQAqdAJ9tu8IrR/Blytruh93X +PVSnX4gP3g== +=6Rbj -----END PGP PUBLIC KEY BLOCK----- @@ -3682,7 +2850,6 @@ uid Colm MacCarthaigh <colm.maccarthaigh@heanet.ie> sub 2048g/2C7157D3 2005-07-14 -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.1 (GNU/Linux) mQGiBELW4V8RBACRZw1GIal1EKcPqtPyTAEtvtSQqv/ZLj3l9ne9kNHFgp52TyRp vV1JRwrlptNhClkBFD2/o6OAOvR2YcDvWXkoNGIlbgrsRaU9H9l7ZVFU5titPj+s @@ -3695,95 +2862,26 @@ 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 -Wq8UfA31IsLnxfIOGQ== -=95yW +9CJcQACg34GFUHLb79GWPAq1eq2Q/rkWWby0I0NvbG0gTWFjQ2FydGhhaWdoIDxj +b2xtQHN0ZGxpYi5uZXQ+iF4EExECAB4FAkLW4V8CGwMGCwkIBwMCAxUCAwMWAgEC +HgECF4AACgkQdcqio/ObN1BDlACdHWGvtR1w9KrHSUpmQNVx9REVHNUAnA31s2Si +bQsdJ216/538PMYZgPLutC9Db2xtIE1hY0NhcnRoYWlnaCA8Y29sbS5tYWNjYXJ0 +aGFpZ2hAaGVhbmV0LmllPoheBBMRAgAeBQJDIJFVAhsDBgsJCAcDAgMVAgMDFgIB +Ah4BAheAAAoJEHXKoqPzmzdQdvoAnRX9Td7jsxuJtPtZTUuSzFP8ayWOAKDPnEXH +SMWf83yGbYmYbjd1k6AVGbkCDQRC1uF9EAgAgaodPcwlIct4wWAHDxe413Bgw6/v +/kNp4Q0nbnLwQ++gsN3sCkK0O6qASsed+Ffsjhn2VEjAF03RT2T8Ir7AuA++EuWu +AphBDTZLF/ARszSnYWEz3cELsuuqj1yXl4Gc3mj61vDmST7g3iPxNbWGZNf0jinD +1ycRYd+ZSs+5yQzOt6g2VtAE8DneL4M0o+tXZXlvRl67PlrYbRIE81VYTm2C+k3e +F0PWsdDyL8lPmV6ryIjvDK/EKLGynIQN2yWASzqZQl9mJGdwHKXMNxG5R0AQc0au +Jjk47sCj8ktP8+k6MPy2y2ZGv0PtSNSogROwMvJpMpqWoMtZdmrkXuGn9wADBQf/ +QAbCM0qCv6ogLmfsyyBubl42DkB8vMgRYoY0/kQW3qKBnIsCHhuQfYRX9oV+LVtq +7vNd1NQe0HFMW3ZxOLA7e0lVPf2vJUWGG2wBWHOs2BxnS/691KUeB7NUA3Meiqai +PW5IM1+pWT5+/Ps9mJXnSHYYqaJdDHSiKeAvEYRzqGlwn1KpopIhtLZRMwio1ez5 +aNAQ6otD0vHFit3X+SCkl6+1+tvEfPTupUpbjBsG3geL3D1csPC45KsMCE7zwqAn +XiVTYCGXumFEBS6b4bfh2uM8fZP2Sy0xEP0nxzmDmK5ERs8R3rshRHFZiil/qtql +MfucZER4XxWZidEoath1xYhJBBgRAgAJBQJC1uF9AhsMAAoJEHXKoqPzmzdQTTsA +nRwKwOe+n2LgPgqAReIqMvbIHUxEAKDbuZIzxAtkWq8UfA31IsLnxfIOGQ== +=Ulbc -----END PGP PUBLIC KEY BLOCK----- @@ -3800,7 +2898,6 @@ sub 4096g/3B3BAB8F 2009-08-12 sig 311A3DE5 2009-08-12 Ruediger Pluem <rpluem@apache.org> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.5 (GNU/Linux) mQGiBEM/yAsRBACVZVt6oK9fpc9B/7vPny00aHnuhDQ0MsM5rbEGZ57aBnmHYyX0 gTKLWGBXhlkos0hxBBIc9UUbOmaVBp4VFu0rz8IQ2OUZ93J7lR/khRG3wlmYx25Z @@ -3813,184 +2910,68 @@ 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 -DBlOT12zgK3B8A== -=E5qG +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 +T12zgK3B8A== +=1cIV -----END PGP PUBLIC KEY BLOCK----- @@ -4002,7 +2983,6 @@ uid Maxime Petazzoni (Apache Software Foundation) <maxime@apach sub 1024g/EA644EE9 2003-05-08 -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.2 (GNU/Linux) mQGiBD66FGARBACW/hHKwrc3NIMstpxwopJI2h7KMr70Ecmn5i6NFOPr8I8smABx dIBNE0E07oCWKlS5mT47mio6wY46j5Q3EUmxbfZDlox7IO+R+1+s6OpLDz6QyLpW @@ -4016,101 +2996,28 @@ inL+caa8CQY/Tr2NGIR45t03h2i3zD1MrKulZz47kCZYbztSOrQ5TWF4aW1lIFBl dGF6em9uaSAoQnVsaXgub3JnKSA8bWF4aW1lLnBldGF6em9uaUBidWxpeC5vcmc+ iGcEExECACcCGwMGCwkIBwMCAxUCAwMWAgECHgECF4ACGQEFAkGOAVMFCQnvQvMA CgkQ7KsOe4Pmrg03XACePWqWwPgqWx07CfmVr/vHodYJI7YAoLIJanI8VZV4dHIB -VXZf0Kgf3VlgiEYEExECAAYFAkGFmWsACgkQCbw14+5QZGFbKQCfUVJPpvg9taHb -i3fopt+oStAtJ/0AoNrjNX3IQZVGW0A2BrcELzHWA1GSiGEEExECACECGwMGCwkI -BwMCAxUCAwMWAgECHgECF4AFAkCWj6YCGQEACgkQ7KsOe4Pmrg0dwQCZAUZX8G4U -6MBxPaN6SDXmV7AB8lwAnjjlVWgagBa+sGW//R/jNYlozb4FiEwEExECAAwFAkGT -EiQFgwcWRS8ACgkQzTD+AjVP2VIqFgCfSMoeN3UXC6tGlnDJfrJJJJ9hb8EAnRwz -xS785bagDzRQTrD72+kuukB4iEwEEhECAAwFAkG7qckFgwbtrYoACgkQlF9N1bY0 -ib0UuACgsjxfNyZkqZmfyLyLmeLaBIiR35kAn1EP8g8JnpQaatFUiWXzETr1u2EX -iEYEEhECAAYFAkJC8CQACgkQv04Nz8dVki/mbACgx35U9znQ49Mw7gEEb/PkM9SN -OXYAoL/OYqIQUqnnxjNUWdQHHqua+dDgiEwEExECAAwFAkKE3+kFgwYkd2oACgkQ -9lPLMJjT96f6ogCfXfb7Jn7PWfeT5xqOFd5jahaL/aAAoLQdE/nmBOVqvAKXNKn8 -KlwFQeKDiEYEExECAAYFAkLb2vAACgkQW5aAEOBPmoncOACdE4Sqz035hyYWfqqx -JYw+wKrB0MsAniUauUXnaedm5baA3MpLmKE14vmkiEwEEBECAAwFAkLc4GMFgwXM -dvAACgkQ94h19kJyHwBIDQCgnIhgESJ8p6OUuEqLZonnGozpJZAAnjbKeqeHuRaK -Lqtd/PSQKpjcsoLpiEYEExECAAYFAkLdBIEACgkQXP03+sx4yJPdPgCg6uOAE+5N -EK/x+AoyXSi8Y8m/v6EAn3m1F0kFeAQOQOFWz+XCXFmp49GniEwEEBECAAwFAkLj -kskFgwXFxIoACgkQhUnvgY6MdEhTDACgjLv4eCSEm68dlStlK/Ii3jrgKcoAn0lq -qZdlIaK9LA2KRIM7p3JjpdHliEwEEBECAAwFAkLkElYFgwXFRP0ACgkQbQvHOkBY -GDfyZQCeM7mtFt4c3RA2bVPmd9mxnY6k1bMAoIQbVZ1G3d7YP6oLATygKPx+689v -iEwEExECAAwFAkMOxUgFgwWakgsACgkQf7o9T+sfU2R2fACgiz19Npntlekc7KXo -eqIqfQW2EwMAoJVfMZjd5HSu+WX/DJLDGG/P38iTiEwEEBECAAwFAkMOvUcFgwWa -mgwACgkQS3OlVpbZQYk52gCfXD1k4WEozb+oDW4g8w8mPnyD43kAn1es9XXb/sOP -s2QSQpSuPQgKVjduiEYEEBECAAYFAkNM5uwACgkQF4qBnPu4WxVB8gCeMcL7DkgF -9m1IwvS5vlNJ+ZZTtrUAn3BqUvaxgXS6PrbhzqV4ca6h5xRYtCxNYXhpbWUgUGV0 -YXp6b25pIChCdWxpeC5vcmcpIDxzYW1AYnVsaXgub3JnPohkBBMRAgAkAhsDBgsJ -CAcDAgMVAgMDFgIBAh4BAheABQJBjgFXBQkJ70LzAAoJEOyrDnuD5q4NJPcAn3Ii -MneIS7QSFFqbBuWXg1CtKmfbAJwPdXZaz8/XeNwl1IRqHcuF26sVU4hGBBMRAgAG -BQJBhZluAAoJEAm8NePuUGRhVgEAnjECm7Za8pLWh986UN0dALCf6fPcAKC9JwmR -xhk4Z/Jttho6m15LqYotSIhMBBMRAgAMBQJBkxIkBYMHFkUvAAoJEM0w/gI1T9lS -pMoAnjMWb7SCcrNZWJ3eSdlSFk8ZPXcaAJ47na71eks2kL8yXB3fp2HWNOx2Rohe -BBMRAgAeBQJBhZkfAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEOyrDnuD5q4N -PA4An3CRhtEOJ6sJvjTCzSv9vCuSeCCPAJ974rjwU4SCJ/gco7XMM1SZIgvIEYhM -BBIRAgAMBQJBu6nJBYMG7a2KAAoJEJRfTdW2NIm98LcAoINh9Pw9fhCMf4tbGhKs -cS1HVNacAJ4obCxEt7Z88ptYUtrlSru9aZNO/IhGBBIRAgAGBQJCQvApAAoJEL9O -Dc/HVZIvr4oAoJWNbuFkt7K2hxNLSu8b2r80z7jpAJ9+6/MOCJ2Msvdy2y2XF8xE -9L8jZ4hMBBMRAgAMBQJChN/pBYMGJHdqAAoJEPZTyzCY0/enS0UAnREbV//LESUt -zmMSxefuLEHtk+rZAKChzgpgSVLEsKVQQh30GfQgRVWcj4hGBBMRAgAGBQJC29r0 -AAoJEFuWgBDgT5qJZIoAn3Ly8SL/FjA00L0l0gY+sjVR4oLvAKCPEw2fPgMDIRJw -mPeV+Co+W07GnohMBBARAgAMBQJC3OBjBYMFzHbwAAoJEPeIdfZCch8AFNkAn1Vt -31nqcgesRmOtfQnjQBFx5hC4AJ951q/b1oUn47FvyyJtfp+PUWuLX4hGBBMRAgAG -BQJC3QSFAAoJEFz9N/rMeMiTVA8AnAlVBaQjW+twEAbgbWqFaF6dEsGLAKDbwimF -XXTU9ZWQsDzpO8/r1fXW3ohMBBARAgAMBQJC45LJBYMFxcSKAAoJEIVJ74GOjHRI -uHAAn1+BUjTwapsuQ5xy6mOhQVR3uhuzAJ4kz7GyZTQXveowgl3wuLr+zHW3C4hM -BBARAgAMBQJC5BJWBYMFxUT9AAoJEG0LxzpAWBg3+z4AmwbyGsGW5goY5n1Y7n8l -XvRNbek6AJ0eftBgNzQ8Wyliw2zrqrCx79ZS7IhMBBMRAgAMBQJDDsVIBYMFmpIL -AAoJEH+6PU/rH1NkS6IAn30i+PkmC8Y1lrEVxZpSD/iJzcKKAJoCUkHRy6T0KJ1b -TvFORa9yOD1wrYhMBBARAgAMBQJDDr1HBYMFmpoMAAoJEEtzpVaW2UGJUOcAoKyG -1VXvxK830zLq3hnNP4DGCBc7AJ9JDp7sE9EjcgxsBlA7yYxKCHTPdIhGBBARAgAG -BQJDTObxAAoJEBeKgZz7uFsVv2MAn0jeoqWUiSYQ7HULy/30CQNOFwa0AJ0bWNrM -bnyLVOPsg2rDq1bGMGyMsrQ/TWF4aW1lIFBldGF6em9uaSAoTm92YS1tYWcub3Jn -KSA8bWF4aW1lLnBldGF6em9uaUBub3ZhLW1hZy5vcmc+iGQEMBECACQFAkHkYDAd -HSBUaGlzIGVtYWlsIG5vIGxvbmdlciBleGlzdHMACgkQ7KsOe4Pmrg2UrwCgqr4T -NWfG6S1eplFbu9rXumEgezcAnjyz2jhtfVGCCsj2Z3AgAyDl8wCJiEwEEhECAAwF -AkG7qckFgwbtrYoACgkQlF9N1bY0ib1QKQCgotl+L/SfrQrnD76obkGPzNuFqaQA -n1Mj8Wk9FNf/hAsSZzCAbV3tgbI3iF4EExECAB4FAj+NhncCGwMGCwkIBwMCAxUC -AwMWAgECHgECF4AACgkQ7KsOe4Pmrg0zuwCfSIJWxDK4Gkx7BsvaO0AZOCgapFwA -nA+oKOaDt6GlxoqAhxuUiPo0xKZwiEYEExECAAYFAkGFmW4ACgkQCbw14+5QZGER -zgCeIe3ZGHUjzz/UyQW25Yf7s9/8VBcAn2J2p0ZUHEdntWqlOTi6v3jxiVe/iEwE -ExECAAwFAkGTEiQFgwcWRS8ACgkQzTD+AjVP2VKubgCgkVieHF2C0HYExlUCR8e+ -hkJjrQUAniPb3LEwUfj3OofUfREw/I8DGLbCiGQEExECACQCGwMGCwkIBwMCAxUC -AwMWAgECHgECF4AFAkGOAVcFCQnvQvMACgkQ7KsOe4Pmrg2kHACgqrNFxaQR3e2r -jyZ9yt9HThYvbc8An1yP6cOovt1AZ5p6OdU9R8AXBf+PtDJNYXhpbWUgUGV0YXp6 -b25pIChOb3ZhLW1hZy5vcmcpIDxzYW1Abm92YS1tYWcub3JnPohkBDARAgAkBQJB -5GA/HR0gVGhpcyBlbWFpbCBubyBsb25nZXIgZXhpc3RzAAoJEOyrDnuD5q4NGJYA -niQNlo383vzVTSeUdbLew6yRsGzFAJ47Jeh7vghc8e/gdRzqYcAoQuEyaohGBBAR -AgAGBQI/k77UAAoJEO6QdfU5abv28oIAoMexl17WRE9fGmCPjeS5oCEy+gAyAKCH -hRHg53SWgJUPQ6VuDL6cwUNUzYhZBBMRAgAZBQI+uhRgBAsHAwIDFQIDAxYCAQIe -AQIXgAAKCRDsqw57g+auDVyAAJ9V0z5uUuipuRG/5YlUD91mFGonLgCdHKSWkg7d -LmcA0I2fecVd3tyCD6KIRgQTEQIABgUCQFDzaQAKCRAw/hG7Ima1Z1NmAJ9vkgu5 -88uiz+IK/Vrz7bl4/j3T6QCfR+sEvZJIK4+BF3twAOgeqj+torOIRgQTEQIABgUC -P7+2ngAKCRAXioGc+7hbFVSeAJ978TzTftJwzHQik2uipMjBC/BDjgCgh/VdE2kq -A7uycb0AmqOFEG9nzz6IRgQTEQIABgUCP325YQAKCRBfSAZpCvvNYNaTAKCAApn8 -SL3+AeBH8jT/5U1zuhf6ZQCfXAFBAuFRtlf+iml+MOFccjDUlcOIRgQTEQIABgUC -PwSSpAAKCRCrz3ACPcJ28S1jAJ9NMBTPc/16nQWrC9k8+ZL9l23zkgCgxbM23/yQ -xAZwLzxFY4M3F1OKptKITAQSEQIADAUCQbupyQWDBu2tigAKCRCUX03VtjSJvSIn -AJ9zZMfRjjsaG+mrQAT4RAZkOVqICACfc2FH/vtiAsoHPUnQDoq9f3ohgB6IRgQT -EQIABgUCQYWZbgAKCRAJvDXj7lBkYa1nAJ9NgL+MQmis6wQ69+TTXYI0tJaG7gCg -3ghKMJfGtbzNi4RxTZnqviTr49qITAQTEQIADAUCQZMSJAWDBxZFLwAKCRDNMP4C -NU/ZUucTAJ9hGzCVYM3PvY5ci+L9OkJeg3JZ9ACdHk9ajnEBXBXQiHxPrSvEkYpG -dX2IXwQTEQIAHwQLBwMCAxUCAwMWAgECHgECF4AFAkGOAVcFCQnvQvMACgkQ7KsO -e4Pmrg2KmQCfThDO0PQglZ/QyjLq8a+t2nT+p78AoJtiOntKvb3zitjuIf/9l5i/ -to9otEFNYXhpbWUgUGV0YXp6b25pIChBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlv -bikgPG1heGltZUBhcGFjaGUub3JnPohkBBMRAgAkBQJC84EGAhsDBQkJ70LzBgsJ -CAcDAgMVAgMDFgIBAh4BAheAAAoJEOyrDnuD5q4N1ZQAn3JZ4otgS3ogdgCGKFeQ -hhT0PDaPAKDFBgOlH8LdGitENSoZOWVEXSw3ZYhMBBMRAgAMBQJDDsVIBYMFmpIL -AAoJEH+6PU/rH1NkU58An3zcPhOI4SgSr/I7cGuHH4NrqKDnAJ4k2IaWtkxtYV1s -S8VcANTKSEZJDYhMBBARAgAMBQJDDr1HBYMFmpoMAAoJEEtzpVaW2UGJ3usAn2kN -ttPGuLGa65+6LJdavi9inG9LAJ4uTToi+StbM2uYMStiL/iOKyuoA7kBDQQ+uhRh -EAQA0gQ6m2hdo3t55hByLXkQTf2zficxXaW9S8gA9mePQwyqpQcDD5wCXMCmhhnb -XGdFtqs9GlRLK/VcGwkP9L8FedS/u/jtwtbE8aTI9BBE2QVGkRvEb0y38j23pCbQ -EwRdv9RrGNxAFhCDlJiHFxBAE+dabJt9YCLEUXPmqXh6FocAAwUD/1rAGpdLLsez -qBxeXYZPzefwNtxhbpEXs71sBC9+ijZnYoGFa1Acnqh3vJH1DXvLC0RDTnqWma/3 -QsHJJtH9Bfbo0M3zKWs5aaV+yu/2XPDGMiOLm1F47EfGFfb4lCWGasq1onD8zIME -W7kB+6jaDOq+qsu77eWL2kbD/FyC1aNJiEYEGBECAAYFAj66FGEACgkQ7KsOe4Pm -rg1PfwCeKe4JSyAC0hmnPn9sBOQIgsG2s28AoJ7gJ9zLdb4SquLE0vvfZeKQtLYh -=DmIO +VXZf0Kgf3VlgtCxNYXhpbWUgUGV0YXp6b25pIChCdWxpeC5vcmcpIDxzYW1AYnVs +aXgub3JnPohkBBMRAgAkAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheABQJBjgFXBQkJ +70LzAAoJEOyrDnuD5q4NJPcAn3IiMneIS7QSFFqbBuWXg1CtKmfbAJwPdXZaz8/X +eNwl1IRqHcuF26sVU7Q/TWF4aW1lIFBldGF6em9uaSAoTm92YS1tYWcub3JnKSA8 +bWF4aW1lLnBldGF6em9uaUBub3ZhLW1hZy5vcmc+iGQEMBECACQFAkHkYDAdHSBU +aGlzIGVtYWlsIG5vIGxvbmdlciBleGlzdHMACgkQ7KsOe4Pmrg2UrwCgqr4TNWfG +6S1eplFbu9rXumEgezcAnjyz2jhtfVGCCsj2Z3AgAyDl8wCJtDJNYXhpbWUgUGV0 +YXp6b25pIChOb3ZhLW1hZy5vcmcpIDxzYW1Abm92YS1tYWcub3JnPohkBDARAgAk +BQJB5GA/HR0gVGhpcyBlbWFpbCBubyBsb25nZXIgZXhpc3RzAAoJEOyrDnuD5q4N +GJYAniQNlo383vzVTSeUdbLew6yRsGzFAJ47Jeh7vghc8e/gdRzqYcAoQuEyarRB +TWF4aW1lIFBldGF6em9uaSAoQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24pIDxt +YXhpbWVAYXBhY2hlLm9yZz6IZAQTEQIAJAUCQvOBBgIbAwUJCe9C8wYLCQgHAwID +FQIDAxYCAQIeAQIXgAAKCRDsqw57g+auDdWUAJ9yWeKLYEt6IHYAhihXkIYU9Dw2 +jwCgxQYDpR/C3RorRDUqGTllRF0sN2W5AQ0EProUYRAEANIEOptoXaN7eeYQci15 +EE39s34nMV2lvUvIAPZnj0MMqqUHAw+cAlzApoYZ21xnRbarPRpUSyv1XBsJD/S/ +BXnUv7v47cLWxPGkyPQQRNkFRpEbxG9Mt/I9t6Qm0BMEXb/UaxjcQBYQg5SYhxcQ +QBPnWmybfWAixFFz5ql4ehaHAAMFA/9awBqXSy7Hs6gcXl2GT83n8DbcYW6RF7O9 +bAQvfoo2Z2KBhWtQHJ6od7yR9Q17ywtEQ056lpmv90LBySbR/QX26NDN8ylrOWml +fsrv9lzwxjIji5tReOxHxhX2+JQlhmrKtaJw/MyDBFu5Afuo2gzqvqrLu+3li9pG +w/xcgtWjSYhGBBgRAgAGBQI+uhRhAAoJEOyrDnuD5q4NT38AninuCUsgAtIZpz5/ +bATkCILBtrNvAKCe4Cfcy3W+EqrixNL732XikLS2IQ== +=X51S -----END PGP PUBLIC KEY BLOCK----- pub 1024D/40581837 2000-10-23 Key fingerprint = 4535 10BD A6C5 8556 24E0 0923 6D0B C73A 4058 1837 @@ -4118,7 +3025,6 @@ uid Nick Kew <nick@webthing.com> sub 1024g/6A4AF32A 2000-10-23 -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.2 (GNU/Linux) mQGiBDnzkd4RBADgCTgS7k/tgx1KaZ+yI5PdpA9slDq9FNGOaP9U6GXhQPDz+Vwp +DRn62/+k5Er8dN05ioycjNe2oaKRCHW29d+yXC5GeeAhovHYr+uwp1C1wkV8M2L @@ -4131,115 +3037,15 @@ xJDcBADBtiNxviA3H+x6GXc978PvyjypsESU2JNZRaCI86yyT/dj8VRwVwUPzurm eoqjkGnvhwntq6WuHPYaT5pASpiC2wU4HDu7RJcRF1uj0PnVe7QcTmljayBLZXcg PG5pY2tAd2VidGhpbmcuY29tPohXBBMRAgAXBQI585HeBQsHCgMEAxUDAgMWAgEC F4AACgkQbQvHOkBYGDdpugCfco5ZqB5qIKHYOgfIA05mgc2WXqgAoI2SRD4E9UHY -Tdx2EaqMfC9teG9TiJwEEwECAAYFAj/CgIoACgkQN+P0X+5l4yGyPgQA3psQD8uA -j2QoX2bhCLG8rLwYyJfN4eqMvHwQK3iTUDKAF6qEcfnVyXQi8Tu5OY37maq/QOpw -rHi+/50eiBVtStsqXbsHLKO2xxQGEaCSSehYMp5mQSiJmfKvyLTjlCb0BnesBWvD -kRMbiEc3F9zzOIcUTt/pPV/YEXmrICM0HPeIRgQTEQIABgUCP7ppdQAKCRDLMqEH -iMOlpYI+AJ9X3J4vcPGJrZqSMToGS5pzNYRPUACdHyrJ+Rt/ShkqVnJtaM+ONsQj -H8GIRgQTEQIABgUCP7qPYQAKCRBc/Tf6zHjIk18PAKD1JRdPczkSbx75iHqEfooy -O7FlBACeKkMmIs03OfCAOB5VW4YsF0x79E6IRgQTEQIABgUCP8exJwAKCRCkdA85 -0Ue3djCnAJ93/9aXFWDyqq4n9SjR2RW/Rcp1jgCff/eiV+vtiZwn1k324Cgqpjjc -ITOIRgQTEQIABgUCP8OH/gAKCRD6PI0mFCtQm5CrAJ4yOwyw0kjJ23CVpL/AQ5so -5f41JQCcDrDu5DPpL6sTJrUlnWB78S+14V2IRgQSEQIABgUCP7xo0QAKCRDsmT1j -Zf3N7klmAJ4t4NE/syVP1xqfN7f9c9yc0IjTagCgmOv08ypx//V3x3/2sH/Qzr4q -m66IRgQQEQIABgUCP8BknQAKCRAaCdGD/Qk8QbpcAKCZjXmmLt+vFPChYsA2VafU -TJFCzQCfYPRG2bFBd3iZntiHAqLKpTRy8DiIRgQQEQIABgUCP7+tkwAKCRCyvrxA -FSkkrwFsAJwKLTY7SnbEi4m0VLR6/JrjzBRZxQCguYUsuBvze88BDVIRX0epyK21 -RhaIRgQQEQIABgUCP7+twgAKCRDBHntHlk8x2fzLAKDgadjCownEBcSPk5zbg/Jh -/HqFPQCgok3nbkTIvD3ottYB3+RjkQaDD1+JARwEEgECAAYFAj+/xR0ACgkQBurP -qnbYPMbsLgf/foiuojq63JT4kDNAGSiBnk7NShOC9MRc4odQifQI6stCp1b0nn4h -d1o/OlBZ1TZfXW/dyW+dMxYlkiaaV/WdbHY4r/ImynGR88aLgG6YVwl1oVUbHY+w -ImAZLH/rJp4uafWtzX7/p21hVCeS9DckmR9Px23l5UPQyYZLHuI+iZdP0hhPkM0m -rwC/km8UTuJ4o7+Y0+Zwl75TcTuBe5WodeRkbnIv46cnd6WyJjlgRfz+R2e6gJlG -ysBkit62Qsl4qIKry+/F/jvy6nOJjJWNjtHTFQs5ijNHGhIagJUvytTFuNcNg3db -MBEA88D2Js2n0qwLLh1a2aq2T++sj3Jae4hGBBMRAgAGBQI/uaNIAAoJEBD6TIil -TaLfK7sAoNPyR6W2qBRLEn1usNwpKJcH9nMrAKCeLD1bpWkVXrbCJNsbRLZQcUVg -MohGBBMRAgAGBQI/uasYAAoJEKge5knOGdXGnXgAoMMltbfOC8a0jhMzzLS0c2s5 -VoGGAKC1UMyYcatFXUT4m+Of45z/+xUL1IhGBBMRAgAGBQI/vc+wAAoJEL66K4f1 -/EtC25QAoNvrYI4Gz40AHHWuSNU3GcuC98GoAJ4w9jfiVYWDftQ020FEKMzDFFdk -VohGBBIRAgAGBQI/udRNAAoJELkkUqxMkWW22kwAn2XBo4h4t1jxReXckDKhy+7r -AgqeAJ9uvifvKci3nnfkcKvy/rsGmJC+44hGBBIRAgAGBQI/wVDVAAoJEMwhMCCh -1pdZMdkAn2kkyMexCUuKCEHPoc2luhU1cuprAJ4peVxHFvyur9mBN0UQ5v2VGVnX -sohGBBMRAgAGBQI/yuaJAAoJEGhad8ruVlUOIaQAoIX9Au+wI+URjTKwADRf2uHv -EtDzAJ43TC/BwVHYDpsBu/+7Fjv4wqOY5YhGBBMRAgAGBQI/zd4FAAoJEBMuSdTk -Htx+ZCoAoKJyCqZuCf0tN/z3NBNWaPgqU4C9AJwPztLCMNJ7J9skWbndk74IdiJX -M4hGBBMRAgAGBQI/y4vVAAoJEAlaRdyhHVb7g7wAoLvvB/TarlHX/a2jm+BXFPdw -V9e7AJ9AcySdlGowiXXtEW1cCPyQ+teqnohGBBMRAgAGBQI/0M5fAAoJEGQHhtmt -v54amD0AoKdcXerf53vHCRVVjeJIdPugbM9OAJ4x8qs74w+PfZ9a+jwK7Mw9EYOt -XIiZBBIBAgAGBQI/ym90AAoJED6Pt/L4g0HZEXAD50Gfce2rIDHB4DSf5BZyL2Qt -NhbM3Qr61TlmlduTsyHWTruY1mB95nX/KPGaTiCWBqo95yrf1pcUn4rVH7Im7gyD -XF82j/QYLSH1rN9CN9ESsFBjaGzi0BoRAAlqgaAELJAoQLsl53vAAaYQiWtaybd9 -u5UNIX7xy/pmYHNpiEYEEBECAAYFAkBVneAACgkQGFXfHI9FVgaXgACgonzAibvO -s/UHFomOC1R94nKM9HcAnjmjgDH4Q/XOtpJX1Av6ZqTsJo7liEYEEhECAAYFAkAw -G0cACgkQLovQgMxpzu1GygCfYyI+cF1P8qZvscDQJwwscBktk40AnRnz6qzzAfOS -LZ9xYJ0s1IQnMGGViEYEExECAAYFAkAV0+kACgkQFT+gzXWmdpJuYwCfYxbaEOfR -JQXdRj2BlYA0rbUaQ0YAn1MIZa+mkXo2LBwJgufuNVHKfFMuiD8DBRBAX1NazLLr -Ruds9tARAn2XAJ9/ozPEegLNIXDRFHil+yEe/wz/2gCfXYXgwLrwoyeID7RIrwdc -hIORke6IRgQTEQIABgUCQY7oHgAKCRBbloAQ4E+aiTqZAJ9SiogzAQfXUoeV12aT -7PmwkqiulgCeJp8F5t6kEaBrA5yurTKX+6e5uV2IRgQQEQIABgUCP8IXWQAKCRCJ -2EyvRrJixs9uAKCHjl+/UO32mu6ikEU6gmYFMLqB3QCdH+3pfTEDcGAvStQpZzE7 -ys/vZmCIRgQQEQIABgUCQt7ToAAKCRDKaTl0gQOjfpfQAKCkkLYJL5/0yrhd045h -bIcgTN+9YQCfS64ZOAN1lh3l/SjlXLHWDzXmjlWIRgQQEQIABgUCQt9FqAAKCRBB -6gmgV5NJj7p8AKCcfGPPWrDaq3SodTopRts4Kmo8EACgjJRLCg2DHKAzise70OVN -THGYLm2IRgQQEQIABgUCQt+G2QAKCRAEYzpXfCAJQexCAJ97xbwzZhMOOXiM4aj5 -Ulzrja9nVwCdFZsZgtozofpvmZaHeEtKucxGG3qIRgQQEQIABgUCQt+SVwAKCRAB -BWa85BNjkr5mAJ9qlkrrGciNUdkcGGjfAb444/G9rgCfTVtutNz831bCqDowpSqZ -M5bAuUOIRgQQEQIABgUCQuAc7gAKCRCM43a4HNSGH39EAJ98iw5WB5CZOXHbhEPw -dUnTSVKwkwCfcWJD5Yr0bSriF9aVLChmAzi9jjCIRgQQEQIABgUCQuOlhgAKCRAE -kTRC6hujjbJoAJ9Mw8UfCDIttO0SGqaodq932IIUngCgj+E2QuHkF0TyMApSaEIO -w8NOPsKIRgQQEQIABgUCQuSFYgAKCRBhGWouMz5OhB7XAKC4J7nTmBWA6cn67C0B -vja2bxzRrwCeMAWS6xn1tBZ1vm6vP2A6WtNRWlmIRgQSEQIABgUCQt6mVwAKCRCL -lilD/CQ/PGZGAJ0RRqxeZpOhWoM2ADUfrkqTkTXk+wCfWiWHJ64H7Ubs7z58fBsi -M69wpeuIRgQTEQIABgUCQoptEwAKCRDI4/o2Nmo3W05JAJ9arsg7sN3ft5siNuGB -pnd3Q01ToQCdHjxosGdQalkXeymtXD8SjACn1x6IRgQTEQIABgUCQt6v4QAKCRD9 -b4jGIdCnG4UIAKCJOOihLbPfW+c2CrkE6nEPxQ29SQCgkBCbx+h8aMEyqJqjPWpd -QvfQofuIRgQTEQIABgUCQt66EwAKCRAyyeTONkLLSyDiAJ94yVjfasZoGZodSR/2 -kYqF4ZQEdQCgvOrzez4RP1JCHWsFTn15tUQgNh2IRgQTEQIABgUCQt7UjgAKCRDu -0eo5ImHQc6jEAJ921c05ZPfI+9uWI97wsopfW+PDFACfQ/PxEyEzeCXbYFoEUe7B -tOgp1AyIRgQTEQIABgUCQt9sXgAKCRBQjq7FMC2laOH/AKCwImpjMHoE9H7sQx7L -I+9m1PmOeQCdH4x9T3vUF4gHL8BypAse/UuLQbmIRgQTEQIABgUCQt9sYAAKCRDd -umS6LDEtLxjpAKDoV9vn0QheFsQLYuUeDF/5m20TkgCgwkSVcCDP/7m6aZ8blA/h -cAeKrJCIRgQTEQIABgUCQuDsmAAKCRDJtabs4td03wkIAKCmhOt1jrHnnknNr623 -OtngC3yhkwCeMH2xnonwIboYmyo3hzC84VHzr1SIRgQTEQIABgUCQuDs5gAKCRA3 -9o/1AVr8ilTiAKCLvPNLPVjXY8epjHhSxkRY6+HU2wCfZnVkzoW+c7NQ0G7Db5/G -rMjEgdyIRgQTEQIABgUCQuJhxQAKCRBtmI0XhzFcMY0AAJwKmpwnqrX8aDV2+t+E -uTrM4i+42wCcDiK/v3y0jmXbylU5eZ93mrealSKIRgQTEQIABgUCQuNVMwAKCRAT -LknU5B7cflj2AJ9ZTTFhGTJALO2/xVX8eVGucVbO5QCfe3mRMPaSx5nKne3TQWIR -2Pck102IRgQTEQIABgUCQuNkkgAKCRB1yqKj85s3UN2KAKCH9B6mMup+BSkf/qog -WTp+wkzt8ACfdLzMTdNnt15YpS0TEmSNrq0waweIRgQTEQIABgUCQuPrZQAKCRDy -AsuClhyUYN+TAKCQGVfmlOhNu/L67ZmneL1KA7iMXACePs6DOTSlIh0LKzGvZh0H -8jAwtR2IRgQTEQIABgUCQuPs9AAKCRAyhk5BnIUiKxpRAKCHGnESODZlUhkrPZ9G -bKZj/WKMgACfY7HDgvOuK7N9evmNB1+8dUTZnuyIRgQTEQIABgUCQuUQeAAKCRBS -eS+vmXivhsKnAJ9a1Pp8ZyZWTtryRgeRyIZ6CaG9DACeJtY83ZL2LatOpgfcLCt5 -U/F2okmIRgQTEQIABgUCQuURcgAKCRBrc6EGKmI/cllgAJ9LOwF1qeUlQplpr+mn -mlLB9JyV+gCg8d75X/XaHWMYCqBs8dh0E/0zf6GIRgQTEQIABgUCQudgyQAKCRBu -lHWUwVJDGoW3AKCvlrR3dxaHHPAa3Gxae3NTu9/j+ACdG66gH2TAfa9qSx/E+9Df -H0pdIseInAQTAQIABgUCQt6sNQAKCRAxpj2W7BQLgUYIBACQv85g415QDF40KBaq -b+3GMOtrHq0gbhG/xq8EfVq2NN+W4jRBgpDIdj17zgTgDy1Xby/04UK+7CMNhAFA -li5QXPQgO+iKgmV3Dvdzml9P+IGGb7CjU7/oANNfJoCwFUeZanizFzZepTkyci9x -H5OHcfe4Lhiq18wCmlb4nkG7wYicBBMBAgAGBQJC32xcAAoJEJrNPMCpn3XdRfoD -/i0tYfOTUwa3OQ8hj9RUx9KTYJe/M0vGuyuNxEWdRB5R6AUolIeboIunb5auAbRb -ubrVbXjRkvJS5wCqOO7WyL49w9G4BVAO0Uw+QptION+UdpV9ZfXHd+nsgDuiRkVM -yhX0336SoD57RyiT5rglKpKOCb7l4e12S0dVr15PXc7IiQEcBBMBAgAGBQJC/ToO -AAoJEFwyh8czExtlBa4H/jj+/4NJgM7ciC0A45ySTdJZY+DYFJyRCu5bCPkcYS6A -3PKInXc8RgFykWfz0X57UtobvH+s0O+Gyg6ArSErEHXsCZGYlHPpcACgFLiLS7yE -gEpzDLClmSIMmb7kRGr9LX5RyQhAPAjszlIk9jPdcn3jkTtvr+oHrVLmTy8tcW3u -d9G8oD7PCZAeD2P8XA2eHiY+9/oPu5y/cJKLYl3J+gL6Ptk7jngft3hwr/6X/dAc -bE9h09ZS9ZRmf28NiCEBJ6meswMA8C2ocJLmW+7X2Cctfo2LIPpvI0uKzvAeh+Hl -/97HmmyArknk8qEFYHNh5sI7yT8okbuZ5daI0Ibp1NKIRgQTEQIABgUCQv04lgAK -CRB+iDZMgoRJhB28AJ4wWlHXGXU73JYV3b/A5l0gdVF+qwCeKkLJspvZ+BF2cV3u -4FKwIeq4FaqIRQQSEQIABgUCQuE1ugAKCRCiEVrhX2uLchEGAJUSSguS2p3XVs6l -3ssMx/Cm11RoAJ4hazOLz9zi9bkkZe4Jsnj8t8dkPIhGBBARAgAGBQJDJH2xAAoJ -EPwPhYn4lL4SDsgAniHK2LhZ+mFApRlM1EHt1XwuZic7AJ9DK42czJ0hWYRJuUge -gH1hRJM3l7kBDQQ585IFEAQAqsJfRx6LMF9sBtHmNf83j1V2SCVv4NK8OoPcKWBg -MKQxnDkpWD7DdV69p6azP6N/ENfmK8qsSiXHUUEwOS2UMct7T3Tqi5f/EAVSgw4T -rTC9dgpafTUpU5A8MW7h+Psm0XDwmwlqREUvyK2gqnpVaMXhZIVU71yTeXxy/3Vs -7ysAAwUD/iJg+Bc0iZ7LNnW1xZuvc4/6LOEGelQpmM5SPr+gG6DHXhR+TrUMDt7R -e+WkPGS8yqqxZ/4JefF5X6KgQwDadfQAYldFwW0XakOBCP17yK3aJsYtdaxTyx5e -R0LuGbxVdMz3u/UtY1Txn72wlEEqnPhNokbvAI50jyc71TTXWKaviEYEGBECAAYF -AjnzkgUACgkQbQvHOkBYGDcHiwCeNV4G2NP0SvG75RaqmYvnvbyC1xUAn1qF30A0 -W/Kdk2iuwPLJw9rN5PFA -=WPl7 +Tdx2EaqMfC9teG9TuQENBDnzkgUQBACqwl9HHoswX2wG0eY1/zePVXZIJW/g0rw6 +g9wpYGAwpDGcOSlYPsN1Xr2nprM/o38Q1+YryqxKJcdRQTA5LZQxy3tPdOqLl/8Q +BVKDDhOtML12Clp9NSlTkDwxbuH4+ybRcPCbCWpERS/IraCqelVoxeFkhVTvXJN5 +fHL/dWzvKwADBQP+ImD4FzSJnss2dbXFm69zj/os4QZ6VCmYzlI+v6AboMdeFH5O +tQwO3tF75aQ8ZLzKqrFn/gl58XlfoqBDANp19ABiV0XBbRdqQ4EI/XvIrdomxi11 +rFPLHl5HQu4ZvFV0zPe79S1jVPGfvbCUQSqc+E2iRu8AjnSPJzvVNNdYpq+IRgQY +EQIABgUCOfOSBQAKCRBtC8c6QFgYNweLAJ41XgbY0/RK8bvlFqqZi+e9vILXFQCf +WoXfQDRb8p2TaK7A8snD2s3k8UA= +=51LJ -----END PGP PUBLIC KEY BLOCK----- pub 4096R/F51BB88A 2009-11-04 [expires: 2016-02-17] Key fingerprint = FC5A 6FC6 2E25 2DFD 8007 EE23 9BB8 63B0 F51B B88A @@ -4409,8 +3215,6 @@ sub 4096R/632F5ABD 2012-06-18 [expires: 2016-02-17] sig F51BB88A 2013-02-17 Sander Temme <sander@temme.net> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG/MacGPG2 v2.0.17 (Darwin) -Comment: GPGTools - http://gpgtools.org mQINBErx+bIBEADFBcP1jJ1LFue4GUVlmDbqG6fbdE+jYG3ITo/EXLcGfjfOyR7D vkdXOXFJ1uzo7NHjleVuu5V+XKrsK1ZIFq07c9eGcqByOC9FOzAZFkC46iuoDM8w @@ -4423,818 +3227,196 @@ mb64TVNvjB5AG02S1yaRWz73kRJ/vhNnKOZbUab+bYlzkb9ae+rCYg8YTif1CKSX 03PuTs/ccJtmZFfj6xNIcooKs1YY4BvWhFMrjtuAOcXlSmgbooV55sJKbWTPmdLX 5jZrhs620II6fZ8wNBmb0+97IxC9SzRh+cfe1JPM6W1extE8j+HXnXovsk5FHKhi BQwLiLE/BZIDvSOj1cggqVvoWaoKiwbNNbGGm9HO5g/+ysonTg84SDs6lQARAQAB -tB9TYW5kZXIgVGVtbWUgPHNhbmRlckB0ZW1tZS5uZXQ+iEYEEBECAAYFAkrx/JkA -CgkQsr68QBUpJK+7/gCgp9v0Jbz4vP0GKZcNPhqJs7MuP0wAni/6duAbG+RPP/2e -rBXBuDpq1qgiiQIcBBABAgAGBQJLPcnoAAoJEO04c/XTJici+H8QAKt02h69emh6 -ILw95dehF9oCggNwrl2W4JS8vwMNe9v0edroDCknPYtK+5UsikW3d7vGBuHGVFKD -UDyWxvmT1v5CcJQHGoGLNzQzc3nplPHbFbYdzuxkmJ4aVBeX6WqQ9y6c4e6uQB0t -APzNvdGW6Oajg/sunMJKeO+m9IROq0alK3DFw9ilVJVpHXmfK29MIj+j+KTOO/CM -nGrfl50mzRV62qhzV/Kud50qpZSvI3rBP9p1oz9/DAbpsbC2/Zh31+FEXblrE7J5 -TxBedJJqCyDf9pvFi+Xqx2vivxpgx79SjotDx02o+GFka1UWSdKQNg0Vo5vXV486 -o+yTwgZyI89FwvuRaBwEcfA++tTcDbrpaiFd1sABvZuWwDhBt2Oe1uTaUg+0m5He -20+snyk5nrH7+5cF0r3ocHxsALCNLh+51K+0NIyPLF3VcrYMSaPEdHGbYcAEaDiy -J0EUR8jj9h/TEF+Yf2Czo5sOLV8+C/CEaHpuj4JCzOilHGGEjGUmeaiagQs6Oj+1 -KcY4ILYnM0MaGqa2p64pTasUDYnCMySZKihdqTTwYLmmCMlSdTiS9kFx9qhUoscb -Z66FameAzqyfUDezjpExkB4TQLk4eeUPnDnhH9gkXXVBPBJbiBlUW+1ljscCVINS -kx3Ozmtl2uqn65zPCq0BxzA/c9cJcboJiQIcBBABCgAGBQJLJUYvAAoJEDF8bfg8 -dwXPtUQP/2+nqnjP9eQqI90eCUgDF11nSzPhq/3kGBEgdELRNOkhwr8qfnt+dCA8 -2zayHFy2fdwhpCeqO8Xrz6ByBgmolDKuZm6BZvEEBvQjae8nTU6ZWfR19iYUIFA3 -1oXLR+a2soTr0bYF2JSn80gyfALjbqStkR5abHmrbMtAXKdoG6DTBkIVBpjpODN7 -qLVrTi37zxVzqDdBMm2gAZUczsELB+Tf+2dCHIukIFNZrG4B6ttQrv4J3qPfp7A2 -yqYNXMYQwNK4RZ69uzDFKHLzIoJrBDkABU/JibSr6/+1Lp+CzUqYU0EGAiyhdOdO -1LK1WsyI0Q7BOXNFU2XEijtfFjcHeDoiehKB+5U44meWf/ShTz7XnBUTvhfWrDT2 -L8G0F9XOSU6L/Yu0KxNiaUHX8GCTBuHERj/iiGX4REL1QAdzdJVygeBJHHOJubqC -8DwKo9mQFfox9jJPDwlcHUix8qf4PCB+RhbrykGLZR7FWJhDEMFC3MXlkZLOqisj -rfU+tGdDvz6uvHa3zwrYzN7u3q6ontDRkckTNxYCI5TsYazqNwQnsBgd1eZY0Veo -etjfN3cdGR3sGtLICvHWjm2rqV6586Z3LTLOo0+zPKcV0QXMdo1UPgLHuSwycCLr -vH9ogos6w+RZKQ/2Zn+PNadik4AlGsJn5NAzeYbLLAfvSr7YjiwqiQQcBBABCAAG -BQJLFDXNAAoJEIqviNbYTkGuE/0f/0vnfSfYJE5URq0UR7zGmZuY6MQDEe5nHdrT -j+5tWeatSQTOI8lNHlkUPSRuRv4caN6fBZw5mM7xbUhz6u0tqbO26euazAQVp2fC -NQcBPWbEHLoxJF0ZkEDctVtYoshajtr9tdFxv/4p6HIsfIf0l4aoQBsdS8jxxJOS -kN1ZrtYyBMz732OxvScwgd/rKphMLu65iT8YiQyPEVBd9glDVlASa10QOhQyyTcJ -mfdkGzbYxAI8u5qFDhtWVPP1wSbJ53DGPjkmtG4J57bJtaxcz019bVK9LoY8Jemi -J0t5Tu5GJZBLxO/0wfGAdb7c0ggws4yIwqARnKxLKJC4dbUVQlE34W9Ql59s3drJ -uy6inOLr92D4iyKwuMkWvJtmrhwTgUcEam4giXsOGYQIWyHGheTHdwVN7XJfjUgd -dCVvdjc5tJvA6zrXNhVm1SZM63SwvZ27zY8SgJz3nl89hT+iEaLE9Fp7+YqzdOXf -kfm5Vp/y2y1qNNJ8nFn9gSHMBidHDwN/B1lGn5KBc3p34Iw047q+o+qi4YOV4VEq -fHzwOTXD9vADvllRM1y19i22fUj0ke5tT6OX9djHfqzFQvUo0XAHXEL54lvAqoMQ -11JYreYMKULtI4wE+CGqte4G2Bw1yCzyD5m6FIUlBFwcmJhnhkdjDr/dzOBaFtzG -27zsd6GlQoPfDCjuE7/3/5nolpRzxrOWzBP0O4AiGOPnnmcRJtmDdDgx/QOuX5t5 -kazagZPkiUr0BFODjskJdFF5ojTx2n2cw3WsaU/55dQxSYVR3LKHLPI6Cu/CmAIV -7mAJPe2pzJvWsH4xjuaFUTRBsBvBuRxsKeoVCc5RvEizqZS4x2SdziKGZi/SgILH -GuYDwVRbZJRs7cYNkeQFeqZegj9SzkgITJsWa5ZgoCKZasSW6t+Z9i0fFZWPYzsa -NdwcH12wPS5ZN4ToVwcjkfMv24zrE6Y/SPHLYYeDvNzbIjbCSxmarYlbwX36mEpZ -CfwaGWCQ14hDKKgiRuICgsOMWJMeocZHQZnTN6EBv4b8TqHHh4Ux1HOnkC1B5V/5 -MjVsyWvqxRq7i74bk9sm6ZfvqFNHmm0jc/t50x4so5CHqD8KUXmDRf9myFj27tWl -Br59qdnftjk3bXBtplmWagkOrG9SE/eqb40BzqkBxFirCByFnGTkdvhxZTtbJTWd -7KBR/f+SEij1P+CTf8iXzj1aDGzYS1O65D9OJRt3YNLLxZWD4sI+Y4ggF1ZbKQYf -/3NMfWrJvc6Q7HDTPr6D/C5VSb2D0ycZx9ZEbbMiLYYhAbF5di0Mg1d8LY8NlZvo -nkDd0PrwMjJKUGdlG/IXm+yUOs7ugTxssf/Rml7+Jlpa+Rbju2OIRgQQEQIABgUC -S6J7ZwAKCRCGC77m0fmVkKppAJ9ZetTyKSx0sBhWwccZAAmRrS8hSgCgqyFAGP/v -B2RpQA9XtWaYdcc166WJAhwEEAECAAYFAktfZQQACgkQGT8YCrVdmXdQCg//VL7e -PcPmYCOCu+Zka9xeFZzgV/l0/grgC36IuicZVCa93lj3gmtvTnbm3Fh83avsB5tZ -DnWujFu3SfqqqRz1VWSwcGdobpQooL+LH9p6jXNkQLVfWKI4giNLzPCP7imWpjy3 -v3x5cRAKGQ9xuTARqTvG5ZZBaeoBOP4bVsZ3CS2LnvfZLq5z4/D3wSLGKsBvsJcX -b8eoxkqpWVFlIl5LCziA7Eqs7hKNSKhryyvbfjVYROOyNOqhKQJlyg2Z2hfVdn8g -EGJ5e9qL9vSNJA46GIpnx7hf/1WXdVyohkAWbKIJdjUDfy6/c+hAovKwONacY92u -7Ly4TyyZHOj4D4wF2q3LJCGAXhp6DlOW8qDSfOUOszT4MAR2l2HyUniP+p21yc84 -cC2OMyFGtLPeInlO6xt2rXFlsfLqv9sdG2Bx+yS2qVa1+KSCmMvnLGPI3u9jT46/ -UtjrnV+HfdH5BiFzfSMLnILTgUAlsg/XeyaZtQt2BAnAZLASD7G8yawoW7elIOFD -kWoSpA3S8Nu0QZt8VaeXsHW59W+1myojN2FPab2NiGlfCiWtWCtjH/ihYcIrkCLf -14WLOaTCz7rSxKlMMwZXvwHXBHr+tGDHkmqLJwYtsS/IEUYqw4M6lU3dSMXBu02o -Yzfx0bWntoTsjgFlcFU9OPhNFceyhvnGqKl7eEyJAhwEEAECAAYFAktfdS4ACgkQ -VWu/8D8KBLYvihAAru3HWQkjUn0XZzsR9fOFU9Zq3OMdq5NyCnSrtVQPLhhJV9Bl -euoMk8Y1zsyHljQ4OClWUXV6bFso+a13BmeieRvh0GhRBKY8HldaBaFsIuooPyap -NOSwoBVsdXREXpecTIhfVgR42rms+GJNvmCDbQnbFLAH5UvR+jLLMoDzEJkCSf+d -S63FkItHNzbuAsdf76Ggtk9el9N0bFBSt4fKPr8l6sA1PhyPbHiSL30Lie5Lga0P -Si51YBJPZbH/0Br55Z3pzq5vqTam8RtLl/zN02mD9vSu7Vm1Wi7mYwqgFbTlYG/5 -t1YASu7ovHDui4I503f2+yTkGYcps+DXnLUfceBwUy1u7NgPuOoiotYQKwx6zLJO -QuDX5upj/ZdQJ6xim6f5g7wOwikEnGFAh7Z0W/q2/lVxwXqQf7xqQLUkDym3Aje9 -519rEmm3/2vM23E9ZkDwVMZjM4U9619y64YwigjEteQ9cvyXXmkL19x3Alxzurwj -CJnhM3FnFF2ISzsWbVFvbfP7DE8QVzjiflsUD3IqhIyBBtaRQRL5p7fOrRUGnKM0 -/dmUbSPj1Hb95yB1mDBdwP0T/pXaDxD89D1pxSaPpQAHnvpQoCICQT241SCh+60i -g2GFQXcXdKa+Tdd9ggKeh8i0tffTt69FRZQ5eorS4MOVUaEgTWzPhBkvk0CJAhwE -EAEKAAYFAktfZUwACgkQUz3vFV17vFpDtw/+P3CRrcBDZs/VHYPrs70dkUp7KC/C -GKOD0jLOe455FUpk6LQTwH9rwtk+2F8gfY+i5j9+aHqj1U19p5kpU6sOnv0UXUhg -YgX+rbIj8eSPPhTnj9pP43W8tfdt1bhT655t5VXGdzElNuV0SPLSl6WkREH3GsIZ -YQSVSOqfcbj15+eWZWD6VdOkvCxOVvGGCbx3JDx9yVgCWpwp0zcO0EeyJYTCcOJg -7Phpcekt+ek6S65vUYVt78ggdLXmrfiMIOCzc7BtECmHHBpUNlCLMSD9Ms68sbUt -miHysFQbo4YHLHw97B3qvU4xGhn0lFOrBQBOjv3NXcbGGjvjqWHhtWVq8Fzv5RCm -UkGz/qosxAgWD1rVGdOUIFX5m8IFAy77/C+OI2gdUebzsxcvAJpfWrl7fMVu0aim -Q7kT8w2IQsSPw0Y1Uz0vtWQyZQDyEK2YMBqWuuVGA0d+DWa9DRKEDbUTFfnzoejh -ep+5hIj76fIyDfF3h2SRTfFrsu1luZAyIsuxsryuH5xPH7mxlnNbSStHe9JUTFm5 -DG92Ls62jnxcxVwL3gFPr7jjCazz7sI1sd50OY/TydXflwn6qLy+TT3WODTjfzEi -vzyqutiEtJDJtXZd7XHztpK1/2I+mLBaHGB5jHg+SV2zilRix1Ud35RTs+HL6J5r -/0p9bamIRQm5HsuJAhwEEAEKAAYFAkx2khwACgkQ4TYIihgkvcFD1A/9FYpfwTQX -gFjolMgWbfYCUsp//8CRX1P8r4ttw7u8kkEe4IYpObasVoZzaJZD+89n6/1Kx4uB -ozPhwmoEYsBAsLtTKMEt0T0U7/ZDD4c4ZhNYVSTbQawn/pcf4jSy919tzMeqHfrM -0IFwARK24C02BOrRzboiJU+1pXGaL8ivbEv66IC/aNC5B5lqN20bX/imXaj4KKiO -i9Z8NnWHH+5UTGVIX+f8y1ADkGzs8SxkLl4Bc4AJUa0yDKoy2OpYc+0KOYRjTfdy -YhcVfdQbd6xDujArpzBnDP1nzHAXdUae+sMr8X0sUEo+8Izoku4Dj/J2SyqQ1tt2 -I40z6cfgOsn36bQUdouBEPm5PL/92sCI95O4ZB8LUJxKySI+AHgxqm4WMMy6FZ3x -HOyH84+cc340CRNPMUcr85eTrCPnbafId8W4/P7RWHNJRtItmO3tZC82OgujqLd9 -Z5VbsAGgK7E4Q7JaM1bRoCw8C+gSpkSUoVyVWzs1e4FO9UMkJUE4ExOQ3ZEQhybp -X/fSSrjX5Lz54MUCWKS6ADiQ9PgmmARtGWxIcnkHnAEQy0Ref8EfMtvqsgTnu9gI -dOObLMPn0a434kppMPK7JCUG5R6xc95sUexyZGDTDSynJYhGwmWX10iWz7jrdpup -k1LipcVzSi5LmE/efcGJFo4UfeOcfh+wD+2IRgQQEQIABgUCTNsu6wAKCRAbSHfp -sWaSh8siAJ91oX1vi7kLBJ98UWMKbVKSJL5CbgCcD380dJQuYlUYmtBcVAZNKhh/ -1emIdQQQEQIANQUCTOJSoi4cSmVhbi1TZWJhc3RpZW4gRGVsZmlubyA8anNkZWxm -aW5vQGFwYWNoZS5vcmc+AAoJEKR9Hi3QHg4YANYAoJjhPnn2X9aUeepb6HzKkP2R -EJTOAJwMqNSRlUdSQUBfUC93xCAS6sUJFYjKBBARAgCKBQJM0rRDHxxKaW0gSmFn -aWVsc2tpIDxqaW1AYXBhY2hlLm9yZz4gHEppbSBKYWdpZWxza2kgPGppbUBqYWd1 -TkVULmNvbT4fHEppbSBKYWdpZWxza2kgPGppbUBqaW1qYWcuY29tPiIcSmltIEph -Z2llbHNraSA8amltakBjb3ZhbGVudC5uZXQ+AAoJEIs6YB8IyXXlWaQAn1tiQjM4 -MyZA2v4GlT2Te9p05dSTAKCRpuwROcbdZlTLygOhH9j0/1lXXYkCHAQQAQoABgUC -TNK09wAKCRCCeB3kbVlU+gW/D/9Utj7lCI9FR3vViba7MUi3QrP+mIIm9lIS6bR1 -HuhYT8XUDB4QSgPvSsvjz5Z9Iv1w0nAjFJsWUSyLPCuPCpD+v69yUTHhI8r7Td4h -62DcFPW4OcUzhtLjO8lngxRcFOtnJGHsrDwOFCUsPi/S/8yixxBnIyFmCya3O7k+ -GIVk3J1ULeFxl/6LuVOFnFsoqRdIlQF6H/LhZFqTR8ZvdeUISpZ0jVIwqBW8aHaf -VLDtup9UeIK2mHALxGmlT+yt5bH9xHSaLi0hT7HKig1P7AiELZplJy+e5DiosLmc -4ajiIhCs1C+AZPU8LY3trFATpf6vStMnNOOcbRFEaTZpGNWTmHIDtdXOGGPzD/6i -u0klzQk1UCzxQfGpdsMfR0UAkQfaKcQ0pfG8JKs1zpw2PMtx7u4qjzlraiEem0/g -YJ2lbuYZ5gJ1VFN2PnTjQae/vmxDpX1nZDluuvPRFZNt/eGBrOOOSSwTQW8z4Qqb -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 -pZL2wS2f4Ng9CNDkLIRW3AoeGV1ZIEdmQ6IqAtqFHTgI+oeaKksLbbGOS9TjG0kj -58V+TcFS6Myf2FT/8Oa5Zd/vrJZBb8TT2YveuYoa1oheoRCW7t0i/olsVMchK/vD -gJNAHr/985AHi+wbIal/vH28SMy3z/eTSCec339E3N7XFHSzipaUD8FNQy7runfo -zLgd/l2/omPBfLEjZhSzGZSpcnL9xlHr2M7iTVLiYBgGV0gXVT2V6f3jYfHUtBbK -neu7T50SBXX5I6r5YlEnjY7KSbOm4ixNkPRj+ExGMyOg+akcZvNBPinuO5I0XbfG -YQx+XqN3oD/3c28dGbL0EXUI/zb8yG6MAfbZL9vmm7bBCB1gExAcLi/FHcEd4gj1 -sInQD12QSZxJHpxv+ctJPDN77RG90fqqfoibsxGHX7tOwQebspaDK5DSU3BrzeDB -0flWBIZCC8aabQbUfykvRg3U9eopt+6Ny14GOrg1++WRttTnHASiCLkPm9iIRgQQ -EQIABgUCTNsu6wAKCRAbSHfpsWaSh/1fAKCFCR55YV97JMNHT4Ezwe15hIq0kQCf -WFcpcUyo4ZpWZ6Kh15b5rnxpmzWIdQQQEQIANQUCTOJSoi4cSmVhbi1TZWJhc3Rp -ZW4gRGVsZmlubyA8anNkZWxmaW5vQGFwYWNoZS5vcmc+AAoJEKR9Hi3QHg4YANYA -oJjhPnn2X9aUeepb6HzKkP2REJTOAJwMqNSRlUdSQUBfUC93xCAS6sUJFYjKBBAR -AgCKBQJM0rRDHxxKaW0gSmFnaWVsc2tpIDxqaW1AYXBhY2hlLm9yZz4gHEppbSBK -YWdpZWxza2kgPGppbUBqYWd1TkVULmNvbT4fHEppbSBKYWdpZWxza2kgPGppbUBq -aW1qYWcuY29tPiIcSmltIEphZ2llbHNraSA8amltakBjb3ZhbGVudC5uZXQ+AAoJ -EIs6YB8IyXXlWaQAn1tiQjM4MyZA2v4GlT2Te9p05dSTAKCRpuwROcbdZlTLygOh -H9j0/1lXXYkCHAQQAQoABgUCTNK09wAKCRCCeB3kbVlU+pNdD/9BM8Oi/xVaeuux -DQ2Mf4Smv55ZTI1D4EC/BA/I5ctWkxm/xwEdJ2Hcd0Q6aPTNQlJuhzbnwRmRU65j -osF+NiK4lI0EfV55KP+HEO85v3IrjiO9H0xoV5/L7NDKHaPMEXP7RKMiiw3Ogful -u3SvzH6ZiOZ4ZvvkkFpMsiKJaeKIey0S8IW+CHDdFbbnmNbhsIyPv9XgHDii94gv -LbgtL/RaKEV4Av3wpYuCd8GlyOmiJlGZ8Z4PNwpRmTB5h5DJGPzDq1jPlBf/9avL -ukhgHWqFmGjpbRRl35mL/d7LbAramuSYoZREiP1CMLPbKMWxaYuT4f1Q6z0ykTNa -8zVQfeP40V/L4QtmNrkfgQxKY6TRByckBupsq9p8AJUZj6tj2csXPCm0REyBzkoG -ZcH/3PV2sCa/PAd/v+uJCT+mYwNdUvHImrG0gcwqgj4laewxB8QUrl6ghFWNsjvL -rcZxAX1qBvPftM4Mg1QihVSPOl9HM3kck632Y5DKAxgS9aqXk6Z/hvQ+i2L4PGKN -U+ubhpClk7J4aaLLr3B3vyTmg7vZb/el/fHyJZ5O5qh5d9XyuTjINSdSisMdTf57 -UldOjJlnCg4ij3Y765P5EoTEIa+5DLh3sHiX6VM3kHQAdJ8Fzg1dslxqhcmPVvLC -p9L8UJcqrYqMgSN6ExYP/rAq7gx8k4kCHAQQAQoABgUCTRxM4AAKCRA/z1Kf8vJ6 -Bu11D/0cu/nu3LDNyiyDSPKd9PTkds6o3Oa26eqHTZ9CEgjdJktqbZ6qIGaovcD7 -oawiHcBWC3GY5ZhV70JCE2gufOgBEz7pQGMqNOM5WiUowznwbJIJnl75KbHC+6S7 -T801HGkOdYY2Zs8zLPGJ/wzK2oYGqWgiQrlKUyMBGkN3bFPPPAJ4fhZhkY3Qwyz8 -j+D+CF0QGWlnHtgMef9mN5TSxtJoVRDZnK9voxvW0fP9Ro2z1fLzBc9zcvjTVYk3 -2c/wKSFto/ANgqmlHo4SSuDNoCqN8VRVuF4QBpdc9Hf/LAJFq5eKMRWWB3ABVEBF -2WygXtDGsFBb1P0raXJAC4RkmlbRqp5KiTnYATlQ6d60ApCIT+Z8LewrREbcmJyM -5MAH3pVPd+OhtTnSXNSHXfGak5E7LSkCnchV+NoaHPXHy0tXC3O3d8bkWk53RsjE -OCtCFWPcRVdWauNQE78SqP0VZqeLl7PDzMe6MFV+kB5ELg+LR7UtLgSbQCmJXpOe -2TDPl6on7Q2kOvT22nUQLfuaoXvwTgW3NgIlizHSkiYc+N/iofTFfJbv+scZj7Km -PnqrBpMx2sdxDrYowTvCd/0gsgofH6wI1Grd8YhBMuzIZ5qDqHNvXS6P8ClhzZQt -TmYBKa5C5/2deSmOwRptlVWL95mhYNvHabGmIpdZkOlbtSRmOokCUgQQAQIAPAUC -TNLNqTUcVGhvbWFzIER1ZHppYWsgKENPREUgU0lHTklORyBLRVkpIDx0b21kekBh -cGFjaGUub3JnPgAKCRDqTcrcTcqoj+ksD/97lFmqIfbJKNxGSACbAoR/CmKLEy8b -HLWpPcm0e95PDKC8byDDab6McADwsECHZaKgHizynRn1OcmBSHVrcA8eHwwBHqxV -71Ocu5M6IhQ2nU1aW7V2+d028XiKich++KUDqtzighIjvOYTBtuFAl33vdggAY1P -El57UsPWy8PxNjJW0i1VMaGboOw1lnoCgxN99VkuaKrEefL2p9xUp+yBZItEKJEu -SpQkbNp8ANkHAhbjJrmA5shYIDTlsVqGADMt44cw0ugiQtqDwWjo/bXwZzoFWcC9 -a8Z55bj4w+atrPzCUsOuKpqHq0DU5+SnvTHLzXoreKfdRq+uNvfczRjx1AZlft1h -mr0m0Y0yw+oktNRLbZzXUAJC5P+PDkKOmb82r0dFtF9uea2kX1gsCEP55dUnKk1E -go/gm68vlxLP1VnaLPRgLpKPW/mUsnuTY/7tmGzj2XUhAqwJWVv5rhS5/UaqucgH -9nXnaZIrvLS9SWu3LzZ5SLXKPw1ir9YZC1pTPrtd6nXPnJEffNbuhKH8/3A3UIt3 -NVEN9oBxmJiof9jRBWKyf1DSU13aP/wGmCCOiU7gN1I+BLMM3ZqP0WF0Mb6Y4mR6 -cAFHY+Ug/UjLX21okPE6djKG1B7UeGSUwJGcof6PU67dxaJfUmk47+DIQoOb8aP2 -whFZ197D7CitG4kCWgQQAQIARAUCTNK42j0cQW50b2luZSBMZXZ5LUxhbWJlcnQg -KENPREUgU0lHTklORyBLRVkpIDxhbnRvaW5lQGFwYWNoZS5vcmc+AAoJEF762f6C -p/vNNX4QANyh0StE9iY6zxHOB2/fkK93itUVxQx5VsZ7/FkWs1Um01gRaDJ3so2V -YtGJoH6wFGKy29VWj2zNLhDv7VUUnosBuasnZXgcjXCW6OgEg+t/fnuNXAHXLEIa -qZsZwYgx80rJEMIAW2NEhxydzAj3m1gOf5urOqPpyDKcyB1VA3AVKa/08K6aS2Aa -2xIZqt0ghGj3NVPBgRhkB+MHXmZypmbhRVZZn6bWXs0lhYdmBruljW2u5fgHJIS7 -Jdl5yvz3DaF9MizzaHvYBDWC3w1hbdE95cTWhPp8dRsp0sbJAzPHf3BgkaAP08e/ -v4txUmqlSw4JfxFecWt0JV64qT2tKotVQrqIeMOgimPJ9ovhfqOlAKBvzJCBZ6T8 -d9bcs/xThqCSMPaQCh+PiN9T7/h8xxfG7+gfGP5fwOOCEOVkKFi+9xMXye1vx4A2 -qWh1ScALs92GvhMwy1PYoLfjfsEgeYvRGtAX2TMKkyOsHQMqDGOdRxb6yFeBMZPQ -D6SQaNHOt6l2gIqstnTy9Vk+I9MUT3ynmSX/rkF7YVdPkDJP6kUAsxI3rACZrZz8 -gN0SIH8/3+WaT39+OQXVLleP/BbkKBtxnopi5De72CTG1ocwJZz00ZvZdi1/DvEl -Ls7ia/5IyNEviCw7m2EQdvLSSzl2/Py3pYz1/rfmQkC39FOQ1neOiQJdBBABAgBH -BQJM0tGrQBxKb3NlcGggRWR3YXJkIEJlcmdtYXJrIChDT0RFIFNJR05JTkcgS0VZ -KSA8YmVyZ21hcmtAYXBhY2hlLm9yZz4ACgkQsNmRtHxAhzdp/hAAtF/zQVGiDrcS -QuuYGU7Ez01J2Xk/9LSZ819Q3jsWopdQYzxGCmK+V8plEkGLIcM/jsK+NLAhZVzt -7qg64vy3MTQ7anvjYx+1+mX1Z0p/g/r5IXXQ73Deg0RPPEtScM7ZanFlBUTniMEk -ZPt8qo5CZw23MeP2E4fl3UzHy1vt0CyB1dOJjsy9XPXLX258ON9IBnjS5s99fKqn -Cs2k0VFyNkOlsIdWzsvFCoQl7URnEEUI4OrrvftxQHouql3x2SxE9K7pIHZewg63 -1W+UXuH72BC02kIXrHixu7yQIE84fLzaptZJWZ9Xgoigk12L40ygMQbc4zbRfoVY -Gymn/jdZ6W/4TG9ksq8FHFi5eZNg+hv8YwFabfYH9cshjh1+ldUbHKE1YbY5TpXQ -9wNZOu0XHMsvo/pijcptUiC8yvmeP1Ky7dyJb7PkoOcQ3cjf31wGiGP0cgDhw1Fb -S14g2OI+fng7Ns+9LLOZ34/QryK+hBLppEdAnLgAvIZzyuydK6KbdIPEzotffoJJ -8PfEPoYa7ZHZZq3fJTno+DO8mhEi9V2jHkpDZDTNUkRYEIevSnfD8F/44bjvZHUy -63T9Hrr+DTjqG2ucCDZeAkaMue/NRXev53RIJ8AHLTUG2dbfb+GHfC/OkkwFe64Z -O0is/SucfzHqQArAUB5mo5B+RC0o9huJApMEEAECAH0FAkzStCk1HEppbSBKYWdp -ZWxza2kgKFJlbGVhc2UgU2lnbmluZyBLZXkpIDxqaW1AYXBhY2hlLm9yZz4gHEpp -bSBKYWdpZWxza2kgPGppbUBqYWd1TkVULmNvbT4fHEppbSBKYWdpZWxza2kgPGpp -bUBqaW1qYWcuY29tPgAKCRA06nbmeRSFqOljEAC+JPGA6EtNP7fhaBEuLL2dhgTs -4vPGvWivygw4WKR4ONGVEMBCQQCxafRxXdUQEjvRTxxdnI/2S7VpGvQlEjSAPkVc -wuX+lwxPYb/7L8D78a11AtAxnxN16QsDBG7s4m+aBBfjn+keQ1lIdScVqU20ZB4y -0qrJb5Zv2hfaDUlg+99VS08VohymSFPEFzUWDufyCC/nJbPnrKZppbBHZmJT6WZm -8y0i+oC65ZbRCxaMV8FVRhcmiafXeZoC/SURf4YSX5tgI8++/Ydwzxp2wxI1NCxK -zsG7sERjLmtoXi9lrDLlWJnhbO5Yid6/7EXqzHjcWmUqag6jldJVQRjUR8G7Coj5 -zUjuEUZRlTM8tllrWLLSamuKhyk1q+UB5gDTIqGDpFxj/SvdKeScL0fzsCmnroaL -MXtd+QCBHmEk2umA9hb2N3bcq2Ht9+zZ5av1RHkNdT0L7l3TiFgyP8cx/qw5of/Z -TQzcvD+Nsl3ijShyvihNHstPYDeANCcHdRlnmH6fusZGGV9t3H8O1kGIGi2R4Pw6 -pUDPuO1BHfA11Ld2uCuVbJwC+2aG8tl8v7XzSovCrn6cZW5oPxnT724UMZ1ms2EC -Mu0Re+4T/q5r1N93vmqHj2ANAm/Kh0l4xBlO/W4lpVqmZUOsdup5mKQMLQWEgxBY -LNgEqimt1u0kP1qmn4hGBBARAgAGBQJNJK0WAAoJEH4q/cwONxoJHQIAn2msette -hgxjatfizrygcPR/2MG1AJ0TfFlSZEdBVOcbyeQp9QHR44imhohGBBIRAgAGBQJM -1CP3AAoJEPQmjufy79DwrF8AoKX1C2MHxi+3OURgekLqqLhhXcmsAJsGXHUPOxWI -AO8gWdOUbSan0395mYkCIgQTAQIADAUCTgOM3wWDApIJwAAKCRCMleyeQza0SER2 -EACxkaUEHDutAFu1isg+H4N1+w1j++I4VbbminesbaWRl3X8or0CFeGJD7aFCZ10 -oj1tYwDQ79+lv7Nza7UgbM369lteJzF/uzHy0now2r1pfqZ/LDTegTbDaLx0l1l6 -T1RPr9Z7udWADOG9o2FfaPZx1sKZvHGdBAIQP0QGIwNaesXTOBALELN5YqFFJGw/ -QvZPjgrhiVekV3CecWtRe5F8oYPV2K4zwV1hOzD8t8nmK8U4C++vK6alVC7iQt7D -1uyMeeX/Sj5wWdXQUo8PKauzDSRO7J786j7nl+c04OI83uij75nckwpKoaSKVuaJ -1CIiAObWnU4X5qiWXhbO/D1iYDu9U/hbKrcBR6AAgF5UTLd8gc4cmMxMh156OMMv -fbovNeLiMvtk+I59RMoFXR+M6vrF0IpPLuTD1v0HLvog2FEuBvDbXDeQp0CpR8xC -VjiLGDNWBjtNnYYWUFBUY8AjmOjmlOKyhVyGzZKY2OFsTRaYHnpoWVWDbxMwdF4x -OU2WiPp57gvxdLDuRugeyZ7at0uJ9qULzPdmY85ZpQ24iC6IvGeKbvbBRy03NO2f -kC5QYiZ5GkjIdjMUJUAkBUnDRVfNWfxCt4WWDOj/b2Dx9j+wLlvoYSp8vJMOgzdY -RCmLP4ILYHestBxjX5XL4/jP/ermAtE3Z1stjHPT0WypDohGBBARAgAGBQJOvCRS -AAoJEAsDrm5OJFF8OV0Ani98tYfmIfP5XZQ5OB7i0utm+mUvAJ9i4Avj7LjRTUS/ -/Y8WEjwECKU/V4hGBBARAgAGBQJOvCmzAAoJEKvWMuzE/Jpl5R8An1XRpZqcpO/O -Xhxah6XLsEpOyZwiAKC19goK1pK3aCPjqUQEZeTwjux3OYhGBBARAgAGBQJOvE7t -AAoJEC8+XTEfSeylBJgAn3BMgHkHaW7aRruEYxqv6DRs2zotAKDSVf9WP7k8QRNM -fX2OGjq0NY6AsokCHAQQAQIABgUCTrxfWgAKCRCarPtWNSrPdsfjD/9qBA81KkYP -OINOIgYogWlJJ1v2glEbcICRvuBIOSpFgQqdT9cLyXrCl38Akhh+kO+A2PEtkBOw -5fDMyENbO3scVOXSIui6SvqDZsTUhcua2jHSWILg1EYr0mWDa7WrbWWcFNna60QP -M+sjYRAkO0oGES7xfg7mb12vHetZVlv6fitIRRBSXDnx09QrvmsVxj528TuR6l0Z -p15MgqAALntYZRkgOwajBIlMcbYkFJg4PsOIzV2ucVYruoPaBpjRnh2AON6qaXF2 -k+0Hbt2DNwB1ZrV/CLlpWmrrgWdyBiO/niqxD5xJaYIr0A9aW01cdgp7kwEGvTXZ -t3qpNr+Dc/Dqgjt94GoEEHJ+ugiifGD+kyox2kXIlNMT38FdorLxmTEPiyAQBDrS -kQGXmZGW2ua05Ns6ElU5WDLpdqZlOg2GjQY7LHzuXNbILiKleoIMdkc1EmSRpLjd -IeyGo94V2ae9G+R345KAsmZfP4Yszkb5W86KBDUErw3MY5wye6DdXPZKpy2w9XWh -lMsz114+xpcJjo1Fv9/GlHSIoeEUBVl+TxoeVa8pjUOjWO7aCuf4ZXk9vfLhIJYw -WfH9zlT7sTH+yQ2S1PqpfAhrYUNjxy05ZmSHKR0/QfLb/WmIVD5D7zoG8F5pV4uC -WtMVuOHEId6U7W4/3BSKv2+qaOWKKy5+aYkCHAQQAQIABgUCTr1SiQAKCRBNFUEQ -uEUI7JBKD/93jZP1q/wInzVCBN0zl5PI3Af9v4q8qoazYHrtaUxm8Zba0EmZlpLF -H0VfgHxTnSQo5gJfSoN2fi/jcaSpr7hZozLw9eMkEL1XLbGb4LiOlwIR7bRhq+xh -OTuSSJRi0VWdjaPZOXTnyefnkSgGe9bnW/imulKrto+c63rSfr2pL/xSPOu9wgbK -fdRuhYQOZcnG39zDhFwYYGbLsriyJFxoc6F9u/5RRURVd67XQ/ZpdgjjkuebpmvG -Hn3OTmsEnMJQrkeib/S7Oylv1Yhb9QlRIDEvsoOZGeEF/hAvlHDDYR8zAKpfOjSy -eApK7sPaZp85+BUQ7ciT9Ty0bhMMNQRP3Bj/M6SpsVzgMUmUN9B4Mip7Kr5XDtY7 -CiGf7u212r1MOTZ/o0Wmh++66QI7rw0b6GmUlnJORJz7D+YiVfY0knRgU1dt0FYq -+qLUjVneqRmp5gfx4+5BWtOESYrITZUvc8VKTOYgRIeD4aJ13+IPhdCfDbWoH7YX -e8z+lt2hLOE2KLiIoa15XQAI5t0hKEQQt1rYe+nEKB1k/azSgUtLh7uVUhYFJnKq -3643pTKFoWJIuEUIaf2m96hZiUXFRxXWV3PIa2/GElJpdVZIPtwoliOcUDWn8Jpp -o3OIM0wwHyuYjFq2rbgiyxygFAIlSZgMJvTnYASL+kUYQYZHWQu9zYkCHAQQAQIA -BgUCTr5o4AAKCRD7Yz3o9cuuaxSaD/4qIpKpgCw4oe4DkpUlTgJM4RRtC5Wyd98/ -zavht3X9I/n+/rfrLVUgOiofHWGgBAD8U8RxUDw8EfW8ohR+U+u9RIBHUR57VFF0 -zU09F+UbI8m99paOb31vI2EratGOd6kmDIcVgaIBhY2JRbNxuet1bC6fphouPga/ -aUQtxISKwG6sUpWugCgD9oVtg2UhUfj6eH8A6Or4ARu9s5m1JbyDl9XEHY2v8LbM -joyxd4kCWsYcuwqluE8BoEJw+R2QDra0y2voNcfgGMvnLbJFn1ivufgqLdtG5r3h -2xnA7idL0jvp9YMXEFbVMzP+BnUxKIOnSo8hTDxfgwkiJbFqlgQIxzmAUjGAg9Ve -rssFWUMsFs0Bm7gkiNhU76OFt+RdX3RmoQIDeUMUlJ56jvWi0wY1orNuTG5anu0o -OiWHZAkVeptiiiAHF6sJlV4YeCzDXID6cz8+iVSK3ARlQnvwgzOfJzs+rs9AbtSU -9BSWQNEaAcG1Cln1pjIeK9GasNBW+xLHxQNYUJWk+jmBMrRz5AXn8jzMv6BvRzVy -weYosn0DhKuK7LAtFX8mmxPX2JGCC69Q/FYXVEvRuh4iI5P6heppDcEtRh/+oviv -ZeIrAWLTij200V0t+XVRhAM03Q/sPKqKWN4W0ye2wpAD5RNwaPotS/dE6HhO+fsi -0HcJmVg9IIkCHAQQAQIABgUCTsrLfgAKCRCJofZRKiOcLJ7ND/9NGFshib9CgkmD -BG0M48kfXydfV6B/DQdtYRsPXQDmS8slTakrQQRBtNHFyX+YCYKRAPVgoTzn46X5 -e2CrF8Bi+qySJP4e7rP9F3DQG1LqPoYJPBdx68v23x1Uv4vJ/q8vTD3kWdktxWM7 -HxJwJnJCkiitg8JeYfdJAe7pjahN/ve/gMlbUUS9lzUqCmBVRIwxiVE2lPml54h6 -dtDtzKu942y9SzxgkQKRPIkKjN3ZUWHTkT+kE7KOh1cc3SyB9P6A2alm8GoYe6ky -tmgvI1u6NtUPNMvPycLyWYIesORNwtD0ALzSRDRbbALEMby46xWBNddDR/3TKpdc -bUFFjoXZTGGnSB/HD6b5fuul0tvzYebnyBzwNppd/WgGr1LeXYDUUohHWs63CKLF -KH9EZmAYyPDKTIyIstmC5rndiBczHMlkKvPQcXId5QTNVIDS7ze/jRgX+yAqEump -0Jt2S0V27km3NQoj0VpahzJYn/3xqchj+gRFoc2IwVxcqKP1ouV0Igmy2ddJRoQl -VbsZ8fDdiIOP0tWDroZhy08lxmeC48YHoY46dqlVV3qOulmj5CwJttsaGV8N6UuW -uplS7pqXioR+XBSsg4uGx2ht5jS5Ka/H3BJk+7QyUSKyfLbboamf5m9aQsDtuErF -KsYMy4Aoh/dg2SgFFUNC4k5/oDz4sYkCHAQQAQoABgUCTsFkCgAKCRBOvAyfAgj8 -Ea1/D/4kr5cLC+J58QXTpFvDtem2Yf8KrQDMKm4pb3Abw3L5VA9w+z+AqzhKMwHY -8WgakY0dA1uxnAl0hSZTg9oAt32vPzRZL1dCthHSSVr9iykWrJ0GPndVcPiJc3z5 -UIoSXZ9kN7HDBk0Fk4o9guWBMPmJ2BFrwsDjD6zW5L3xPzxhYN+D58e6VjRg6YoD -vwUCLXwm1xtHPGBSM4CiLu8GC7VmBVL0k5x7FeczVaeCIF6uwgLHu/cb0dt7kJaD -U6VodDOadM3xd7MRwU5v63gwR4JmqH85lZFYI7phjbVhnWOKMpUYYoNHT2Iuk36p -ojyrwbMM0EqWA5WFvqNvedqwzJJ9GGTRx0zkrgM0i93GpQI8IvIC2QJXZcA5BcpQ -ggQyVitnxb9ZNnp/YDDeIUmvRVCbc4IYtzwpYEGCESCW6gEFjafYdYyajKEGRmb9 -0/+69YbTBweOdihGMWrqhQpCE5caOj2e9LL0ZgGlmioSBALvfcVvGbte3XE9na1P -dBFN2osybG+uZXld0uoa8OmSdjL+1LqBRyLIVHyRUIQZLfr+KtokMWK8GlL5WCPF -i6RZOZcQ/KXWadTb++/Le+6qatmzyQ5B00ZNzBsUvmYBXbX75VeaEOWXelAU1OWG -erO2SDEPifkaC+pHP1Ud+vH3SjeF3KoBENqBpkEKGUi937bpWYkCHAQQAQoABgUC -Ts2X0QAKCRD1T+ZICIM1qafXD/9PLM0s0X635yhWfZRFxd8fM4NWiBMx5dgVMR3E -aq+iXjeNJqqMt8u1MQvYqIXrzm+uOTJ5nBbh0UoWmXO02XBgIWENccgA8wWy17X1 -E/GKWYMFhr8ond32N7+kn/7ftrBQZasbBXSdz0zNFTi7B3ilZnq19whN8A63ctYC -GNMxKfu31F/Mp4Ukz4oiNsXmBq4+2SLfoR6xZ8xomDEcpRDPu0yQM7q5YWEF9KNJ -E9fsZ1ltRxoson6jjpGbwGS4N1MMlJrWndwKhz5ZwPWdMCiiAZW6X7ZvE5So7J1n -CWR+NxnJAFqVwp9PZxjiiKCIHZPz8m20qm5CoCR/j/hk+hLbL5cB+ie8wgushd1O -V6P9GV6ld4umM3Qh57cmZBZwhQoouDpjMHeMEK/P9EEjPKizfhF8T4qVVQEpQlJQ -7U13xR9PuQh8ofDs2qDplKpZR0BVSBxQb7l2JNDJsjwxKiqeGrFhEu4RaeuXl7do -PWHsJqTbxul49M6lh1IMn06XYlMxR/dViMmPCh710T4ShyPQHr3ubz3gQPNyUsJk -FkiBCBTJ4A3yVgdsSLMCv2TCUYlVGgazIyXYj6CGlj5C9X7b2PFGOsmIuuMWJrZu -K64ISrbZUU7weXYn7d9NCCzUFCZHWNxM5MqdKBHy6jVONdksvgXmmGJ32sN4WJDM -5wutm4kCHAQSAQgABgUCTubiXgAKCRDGh181Qc794DR3EACrmqG2CZRKvWPToU9c -YFMbTNQR7tMB3Iuz0Cks/JzgRpRnBIg3tNoWpJfuQeTYV/rWgbov9hF42X1aahKh -yO7iAT5uc4n5C8YoWzvkViGDtkueOGcCgOV/DlMsYtaUlPpgAqqFwCwiboJShsRy -d2Jxg1KxMbJK/b4iFYSqox0tqUT/E4+7fFkayY9hbG6VfX1Dt/rv+kWPcqcvbEFq -U2ZOQ91QGic7ZLZ6TWkkJtmJnOc8q8WLzUz6jKPqJNwa4bcxc1+I5/fOVS2xlaOx -ZXqX4eWSTy7Jx2Ya7ise6H+WDt7r3M+n8NgqpT7KHzd6ZDel/NXHL9HpL1sVvfBd -nkTNnUH2ZAL4QN5u2FdZkR4N8sJ7VFbHFbpQTP7pFAWM5NxPhXcOvZz7CCYrCw0/ -3xSaQk2M7jUp2JbnWq/fxRzwBXG9YUe6ZzFmovgX9MjCf1kPQohKBjSZyfefB/7y -IBO1gN/lq9R4KzeVqbBUHTv1yytEfhmSdiJD6Zn1I0+rBj0lOPFBh7FavZ8Mf3qa -nBQdYwfviMIEsw1rxwi+m9q5RwPzN4c10GLxPyA9HiveA4dj8DI2bD/mHymhjM5E -Di8plId5A2mqfb36CYVgi3zVgF6fdkSclqXJgmaO53Q0UCCl7qnKaBQiUvZ4m50S -vun+iQyHOgf1OJocid27Fe0eaokCPQQTAQIAJwIbAwULCQgHAwUVCgkICwUWAgMB -AAIeAQIXgAUCUSCPTgUJC9IwFQAKCRCbuGOw9Ru4igXDD/4wg4dxsAhXkOWYQb/8 -rN0plsvZHkacnRc3w0h6+5FfvNMbuUQY0YW3kD3APerX9mkYBsQbloY9d7KXMl7M -ATQtdXl07HZZMS1PXEyIWPk5es1tHpfR+6NAU3nJyJdniSO/8GDjhiN4sq++uIF4 -NMvZC6/7XG4uT39BlPFqRHpFxLu9uJuzNkiQnPkHQZ08r9FKq854/KGDtaV1aAzP -s4f1cghvh2JOrioKkNuS3yXWIn6AxhXmvYhufqHXajCBovv/Edwf+ErkZ6uYgJg7 -EjjU0f8sDsyoEThV0ChBcvIaxhYEne5QNRpcaLMU0w+/u03DTbKUmOGeYyOToB4y -5HIhuiNB47DtFY0K9FQbT9gw4MOuQkVLX9WG9Ksnc7cPPHL2B6DtLER2lMczp3eW -rftx4q+CcI/jfWDrpDN1a2MI1fwR0cxCF7tSxGWl3EmFnjC38qMWQvXWMXsFqGUI -sTOGEmd4w1L2xnYVRXDh6Ic9OmYu95iIgUE064E8xeurDAM5ela2C9KVXcpefkU8 -0vuq8FqNofZzvV/LVQczE5W+O8b+pqh+PUa9vLbv3ukdDe+zJm9E4/bGF7NjPgjT -YBkb7L0PQLb1zsAUj0oo9HdyEPwHf971N745js2m3jQrKAgAuUOXBFnpAQ8qhhxk -eacb87oIzHdX8TdtqaSqAg18M4kCPQQTAQIAJwUCSvH9lAIbAwUJBaOc7QULCQgH -AwUVCgkICwUWAgMBAAIeAQIXgAAKCRCbuGOw9Ru4iq3HD/0SKrQhKwuBcYSSbRNn -i5w0l6erZ/ZllogFTHyn2J6sAYtG/GxJ268xBVhXgmSpXWt3G+809rYh8BMKp+UN -4sMuphTs/eT61LTDjoPIACN7R1FxWjlhK1PzsaV6dlfQXaePjr8r1vqV99kl8Khx -iAWpLBJVDjyCXlv5vTGzX/PuZdnE3R1OkVhjHANcWLr9M5j86WgORhhR1KkDpB+B -pwYbCCg46yJqkRVF1FZsns9nYyMnbqCq4mTkRgj2hSoAzBgJ7WFpdJ0qSo++lWxR -r54pXTgZHda+GVO4I1APyyyO0Xl+BBwwNbpxT1PyaBgz7/x4lTf1vng/8dKzJc7k -cHQftTgcRdDMhzjoqBAR7P5hACK84mjcSfB4a4THBAW9hO7rGHFWs/kVoZbRy6+m -n9Gk8bm3xyzR3kGSSSA2S3/LYxmNfBRXNPvG9M1j6/KPa2dLBdBB/09Zk/lgHtoc -lOW25dHcAlieYSbqJH46WJmK+YANzwfJwd1ofSuvM3iXBRdcuGvTZ8LHpq3Aspgv -2MwwDtZUyjOMUoC1JSUIVLRfM3498RGVd1K6kOU2IVM5fFG33fFjzbmDMqZa2dcw -w42/Vk0XIjLOUoA9/BdmZsX1l+YoyiCWm8KPzMWMjpeuxKCgdjTW67wB5ReU8Amp -rzaaAByaElVk1FZiiZH3MJEhRNH/AABZ5v8AAFnhARAAAQEAAAAAAAAAAAAAAAD/ -2P/gABBKRklGAAECAQBIAEgAAP/hC+RFeGlmAABNTQAqAAAACAAHARIAAwAAAAEA -AQAAARoABQAAAAEAAABiARsABQAAAAEAAABqASgAAwAAAAEAAgAAATEAAgAAABQA -AAByATIAAgAAABQAAACGh2kABAAAAAEAAACcAAAAyAAAAEgAAAABAAAASAAAAAFB -ZG9iZSBQaG90b3Nob3AgNy4wADIwMDQ6MDk6MjggMTY6NTk6NTkAAAAAA6ABAAMA -AAAB//8AAKACAAQAAAABAAAASKADAAQAAAABAAAAZQAAAAAAAAAGAQMAAwAAAAEA -BgAAARoABQAAAAEAAAEWARsABQAAAAEAAAEeASgAAwAAAAEAAgAAAgEABAAAAAEA -AAEmAgIABAAAAAEAAAq2AAAAAAAAAEgAAAABAAAASAAAAAH/2P/gABBKRklGAAEC -AQBIAEgAAP/tAAxBZG9iZV9DTQAC/+4ADkFkb2JlAGSAAAAAAf/bAIQADAgICAkI -DAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwM -DAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEM -DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgAZQBIAwEiAAIRAQMRAf/d -AAQABf/EAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEA -AAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFh -EyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX -0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5en -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 -3lmxyMbMoHSPn/zuJO5m7cCC0tJBaeRBVc47Q/c0lh8lo5GTh33ssxrG2C1pnb+8 -zxH9RyY0Bwkcqoe4bkNgJCpDQgtWui4nSw/ctPp+PXTNlj9r3gsbYTqHOG1kEoGO -xzTtLfmq/WnWuycDGpguFvrFh4d6bXOax39b3Ixs+PgiZrrXj2czPuyTUepUuNlQ -ivLe3SeGtyHsH0N/0LVkvcaHC+g7ayZIH5p/eZ/JVrHzxXb6jBu9STbV/g9hGz0t -kbfo/TVS6sYtwrEuxbhupJ7T9Kp39VSYZ6CMjr/LRbzHL5OH3uHhgf8AG/vSi6/S -sq7I9SuvI9C4w8Ena10aOY535u5qSwqnnGvHdrTIB7t/dST/AGxx8X8ra3EeHh6X -b//V4LOGLI+yF514eAB/J2wVev8AsHq/oC8CRpEgn8791zVzKSGff6fRs8h84+bc -fL/3X9V9CrNBOH6Qh25vp7SCOD9o36N/wf8A01uV+lOnzXkKSght1+v7GTJXHOv3 -j/e/wuJ9mHoSsvqPo/tTGgv9aTs2c8O+ivLUk6Xyny/R3Wx+Yftezv8AsPo5H2Ta -GSJ7nnWN35u76K0qHdGb0TIGTVXYzZ9PIseywu/N+y1UU3MbZ/o/0y86SUQ/aP73 -/ozeP81O/cq5b/L8sf579P2nayPo187p9s8x/KSWKkr32uL16b/R/9n/7RCMUGhv -dG9zaG9wIDMuMAA4QklNBCUAAAAAABAAAAAAAAAAAAAAAAAAAAAAOEJJTQPtAAAA -AAAQAEgAAAABAAEASAAAAAEAAThCSU0EJgAAAAAADgAAAAAAAAAAAAA/gAAAOEJJ -TQQNAAAAAAAEAAAAHjhCSU0EGQAAAAAABAAAAB44QklNA/MAAAAAAAkAAAAAAAAA -AAEAOEJJTQQKAAAAAAABAAA4QklNJxAAAAAAAAoAAQAAAAAAAAABOEJJTQP1AAAA -AABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoA -AAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD///////// -////////////////////A+gAAAAA/////////////////////////////wPoAAAA -AP////////////////////////////8D6AAAAAD///////////////////////// -////A+gAADhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAAAAQA -AAAAOEJJTQQaAAAAAANVAAAABgAAAAAAAAAAAAAAZQAAAEgAAAAQAE4AZQB3AE8A -cgBsAGUAYQBuAHMAUwBxAHUAYQByAGUAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEA -AAAAAAAAAAAAAEgAAABlAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAA -AAAAEAAAAAEAAAAAAABudWxsAAAAAgAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJj -dDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxv -bmcAAABlAAAAAFJnaHRsb25nAAAASAAAAAZzbGljZXNWbExzAAAAAU9iamMAAAAB -AAAAAAAFc2xpY2UAAAASAAAAB3NsaWNlSURsb25nAAAAAAAAAAdncm91cElEbG9u -ZwAAAAAAAAAGb3JpZ2luZW51bQAAAAxFU2xpY2VPcmlnaW4AAAANYXV0b0dlbmVy -YXRlZAAAAABUeXBlZW51bQAAAApFU2xpY2VUeXBlAAAAAEltZyAAAAAGYm91bmRz -T2JqYwAAAAEAAAAAAABSY3QxAAAABAAAAABUb3AgbG9uZwAAAAAAAAAATGVmdGxv -bmcAAAAAAAAAAEJ0b21sb25nAAAAZQAAAABSZ2h0bG9uZwAAAEgAAAADdXJsVEVY -VAAAAAEAAAAAAABudWxsVEVYVAAAAAEAAAAAAABNc2dlVEVYVAAAAAEAAAAAAAZh -bHRUYWdURVhUAAAAAQAAAAAADmNlbGxUZXh0SXNIVE1MYm9vbAEAAAAIY2VsbFRl -eHRURVhUAAAAAQAAAAAACWhvcnpBbGlnbmVudW0AAAAPRVNsaWNlSG9yekFsaWdu -AAAAB2RlZmF1bHQAAAAJdmVydEFsaWduZW51bQAAAA9FU2xpY2VWZXJ0QWxpZ24A -AAAHZGVmYXVsdAAAAAtiZ0NvbG9yVHlwZWVudW0AAAARRVNsaWNlQkdDb2xvclR5 -cGUAAAAATm9uZQAAAAl0b3BPdXRzZXRsb25nAAAAAAAAAApsZWZ0T3V0c2V0bG9u -ZwAAAAAAAAAMYm90dG9tT3V0c2V0bG9uZwAAAAAAAAALcmlnaHRPdXRzZXRsb25n -AAAAAAA4QklNBBEAAAAAAAEBADhCSU0EFAAAAAAABAAAAAE4QklNBAwAAAAACtIA -AAABAAAASAAAAGUAAADYAABVOAAACrYAGAAB/9j/4AAQSkZJRgABAgEASABIAAD/ -7QAMQWRvYmVfQ00AAv/uAA5BZG9iZQBkgAAAAAH/2wCEAAwICAgJCAwJCQwRCwoL -ERUPDAwPFRgTExUTExgRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM -DAwBDQsLDQ4NEA4OEBQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwM -DAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIAGUASAMBIgACEQEDEQH/3QAEAAX/xAE/ -AAABBQEBAQEBAQAAAAAAAAADAAECBAUGBwgJCgsBAAEFAQEBAQEBAAAAAAAAAAEA -AgMEBQYHCAkKCxAAAQQBAwIEAgUHBggFAwwzAQACEQMEIRIxBUFRYRMicYEyBhSR -obFCIyQVUsFiMzRygtFDByWSU/Dh8WNzNRaisoMmRJNUZEXCo3Q2F9JV4mXys4TD -03Xj80YnlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3EQAC -AgECBAQDBAUGBwcGBTUBAAIRAyExEgRBUWFxIhMFMoGRFKGxQiPBUtHwMyRi4XKC -kkNTFWNzNPElBhaisoMHJjXC0kSTVKMXZEVVNnRl4vKzhMPTdePzRpSkhbSVxNTk -9KW1xdXl9VZmdoaWprbG1ub2JzdHV2d3h5ent8f/2gAMAwEAAhEDEQA/AKRLAXNa -whxAO4A/nOdu9wH0lF997A31WO3/AEtIjQN3e79J++ifs0O4trf4e1v/AHzais6d -lO9rC0/DeD/0HqbhLW4wua7r7PaC4+DRJOljVuYv1T6rZjAudXU97QQx2haY27fz -vBWeljF6ZQ10H7W8APLnb9v9SV0uHYx9DXBwJfrMqE5blQ+1sRxVGy8t/wA085jH -NG1zgBBGkn873KhZ0vO6c4jJq21vgixpkTqIc5dxkZddMgnVSY+jJrLSGvadHNME -JDILq7Ucel1TwG4BrzBlsO8AduuizMdgf6jCwNYASwcxOrmv/wCuNXXdd+r76a35 -WHDq9d9fu3NaR+ZG7cuSo31WS/Vuokk6T/1pv/VKXivZiII3XYQBe0PG5rQZgwSR -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 -u+itKh3Rm9EyBk1V2M2fTyLHssLvzfstVFNzG2f6P9MvOklEP2j+9/6M3j/NTv3K -uW/y/LH+e/T9p2sj6NfO6fbPMfyklipK99ri9em/0f/ZOEJJTQQhAAAAAABVAAAA -AQEAAAAPAEEAZABvAGIAZQAgAFAAaABvAHQAbwBzAGgAbwBwAAAAEwBBAGQAbwBi -AGUAIABQAGgAbwB0AG8AcwBoAG8AcAAgADcALgAwAAAAAQA4QklNBAYAAAAAAAcA -CAAAAAEBAP/hEkhodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvADw/eHBhY2tl -dCBiZWdpbj0n77u/JyBpZD0nVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkJz8+Cjw/ -YWRvYmUteGFwLWZpbHRlcnMgZXNjPSJDUiI/Pgo8eDp4YXBtZXRhIHhtbG5zOng9 -J2Fkb2JlOm5zOm1ldGEvJyB4OnhhcHRrPSdYTVAgdG9vbGtpdCAyLjguMi0zMywg -ZnJhbWV3b3JrIDEuNSc+CjxyZGY6UkRGIHhtbG5zOnJkZj0naHR0cDovL3d3dy53 -My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIycgeG1sbnM6aVg9J2h0dHA6 -Ly9ucy5hZG9iZS5jb20vaVgvMS4wLyc+CgogPHJkZjpEZXNjcmlwdGlvbiBhYm91 -dD0ndXVpZDpkYWJlYjcxYS0xMWE4LTExZDktYWVmOS04MDNmYjlmNDliNmUnCiAg -eG1sbnM6eGFwTU09J2h0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8nPgog -IDx4YXBNTTpEb2N1bWVudElEPmFkb2JlOmRvY2lkOnBob3Rvc2hvcDpkYWJlYjcx -Ni0xMWE4LTExZDktYWVmOS04MDNmYjlmNDliNmU8L3hhcE1NOkRvY3VtZW50SUQ+ -CiA8L3JkZjpEZXNjcmlwdGlvbj4KCjwvcmRmOlJERj4KPC94OnhhcG1ldGE+CiAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg +tB9TYW5kZXIgVGVtbWUgPHNhbmRlckB0ZW1tZS5uZXQ+iQJABBMBAgAqAhsDAh4B +AheABQsJCAcDBRUKCQgLBRYCAwEAAhkBBQJRII9HBQkL0jAVAAoJEJu4Y7D1G7iK +2McP/jYqrS0KdYp8ljvXV+/oAHobtCmmclaZKHr8qOLSIxUcUiRTCRXNH4sn3KGY +I4lpJc4y/HAoSPbRbrDj6rG2CI6P+VzgLcg0YKzu0vELCsmowWbp2E05F4Gqusyf +k7wdjofgCInKLG+6xCaf74hUbdNyb8Sr4uo+qkAwHXqeo8SwE1hG1lDlCqhpaHJF +5ms2EEyqIZjcrzfKvvvsJhZjv8iu1nAO1AlwGxfNVoxzvGTTPYT/PfpG1ZqZVrAc +hgGwLhbdRx3xgiMznUsza2bs7rF2UXesRsjGxfI87PrfEvNSszkyx2uzB6PKT1Uw +UfvZH1+37LH0/IxTYyRBxlVgPpIqp5UX5o3grpXwRSqFxSLxSyVHnhH0pe+2pLpF +gR5a0dTx4CS5RBcgWm4Wkoh9W78qyumJFE5aAmeZCfKb3uZu9jzVcVi6+4rjVJg2 +q9QJzfbyQtzHwbF3I2+FcEv1hcXSkLoRAbCIta2eqRH4z0efY0pRXYr1xHM54J5J +U12bGj4oDqJlKMy1m2hxlI2SFW95/SaDLesl65uuz79DRlwy3Q0FqYaUD44XRtQ3 +AGeGltvM+kPPRO+Sq29fzcQ5WzJU3A5yYmUgG/jn3acpjhO1TaHJvQEMXZEPR8b4 +nRoGzosJgTKH8A9lQhqCgxOVkItTt220wNwVbiT9z4kX6B8dtBxTYW5kZXIgVGVt +bWUgPHNhbmRlckBtZS5jb20+iQI9BBMBAgAnAhsDBQsJCAcDBRUKCQgLBRYCAwEA +Ah4BAheABQJRII9OBQkL0jAVAAoJEJu4Y7D1G7iKBcMP/jCDh3GwCFeQ5ZhBv/ys +3SmWy9keRpydFzfDSHr7kV+80xu5RBjRhbeQPcA96tf2aRgGxBuWhj13spcyXswB +NC11eXTsdlkxLU9cTIhY+Tl6zW0el9H7o0BTecnIl2eJI7/wYOOGI3iyr764gXg0 +y9kLr/tcbi5Pf0GU8WpEekXEu724m7M2SJCc+QdBnTyv0Uqrznj8oYO1pXVoDM+z +h/VyCG+HYk6uKgqQ25LfJdYifoDGFea9iG5+oddqMIGi+/8R3B/4SuRnq5iAmDsS +ONTR/ywOzKgROFXQKEFy8hrGFgSd7lA1GlxosxTTD7+7TcNNspSY4Z5jI5OgHjLk +ciG6I0HjsO0VjQr0VBtP2DDgw65CRUtf1Yb0qydztw88cvYHoO0sRHaUxzOnd5at ++3Hir4Jwj+N9YOukM3VrYwjV/BHRzEIXu1LEZaXcSYWeMLfyoxZC9dYxewWoZQix +M4YSZ3jDUvbGdhVFcOHohz06Zi73mIiBQTTrgTzF66sMAzl6VrYL0pVdyl5+RTzS ++6rwWo2h9nO9X8tVBzMTlb47xv6mqH49Rr28tu/e6R0N77Mmb0Tj9sYXs2M+CNNg +GRvsvQ9AtvXOwBSPSij0d3IQ/Ad/3vU3vjmOzabeNCsoCAC5Q5cEWekBDyqGHGR5 +pxvzugjMd1fxN22ppKoCDXwz0f8AAFnm/wAAWeEBEAABAQAAAAAAAAAAAAAAAP/Y +/+AAEEpGSUYAAQIBAEgASAAA/+EL5EV4aWYAAE1NACoAAAAIAAcBEgADAAAAAQAB +AAABGgAFAAAAAQAAAGIBGwAFAAAAAQAAAGoBKAADAAAAAQACAAABMQACAAAAFAAA +AHIBMgACAAAAFAAAAIaHaQAEAAAAAQAAAJwAAADIAAAASAAAAAEAAABIAAAAAUFk +b2JlIFBob3Rvc2hvcCA3LjAAMjAwNDowOToyOCAxNjo1OTo1OQAAAAADoAEAAwAA +AAH//wAAoAIABAAAAAEAAABIoAMABAAAAAEAAABlAAAAAAAAAAYBAwADAAAAAQAG +AAABGgAFAAAAAQAAARYBGwAFAAAAAQAAAR4BKAADAAAAAQACAAACAQAEAAAAAQAA +ASYCAgAEAAAAAQAACrYAAAAAAAAASAAAAAEAAABIAAAAAf/Y/+AAEEpGSUYAAQIB +AEgASAAA/+0ADEFkb2JlX0NNAAL/7gAOQWRvYmUAZIAAAAAB/9sAhAAMCAgICQgM +CQkMEQsKCxEVDwwMDxUYExMVExMYEQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwM +DAwMDAwMDAwMAQ0LCw0ODRAODhAUDg4OFBQODg4OFBEMDAwMDBERDAwMDAwMEQwM +DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABlAEgDASIAAhEBAxEB/90A +BAAF/8QBPwAAAQUBAQEBAQEAAAAAAAAAAwABAgQFBgcICQoLAQABBQEBAQEBAQAA +AAAAAAABAAIDBAUGBwgJCgsQAAEEAQMCBAIFBwYIBQMMMwEAAhEDBCESMQVBUWET +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 +//////////////////8D6AAAAAD/////////////////////////////A+gAAAAA +/////////////////////////////wPoAAAAAP////////////////////////// +//8D6AAAOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAAAAAABAAA +AAA4QklNBBoAAAAAA1UAAAAGAAAAAAAAAAAAAABlAAAASAAAABAATgBlAHcATwBy +AGwAZQBhAG4AcwBTAHEAdQBhAHIAZQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAA +AAAAAAAAAAAASAAAAGUAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA +AAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0 +MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9u +ZwAAAGUAAAAAUmdodGxvbmcAAABIAAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEA +AAAAAAVzbGljZQAAABIAAAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25n +AAAAAAAAAAZvcmlnaW5lbnVtAAAADEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJh +dGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5cGUAAAAASW1nIAAAAAZib3VuZHNP +YmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9u +ZwAAAAAAAAAAQnRvbWxvbmcAAABlAAAAAFJnaHRsb25nAAAASAAAAAN1cmxURVhU +AAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAABmFs +dFRhZ1RFWFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4 +dFRFWFQAAAABAAAAAAAJaG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24A +AAAHZGVmYXVsdAAAAAl2ZXJ0QWxpZ25lbnVtAAAAD0VTbGljZVZlcnRBbGlnbgAA +AAdkZWZhdWx0AAAAC2JnQ29sb3JUeXBlZW51bQAAABFFU2xpY2VCR0NvbG9yVHlw +ZQAAAABOb25lAAAACXRvcE91dHNldGxvbmcAAAAAAAAACmxlZnRPdXRzZXRsb25n +AAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAAAAAAAAtyaWdodE91dHNldGxvbmcA +AAAAADhCSU0EEQAAAAAAAQEAOEJJTQQUAAAAAAAEAAAAAThCSU0EDAAAAAAK0gAA +AAEAAABIAAAAZQAAANgAAFU4AAAKtgAYAAH/2P/gABBKRklGAAECAQBIAEgAAP/t +AAxBZG9iZV9DTQAC/+4ADkFkb2JlAGSAAAAAAf/bAIQADAgICAkIDAkJDBELCgsR +FQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM +DAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwM +DAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgAZQBIAwEiAAIRAQMRAf/dAAQABf/EAT8A +AAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQAC +AwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGh +sUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPT +dePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5/cRAAIC +AQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKS +Q1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0 +pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8ApEsBc1rC +HEA7gD+c5273AfSUX33sDfVY7f8AS0iNA3d7v0n76J+zQ7i2t/h7W/8AfNqKzp2U +72sLT8N4P/QepuEtbjC5ruvs9oLj4NEk6WNW5i/VPqtmMC51dT3tBDHaFpjbt/O8 +FZ6WMXplDXQftbwA8udv2/1JXS4djH0NcHAl+syoTluVD7WxHFUbLy3/ADTzmMc0 +bXOAEEaSfzvcqFnS87pziMmrbW+CLGmROohzl3GRl10yCdVJj6MmstIa9p0c0wQk +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 +OH6Qh25vp7SCOD9o36N/wf8A01uV+lOnzXkKSght1+v7GTJXHOv3j/e/wuJ9mHoS +svqPo/tTGgv9aTs2c8O+ivLUk6Xyny/R3Wx+Yftezv8AsPo5H2TaGSJ7nnWN35u7 +6K0qHdGb0TIGTVXYzZ9PIseywu/N+y1UU3MbZ/o/0y86SUQ/aP73/ozeP81O/cq5 +b/L8sf579P2nayPo187p9s8x/KSWKkr32uL16b/R/9k4QklNBCEAAAAAAFUAAAAB +AQAAAA8AQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAAAATAEEAZABvAGIA +ZQAgAFAAaABvAHQAbwBzAGgAbwBwACAANwAuADAAAAABADhCSU0EBgAAAAAABwAI +AAAAAQEA/+ESSGh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0 +IGJlZ2luPSfvu78nIGlkPSdXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQnPz4KPD9h +ZG9iZS14YXAtZmlsdGVycyBlc2M9IkNSIj8+Cjx4OnhhcG1ldGEgeG1sbnM6eD0n +YWRvYmU6bnM6bWV0YS8nIHg6eGFwdGs9J1hNUCB0b29sa2l0IDIuOC4yLTMzLCBm +cmFtZXdvcmsgMS41Jz4KPHJkZjpSREYgeG1sbnM6cmRmPSdodHRwOi8vd3d3Lncz +Lm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjJyB4bWxuczppWD0naHR0cDov +L25zLmFkb2JlLmNvbS9pWC8xLjAvJz4KCiA8cmRmOkRlc2NyaXB0aW9uIGFib3V0 +PSd1dWlkOmRhYmViNzFhLTExYTgtMTFkOS1hZWY5LTgwM2ZiOWY0OWI2ZScKICB4 +bWxuczp4YXBNTT0naHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyc+CiAg +PHhhcE1NOkRvY3VtZW50SUQ+YWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmRhYmViNzE2 +LTExYTgtMTFkOS1hZWY5LTgwM2ZiOWY0OWI2ZTwveGFwTU06RG9jdW1lbnRJRD4K +IDwvcmRmOkRlc2NyaXB0aW9uPgoKPC9yZGY6UkRGPgo8L3g6eGFwbWV0YT4KICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg @@ -5280,1093 +3462,371 @@ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSd3Jz8+/+4ADkFkb2JlAGRAAAAA -Af/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB -AQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQEBAQEBAgIBAgIDAwMDAwMDAwMD -AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAZQBI -AwERAAIRAQMRAf/dAAQACf/EAaIAAAAGAgMBAAAAAAAAAAAAAAcIBgUECQMKAgEA -CwEAAAYDAQEBAAAAAAAAAAAABgUEAwcCCAEJAAoLEAACAQMEAQMDAgMDAwIGCXUB -AgMEEQUSBiEHEyIACDEUQTIjFQlRQhZhJDMXUnGBGGKRJUOhsfAmNHIKGcHRNSfh -UzaC8ZKiRFRzRUY3R2MoVVZXGrLC0uLyZIN0k4Rlo7PD0+MpOGbzdSo5OkhJSlhZ -WmdoaWp2d3h5eoWGh4iJipSVlpeYmZqkpaanqKmqtLW2t7i5usTFxsfIycrU1dbX -2Nna5OXm5+jp6vT19vf4+foRAAIBAwIEBAMFBAQEBgYFbQECAxEEIRIFMQYAIhNB -UQcyYRRxCEKBI5EVUqFiFjMJsSTB0UNy8BfhgjQlklMYY0TxorImNRlUNkVkJwpz -g5NGdMLS4vJVZXVWN4SFo7PD0+PzKRqUpLTE1OT0laW1xdXl9ShHV2Y4doaWprbG -1ub2Z3eHl6e3x9fn90hYaHiImKi4yNjo+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6 -ytrq+v/aAAwDAQACEQMRAD8ALBPU4OCryWJxO1czS5CopsTVx5OjxOalpoP7ybvz -X8b+3zNDi54qjM1k4qp4aWlOm6xCULGEBHyw63QxwsCJV4jjWpYg8ak5PBeFeoku -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 -WVv5rhS5/UaqucgH9nXnaZIrvLS9SWu3LzZ5SLXKPw1ir9YZC1pTPrtd6nXPnJEf -fNbuhKH8/3A3UIt3NVEN9oBxmJiof9jRBWKyf1DSU13aP/wGmCCOiU7gN1I+BLMM -3ZqP0WF0Mb6Y4mR6cAFHY+Ug/UjLX21okPE6djKG1B7UeGSUwJGcof6PU67dxaJf -Umk47+DIQoOb8aP2whFZ197D7CitG4kCWgQQAQIARAUCTNK42j0cQW50b2luZSBM -ZXZ5LUxhbWJlcnQgKENPREUgU0lHTklORyBLRVkpIDxhbnRvaW5lQGFwYWNoZS5v -cmc+AAoJEF762f6Cp/vNNX4QANyh0StE9iY6zxHOB2/fkK93itUVxQx5VsZ7/FkW -s1Um01gRaDJ3so2VYtGJoH6wFGKy29VWj2zNLhDv7VUUnosBuasnZXgcjXCW6OgE -g+t/fnuNXAHXLEIaqZsZwYgx80rJEMIAW2NEhxydzAj3m1gOf5urOqPpyDKcyB1V -A3AVKa/08K6aS2Aa2xIZqt0ghGj3NVPBgRhkB+MHXmZypmbhRVZZn6bWXs0lhYdm -BruljW2u5fgHJIS7Jdl5yvz3DaF9MizzaHvYBDWC3w1hbdE95cTWhPp8dRsp0sbJ -AzPHf3BgkaAP08e/v4txUmqlSw4JfxFecWt0JV64qT2tKotVQrqIeMOgimPJ9ovh -fqOlAKBvzJCBZ6T8d9bcs/xThqCSMPaQCh+PiN9T7/h8xxfG7+gfGP5fwOOCEOVk -KFi+9xMXye1vx4A2qWh1ScALs92GvhMwy1PYoLfjfsEgeYvRGtAX2TMKkyOsHQMq -DGOdRxb6yFeBMZPQD6SQaNHOt6l2gIqstnTy9Vk+I9MUT3ynmSX/rkF7YVdPkDJP -6kUAsxI3rACZrZz8gN0SIH8/3+WaT39+OQXVLleP/BbkKBtxnopi5De72CTG1ocw -JZz00ZvZdi1/DvElLs7ia/5IyNEviCw7m2EQdvLSSzl2/Py3pYz1/rfmQkC39FOQ -1neOiQJdBBABAgBHBQJM0tGrQBxKb3NlcGggRWR3YXJkIEJlcmdtYXJrIChDT0RF -IFNJR05JTkcgS0VZKSA8YmVyZ21hcmtAYXBhY2hlLm9yZz4ACgkQsNmRtHxAhzdp -/hAAtF/zQVGiDrcSQuuYGU7Ez01J2Xk/9LSZ819Q3jsWopdQYzxGCmK+V8plEkGL -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 -YGX9xIlFt+fyh76GksQSYwhv -=BVQL +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9J3cnPz7/7gAOQWRvYmUAZEAAAAAB +/9sAhAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB +AgICAgICAgICAgIDAwMDAwMDAwMDAQEBAQEBAQEBAQECAgECAgMDAwMDAwMDAwMD +AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwP/wAARCABlAEgD +AREAAhEBAxEB/90ABAAJ/8QBogAAAAYCAwEAAAAAAAAAAAAABwgGBQQJAwoCAQAL +AQAABgMBAQEAAAAAAAAAAAAGBQQDBwIIAQkACgsQAAIBAwQBAwMCAwMDAgYJdQEC +AwQRBRIGIQcTIgAIMRRBMiMVCVFCFmEkMxdScYEYYpElQ6Gx8CY0cgoZwdE1J+FT +NoLxkqJEVHNFRjdHYyhVVlcassLS4vJkg3SThGWjs8PT4yk4ZvN1Kjk6SElKWFla +Z2hpanZ3eHl6hYaHiImKlJWWl5iZmqSlpqeoqaq0tba3uLm6xMXGx8jJytTV1tfY +2drk5ebn6Onq9PX29/j5+hEAAgEDAgQEAwUEBAQGBgVtAQIDEQQhEgUxBgAiE0FR +BzJhFHEIQoEjkRVSoWIWMwmxJMHRQ3LwF+GCNCWSUxhjRPGisiY1GVQ2RWQnCnOD +k0Z0wtLi8lVldVY3hIWjs8PT4/MpGpSktMTU5PSVpbXF1eX1KEdXZjh2hpamtsbW +5vZnd4eXp7fH1+f3SFhoeIiYqLjI2Oj4OUlZaXmJmam5ydnp+So6SlpqeoqaqrrK +2ur6/9oADAMBAAIRAxEAPwAsE9Tg4KvJYnE7VzNLkKimxNXHk6PE5qWmg/vJu/Nf +xv7fM0OLniqMzWTiqnhpaU6brEJQsYQEfLDrdDHCwIlXiONaliDxqTk8F4V6iS4k +ZbZlLIdULVIPClNNRjgKjUc+g6b8tvPe2GpMCd1bc3CmfVKrPOlLT0UGFpqnGYvB +UmTpBnIaHdVVQ46qrtwqqRQUjJHJBOvjSOIyLdmv55hG6SK0ZDkgdtTQFa5Oak+u +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 +lPnWnEfbinp05tVsLGJWYNGR8S1qhHqo8vypnj1bv1xtWt+RXxF7imi3NNHkNybZ +3PQ0uNxeNx0U+Neix7TKk01dTNUT1WTnpSwebXGF5Q6xqB/yJtEsrGeK4eG6glDB +RivDiePdkefDoH85blCl1HayWyvbTRFSzVNOIwOHbj5j59abe5N3bv24sldNuqOa +kx82QpaV4sdt+tjirYYpnfGiqrcNDCk5gi0yDW7hLXUqwvkPeQbxtsDz3N6PERgA +unOlu3UMV0k4qaA5yadQclhs9zI8aWZMT8aE01AVAJBGRStB8sdf/9PUxpcbu/qD +c+HXfeG3BtLcm09/YOsyWLymMeiztFHTrBlaSpXH18KipppUVZYeDFUIBoaxDByV +W+mdCnEkenlw/n0gtxC+6F0eo8MN/MCny6V25p87D2BmNuVZrJtyZfdMmJlSognp +6mSpy1Z5aiqko6gvU07GKQel/WgJHHsD28DL+oDRFr/LH7a/5+pKtNLhbdgNTlQf +Pjn+Qp1fz0ltKHFYzCY1EUmgxdBj5JW4JeGKNZXJP+rkF7e0ckTXUuqmSePn1Jdi +Fj8GIOBGq/8AFf4Oj99f/wAMoVnpMjeORpwI5dHjCyKoGj6EHX9SST/hbn2YW8cc +RAYaQfPPRr4XjodEgLjiK8R0Mf3VBBJHSh4ZYpo2byDSHRWNwW1f6kAn/C309qGC +UpUEdNrbOiVZdJJwP8nSS3b1dgd90zUyV0L1akPECqSxtcLdXH9pRxexHPsqvLVZ +gQpqR1YRvaoGlUhT6/4Om7c3S+Y2N0xuuZc/Ni6mLFV+TpZKeKNYGjWIjy11Qyfc +zxoq8B3sCP8AWsQJscDXhaVuIPDA4f4Oi+/u5GgZLdO5BT/iuk1/Lq+Z+9eqeysL +tWkydNkMrn8pQ7erMZkDNLjNwmoligWD/J6imQZGdJC1MtYkyNq/ZdWLRPW8nk2f +/HtvOm4U4IrkUppPr/qOOgXNaJugEV5VkPn5qfX+Xl+fVW/za25tPf8A3XvfA7Lq +sLs/Yud+RWUwuIoKaohhxe38bnd8ZTF0eSixzVT1ApaaJJrSSeNSgVBYWUZETySN +yyI75ibx44HLGp0/BqBb5agQv2k9RXuklp9bAbJBphWRWFFXWQDRgFyWqrAueIpT +r//U1ytp/JNctPtSi3NiNtZrD0+brjtnr/sOml3JsbF0eHkm++nw+6aiai3f1pGk +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 +=XcXi -----END PGP PUBLIC KEY BLOCK----- pub 1024D/EC88A0BF 2006-11-09 uid Philip M. Gollucci <pgollucci@p6m7g8.com> @@ -6403,48 +3863,6 @@ QrnWO3UkWeAgmGQ70w== =wxvV -----END PGP PUBLIC KEY BLOCK----- -pub 1024D/0E44CF0C 2001-06-19 - Key fingerprint = 6D0C 7498 5535 060B 2330 0BFE 47F6 969D 0E44 CF0C -uid Joe Orton <jorton@redhat.com> -sig 3 0E44CF0C 2001-06-19 Joe Orton <jorton@redhat.com> -sig 2 78688BF5 2004-04-01 Nalin Dahyabhai <nalin.dahyabhai@pobox.com> -sig 1 D39DA0E3 2004-11-28 Jason Harris <jharris@widomaker.com> -sig D23A41C8 2004-12-21 Douglas J Hunley <doug@hunley.homeip.net> -sig 2 6F9E049D 2005-06-25 Pim Rupert <info@pimrupert.nl> -sub 1024g/54F12E58 2001-06-19 -sig 0E44CF0C 2001-06-19 Joe Orton <jorton@redhat.com> - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.7 (GNU/Linux) - -mQGiBDsvsLgRBACsHi7eM94mA9jlBxxwLC4ntK0Mj9WWm85V0C1y0Ei1MGz7q6Vu -WdxKgkNMauWrqKCBDQxOI3q5InZd/tZcOXQzGMtA6DxdAa50ZthfCbo0+8bfm00a -wCa5s/1x2tu7zuqcA7/3nOscZgss2k1RrZIALFimfXvq6hkchQyj9mnfKwCg1aOA -Wk7psAeH7UZgBqGHLcEKLjsD/11APufZVhmQtwKP8+yVe4d6UI7e2r4lURoT942g -tLlye1Rvh+FggkWjxKrwmyUaTW4jNDWEO1Sy1KCy/zb17lDQJReBNb4Q6wQwuySL -QqpFYUy3LtCJHnWsriC2d/iuLbBuQJxxQQQ0B0gichI+pqyZN2fmtiyucA3EzXv2 -8WQQA/9eSsUHv1nq+t0mbOBg1wpo0qlofJ96kM6kh8tzD6SxsHx6WDqE2TkZ+6Kf -Lr6yFo4XLY+5DOZ5XgR5LBTyH4PH8M5gZkqfzDTCJfk4qc2XzVW91zSbzQ0fMGWq -CU937R2LwnIWyVXjBgT8QLO58ZW8/X17YIGcgqHW1i4VD7XwR7QdSm9lIE9ydG9u -IDxqb3J0b25AcmVkaGF0LmNvbT6IVwQTEQIAFwUCOy+wuAULBwoDBAMVAwIDFgIB -AheAAAoJEEf2lp0ORM8M6boAnAz/+oVQGgGcHIpF9ugtJumGRApTAJ4liHEQvna0 -FOuzpUZ6kMT3sgIaBIhGBBIRAgAGBQJAbHSUAAoJEDebzld4aIv1rb8An333fo64 -a38vUnnO6rRdVquUpYC4AJ9x3lLonu/WI5WmDHjTy1Ar2kDt/4hGBBERAgAGBQJB -qmYnAAoJEEsqSJfTnaDjyOEAn13slJuH8G6VVPpV2m9S7FxRWh0iAKCEUKMYF+ZI -mQIyWAv/y1Y7A0chi4hGBBARAgAGBQJByJzOAAoJELGJ9rTSOkHIqX4An0obHgj3 -3Oiudie1rqgHj1mxxAprAJ4ps3XhNLDkxtLgwdao85VYj34w4IhGBBIRAgAGBQJC -vW/eAAoJEPxPSY5vngSdRqwAn3BthXNxPJBzDHRBgZ5d/1xzmFfqAJ0eJfe52uvk -h6ZzEc1sdl0sjKuea7kBDQQ7L7C6EAQA3lBouLYzyMT83ZtRUNgYmDZqNai1crEl -kuctL678IwQoEr4zGWTfwIb+vXkqf1VL2HJRXMTamrDfWo/Vy6ZiyB9IRpXNcNXT -dYmf6wXqPZqOCK9Q1mp/sWJGafHVbjDsWzGYTl9XiJUrMBPwPIlLj9SEvNwG7Qrh -jbrsBKkTWwcAAwUD/RWNLmA2OGhkkau62AHi2i20+zmPGLH0AnyaIPJAB6HaZCxU -uOSNBIRsaZoOoizzvaF6Qtaa7KJw3SUviWTfyAv4Lob+bo0e9MdI2olIvjg7VOi5 -wNPldVa4Cs4desqeXecJowP71gFV/NBdBPr2DLMXG3aOhtRZkG7aueoUkuk+iEYE -GBECAAYFAjsvsLoACgkQR/aWnQ5EzwyKgACcD+v7ABREHJd0RglLfFoAuCcZ7FoA -oNQYheE5UpBrTY6qK063clE3Gt2J -=NWjz ------END PGP PUBLIC KEY BLOCK----- - pub 2048R/4DAA1988 2008-08-20 Key fingerprint = 7CDB ED10 0806 5521 82F9 8844 E8E7 E00B 4DAA 1988 uid Bojan Smojver <bojan@rexursive.com> @@ -6538,7 +3956,6 @@ sub 1024g/6741A3F9 2004-02-22 sig 6F9522D8 2004-02-22 Issac Goldstand <margol@beamartyr.net> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.1 (GNU/Linux) mQGiBEA4Z/MRBADgHIqs9R8lj7gPlUps8D3JgLJEEDnCCVabppX6+pdogmNdTYPz tjp8KLHjBSfqq+r4aUxp92CtZzTlpSAEEn9uo/dgb+/4233Eg4hpSff2f2fZzvpJ @@ -6550,67 +3967,16 @@ vrLfBACUU8Ch4aRwXHSwFyvNEQb/ICKc2wOk278JB8uRSavdmbaDeAKoWj+7LTx7 H0xcwUyP960dJea8CYYGSrr5IESOH6sFjwy8Dv7P/xo3COf5kO2KfhoBL+ABEJvG VmNFsoNCkiNXGjkBLJTwav0/R2pYRxQp04h/ctVrJr+lto6z3bQmSXNzYWMgR29s ZHN0YW5kIDxtYXJnb2xAYmVhbWFydHlyLm5ldD6IWQQTEQIAGQUCQDhn8wQLBwMC -AxUCAwMWAgECHgECF4AACgkQ7bEFiW+VItgf4wCgpUd2Ln/cCyPgV4V09kqM6+g3 -ObMAoK/qeEztO7STfdgcKJnAR2GQvB9PiEYEEBECAAYFAkA+YAwACgkQN2uCuGP2 -mw7l3ACgmPGmdtk+n1jQkPNlmy1cgIVPcGgAoI6vVfqJ9+AcnwehoagbD3f5LLeI -iEYEExECAAYFAkA+P4kACgkQ/sGarBK5qmnIYACgslT6Mb6VfEvs/qN7GoWN/oZ/ -jgEAoKhcKA6gqbWBsh/ihQijlF6zICssiEYEExECAAYFAkA+ZzYACgkQVCwRwOvS -dBjipwCeNnKqRspkZufe4XjL2GFQdTXaaZQAn1Gm/O5Fah42HxoNt3PrXh3WFnTA -iEYEExECAAYFAkA/5f0ACgkQdW1LhZ/Igf6nAgCeOHExK0HUSqXQq9vKik0ZkzFK -+VAAoIq8NmLML388JYGLMK32/HegJAF8iEYEEBECAAYFAkdAlWYACgkQN/aP9QFa -/Ir4hwCfTY2KuaV1ysNFb32LW6VEYZccmVgAnRACJIthab6J0zQIj5cAlW7vfrHr -iKkEEBECAGkFAkdDlCcgHFNhbmRlciBUZW1tZSA8c2FuZGVyQHRlbW1lLm5ldD4i -HFNhbmRlciBUZW1tZSA8c2N0ZW1tZUBhcGFjaGUub3JnPh4cU2FuZGVyIFRlbW1l -IDxzYW5kZXJAbWFjLmNvbT4ACgkQsr68QBUpJK9cGgCg18E4t5jbxd4N72X2AD3v -cEzTDNkAoLUp1EObt5Yr/mFkTKPSZwRP7EVCiEYEEBECAAYFAkdnnDMACgkQQMKr -HBzhftxAZgCfeHQhdRf04uxEd5rS9mN1gF0ZnloAoIgsXNemGq2wGuJJAmeauDoC -kVBqiEYEEBECAAYFAkc9FkcACgkQLNaoAyBG0PUzcACfchAh4Apr6TdP1ka8FuT1 -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 -j42b8RDsM44NwP9oQj99Qyo= -=awFp +AxUCAwMWAgECHgECF4AACgkQ7bEFiW+VItgf4wCgrmPS4kyFB//jFoiF5nO+Md9j +WJMAniyuAfgi87ZNZdKboCpV82t7BwzxuQENBEA4Z/QQBAC0cGDsns4j+wtllwA/ +npIQX/GP7IBp+ySSDHMJupoLXSktZwmiQ0y8vNbbJcofqSrb888WxSERxGlhM5fi +Ng6KVJ84EYR39oK1r/qsY2DRnDUJY7SwwzP58/cUOvOp7Z3smXsX8pFN4iCntQhh +IcddLdRCm/o2s5QG1B+WQ/M4AwADBQP/a7/zLwfG+/JJl0LBG8I4BK3tJko1sjOs +5VBxO9kw779Rjw6NQqWy25QS+UXNL0BMwSR0/MRsekNo0mmXLOtpPzWZf04Q2vVk +M87Vuciev5xD8GdrIyjgQEdF/PIOuMSDR58X/5MhcFCPbQEsiR9CDIzpkoyFkfZq +Bv1HYAkHRWOIRgQYEQIABgUCQDhn9AAKCRDtsQWJb5Ui2IccAKCVJoJc4s/AXocL +LtjXDdMjU1V3+wCgw3EGj42b8RDsM44NwP9oQj99Qyo= +=3tn0 -----END PGP PUBLIC KEY BLOCK----- pub 1024D/E55B0D0E 2007-01-01 Key fingerprint = 3E6A C004 854F 3A7F 0356 6B59 2FF0 6894 E55B 0D0E @@ -6757,7 +4123,6 @@ sub 4096R/9B6D9BF7 2010-11-04 sig 791485A8 2010-11-04 Jim Jagielski (Release Signing Key) <jim@apache.org> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2.0.16 (Darwin) mQINBEzSCGYBEADM35SrGvF8jjtPHoVtoU3LKaFqqYInTOKiGeBxkCReGSQrUL+g nvEqs69xSnHffHY8MwjsJY/k0zaegHgivWW3fjiA53oFnu6yTl30PeNN+l5QS7kR @@ -6783,161 +4148,55 @@ wnOwp7UbSOqX9Pfiyct7iEZXMH71QBpNr6sKKHcfwUPQ2Qmd+hmmj9aFbYCmbiP1 DrQU8uqqmQx241tpMgu40c9v+ym55ZS8DEgtFrsvQ2xhud2gYlx29kKhfMWmhf9K M3U1hibkY9V31IsgpbLkXGg1dny2dzzzUih5gIViScs4kC100SurlLQQCROWQtTl RmkZAU33IYucwJW75iuv5gxyZkOsD29QXNSHGEUe0BooakzrnKlhriuzvaGXKhRF -JYosiEYEEBEKAAYFAkzSCcAACgkQizpgHwjJdeVlSgCePJsV6CDpUawSxj0/ceuB -Ht1u2vUAoOc7vAkh3ihIjKpbf7XU/XnDf2NYiQIcBBABAgAGBQJM0sMzAAoJEJu4 -Y7D1G7iKnBYP/3aYH+gw1dmAV+/ytfaEFioFpkB5v4nMUDrZnlnM1xSLsxSsqyWx -rxDpvGVf7VN9bMrXm1oKXBwnpnrdXvBeaHmH7cIjpN7sp8L1QQ2g+6B9Vml3DQmS -VWnX8YwiFYPfVEpLvlIGlA9lc+n1JfAPsxH3qb+L+g+4qUW3LAvGNTi63t9rjT8g -RYzWFcYBTruLdT2MdXIYpVGCdYvM2+QwLFcSsgNaK6LHuF5gW9lPz8fAVkgJ6M0g -cFQK/AiKaFIicX8bGIQX3YCdo2gaE76CbJiICN6h32AnlukwISeYkfmEHl7VOx6q -qIY7jjmP9p9Cmv5qQGy7UhwXFko5dBHvaG9Ac6N/FskXxBt87+TEort4ghcHPSa2 -EV355h0kRPeChOfTjTHHZi7RfS+YVOoaQVPyxe79GHX5La4lQn81uylrU99Sow+2 -QNuB61exOPyHgT/QBXDZ/0fucUW36uEKT4YSFAHV9lGpGywwLkKqyHNA3VGGf3Xc -+FpOzlxlfD/TYzPklbPiOddznGFa3gTsoNHvHjaG0XbA6coErCuchF3zDVVtBZ1f -f3HdYH9m7NoRHcoUVqj00lixJ8PqMyS1CzXJ9fFRo5G1LB80CkPryY1rW9+IewoA -2fKAuE0GWtQbVR8+I0KjOv0kOzMzA2exZ+cYME6sK2I9bfEJCXLAQFdTiQIcBBAB -CgAGBQJM1t6BAAoJEJrilv0C6fZbyxIP/jvJ6wNcj1ko/mZpJTsIkXxOJxc9JF5e -5aCl8rpoXubmWB6zDZKoiJ1Jwl0pxVKRfiHwlP5NO5jne6Njj6xia6rBcHkh0o7f -5JMDNSVehej97y9jc2dX1+kNmzf9eJZTeE8CUqBELY673L/dITg1eOgmwbvFZ50t -Tc+PnP5eHTlXRcIdb3mRVHmwjlvFVb4fxy9DEkDOUK3ZsKpWUMl2a5XUURwKOwGW -sQ+9CwHd3reSSI8GEtutQTZTc1XTTbukYRYjyHpY9nRWE7+dd5jgv6Jv184Za5bR -CtILNmYjgJFtb2/5djLNErAIpGIg31+sABq8D1whe/AQhq9duTkc0+sNQdP9Abc9 -FkTeat3vFk7D+L1YFMY6Q1EcM97SbsBTf/I4Grm7ndNGEBHgi2RN9CxToTpPzkzG -Uz2soE8ccB6aInbPldbxmwarZ8WZbMNC0hLa4PKmFfD6ptP4cDkY+F+qQLV1h1bo -4Ccse/dDXfE4h0j23+uowGvT0ZXU9Uq2cpaij+9Y3clMVgly5aHDYv7a7CXznMO8 -fjyh3ZcQOjvNEusRPH2c5akiOYWF+xz7cqvzL+CI4SX43NFK9A/lSnJiFfMzus34 -nqydBsJLYCOx0CZAz+aLwkxFJzcmre3Qv/8Grnw3gQfGBHa/OPiHKQ4zIZncVYqI -y7UHY0KiTZVuiQIcBBABCgAGBQJM1wKOAAoJENIc0iPujg3VOTcP+gKPRPv+Gbs/ -X/8x3G7rwIuo14+1xKBJZco8kmSGWEpos/DKPo9Aw5Gcgz6gOlh2EVWyGjwaoXdE -mhPLOhyTf7EVbUuIpmLZGoA4AAR4OnJRxGjmwTCkPoUZ+U8lzSG6VpSRmmTOylZV -Hs6kmaRzvC0puxAdUEYL21IbQyLODXR0k3DmjY3LLssPMPiXuT428HVvCiJdPu0s -b3jEViA65E7cipu1nF0PJBUBNAqVMHyydXT/yXKxHVLCJOHWeD3ZUzorxRc0e+Vj -PfVtaY/nR1GDLKm3AtUDYZNXIB4YfYpwtulrlfNv+ia60ejAQZDyjx+eG0r+cw7v -L8WwrAZLC5NitH6I8xESKzdJ8sTGnfVdexMsUvwvFPBJ3jNoxZI8my35BK/snap3 -eBDj2sNU8tE0R0L09QpytwMQorqRFha86kcrmsPB6po83za3xoli7GiI6P6pW64W -2X8d1sLLUM7BcPyWYZ/Ps7chnHb4eRUVHuAuDG/v7GNzHzFWEbCV+/lTjCXCVnRL -VOfwkMjWi2HN/GifrDVEiXyqGW2uGpLT05a1ppNu8fMvNwqzIm3If5o9wqdU0Pjf -mFWRKILqoXuE9nWdtfXrAMBK3t1nV/HuMVrwuvMIPo2yPTxb2oHlrsqY9HuWYugm -5TIo/bbUGHduo2VAKOoYmk6Hg8a6h7WCtB9KaW0gSmFnaWVsc2tpIDxqaW1AamFn -dU5FVC5jb20+iQI3BBMBCgAhBQJM0gjBAhsDBQsJCAcDBRUKCQgLBRYCAwEAAh4B -AheAAAoJEDTqduZ5FIWoA80P/18XFs37N7+D8VFB8NsU3kBTvh9UZx2x+ZGcHIH0 -MnEgzACcoOsSSFdcOwgkc2gVGBEgynM1HSmSgtSpxPGrW1UzmKRN5hN9bq/B6hyi -7xAEFyMiOUcTobH85eSAbFuxv1Gb6PbKtnlcZWx5YNlAOi+7OBD2g5lAA7waT5sM -DisxOlgkTYvzn2ouOwnQ2RG8I+qd/htswvgo1wI7GZJcnf9ZFn4ejsJmXoTmC6+Q -J7iI2K/YbSCs/tGy9yowTx0QRO4cOF2Wa2bo33ALCSaNjMOEsu3TTDMCdV/1T6Ys -6ppxfKbT5/bOhWpfGye+mCArMrV1gr9ydo9WcGXkbDWeg+3j+hpsUGmp809fzono -ziZb10TRIa7C9sY+Np+WHPNgZ31RHLY6RWXweqBjkDOPcJyD/tnC6sRugY/CDuRV -eWxfKgUKHaVNLj7XxCTWazxZVT55WFvvNknugSjjp2FKlnHb3lR/KtIUp6YLvSIr -VgdyDAbXW2CV1kamuFrA35bAazXsyvEXye+P8B+lA/pd0achXqxzIlBj0tKNob4u -gCQ3AN/E6Pivjg+o/N+8Uzwiu45yKvuUGmtnKJQTdNF/+5E6QYm95c26VpMYxhq6 -CEISO+GhJnbPB8ND19AUEoNGrvRROE4FsiGNpUWN4/KPW2Pc+mt8Q/yqOnWQM1GQ -xznxiEYEEBEKAAYFAkzSChoACgkQizpgHwjJdeXSpQCgp3af5lJ3s12S9jF9Ipdp -zwVnkPIAoOJEjS3pAs9uuGdImfYzGKc7c8f4iQIcBBABAgAGBQJM0sMzAAoJEJu4 -Y7D1G7iKse4P/ipNLcumGrfCuRk2jpUChmhIc51wdJGeTF3+GPkXYjEckX2nWTqg -KElf0yPfaU8XMqzLnp13tCYg8a8XE/MZR0O6byIbQ3ODr/WASQZ+xhMawSmSiMEu -EWX/VKs2+4hhDaVbC7PluVXoOLz4sgSIU1/QxJoarD8rqIWYZFoS4mp/rlAkiNsw -mM2xeA6sqUTj9hSRQJeqnLI7B5eN2VCB+yooeY8k4AraG8XGJCHwcJprksIPqi4R -EzaE6VNrtA59GKFK37z7kA1//yBm0kCoqkCkC8LFYDEnQhQXdZrZL7zHLQRP9hNG -3CxnKUkD1HzRYNxRemC5Mmvxfj6xCRtBI6bhlNUpKzYWqfslXvVXPy+diJLhbXj9 -u5I2W5AKMlgO00Eg4JRp9WcvOqsVaVD4Tlet8uuIIeLuC28l3w8fjm7TCrHjcjN5 -CH0QWH0nRTNaIR2ogFvIwYAsR9rIN4qJzNy9crYLJEJwcVgTh3tVW4qr8jn7sjVt -MeF3JIZIDGGE/b4ZSeceTdaJ5QsFoXmRT0SEFyRtbT8pE8WhNma7Jl0d2/b/qLV8 -H8n32AKoByuV1Vd3HOaT3XN1yACren64JCqZZCyNNRWa9Wu2fEH428nYjcqMCZQw -PuPyRNQsPnvU1fNHzmPEkA3UtVYwsKtFxnUmCfo30klOhzPTZrl4L1I7iQIcBBAB -CgAGBQJM1t6BAAoJEJrilv0C6fZbNrIQAIX1DqlW7CAI6irpaPq+l5s22nBolPce -MLMhHPgp/vB7JqV6wMDUc33aFDCkDuSFewDQKaf1BSaAQHWCxRfVSkgY/YqBx4vJ -xE24M9ljvH/PEDruCHAem5Aij7TWmPFTKGhV1h4Rt9CWWvSxZQaNFQgUxq+W7HwO -gIxugYiNz7NKt8mdzl/48S4rSf0mvsQ55Z2xM+GMrYMQqAcunIiLNGoaXk6z+B5k -Qmm8T9UnR8cegG6AxIvcFm23KahUWjIYfhLFa/Xeg4ddVwaeN6lhwLOwmzEh9qeg -gOTreZvh/5i7Wwk/LbnRElm/ejkj62p7sxE7RzRNGdWagTRbZO6rfEZQYNoWNnej -jjG0MP2YIXNMEZ8LmLF+r0RWJMzVoLHsTxSD7c4vSNjhERuPgG2XM/OsxX8KN/Zb -Eo/dn2I9vQ7Oa27E7hGvHGzlj+UR3yTdoSoao3gJs9GDqwdyRwFLALMzwRmp1z3r -/4CTowRsebJI9G/G1U+fGJig8RupFnSrh7vMRMsp5JHQ/+aC21UcJ1jk+6P76wJR -BCSYg5gLdMvkK8SxmPGbDD4PrQP2ZkqQjl+ivh9IXKnjle1QgnOWebRMV9LXc8dv -WfEawbavR8bmu9CHZeAqfHFSaflU3A82fX3d+3Pnvq/zQVddJRnUMFju2lxPgsFu -Skzw/eotq+xqiQIcBBABCgAGBQJM1wKOAAoJENIc0iPujg3VGS0QAJRIkubc5Uca -otfdf3fDQwoc8+hN1hMjV5spdQOl8W6dC3fskVoVL/OJ0rCXLFeCCciB2CrXdVMF -xNVDfLisYSY9pvKd+Oku9eMK1ncC/D7Sm3XXMHShAUqnCA/dFhIyY1LEDL03qqTW -PjmCXFO45jA0pGwlbpT92GVxOui8sUL/YFZQ1Z1mQTpiiZj/qsScivI8P++PMOqu -IzuXgK1qGhuHS+DnuxKo5xDvVvOfiPhLW0A0EcjmZ94hedCxCkN8JpzdGOnM/WEI -X1RNvUML4nqz3CK0CGQfzpttb7PmNDYprw8td99Z3rK79CA9CdhRA1sREnNxfeWd -L/+8EyBm6zHHNwA+kwMCFx8iDeDF86bcia0WQiOihFW23yT4J8XtzrNcMMdaduOy -f6MupTn6eNlsQDOCm1kLFffkCnrUStS8NB7yhOQhGfEJbllHeq3esgoA1ivSpp41 -mtDdrlE9m/MFilrrvv8VNAaTZqptqJIASRIE3b03SVskqcgzTId0V6AkpvzKArrS -2ratHqDE4Z3Kv5Mo69nq9iju+WvRF2dY2XY2z4otX82byFIsqP4kaKTuhfBXKwW9 -SCFWANj2wwbFtoOngjbLZPXS3d1tgVokPDpJfgGEEDgMIyyabN/BJ3By/EJn9GiA -m/UKO72aI4Hk/0RfGi+mYyJRO83Zrt/AtB5KaW0gSmFnaWVsc2tpIDxqaW1Aamlt -amFnLmNvbT6JAjcEEwEKACEFAkzSCNsCGwMFCwkIBwMFFQoJCAsFFgIDAQACHgEC -F4AACgkQNOp25nkUhajI9hAAuSZHbMznyoM0ANPP2bTkkFwT9WkdB33Tdbs+5893 -sDnq59xT4Z80JcXzH3WFtQ76J4GYtU87DpGZUsYt8EZOo+rGUySGDOw7BbaNR9vq -pMrH2ZMJFAx1GsL22csHhXOiZNdvoL3Ns7k7ni3/dcJpVp5RUFgWyBUyybymAE0X -kv1ER8sPha/aZvbQg5Xr0pKKA+mU3G/1KEC0prVsb7j6U2BoZGfP/5Svk22ZrCqT -uImBXVNu+Mz+7LjZKnityc6ZTx2pFiJMPBI1XiXO40ix7ctyMM+QtKUPkSnGsJn3 -JPasomIL6SrDjAVHu1HdnqAYUWvjc038rj+/ntuvqoH7NYZDvA7sFcZjZyhSt2ci -46G9aCX7KZh7JH4pMG028E80jDofWSFxHxXVHo7ERBghKRhkjj1lAwdnrT3lTED7 -TX0oJbFwAT6h1+rjWJOOGlQpFPQ5+0LkcyTiq9790agphfm8RF4oVqTaCFdbltr6 -s1a6Va0H2z68Rp7wAs0jmjEZoMC9G06BsWqXb8/RwtsOhDfQqdevnEyk6ejecX+0 -YaA1Y7jVvfiho3nCHVBKO2UVpv3TpEShnVug/hl0oY9UZIsGe41JMp88CL2MJZt0 -HUvbSFOrNNdzSpi1jOaJ/UkWcC4kIUTUqwomD1hz8adqUUhR/dMWUXevHvdoF7lu -95iIRgQQEQoABgUCTNIJ/gAKCRCLOmAfCMl15R6vAJoCZeiA1glNhoaQIcQlzKBt -aSTN8wCgvfk6xZ1+PYU2b0pmBS14mg4DYHWJAhwEEAECAAYFAkzSwzMACgkQm7hj -sPUbuIpeChAAwxvkZYeJME3ox3WKbqYb54PeKKB+J9dSHQs3bvu2yWq0+pMUEmx6 -tdAPjP0VgGvjulfy2VrM4wUgBJ4CzPAM0KRsRiYE7C3cLQ2D3Uj35r4ws+UfkD4Z -DKoCMPKcfSOVFiv706JgJojIgaDJqYMn2b7y3HkA2yGuPQ0kWG9HxuOjdrbLB64y -ipkukAXFWcYskUcEgQfU19mmYHIKErjXPCc3AV2TCYdd6zgj3WpJ6aBd+dxJ456C -OvlIVx+AlCb0LhnQJtfU0B1lhSwU+eqbMN6ttkNgkxAtkBz7hAM7rQQvOAhrOhTn -FQakkqhOj1bEp1ofwi+EfPjv2162a149cavWCbsPnxvjlhbAkHq/upk+a9glSELP -7M9U4W04e/kFGQh3QaMxw829cc9tmysHxmKi79btfLNJMEzwzXhRsY1uoJ+MkCA9 -GIzOzFC+VzGcEPWXwFUszozj7wTTBwdd9FaF75pJ6SZ01cIrCv9agUnYHST62nYF -Kwy7gtBm9eVLSjUA2l/avp99GVexdKy+HfWVgOP/d90UZgX6gsnemB1C2u0LjNQr -cfm7+8EsgekJNZqOdQqqHwJYEV2BHu3YXNAlFYCvROd/+ffqLhbgH2QMD6zOhBZ8 -MCN0KjC+WrGsN1F3jfNN5iETymZu3icu+aSBO55czPQgcFa4JgPoKyqJAhwEEAEK -AAYFAkzW3oEACgkQmuKW/QLp9lvPvg/+J58Vek+EyGg3u7pACHDru4UilxwLcnUU -Ywip+xCWmyHYjVRxyenkUgHAu1O3yDuFNf2tKW4cFCZ8KVhpsOiz6EKQHHitwh5R -2vh7gT+4lcOJSiMOq5yrGvJlVdsqf6HjDielzPBS6ByVblqsl2GoiP6tw41nenYM -5jDWpvRnO53qp/bOmlAGP6ej8WJOtF2dlr1rDmz4+XGh7NqvytWYu2GLPKSx5PCA -7e+vdwEvuE1MdwJQ81izI/0HXL39jqw5fKUyci+cs07dTUrzXftm3qE0j6+H/y/1 -rK2QY7xqBsQUsGRV+tYSPFaahQFF+QxF+SfQRhjo2BXJkiw2Q8hcN9TKEzdY3Ngi -LH06G4nVOC4YmRIeMsdPfQSUQLPgpWfjzB9Twf3gNIyN78vfu4gB3AQlcpuAgGVe -4xAZwjrbUJVSVLa27C5ZS0vlU0Kl79KLRmj30UBt6DjrGrj4IZduzUyvJ2+L+hp/ -LzOEJIjyzdfpLhoLfeb/ceMY6OXt/lqLLSgdeU84uOdpQM82LvVfKUqkcJEribhS -N+CpV/1xsWmoDihCS79w7OsaJxmMu7a9ksxJsuKxmFABMOaZ4lhdU5T8NaYXCpuH -ti0aKFFWqdDu2sYUUAmMpj1pW+K2bFl4qwKUvsi8xbWlzBlR8vOtTJAnYEC1ErR4 -QieuW7Myj+eJAhwEEAEKAAYFAkzXAo4ACgkQ0hzSI+6ODdWmvxAAgrvSD8lIIVyp -NvKNWKXjIMLIlUqcH5I4SmKcixB6UL80j2+z17WT6wcvvgV54uM49yTa8KLpBBwB -d8a1WfsWyVQNZV7RiwSnl/WwNua/rv/krKlVmDvcKIcwgJiBTkc0jYcrMwKg07S3 -zla6mg/nhwlfNhdeKDLHG7CMNhNmLxmwTtoUfFMW8sxVATcX73eHBAhpHMDAbXzA -xVdyTS5i4eO7vXddBq2sKIEecXZ8r1eqNsCR0VhNEbh8o2bKwt3sZYqVdI/eaEiS -25sWzx+lCXKYycxOfBcQJKTle6NShTNa9bPq2cUiYJPZNAgd7lGdOoPYD5DqjIFL -z6TcqW4PWNjnZkiamyue9lbI99whCUkemnRDM+tIS/0N76FN7ROom9Sxm5+vL6Ei -B5TXJe7gK4/CanENhSPO5h2MtD5EiFV+ALv6eQzjG+VuBh7GfZPR1wX2hhOkhbBd -p0aQITE5X8EfkLbYwvDCkKFVXknc+XfbAqczCoLIT+MC+TQPVRwiZoOhjA7Oh0mn -Q9keDiWfkMpMFDeu6+l3Im2xYDNzCTdSPlGLOZt15tUIonw55gOf88ScMPP7ri2A -cGxHP6fpgB8KRqjiMrEkuqDWJ26Q6/4K4CxMt4zC7F0PZNDjsJfMFrgBBOnGeEzZ -3uwBU/OPixA2toAFaryvY84tEFOAqCS5Ag0ETNII5QEQAO1cyflVhAw/kl1NI9ZS -GfcFmulOt9hM6PyKihstoppuLWdMWZ2OY7ZEnS2Ots6kkZ4GY4ak/p19sDHlC6O4 -x/dlYMLcbd8kpIE0naTshCRCuPPVwiiXCtlp6odemYpxgDgGCnEJ7NaW4AeauNUN -R2VrTS76htpuMvgGydqmZ7RHGtwTRp9QYniRkvoO3Yf06E0YSpFv9r729h7gE26y -bjCzlKHqYek5GgWlD2zeW9Dj/6y792sasQ0mYbp1Z4hR7/jFXfXq5LgTJUUDypRY -Emzg34nnRYwRtRsi0+Gahpfxzph3Pw2r/OSrNV6N9/1mtN2pB1UpwxbrFgSw6A/W -6004LXX0OR5ZazKYgwpmiQqF1hYjIijQr6ej4Kzk+lHglz+F78U4Oa1XVlpX52lS -7Cxze2pKhg44TybpzeivmvPPuC5kY6SBk+JFWi+YOR79CaJG2fH74DIJJsqoBeHU -FsS/IyFs7aO348ySyz7AUgn/yUopH/B1re6fMqtfxJez6ZFn0ZUbB5oZg4F4sPBz -YJLPhmqItqTISaaUGVoiD3GLxEVV9DeqWevsWmt+RlnyV+R6OZuZ1YR6usYNLbEU -1PY5VgAjgri+/GS6ujwXDbo78kZU/RVqTA6f2Ns19Zmcyw/P2zdCLy691gm7Fzke -+zGrreMscTP7mcPz7LlhtI0BABEBAAGJAh8EGAEKAAkFAkzSCOUCGwwACgkQNOp2 -5nkUhaj0ARAApkyrWmGDwiUC4Y/0vzjH18pJt/MlPv+4YC9YtW0hgqjWrWzaWh4H -LP1CkQUUAzZHm6x9bM/AKq1y4j7uSoeH5kFrZJxIM3ikzbw5MI+ZjWlGjGjaaVRL -rrD3i06P3FrQvpvNSfs7imggenLVgiVSaumzIHVN2VDLjQycUTXlYInyXJZuTdMl -5SWrHdBxKmaWXp0HTbuKDEDRDj6IQUaf+FaV/y2nSZl+XmjLaq+1SRDATVWlASaJ -/YDSU0JVtp4IMtpzifhiP/AdgCx87/QpwT6zNfX4WHEF01scSjfC2ahl1+sH5S+s -h+fDQd7ApuWCVfkRKJ2/tn05jg5qkSSxp4hRCYDr3eDdhYMzatFzKulfFhusWBPt -SuqYp2B3KM7Gs/cjJ9gE79TDcSIdT2tQxr1iR6aWbFP5tgijUjcOV3i/GQqZGRz3 -FHA26GvRHR9X4WOcxE7XfaCRbDcRBBOqiHWLI7pOzPPreoTeRWzUkZXEjhr0lyVP -TC/AHoAenOjlxy1V+NEahyBQCT+WgLMgA+Kr0dZBLAz1E7U7FAcjOlLeNKSFaUMi -G38f7S/D8UVWuHHd/G5skc1KIMHL/jnTS6q9o97SfmqmVZ24pKHKF0lM6UM2rRz8 -E/274DCVg+wK/pQiWn9O1zQQRh9KIJACgd71jF6z4RMaRUcvpYYaywc= -=qdRu +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 +1zQQRh9KIJACgd71jF6z4RMaRUcvpYYaywc= +=3SWO -----END PGP PUBLIC KEY BLOCK----- pub 4096R/6D5954FA 2009-11-17 Key fingerprint = 65B2 D44F E74B D5E3 DE3A C3F0 8278 1DE4 6D59 54FA @@ -6962,7 +4221,6 @@ sub 4096R/2B4C4B38 2009-11-17 sig 6D5954FA 2009-11-17 Eric Covener <covener@apache.org> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.11 (GNU/Linux) mQINBEsCKnYBEACb/ldlhkVPPopZa4HvQhckhpQCQBE105N6Q7IPpzq9djl4K9QH TVSOvnhTd0s3J+7bB08jsYbaN2xMLLLZxjGW+EsQppXIsrY6K0m/aJfAb7MtdgoM @@ -6987,199 +4245,43 @@ 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 -aMEt6fgvm36lzfsgLWfrsGUdQJ6cma2+B5osI3vB3PQUZ/0HGoEW1nQM/3RUsnb2 -95dB3A3bzhJDrtGthhg84ztxBnj9WnVllb8CXPpTLJmS1ZWeqgdpIX4lkSYdS1OL -CvJWIYurZ4TC0EKFQ3nScnU0tXLsS9cnjpqQVH5cZU8kZU8cOIlmG9GhYqQjGGPz -BsBXJ/NcGCJLgYmK6ks6btdvPrOeez6G3HNQPI6e6i0X+n5XGWBUkHdv7FL1mSCI -dQQQEQIANQUCTOJSoi4cSmVhbi1TZWJhc3RpZW4gRGVsZmlubyA8anNkZWxmaW5v -QGFwYWNoZS5vcmc+AAoJEKR9Hi3QHg4YtswAoIj238Jwspzp1VJ6jdF03OTym+uT -AJ4+G5xZO8b00Yjnfx0YSyjFvOiCzIjKBBARAgCKBQJM0rRDHxxKaW0gSmFnaWVs -c2tpIDxqaW1AYXBhY2hlLm9yZz4gHEppbSBKYWdpZWxza2kgPGppbUBqYWd1TkVU -LmNvbT4fHEppbSBKYWdpZWxza2kgPGppbUBqaW1qYWcuY29tPiIcSmltIEphZ2ll -bHNraSA8amltakBjb3ZhbGVudC5uZXQ+AAoJEIs6YB8IyXXlqTcAnRUlfUyIBr5K -sisrAkeThmeA7gCXAKDo/DLtoAHtda8clNwhnsXxfUJ3U4kCHAQQAQoABgUCTRxN -tgAKCRA/z1Kf8vJ6BnX9D/0cenA1sQ8jbmjEWOlp4G6mwuHlorD2UVWf/vpJjdbk -HTQXPwdN7UtQiDlB6BMynKOoJzzbp9W8x3tBHgUL63LoehMtmUDzmy519quSIpzY -S21SHPn1WukZSK3Q26gmNbr5spxeDJJsy9jPMLDiHbM7CVmjEyh+e0ms7L1nqXdo -i7d/wBVakfor3MLnrGrpqWHCMnjRHgEKUSOQ3f/aH0kMIzo4G7+7i9/E/F5n64qL -wGFB7odaOIUIRMiqGGUTQ5FWtNrUP3PZiUyYlyd2wK3uBVJf9eS4/6o6vGQ+VFRu -h8L78OMsqEnDl0Fc+y2Nw0s0P3u2KBwvjnWerG8QDDs1SYsohhG6SDZiwT/4/ubQ -8WaYptTZ77TgDdYKd+0Z5of0l816QIl1LX+nNcq7kVRnRbvz+chUecbe/7/cslka -hx0MlwCRUAaxVEbUTaysRffsF54qneagDGHb4L3VqAN0iTKxbWVnRtemb7/wYNlU -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 -3m8PNeECSOwI4SmjPJWB63CJuej9QT6cQ1gIN/T7PD3WOc4btSipaiT4dYgIhFbQ -FlTwRgQ2+XBlpzRczvNczvQMvySFPYwDzQqvHKcXilBf2YKbF5hGWSgDXQLdGyKT -LukuB0YfzxrXYkIoIyuZIQ84Z58qXaEAYokCXQQQAQIARwUCTNLRrUAcSm9zZXBo -IEVkd2FyZCBCZXJnbWFyayAoQ09ERSBTSUdOSU5HIEtFWSkgPGJlcmdtYXJrQGFw -YWNoZS5vcmc+AAoJELDZkbR8QIc3nMAP/jav4fF573xHr4c2jT/Iujt82+s/lefd -Pw1GOwHaDrEB4bL0AlC+MnHCR8T6HkoXJRFIzUzfyrA/hyjzlfXLn/RvfSMFkvoF -tpPzjT5QC2DcagF9Yz7YfaPK78VcKIpmqCP1j4FT4kJMsOMKOpi0Bw0zJEDIxJPL -ByIf6V9bWelkk/IepTxM1dfwSzzM9F9nq8hsmp5daUDsnehTscoomrv4CU8tJ8+V -uDRoWMZi4FECMoxWrZpwhj4dD2Ocgep7fPN9Q1pHf0Wn1Sdbzywin9rBL98UEH2V -BDv6fli2QlyU9zbww62LcTdR8SjlE5fVTt4CUBDnBm3PEIPVkbBeDXriQunVwVNm -afZPbvfLZ3IEUoVfk7Pho6ivwRelb1u70eyP0zudWb8q8G5Qquhb1rq6Ib5SM0XS -D5knEIJQLAEBbbul+SqBW/lcaLLp29mquK1Ci5xC+bBWaY4Yn8x/8Zc0RiJPX16M -uYAaHj/sgJW4nI/BrqftKcFsB7tYFvRE1NBMGIFepq5NcZfWhWbYYglRJOc7TSx2 -jZksSMdfcMEy3nUEn8jnjge+tmKi4gE7KqLMhoD0y1u2dJ9dHshMi5IcM8SsNJNN -fqxBzOI61aS3wxNTOtDA33/6c0Mz8D6CkftRDPlEqa0JyHJdVXIJHk1tCcshEMBX -jEhmJrv0Ty5aiQKTBBABAgB9BQJM0rQoNRxKaW0gSmFnaWVsc2tpIChSZWxlYXNl -IFNpZ25pbmcgS2V5KSA8amltQGFwYWNoZS5vcmc+IBxKaW0gSmFnaWVsc2tpIDxq -aW1AamFndU5FVC5jb20+HxxKaW0gSmFnaWVsc2tpIDxqaW1AamltamFnLmNvbT4A -CgkQNOp25nkUhag2xQ/8D8Rt8++/KUdrXTeM5ID0HZ0FAUe9DNarE6XAT/EWt3Ch -4leZCX3gAbH/Fw1/G/txURqmcwH8/U54QHvJJA0GDHigeealRawZbTYXMzwmscBq -x1on5ztGD+IHWlNaY+oBlvLX6QEIMWBXaywrSNM8fru6Rc5yOs7K3yHgRRWn4t4X -iuMR0eEJRkDD/rJ07yvg0KamtApvK49k+qiPjKU3optLNIlGV5pP+vSSqxWD0Dsp -XEUAlpgTlhHyajHflFCubdaW+IXJuw2ux9JO6dCNJh0Uoylm6/udrUm97196Tq6a -AjZi61ClCGpTg0yGNokvCgRDbrFt4W1TtGwH/iJ0tJq2PDNUm4ATaORlE29q8XmI -g/wi/77pf96XMgQ4F+HOIilS0FGxszBXHoxzYDUmkUB1vVNJvIL29/HjPSFbCZWP -GFlBulwSw1YNRIxa/msV95WdvygbauaR40Rpy3VeOZKUm7JR+wPbbq5XHK1SK0rQ -mCllPwM7FqSgk3Lqs5/DrNFlXtUuk/3ZP3fTJ4MRGgRWktjmwb342imeqi740bA4 -i8oBuQcTpHWmHfEBnQvvYVTqHNbXLL5lmA2TbR7aSQWCiXmw8wk79MNWmwbTU/8R -TzaRdDFwDkAhhbk3ETqe2mh9oZgaZk+ZdmpakJ4jCN71NcKKrar3G8tyI5/aRRmJ -AqkEEAECAJMFAkzS47EgHFNhbmRlciBUZW1tZSA8c2FuZGVyQHRlbW1lLm5ldD4i -HFNhbmRlciBUZW1tZSA8c2N0ZW1tZUBhcGFjaGUub3JnPh0cU2FuZGVyIFRlbW1l -IDxzYW5kZXJAbWUuY29tPiocU2FuZGVyIFRlbW1lIDxzY3RlbW1lQGtleXNpbnRo -ZWNsb3VkLmNvbT4ACgkQm7hjsPUbuIobZA//c9PVF5LXRY1WtK7R9lM3e2nSdr7z -/A5Cj4REWOTjPRMXo515XNmb0od3reGRv2yDtXfyvyjoYA6FU7y64INBWyLWPZMW -5glKEwn9ILVxdD4z3XIJFy+XNPVIRZ1QJRrcMh7B7P4eTPQDPRKdh6xyitYsfYhq -UKX/YQ2lrxqmwEPd1KMGW77rjctHJxF93YNiqvr0O9fYF1jeKHa4w+wjcNbCuiej -AQoV6LbeggUtyk3xZWobPLQt1Lr3JG58le5TUjAXyWPdakTGwRRx8NXUmJ7ciwLA -XUaq3jNMkunQ49JHgY89d3if4yhUyko4Im8I0FE1eV6YFK1aaPv+e4OUCgyGeexw -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 -+d0Rh8SR8ykGuA== -=+Q9G +n4KJrcF7DuKn4/5yw0fic6222v3nkhw7XZZg3iD0r960IkVyaWMgQ292ZW5lciA8 +ZWNvdmVuZXJAdXMuaWJtLmNvbT6JAjcEEwEKACEFAk9vK5gCGwMFCwkIBwMFFQoJ +CAsFFgIDAQACHgECF4AACgkQgngd5G1ZVPr9KxAAiuXpDABDRLJZikCKWOOZhPY+ +jEOz6ce+tH4gmprrZN/h52hGqdYtx+Sus8LJxLSc6dfOzd5nx6ybE/OW6QEx4dDg +4/pkfToZmiOH3R3lKUl1zywa8U6NpQubnLydb/EFssrmD67kqBiXY3nDh4xKLzyj +NW+4F1apIFDIWNz04DOTHXzG4UlXzeGOdHTgC5DGh5aLHjixxvsTfPIvxtgqCn6d +JRQqNmOkS0qesu50QLfcHAr0vK2g3KXRDKIEUZtNpKwIySqsVLy9tFarQw3if79s +B3AwLznfMERDNJWjYavAU+xofKaBBnWQxERUegyHbxH3f/vr7eMboyPVk4yDzo8h +iD0uUMRikq3/ugFsu8wCToBB4H2NBKVoC/uBV5o2AEnt3rHbfkFIjx1yJN0wRM3B +mXZGyPitQPMy4hjZIbbMPbNyXWSRMzemTjEENz4dg6FbbHYVWT5IN5rlRztV28Jk +//2ybwmg+a1kO5ag8IpAR4S/A5k8I3byG4KrMuFRquPWR3eEHAwihPgo6KaO23Gs +skzy53+EINyFIOYU8ti0CeGJ3/VbuQhzRdtc4XbsMzlzovTq+97ZQ/RG778IoxRN +n0URvEKsOgLeiKQLj9i130Rj1pwPanpmSkehzz1+IVx0AvI4M+h5wGpm35MquY5i +3c+Nig4CDvL0LaqkKnS5Ag0ESwIqdgEQAOKpbihh9fxE8CUi5hox+vrBseN5MEpS +vxHM1hTaS3X7I207SBZUG2kbZtgOyyCTq/0oq3KdPgL/YGbk+xz6djXL4EtRSloa +gBaIv9iI4rOI/zY3GGR7RfwOw4JvQlAfpFTKtXpCAgpWgXLOy62O910C3Qqxecuw +OET5lI/bNDGvPUz8NZc2DfvZ4SpIXiCaIJA4/6iwMDtKsFhyyf25SGEyzFB3P8BN +MO1cdnpTaGP/Zt6yraRipdMv3FU1ImRHZN7ol0QwnJLKBVfAmMOCb32NR5GAX90t +DOVglCT5nvs4zqNXkMYgkTHAcDT9+GYRNNf/PogRjTTlt340AOw0LAIIjnk5KUoO +J7b9lu1UECFM9tzP6ZmXLHevjdvvPZc6KEsDwtsE59/Z5CpszEPDbp6SoPuXwNUy +6Z3YIQWiR++V0/ymUpRr04cF2FcJ4sHRSGTkc4DOGTYe77BBh/eikmfsWgNLhfVV +sWAgBgmT5Ma3r4cRdZVMgJq+Qcjgig+RQ1Li6FDvNdNimu/37EUp2W8MMyBKj3SY +J5yiMEk3BUJuipzKL7yv+dZNRyaaBBo90yaiCaxq8ZUxJNHM0BunZ+9e3DYkY12j +VnyUbxBBAC6V2j0NTyZV52yEgAhH+roCeNMcRiYOuF+s5f0rqq4w357+d4kMcb9r +2OV5PLD4Ny8jABEBAAGJAh8EGAEKAAkFAksCKnYCGwwACgkQgngd5G1ZVPp/Sw/9 +G8oqMfK8Pr18FHeCI1of4uVkZrNPGHmqB189lQCI58I/rWMfewDUXZph82DF4pZ5 +jtkoBIPxs/sTb8EVHMhtYzGoEzWq4I9QnjYwWaR68VdV1pXx/vNk28CQGsvrxEJT +b8hEhk9xhfvBbXTVM93yt6JFqlMguGgw0lAMF73RfC/x3bmjuyDv8sjxP5qO3Cv8 +4iIlSzP8qTEy5pCplccxxDfe98adYb7CoHY3GOzSnoB4i63QBqJ1fq3vjnnecthi +qdKb1/CvqdgpRonmC9XTsx9G0u9o1uUFXyzu7bzLrrX3+HV2Pce72hcl8SU5EHjv +PcDlOsyMnZ2k6PzGyymqCV2cyV6yYyZV3BAqzfSwSzhQAzLIuOk62qAuLkydIaoO +YULtoGmU0T9v251IlewhKsCe1UXUJGLLHDbqy4Wq0POvsYQelJB+s6hZOBJRRJYE +d1vl++/FToqWF49hdndrNjsUN9s9ih4u1t+P6poueqeYDmqP145HXpM2GplJodba +J4sY/macw1yZ7Ja9c/fS2UyPxVRZFsCzjYhLLAm9QQuxh9e0NuIaIGkWd4/JgLdm +BEBYRbtmH+z9RpLPIj107FAfMpZYxC4FBExpgEKQSwLit2PMTbCuZFl1PhpICKyn +f4VpPPe0dVsBl8apVrrzXT4zFUxte/ndEYfEkfMpBrg= +=t6ni -----END PGP PUBLIC KEY BLOCK----- pub 4096R/7EB5F61A 2015-10-01 @@ -7188,7 +4290,6 @@ pub 4096R/7EB5F61A 2015-10-01 uid Yann Ylavic <ylavic.dev@gmail.com> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2 mQINBFYNNTIBEAD77QsLP77W0f4zwQu1YRSVvnOSbSWmaYA2G3rnIJ6TTubVj4QA juPGJphGcH4BN8ypOY5aeC5q0F5u2LWMP7Kq4Hz/YMqHlfIzEOWbkE+Q1CbIda1C @@ -7201,102 +4302,55 @@ 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 -=+Xpk +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 +=we/C -----END PGP PUBLIC KEY BLOCK----- pub rsa2048/1AD84DFF 2011-06-16 @@ -7305,7 +4359,6 @@ pub rsa2048/1AD84DFF 2011-06-16 uid Daniel Ruggeri <DRuggeri@primary.net> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 mQENBE36jjEBCADLvVAeRbmk/cChq8p9TvCPI+Q5FGOUlrD2YQ3c2kZLY8ktzH3L c4PsOxVv/xIm4TymaMt4A0uujSV9EOp7go2NYLWZQ3eSUVKS0U+4QwQRG6QKDlnG @@ -7320,443 +4373,176 @@ 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 -AAADYgEbAAUAAAABAAADagEoAAMAAAABAAIAAAIBAAQAAAABAAADcgICAAQAAAAB -AAAJ+gAAAAAAAABIAAAAAQAAAEgAAAAB/9j/4AAQSkZJRgABAgEASABIAAD/7QAM -QWRvYmVfQ00AAf/uAA5BZG9iZQBkgAAAAAH/2wCEAAwICAgJCAwJCQwRCwoLERUP -DAwPFRgTExUTExgRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwB -DQsLDQ4NEA4OEBQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwM -DAwMDAwMDAwMDAwMDAwMDP/AABEIAIAAVgMBIgACEQEDEQH/3QAEAAb/xAE/AAAB -BQEBAQEBAQAAAAAAAAADAAECBAUGBwgJCgsBAAEFAQEBAQEBAAAAAAAAAAEAAgME -BQYHCAkKCxAAAQQBAwIEAgUHBggFAwwzAQACEQMEIRIxBUFRYRMicYEyBhSRobFC -IyQVUsFiMzRygtFDByWSU/Dh8WNzNRaisoMmRJNUZEXCo3Q2F9JV4mXys4TD03Xj -80YnlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3EQACAgEC -BAQDBAUGBwcGBTUBAAIRAyExEgRBUWFxIhMFMoGRFKGxQiPBUtHwMyRi4XKCkkNT -FWNzNPElBhaisoMHJjXC0kSTVKMXZEVVNnRl4vKzhMPTdePzRpSkhbSVxNTk9KW1 -xdXl9VZmdoaWprbG1ub2JzdHV2d3h5ent8f/2gAMAwEAAhEDEQA/AOtlPKilKjXs -pUS5NKzerdf6b0pv6zZNpEtpZq8/+Q/tJKdFz4Ud64PO+vmfaSMStmOzsT73f9L2 -qh/zo64XT9rfqdOB/BLVNPpm9LeuBwvrp1Spw+0BuTX3Dhtd/nsXT9K+sXT+pxWx -xqyCP5l+hP8AUd9F6Sqdfem3qMpShamW8pKBOoSSU//Q6uUlGU6jXuL9aevjo2EB -VBy75bSD2H51v9leZ3W5GTY621xe5+rnuOpP9Zb314yDk/WA0gy2hrKwPAn3v/6p -aGL9WsQ0M9SZIBJ+KbKYjv1ZIQMnj2sdOvEaBGbU8gDw4Xb0/VLpz2aOcJ81Zq+p -uFuHvO0c6IDKCu9kjq8AK7QRDTr28kSux9LwdQRqDwRHgvTG/VHp2hbOniqXWPqd -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 -AAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklN -BAoAAAAAAAEAADhCSU0nEAAAAAAACgABAAAAAAAAAAE4QklNA/UAAAAAAEgAL2Zm -AAEAbGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAA -AAEANQAAAAEALQAAAAYAAAAAAAE4QklNA/gAAAAAAHAAAP////////////////// -//////////8D6AAAAAD/////////////////////////////A+gAAAAA//////// -/////////////////////wPoAAAAAP////////////////////////////8D6AAA -OEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAAAAAABAAAAAA4QklN -BBoAAAAAA2UAAAAGAAAAAAAAAAAAAACAAAAAVgAAABgAUAByAG8AZgBpAGwAZQAg -ACgAcgBlAHMAaQB6AGUAZAApACAALQAgAHQAaQBuAHkAAAABAAAAAAAAAAAAAAAA -AAAAAAAAAAEAAAAAAAAAAAAAAFYAAACAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAA -AAAAAAAAAAAAAAAAEAAAAAEAAAAAAABudWxsAAAAAgAAAAZib3VuZHNPYmpjAAAA -AQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAA -AAAAQnRvbWxvbmcAAACAAAAAAFJnaHRsb25nAAAAVgAAAAZzbGljZXNWbExzAAAA -AU9iamMAAAABAAAAAAAFc2xpY2UAAAASAAAAB3NsaWNlSURsb25nAAAAAAAAAAdn -cm91cElEbG9uZwAAAAAAAAAGb3JpZ2luZW51bQAAAAxFU2xpY2VPcmlnaW4AAAAN -YXV0b0dlbmVyYXRlZAAAAABUeXBlZW51bQAAAApFU2xpY2VUeXBlAAAAAEltZyAA -AAAGYm91bmRzT2JqYwAAAAEAAAAAAABSY3QxAAAABAAAAABUb3AgbG9uZwAAAAAA -AAAATGVmdGxvbmcAAAAAAAAAAEJ0b21sb25nAAAAgAAAAABSZ2h0bG9uZwAAAFYA -AAADdXJsVEVYVAAAAAEAAAAAAABudWxsVEVYVAAAAAEAAAAAAABNc2dlVEVYVAAA -AAEAAAAAAAZhbHRUYWdURVhUAAAAAQAAAAAADmNlbGxUZXh0SXNIVE1MYm9vbAEA -AAAIY2VsbFRleHRURVhUAAAAAQAAAAAACWhvcnpBbGlnbmVudW0AAAAPRVNsaWNl -SG9yekFsaWduAAAAB2RlZmF1bHQAAAAJdmVydEFsaWduZW51bQAAAA9FU2xpY2VW -ZXJ0QWxpZ24AAAAHZGVmYXVsdAAAAAtiZ0NvbG9yVHlwZWVudW0AAAARRVNsaWNl -QkdDb2xvclR5cGUAAAAATm9uZQAAAAl0b3BPdXRzZXRsb25nAAAAAAAAAApsZWZ0 -T3V0c2V0bG9uZwAAAAAAAAAMYm90dG9tT3V0c2V0bG9uZwAAAAAAAAALcmlnaHRP -dXRzZXRsb25nAAAAAAA4QklNBBQAAAAAAAQAAAABOEJJTQQMAAAAAAoWAAAAAQAA -AFYAAACAAAABBAAAggAAAAn6ABgAAf/Y/+AAEEpGSUYAAQIBAEgASAAA/+0ADEFk -b2JlX0NNAAH/7gAOQWRvYmUAZIAAAAAB/9sAhAAMCAgICQgMCQkMEQsKCxEVDwwM -DxUYExMVExMYEQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQ0L -Cw0ODRAODhAUDg4OFBQODg4OFBEMDAwMDBERDAwMDAwMEQwMDAwMDAwMDAwMDAwM -DAwMDAwMDAwMDAwMDAz/wAARCACAAFYDASIAAhEBAxEB/90ABAAG/8QBPwAAAQUB -AQEBAQEAAAAAAAAAAwABAgQFBgcICQoLAQABBQEBAQEBAQAAAAAAAAABAAIDBAUG -BwgJCgsQAAEEAQMCBAIFBwYIBQMMMwEAAhEDBCESMQVBUWETInGBMgYUkaGxQiMk -FVLBYjM0coLRQwclklPw4fFjczUWorKDJkSTVGRFwqN0NhfSVeJl8rOEw9N14/NG -J5SkhbSVxNTk9KW1xdXl9VZmdoaWprbG1ub2N0dXZ3eHl6e3x9fn9xEAAgIBAgQE -AwQFBgcHBgU1AQACEQMhMRIEQVFhcSITBTKBkRShsUIjwVLR8DMkYuFygpJDUxVj -czTxJQYWorKDByY1wtJEk1SjF2RFVTZ0ZeLys4TD03Xj80aUpIW0lcTU5PSltcXV -5fVWZnaGlqa2xtbm9ic3R1dnd4eXp7fH/9oADAMBAAIRAxEAPwDrZTyopSo17KVE -uTSs3q3X+m9Kb+s2TaRLaWavP/kP7SSnRc+FHeuDzvr5n2kjErZjs7E+93/S9qof -86OuF0/a36nTgfwS1TT6ZvS3rgcL66dUqcPtAbk19w4bXf57F0/SvrF0/qcVscas -gj+ZfoT/AFHfRekqnX3pt6jKUoWplvKSgTqEklP/0OrlJRlOo17i/Wnr46NhAVQc -u+W0g9h+db/ZXmd1uRk2OttcXufq57jqT/WW99eMg5P1gNIMtoaysDwJ97/+qWhi -/VrENDPUmSASfimymI79WSEDJ49rHTrxGgRm1PIA8OF29P1S6c9mjnCfNWavqbhb -h7ztHOiAygrvZI6vACu0EQ069vJErsfS8HUEag8ER4L0xv1R6doWzp4ql1j6nYT8 -Z9lUse0EiPFHj8Ee34o/qx1qzPoNGSZyKQId3c3xd/LW4vPPq7fZh9dpre6Gl2w9 -tHe3VehIsZCidQkmP0gkgqn/0eoTqMpTpqo175v9ZWl31pvA5NjBp/VauroP6No8 -AFkZuGLPrXdkkiyl9YsrLdYgNr939VyFn9Vy6rNtVrMesaNDgHF0fnKHIDIgBsYv -SDb1+GWubtnVXa/aYXB9M+sWW7IDLH12NJgFg2rpjnW11faGua9pEBsiZTaI0LIC -JCwXo6p26qp1V/p4drvBpJXO4n1u6je91VWPU6DEmxbNeU7Nx3MyqjU4th8atg/n -Byk6LOr57TTPXMV7OTa0x5EyvQidVxGDiPq+s4xTJFNztT4NG5q7WU5hO6ifcElE -n3BJJD//0umlQyGGyi2tpgvY5oPmQpJ5UbIDRt5bAYRXsLpsAG4nkTKr5fS91ptD -AXcAz28Fo5FDaMq6PpOMkeX5v/VKQsBbCqmwW9Qkb76uFX0ki0bmhog8dgeYXWnp -tOR07H2S0VDbsn2nTb71hXZVNDxZaYbwNJkrocHquC7EZD/pQ0ACdT8E4Ek6qlEA -aBxafqvR9oa59Lw9khrmawDp2K28Xppx6DSz1XzpusMAT9KdVbqva6x1bhtc3kK0 -8gMgeCduPJjIrsL7OO3pGDiW5PUcaltmXLnHc46Ax+ja1v0faEYnVGFXpPuyAIba -1sjxcNNyrynRtjy8IAA33tX5ySb85JOYn//T6QFOoSnlRr2r1Kit+O+3aPUYNHxr -AOolc9kZRpodYATHAXVuAc0tdqCII8iuVz6ziXvqt+hyCeC3s5RZI7FsYJ0CLcl1 -mVnQ1xDG9i4hbHT8fLx5Lb6/TkGrXkxDu30lQfXi02Nyq8dr4Or26ELUwOvY2SW0 -txnv1gNGoBlAVWmgZTXU6turOvybtzC11lTSWWVnc0lv06nub7Pct8OO0HuRKrNf -Qzbjsa1jmt3bG6ABEY/1HBg+LvgiFpPRhbe97RWdGtJ+aFKEc3EszLsVlrftFTof -UdHD876J+kpyn1s15GyV/wA5JRn3JIIf/9ToZTyogpKO17KVgfW3Esvxg+ow+C0H -zHvat6VznWuu0P6m3o1UPc1rn3v/AHXAeypv8r/SIHUGumq6G4HfT7Xl+n9UfVZ9 -mytGjRzXeK28XquBiMLqy1jgSQWjmeJVO3pIzbJ2AkfnEK9ifVjAbBtr3u8CTH3J -h4TrszjjGmh8Sv0fMzeo9T+00gmoNLbHmYngf2l2eJUK6/5R+kSs/BxqqWiupgY1 -vAaICqdf64Kaz0/Df+neIusH+DaeW/8AGvRhGWSQjAalBIhEykXD63VTl/WB/Ucd -5aK2hpLT9JzPa1y6TDyBk4tdwMlzfd/WGj/+kuXqADIAjyWh0bPqoe/FvcGB7t1Z -PEn6TVo5+V4MERH1Shuf3r3aMc3FkJOgk7k6pKMpLNbL/9XelUupdb6d0vb9st2u -fq1jRudH70fuomdnY2BjPysl22tn3k9mN/lOXl/U8+7qefdmXEw8ktbztYPoM/st -TYQ4t9l0pU9B1b665WWHV9OBxsYaeqf5x/w/0TVzWFmGnqdWQ8kgvh5PJ3+1x/6S -HVabWEP9rJhkdkGxhkz27qUxHDQGhWiRu+ofQenX+la5pILDxPYrVF9Q1LtAuZwb -Dbi036gvYJ+I0KfqGc6pno0n9I7k/uhU445TkIxFlumcYx4js3+r/WS4E4mAdpOl -lvceTf5Sy8YQNdTMknkk9yquPVHuPPj5rQqbC2uWwRxRofMfmk5ubMch126BKIEe -azrbnX5h9MSyv2tPYn85yt5VpZVtaYe/2tPh+87+ys+54G2ij6TdJHnyppliiHRZ -1a4YFmKXbmGGtM6t9w9v9VJZjNvoWNB7iXdpkJKH24b8I34/8P5WTiPf+r9H/9bm -PrV1r9o5ZppdOLQdtf8AKd+fZ/5BYu0Bkd3cqJJGp57KTD7dVMAAKC0nqjc2Gho0 -AUnCRrz3Uo3IuPgZmc+xuFUbXUML7CI0Hz+k5E0BZU26us/Zem00sEuAILxyDJ9r -VnDqWQLhYI2jTYdZH8p37yCWudqTPxUm0+KbGJj8unUnqV0pcXza1oHocHIpyag+ -o8aOaeQfNXq+Vy2Pbbi2CyvnuOxH7pW3+0GHDfkVnWNob3DjpCvYstj1aSAa8oa6 -dV8i4WOsLNdnsYPP87/pKoT6UMr91z+T4ShseaaAfzncKINtNrQP5x0E+U9kDK6/ -lukBvegz7KaPz+QfNJN6xJkcjk+aSfUfw4fojX9r/9k4QklNBCEAAAAAAFUAAAAB -AQAAAA8AQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAAAATAEEAZABvAGIA -ZQAgAFAAaABvAHQAbwBzAGgAbwBwACAANwAuADAAAAABADhCSU0EBgAAAAAABwAD -AAAAAQEA/+ESSGh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0 -IGJlZ2luPSfvu78nIGlkPSdXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQnPz4KPD9h -ZG9iZS14YXAtZmlsdGVycyBlc2M9IkNSIj8+Cjx4OnhhcG1ldGEgeG1sbnM6eD0n -YWRvYmU6bnM6bWV0YS8nIHg6eGFwdGs9J1hNUCB0b29sa2l0IDIuOC4yLTMzLCBm -cmFtZXdvcmsgMS41Jz4KPHJkZjpSREYgeG1sbnM6cmRmPSdodHRwOi8vd3d3Lncz -Lm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjJyB4bWxuczppWD0naHR0cDov -L25zLmFkb2JlLmNvbS9pWC8xLjAvJz4KCiA8cmRmOkRlc2NyaXB0aW9uIGFib3V0 -PSd1dWlkOmUxZjZmZGE5LWUyZWYtMTFlNS1hYzQ3LWRkYTJjNDYwZjdlYScKICB4 -bWxuczp4YXBNTT0naHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyc+CiAg -PHhhcE1NOkRvY3VtZW50SUQ+YWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmUxZjZmZGEy -LWUyZWYtMTFlNS1hYzQ3LWRkYTJjNDYwZjdlYTwveGFwTU06RG9jdW1lbnRJRD4K -IDwvcmRmOkRlc2NyaXB0aW9uPgoKPC9yZGY6UkRGPgo8L3g6eGFwbWV0YT4KICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +iAPmu3FX0f8AAEgg/wAASBsBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQIB +ASwBLAAA/+ENdEV4aWYAAE1NACoAAAAIAAoBDwACAAAAEgAAAIYBEAACAAAADAAA +AJgBEgADAAAAAQABAAABGgAFAAAAAQAAAKQBGwAFAAAAAQAAAKwBKAADAAAAAQAC +AAABMQACAAAAFAAAALQBMgACAAAAFAAAAMgCEwADAAAAAQACAACHaQAEAAAAAQAA +ANwAAAMUTklLT04gQ09SUE9SQVRJT04ATklLT04gRDMwMFMAAAABLAAAAAEAAAEs +AAAAAUFkb2JlIFBob3Rvc2hvcCA3LjAAMjAxNjowMzowNSAxMDozNjoxOAAAJoKa +AAUAAAABAAACqoKdAAUAAAABAAACsogiAAMAAAABAAEAAIgnAAMAAAABAMgAAJAA +AAcAAAAEMDIyMZADAAIAAAAUAAACupAEAAIAAAAUAAACzpEBAAcAAAAEAQIDAJEC +AAUAAAABAAAC4pIEAAoAAAABAAAC6pIFAAUAAAABAAAC8pIHAAMAAAABAAIAAJII +AAMAAAABAAAAAJIJAAMAAAABAA0AAJIKAAUAAAABAAAC+pKQAAIAAAADNzUAAJKR +AAIAAAADNzUAAJKSAAIAAAADNzUAAKAAAAcAAAAEMDEwMKABAAMAAAABAAEAAKAC +AAQAAAABAAAAVqADAAQAAAABAAAAgKIXAAMAAAABAAIAAKMAAAcAAAABAwAAAKMB +AAcAAAABAQAAAKMCAAcAAAAIAAADAqQBAAMAAAABAAAAAKQCAAMAAAABAAEAAKQD +AAMAAAABAAAAAKQEAAUAAAABAAADCqQFAAMAAAABAGkAAKQGAAMAAAABAAAAAKQH +AAMAAAABAAAAAKQIAAMAAAABAAAAAKQJAAMAAAABAAAAAKQKAAMAAAABAAAAAKQM +AAMAAAABAAAAAOodAAkAAAABAAAAAAAAAAAAAAAKAAAJxAAAADgAAAAKMjAxMjow +MzoyNCAwOToxNDo0OQAyMDEyOjAzOjI0IDA5OjE0OjQ5AAAAAAEAAAABAAAAAAAA +AAYAAAAeAAAACgAAArwAAAAKAAIAAgABAQIAAAABAAAAAQAAAAYBAwADAAAAAQAG +AAABGgAFAAAAAQAAA2IBGwAFAAAAAQAAA2oBKAADAAAAAQACAAACAQAEAAAAAQAA +A3ICAgAEAAAAAQAACfoAAAAAAAAASAAAAAEAAABIAAAAAf/Y/+AAEEpGSUYAAQIB +AEgASAAA/+0ADEFkb2JlX0NNAAH/7gAOQWRvYmUAZIAAAAAB/9sAhAAMCAgICQgM +CQkMEQsKCxEVDwwMDxUYExMVExMYEQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwM +DAwMDAwMDAwMAQ0LCw0ODRAODhAUDg4OFBQODg4OFBEMDAwMDBERDAwMDAwMEQwM +DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCACAAFYDASIAAhEBAxEB/90A +BAAG/8QBPwAAAQUBAQEBAQEAAAAAAAAAAwABAgQFBgcICQoLAQABBQEBAQEBAQAA +AAAAAAABAAIDBAUGBwgJCgsQAAEEAQMCBAIFBwYIBQMMMwEAAhEDBCESMQVBUWET +InGBMgYUkaGxQiMkFVLBYjM0coLRQwclklPw4fFjczUWorKDJkSTVGRFwqN0NhfS +VeJl8rOEw9N14/NGJ5SkhbSVxNTk9KW1xdXl9VZmdoaWprbG1ub2N0dXZ3eHl6e3 +x9fn9xEAAgIBAgQEAwQFBgcHBgU1AQACEQMhMRIEQVFhcSITBTKBkRShsUIjwVLR +8DMkYuFygpJDUxVjczTxJQYWorKDByY1wtJEk1SjF2RFVTZ0ZeLys4TD03Xj80aU +pIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9ic3R1dnd4eXp7fH/9oADAMBAAIRAxEA +PwDrZTyopSo17KVEuTSs3q3X+m9Kb+s2TaRLaWavP/kP7SSnRc+FHeuDzvr5n2kj +ErZjs7E+93/S9qof86OuF0/a36nTgfwS1TT6ZvS3rgcL66dUqcPtAbk19w4bXf57 +F0/SvrF0/qcVscasgj+ZfoT/AFHfRekqnX3pt6jKUoWplvKSgTqEklP/0OrlJRlO +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 +NrQP5x0E+U9kDK6/lukBvegz7KaPz+QfNJN6xJkcjk+aSfUfw4fojX9r/9n/7Q/S +UGhvdG9zaG9wIDMuMAA4QklNBCUAAAAAABAAAAAAAAAAAAAAAAAAAAAAOEJJTQPt +AAAAAAAQASwAAAABAAEBLAAAAAEAAThCSU0EJgAAAAAADgAAAAAAAAAAAAA/gAAA +OEJJTQQNAAAAAAAEAAAAHjhCSU0EGQAAAAAABAAAAB44QklNA/MAAAAAAAkAAAAA +AAAAAAEAOEJJTQQKAAAAAAABAAA4QklNJxAAAAAAAAoAAQAAAAAAAAABOEJJTQP1 +AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAAB +AFoAAAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD///// +////////////////////////A+gAAAAA/////////////////////////////wPo +AAAAAP////////////////////////////8D6AAAAAD///////////////////// +////////A+gAADhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAA +AAQAAAAAOEJJTQQaAAAAAANlAAAABgAAAAAAAAAAAAAAgAAAAFYAAAAYAFAAcgBv +AGYAaQBsAGUAIAAoAHIAZQBzAGkAegBlAGQAKQAgAC0AIAB0AGkAbgB5AAAAAQAA +AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAABWAAAAgAAAAAAAAAAAAAAAAAAA +AAABAAAAAAAAAAAAAAAAAAAAAAAAABAAAAABAAAAAAAAbnVsbAAAAAIAAAAGYm91 +bmRzT2JqYwAAAAEAAAAAAABSY3QxAAAABAAAAABUb3AgbG9uZwAAAAAAAAAATGVm +dGxvbmcAAAAAAAAAAEJ0b21sb25nAAAAgAAAAABSZ2h0bG9uZwAAAFYAAAAGc2xp +Y2VzVmxMcwAAAAFPYmpjAAAAAQAAAAAABXNsaWNlAAAAEgAAAAdzbGljZUlEbG9u +ZwAAAAAAAAAHZ3JvdXBJRGxvbmcAAAAAAAAABm9yaWdpbmVudW0AAAAMRVNsaWNl +T3JpZ2luAAAADWF1dG9HZW5lcmF0ZWQAAAAAVHlwZWVudW0AAAAKRVNsaWNlVHlw +ZQAAAABJbWcgAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9w +IGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAIAAAAAAUmdo +dGxvbmcAAABWAAAAA3VybFRFWFQAAAABAAAAAAAAbnVsbFRFWFQAAAABAAAAAAAA +TXNnZVRFWFQAAAABAAAAAAAGYWx0VGFnVEVYVAAAAAEAAAAAAA5jZWxsVGV4dElz +SFRNTGJvb2wBAAAACGNlbGxUZXh0VEVYVAAAAAEAAAAAAAlob3J6QWxpZ25lbnVt +AAAAD0VTbGljZUhvcnpBbGlnbgAAAAdkZWZhdWx0AAAACXZlcnRBbGlnbmVudW0A +AAAPRVNsaWNlVmVydEFsaWduAAAAB2RlZmF1bHQAAAALYmdDb2xvclR5cGVlbnVt +AAAAEUVTbGljZUJHQ29sb3JUeXBlAAAAAE5vbmUAAAAJdG9wT3V0c2V0bG9uZwAA +AAAAAAAKbGVmdE91dHNldGxvbmcAAAAAAAAADGJvdHRvbU91dHNldGxvbmcAAAAA +AAAAC3JpZ2h0T3V0c2V0bG9uZwAAAAAAOEJJTQQUAAAAAAAEAAAAAThCSU0EDAAA +AAAKFgAAAAEAAABWAAAAgAAAAQQAAIIAAAAJ+gAYAAH/2P/gABBKRklGAAECAQBI +AEgAAP/tAAxBZG9iZV9DTQAB/+4ADkFkb2JlAGSAAAAAAf/bAIQADAgICAkIDAkJ +DBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwM +DAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwM +DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgAgABWAwEiAAIRAQMRAf/dAAQA +Bv/EAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAA +AAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJx +gTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXi +ZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX +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 +3SR58qaZYoh0WdWuGBZil25hhrTOrfcPb/VSWYzb6FjQe4l3aZCSh9uG/CN+P/D+ +Vk4j3/q/R//W5j61da/aOWaaXTi0HbX/ACnfn2f+QWLtAZHd3KiSRqeeykw+3VTA +ACgtJ6o3NhoaNAFJwka891KNyLj4GZnPsbhVG11DC+wiNB8/pORNAWVNurrP2Xpt +NLBLgCC8cgyfa1Zw6lkC4WCNo02HWR/Kd+8glrnakz8VJtPimxiY/Lp1J6ldKXF8 +2taB6HByKcmoPqPGjmnkHzV6vlctj224tgsr57jsR+6Vt/tBhw35FZ1jaG9w46Qr +2LLY9WkgGvKGunVfIuFjrCzXZ7GDz/O/6SqE+lDK/dc/k+EobHmmgH853CiDbTa0 +D+cdBPlPZAyuv5bpAb3oM+ymj8/kHzSTesSZHI5Pmkn1H8OH6I1/a//ZOEJJTQQh +AAAAAABVAAAAAQEAAAAPAEEAZABvAGIAZQAgAFAAaABvAHQAbwBzAGgAbwBwAAAA +EwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAgADcALgAwAAAAAQA4QklN +BAYAAAAAAAcAAwAAAAEBAP/hEkhodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAv +ADw/eHBhY2tldCBiZWdpbj0n77u/JyBpZD0nVzVNME1wQ2VoaUh6cmVTek5UY3pr +YzlkJz8+Cjw/YWRvYmUteGFwLWZpbHRlcnMgZXNjPSJDUiI/Pgo8eDp4YXBtZXRh +IHhtbG5zOng9J2Fkb2JlOm5zOm1ldGEvJyB4OnhhcHRrPSdYTVAgdG9vbGtpdCAy +LjguMi0zMywgZnJhbWV3b3JrIDEuNSc+CjxyZGY6UkRGIHhtbG5zOnJkZj0naHR0 +cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIycgeG1sbnM6 +aVg9J2h0dHA6Ly9ucy5hZG9iZS5jb20vaVgvMS4wLyc+CgogPHJkZjpEZXNjcmlw +dGlvbiBhYm91dD0ndXVpZDplMWY2ZmRhOS1lMmVmLTExZTUtYWM0Ny1kZGEyYzQ2 +MGY3ZWEnCiAgeG1sbnM6eGFwTU09J2h0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEu +MC9tbS8nPgogIDx4YXBNTTpEb2N1bWVudElEPmFkb2JlOmRvY2lkOnBob3Rvc2hv +cDplMWY2ZmRhMi1lMmVmLTExZTUtYWM0Ny1kZGEyYzQ2MGY3ZWE8L3hhcE1NOkRv +Y3VtZW50SUQ+CiA8L3JkZjpEZXNjcmlwdGlvbj4KCjwvcmRmOlJERj4KPC94Onhh +cG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg @@ -7837,454 +4623,699 @@ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9J3cnPz7/4gxYSUNDX1BST0ZJTEUA -AQEAAAxITGlubwIQAABtbnRyUkdCIFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAA -AABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLUhQICAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFjcHJ0AAABUAAA -ADNkZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAAABRyWFlaAAACGAAA -ABRnWFlaAAACLAAAABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRkAAACxAAA -AIh2dWVkAAADTAAAAIZ2aWV3AAAD1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAA -ACR0ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJDAAAEPAAACAxiVFJDAAAEPAAA -CAx0ZXh0AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBhY2thcmQgQ29t -cGFueQAAZGVzYwAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJz -UkdCIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAAAPNRAAEAAAABFsxYWVogAAAAAAAA -AAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAA -GNpYWVogAAAAAAAAJKAAAA+EAAC2z2Rlc2MAAAAAAAAAFklFQyBodHRwOi8vd3d3 -LmllYy5jaAAAAAAAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAAAAAA -AC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IA -AAAAAAAAAAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFj -ZSAtIHNSR0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAsUmVmZXJl -bmNlIFZpZXdpbmcgQ29uZGl0aW9uIGluIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAA -LFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAAABOk/gAUXy4AEM8UAAPtzAAE -EwsAA1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAAAAAAAAABAAAAAAAA -AAAAAAAAAAAAAAAAAo8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQAAAAABQAK -AA8AFAAZAB4AIwAoAC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACB -AIYAiwCQAJUAmgCfAKQAqQCuALIAtwC8AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7 -AQEBBwENARMBGQEfASUBKwEyATgBPgFFAUwBUgFZAWABZwFuAXUBfAGDAYsBkgGa -AaEBqQGxAbkBwQHJAdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgCQQJLAlQCXQJn -AnECegKEAo4CmAKiAqwCtgLBAssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNm -A3IDfgOKA5YDogOuA7oDxwPTA+AD7AP5BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASa -BKgEtgTEBNME4QTwBP4FDQUcBSsFOgVJBVgFZwV3BYYFlgWmBbUFxQXVBeUF9gYG -BhYGJwY3BkgGWQZqBnsGjAadBq8GwAbRBuMG9QcHBxkHKwc9B08HYQd0B4YHmQes -B78H0gflB/gICwgfCDIIRghaCG4IggiWCKoIvgjSCOcI+wkQCSUJOglPCWQJeQmP -CaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrcCvMLCwsiCzkLUQtpC4ALmAuw -C8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUANWg10DY4NqQ3DDd4N+A4T -Di4OSQ5kDn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJECYQQxBhEH4QmxC5 -ENcQ9RETETERTxFtEYwRqhHJEegSBxImEkUSZBKEEqMSwxLjEwMTIxNDE2MTgxOk -E8UT5RQGFCcUSRRqFIsUrRTOFPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbW -FvoXHRdBF2UXiReuF9IX9xgbGEAYZRiKGK8Y1Rj6GSAZRRlrGZEZtxndGgQaKhpR -GncanhrFGuwbFBs7G2MbihuyG9ocAhwqHFIcexyjHMwc9R0eHUcdcB2ZHcMd7B4W -HkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCYIMQg8CEcIUghdSGhIc4h+yIn -IlUigiKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZclxyX3JicmVyaH -Jrcm6CcYJ0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2 -K2krnSvRLAUsOSxuLKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1 -MGwwpDDbMRIxSjGCMbox8jIqMmMymzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWH -NcI1/TY3NnI2rjbpNyQ3YDecN9c4FDhQOIw4yDkFOUI5fzm8Ofk6Njp0OrI67zst -O2s7qjvoPCc8ZTykPOM9Ij1hPaE94D4gPmA+oD7gPyE/YT+iP+JAI0BkQKZA50Ep -QWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RHRIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7 -R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrESwxLU0uaS+JMKkxyTLpNAk1KTZNN3E4l -Tm5Ot08AT0lPk0/dUCdQcVC7UQZRUFGbUeZSMVJ8UsdTE1NfU6pT9lRCVI9U21Uo -VXVVwlYPVlxWqVb3V0RXklfgWC9YfVjLWRpZaVm4WgdaVlqmWvVbRVuVW+VcNVyG -XNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg/GFPYaJh9WJJYpxi8GNDY5dj62RA -ZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpIap9q92tPa6dr/2xX -bK9tCG1gbbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFzXXO4dBR0cHTM -dSh1hXXhdj52m3b4d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyBfOF9QX2h -fgF+Yn7CfyN/hH/lgEeAqIEKgWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6GcobX -hzuHn4gEiGmIzokziZmJ/opkisqLMIuWi/yMY4zKjTGNmI3/jmaOzo82j56QBpBu -kNaRP5GokhGSepLjk02TtpQglIqU9JVflcmWNJaflwqXdZfgmEyYuJkkmZCZ/Jpo -mtWbQpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUehtqImopajBqN2o+akVqTH -pTilqaYapoum/adup+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4trqGvFq+L -sACwdbDqsWCx1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm40blKucK6O7q1 -uy67p7whvJu9Fb2Pvgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZG -xsPHQce/yD3IvMk6ybnKOMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/ -0sHTRNPG1EnUy9VO1dHWVdbY11zX4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i -3ynfr+A24L3hROHM4lPi2+Nj4+vkc+T85YTmDeaW5x/nqegy6LzpRunQ6lvq5etw -6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/8ozzGfOn9DT0wvVQ9d72bfb794r4Gfio -+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t////7gAOQWRvYmUAZAAAAAAB/9sAhAAK -BwcHCAcKCAgKDwoICg8SDQoKDRIUEBASEBAUEQwMDAwMDBEMDAwMDAwMDAwMDAwM -DAwMDAwMDAwMDAwMDAwMAQsMDBUTFSIYGCIUDg4OFBQODg4OFBEMDAwMDBERDAwM -DAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCACAAFYDAREAAhEB -AxEB/90ABAAL/8QBogAAAAcBAQEBAQAAAAAAAAAABAUDAgYBAAcICQoLAQACAgMB -AQEBAQAAAAAAAAABAAIDBAUGBwgJCgsQAAIBAwMCBAIGBwMEAgYCcwECAxEEAAUh -EjFBUQYTYSJxgRQykaEHFbFCI8FS0eEzFmLwJHKC8SVDNFOSorJjc8I1RCeTo7M2 -F1RkdMPS4ggmgwkKGBmElEVGpLRW01UoGvLj88TU5PRldYWVpbXF1eX1ZnaGlqa2 -xtbm9jdHV2d3h5ent8fX5/c4SFhoeIiYqLjI2Oj4KTlJWWl5iZmpucnZ6fkqOkpa -anqKmqq6ytrq+hEAAgIBAgMFBQQFBgQIAwNtAQACEQMEIRIxQQVRE2EiBnGBkTKh -sfAUwdHhI0IVUmJy8TMkNEOCFpJTJaJjssIHc9I14kSDF1STCAkKGBkmNkUaJ2R0 -VTfyo7PDKCnT4/OElKS0xNTk9GV1hZWltcXV5fVGVmZ2hpamtsbW5vZHV2d3h5en -t8fX5/c4SFhoeIiYqLjI2Oj4OUlZaXmJmam5ydnp+So6SlpqeoqaqrrK2ur6/9oA -DAMBAAIRAxEAPwCb1ytsdXFXVxVaWxVYz4Fa5nArueKu54q3zxVrnirXM1xV/9Ca -1ytsdXFWicVSrWfMel6Ov+lS1nIqtum7n5/yf7LAtMI1D8xNSmJFnEltH2J+NyP9 -l8P/AAuNJS3/ABb5gLVN7Judug/CmNJTGw896vCyi54XMXcMOLf8GmCkMv0fzPpu -q0jjYxXRG8EmxP8AqN9l8VTeuKHVxVoncYEv/9GZ1ytsdirH/N/mQaHYARUN7cVW -AH9kD7Uv+xwK8knmubqV5pXLvIas7Ekk/wCthTVrVR679KbDDa0rJC5AA3odsFpp -eI5lIoh37eI7Y2ilSKSSBwwqpFCD0II/lxS9H8pa7LqNu1vdGtzCAQ3d18W/yxkU -FkNcCGidxil//9KZVytsdXAryn8wLk3XmQwBqrbokQHgSOb/APEsUhM7TypZG3j9 -SvIqCT7kZinIXMEAmEPkvTHTZnFffCJlTAIuHyLYc1+M8R12yQkWJiE1XyXpnwle -W3WtN8khLtb8j2D2sksNUkRSQR4jEFBFsL8sXEll5hgikaiFjGewo3w75YeTQe56 -hgQ0T8QxV//TmGVtjq4FeT+a0L+b7kAbmRBt/qrgPJlHmzS3P7pR4AZhOcm1kVZe -NaHJRUphH8Jp1OTYo+KvHfLA1lB6xJ6VjM/gpJ+7Eq8lghr5gs3TqZlNPYkHJjk0 -y5vTid8WC0n4hir/AP/Ul9cqbHVHfFWA31kJfOM90SJYHjEsbLuAQFj+L/VbK5EE -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 -1hWw8puPN82Rdg== -=5heD +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSd3Jz8+/+IMWElD +Q19QUk9GSUxFAAEBAAAMSExpbm8CEAAAbW50clJHQiBYWVogB84AAgAJAAYAMQAA +YWNzcE1TRlQAAAAASUVDIHNSR0IAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1IUCAg +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAR +Y3BydAAAAVAAAAAzZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAAAgQAAAAU +clhZWgAAAhgAAAAUZ1hZWgAAAiwAAAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQAAABw +ZG1kZAAAAsQAAACIdnVlZAAAA0wAAACGdmlldwAAA9QAAAAkbHVtaQAAA/gAAAAU +bWVhcwAABAwAAAAkdGVjaAAABDAAAAAMclRSQwAABDwAAAgMZ1RSQwAABDwAAAgM +YlRSQwAABDwAAAgMdGV4dAAAAABDb3B5cmlnaHQgKGMpIDE5OTggSGV3bGV0dC1Q +YWNrYXJkIENvbXBhbnkAAGRlc2MAAAAAAAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAA +AAAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAADzUQABAAAAARbM +WFlaIAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAA +AABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9kZXNjAAAAAAAAABZJRUMg +aHR0cDovL3d3dy5pZWMuY2gAAAAAAAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMu +Y2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +ZGVzYwAAAAAAAAAuSUVDIDYxOTY2LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3Bh +Y2UgLSBzUkdCAAAAAAAAAAAAAAAuSUVDIDYxOTY2LTIuMSBEZWZhdWx0IFJHQiBj +b2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRlc2MAAAAA +AAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2MTk2Ni0yLjEA +AAAAAAAAAAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4gSUVDNjE5 +NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2aWV3AAAAAAATpP4AFF8u +ABDPFAAD7cwABBMLAANcngAAAAFYWVogAAAAAABMCVYAUAAAAFcf521lYXMAAAAA +AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAKPAAAAAnNpZyAAAAAAQ1JUIGN1cnYAAAAA +AAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBo +AG0AcgB3AHwAgQCGAIsAkACVAJoAnwCkAKkArgCyALcAvADBAMYAywDQANUA2wDg +AOUA6wDwAPYA+wEBAQcBDQETARkBHwElASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1 +AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHpAfIB+gIDAgwCFAIdAiYCLwI4 +AkECSwJUAl0CZwJxAnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAMLAxYDIQMt +AzgDQwNPA1oDZgNyA34DigOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARV +BGMEcQR+BIwEmgSoBLYExATTBOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1 +BcUF1QXlBfYGBgYWBicGNwZIBlkGagZ7BowGnQavBsAG0QbjBvUHBwcZBysHPQdP +B2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgyCEYIWghuCIIIlgiqCL4I0gjnCPsJEAkl +CToJTwlkCXkJjwmkCboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3ArzCwsLIgs5 +C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2O +DakNww3eDfgOEw4uDkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96D5YPsw/PD+wQCRAm +EEMQYRB+EJsQuRDXEPURExExEU8RbRGMEaoRyRHoEgcSJhJFEmQShBKjEsMS4xMD +EyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTwFRIVNBVWFXgVmxW9FeAWAxYm +FkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkgGUUZaxmR +GbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzMHPUdHh1H +HXAdmR3DHeweFh5AHmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFI +IXUhoSHOIfsiJyJVIoIiryLdIwojOCNmI5QjwiPwJB8kTSR8JKsk2iUJJTglaCWX +Jccl9yYnJlcmhya3JugnGCdJJ3onqyfcKA0oPyhxKKIo1CkGKTgpaymdKdAqAio1 +KmgqmyrPKwIrNitpK50r0SwFLDksbiyiLNctDC1BLXYtqy3hLhYuTC6CLrcu7i8k +L1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRl +NJ402DUTNU01hzXCNf02NzZyNq426TckN2A3nDfXOBQ4UDiMOMg5BTlCOX85vDn5 +OjY6dDqyOu87LTtrO6o76DwnPGU8pDzjPSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/i +QCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPARANER0SKRM5FEkVVRZpF3kYi +RmdGq0bwRzVHe0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpMcky6 +TQJNSk2TTdxOJU5uTrdPAE9JT5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1Oq +U/ZUQlSPVNtVKFV1VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1kaWWlZuFoHWlZaplr1 +W0VblVvlXDVchlzWXSddeF3JXhpebF69Xw9fYV+zYAVgV2CqYPxhT2GiYfViSWKc +YvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeTZ+loP2iWaOxpQ2maafFqSGqf +avdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpxlXHwcktypnMB +c11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJeed6RnqlewR7Y3vC +fCF8gXzhfUF9oX4BfmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSDV4O6hB2EgITj +hUeFq4YOhnKG14c7h5+IBIhpiM6JM4mZif6KZIrKizCLlov8jGOMyo0xjZiN/45m +js6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSKlPSVX5XJljSWn5cKl3WX4JhM +mLiZJJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFHobaiJqKW +owajdqPmpFakx6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1E +rbiuLa6hrxavi7AAsHWw6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZ +uNG5SrnCuju6tbsuu6e8IbybvRW9j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPU +xFHEzsVLxcjGRsbDx0HHv8g9yLzJOsm5yjjKt8s2y7bMNcy1zTXNtc42zrbPN8+4 +0DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp22vvbgNwF +3IrdEN2W3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3mlucf56noMui8 +6Ubp0Opb6uXrcOv77IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe +9m32+/eK+Bn4qPk4+cf6V/rn+3f8B/yY/Sn9uv5L/tz/bf///+4ADkFkb2JlAGQA +AAAAAf/bAIQACgcHBwgHCggICg8KCAoPEg0KCg0SFBAQEhAQFBEMDAwMDAwRDAwM +DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAELDAwVExUiGBgiFA4ODhQUDg4ODhQR +DAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgA +gABWAwERAAIRAQMRAf/dAAQAC//EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAH +CAkKCwEAAgIDAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIG +AnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPBUtHhMxZi8CRygvElQzRTkqKy +Y3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE1OT0ZXWFlaW1 +xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ +qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEF +URNhIgZxgZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJ +ChgZJjZFGidkdFU38qOzwygp0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG +1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+DlJWWl5iZmpucnZ6fkqOkpaanqK +mqq6ytrq+v/aAAwDAQACEQMRAD8Am9crbHVxV1cVWlsVWM+BWuZwK7nirueKt88V +a54q1zNcVf/QmtcrbHVxVonFUq1nzHpejr/pUtZyKrbpu5+f8n+ywLTCNQ/MTUpi +RZxJbR9ifjcj/ZfD/wALjSUt/wAW+YC1TeybnboPwpjSUxsPPerwsoueFzF3DDi3 +/BpgpDL9H8z6bqtI42MV0RvBJsT/AKjfZfFU3rih1cVaJ3GBL//RmdcrbHYqx/zf +5kGh2AEVDe3FVgB/ZA+1L/scCvJJ5rm6leaVy7yGrOxJJP8ArYU1a1Ueu/Smww2t +KyQuQAN6HbBaaXiOZSKId+3iO2NopUikkgcMKqRQg9CCP5cUvR/KWuy6jbtb3Rrc +wgEN3dfFv8sZFBZDXAhoncYpf//SmVcrbHVwK8p/MC5N15kMAaq26JEB4Ejm/wDx +LFITO08qWRt4/UryKgk+5GYpyFzBAJhD5L0x02ZxX3wiZUwCLh8i2HNfjPEddskJ +FiYhNV8l6Z8JXlt1rTfJIS7W/I9g9rJLDVJEUkEeIxBQRbC/LFxJZeYYIpGohYxn +sKN8O+WHk0HueoYENE/EMVf/05hlbY6uBXk/mtC/m+5AG5kQbf6q4DyZR5s0tz+6 +UeAGYTnJtZFWXjWhyUVKYR/CadTk2KPirx3ywNZQesSelYzP4KSfuxKvJYIa+YLN +06mZTT2JByY5NMub04nfFgtJ+IYq/wD/1JfXKmx1R3xVgN9ZCXzjPdEiWB4xLGy7 +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 +=Sax4 +-----END PGP PUBLIC KEY BLOCK----- + +pub 4096R/DC55C003 2019-05-11 +uid Daniel Ruggeri (http://home.apache.org/~druggeri/) <druggeri@apache.org> +uid Daniel Ruggeri <druggeri@primary.net> +uid [jpeg image of size 13027] +sub 4096R/14FF4720 2019-05-11 +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +AQBgAGAAAP/hD25FeGlmAABNTQAqAAAACAAHARIAAwAAAAEAAQAAARoABQAAAAEA +AABiARsABQAAAAEAAABqASgAAwAAAAEAAgAAATEAAgAAABQAAAByATIAAgAAABQA +AACGh2kABAAAAAEAAACaAAAAxgEsAAAAAQAAASwAAAABAABBZG9iZSBQaG90b3No +b3AgNy4wADIwMTk6MDQ6MDggMDg6MTA6NTgAAAOgAQADAAAAAf//AACgAgAEAAAA +AQAABYygAwAEAAAAAQAABYwAAAAAAAAABgEDAAMAAAABAAYAAAEaAAUAAAABAAAB +FAEbAAUAAAABAAABHAEoAAMAAAABAAIAAAIBAAQAAAABAAABJAICAAQAAAABAAAO +QgAAAAAAAABIAAAAAQAAAEgAAAAB/9j/4AAQSkZJRgABAgEASABIAAD/7QAMQWRv +YmVfQ00AAv/uAA5BZG9iZQBkgAAAAAH/2wCEAAwICAgJCAwJCQwRCwoLERUPDAwP +FRgTExUTExgRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBDQsL +DQ4NEA4OEBQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwM +DAwMDAwMDAwMDAwMDP/AABEIAIAAgAMBIgACEQEDEQH/3QAEAAj/xAE/AAABBQEB +AQEBAQAAAAAAAAADAAECBAUGBwgJCgsBAAEFAQEBAQEBAAAAAAAAAAEAAgMEBQYH +CAkKCxAAAQQBAwIEAgUHBggFAwwzAQACEQMEIRIxBUFRYRMicYEyBhSRobFCIyQV +UsFiMzRygtFDByWSU/Dh8WNzNRaisoMmRJNUZEXCo3Q2F9JV4mXys4TD03Xj80Yn +lKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3EQACAgECBAQD +BAUGBwcGBTUBAAIRAyExEgRBUWFxIhMFMoGRFKGxQiPBUtHwMyRi4XKCkkNTFWNz +NPElBhaisoMHJjXC0kSTVKMXZEVVNnRl4vKzhMPTdePzRpSkhbSVxNTk9KW1xdXl +9VZmdoaWprbG1ub2JzdHV2d3h5ent8f/2gAMAwEAAhEDEQA/AOuLi3UKdWUSS3uo +EkhQZABkIkKumWQ7cCsy6swVdssA07oL4I1R6LZalynbwUSgkuCLY1kyUN1uNjDf +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 +hyjyYeIabpiTE9w+jVVPaYLZj4KxexxETAa0ue4nRoAlznO+i3asyn669D/ZteZl +l1OU6Wvw2tLn72/Scw/R+zv/AMHa5c71P65ZXUq7KaanU47+KyQ1hg7m+s5v6a7+ +p7K1WjhnI0fSO5/YyGcQN7Sdd+s9dTxRhVNtZWfdbbIafH02N2v3fykPF+u+Ja5o +zsd9J4NlR3t/7bdte3/OesF2OLrDbe51tjjJjQKYwgdGsA/FXYCUABDSI6HX7WIy +mTdvc9P6lg5gBwchl5AnaNHgfy6n7bEs22iu/c4a2NDo+Et/76uKZ0x28OBhzeHD +Qj+q4LaazMymVjKuNpqBaxx+lBO73uH0/wC2pxORGo1XiR7OiepYrdGNBPki1Znq +GDVtB8VTZRVUBwCjV2QYAMI2V1l//9n/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsL +DBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBD +AQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy +MjIyMjIyMjIyMjIyMjIyMjL/wAARCAEAAQADASIAAhEBAxEB/8QAHwAAAQUBAQEB +AQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR +BRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3 +ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWW +l5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo +6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QA +tREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMz +UvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVm +Z2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6 +wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEA +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 +zjIJB+RdjYxImSzlmE2uJO6PKA== +=fPn/ +-----END PGP PUBLIC KEY BLOCK----- + +pub rsa4096 2020-07-24 [SC] + 9352 5CFC F6FD FFB3 FD97 00DD 5A4B 10AE 43B5 6A27 +uid [ultimate] Joe Orton (Release Signing Key) <jorton@apache.org> +sig 3 5A4B10AE43B56A27 2020-07-24 Joe Orton (Release Signing Key) <jorton@apache.org> +sub rsa4096 2020-07-24 [E] +sig 5A4B10AE43B56A27 2020-07-24 Joe Orton (Release Signing Key) <jorton@apache.org> + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +2Zvzzqpnur6uMCSE2aZ8 +=FKwf +-----END PGP PUBLIC KEY BLOCK----- + +pub rsa4096 2021-04-21 [SC] + C55A B7B9 139E B226 3CD1 AABC 19B0 33D1 760C 227B +uid [ ultime ] Christophe JAILLET <christophe.jaillet@wanadoo.fr> +sub rsa4096 2021-04-21 [E] + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +Ot6BQHeyFl0mtrYT1mI= +=L7j3 -----END PGP PUBLIC KEY BLOCK----- + +pub rsa4096 2021-09-01 [SC] + 26F51EF9A82F4ACB43F1903ED377C9E7D1944C66 +uid [ ultimativ ] Stefan Eissing (icing) <stefan@eissing.org> +sub rsa4096 2021-09-01 [E] + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: GPGTools - https://gpgtools.org + +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 +ebJKIV3Evw== +=tHCM +-----END PGP PUBLIC KEY BLOCK----- + diff --git a/debian/watch b/debian/watch index e925270..1f01295 100644 --- a/debian/watch +++ b/debian/watch @@ -1,2 +1,2 @@ -version=3 +version=4 opts=pgpsigurlmangle=s/$/.asc/ https://www.apache.org/dist/httpd/httpd-(\d\.[02468]\.\d+)\.tar\.gz |