subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From svn-r...@apache.org
Subject svn commit: r1758694 [1/2] - in /subversion/branches/1.9.x: ./ subversion/mod_dav_svn/ subversion/mod_dav_svn/posts/ subversion/mod_dav_svn/reports/
Date Thu, 01 Sep 2016 04:00:31 GMT
Author: svn-role
Date: Thu Sep  1 04:00:31 2016
New Revision: 1758694

URL: http://svn.apache.org/viewvc?rev=1758694&view=rev
Log:
Merge the 1.9.x-r1758224-group branch:

 * r1758202, r1758204, r1758207, r1758209, r1758224, r1758385
   Fix unbounded memory usage when mod_dav_svn is paired with mod_headers
   or mod_deflate.
   Justification:
     Resolves a long-standing memory usage issue that can make Subversion
     unusable with a seemingly harmless server configuration.  User
     reported (issue #3084).
   Branch:
     ^/subversion/branches/1.9.x-r1758224-group
   Notes:
     r1758202 is included to avoid unnecessary conflicts.
     r1758204, r1758207, r1758209 and r1758385 lay the necessary
     groundwork for the fix.
     r1758224 is the fix itself.
     .
     The backport branch is required, because of the text conflicts in
     mod_dav_svn/repos.c and mod_dav_svn/merge.c.
   Votes:
     +1: kotkov, ivan, rhuijben

Modified:
    subversion/branches/1.9.x/   (props changed)
    subversion/branches/1.9.x/STATUS
    subversion/branches/1.9.x/subversion/mod_dav_svn/dav_svn.h
    subversion/branches/1.9.x/subversion/mod_dav_svn/merge.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/posts/create_txn.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/dated-rev.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/deleted-rev.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/file-revs.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-location-segments.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locations.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locks.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/inherited-props.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/log.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/mergeinfo.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/replay.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/reports/update.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/repos.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/util.c
    subversion/branches/1.9.x/subversion/mod_dav_svn/version.c

Propchange: subversion/branches/1.9.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 04:00:31 2016
@@ -10,6 +10,7 @@
 /subversion/branches/1.9.x-r1706428:1711251-1716560
 /subversion/branches/1.9.x-r1725180:1727683-1739396
 /subversion/branches/1.9.x-r1757529-group:1757739-1757935
+/subversion/branches/1.9.x-r1758224-group:1758407-1758693
 /subversion/branches/1.9.x-rep-cache-db-fixes:1743185-1757778
 /subversion/branches/10Gb:1388102,1388163-1388190,1388195,1388202,1388205,1388211,1388276,1388362,1388375,1388394,1388636,1388639-1388640,1388643-1388644,1388654,1388720,1388789,1388795,1388801,1388805,1388807,1388810,1388816,1389044,1389276,1389289,1389662,1389867,1390017,1390209,1390216,1390407,1390409,1390414,1390419,1390955
 /subversion/branches/atomic-revprop:965046-1000689
@@ -100,4 +101,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1660545-1660547,1660549-1662901,1663003,1663183-1663184,1663253,1663286,1663338,1663347,1663355,1663374,1663450,1663500,1663530,1663671,1663697,1663706,1663738,1663749,1663791,1663991,1664035,1664078,1664080,1664084-1664085,1664187,1664191,1664193,1664200,1664344,1664476,1664480-1664481,1664483,1664489-1664490,1664507,1664520-1664521,1664523,1664526-1664527,1664531-1664532,1664588,1664593-1664594,1664596,1664653,1664664,1664672,1664674,1664684,1664927,1664938-1664940,1664978,1664984,1664997,1665164,1665195,1665213,1665259,1665318,1665437-1665438,1665609,1665611-1665612,1665845,1665850,1665852,1665873,1665886,1665894,1665896,1666096,1666258,1666270,1666272,1666379,1666449,1666690,1666832,1666851,1666965,1667101,1667106-1667107,1667120,1667228,1667233-1667235,1667249-1667250,1667258,1667290,1667301,1667471,1667691-1667693,1667699-1667700,1667715,1667941,1667976,1668320,1668598-1668600,1668602-1668603,1668607-1668608,1668618,1668625,1669743,1669746,1669749,1669945,167
 0139,1670149,1670152,1670329,1670337,1670347,1670353,1671164,1671388,1672295,1672311,1672372,1672404,1672511-1672512,1672578,1672728,1673044,1673062-1673063,1673065,1673153,1673170,1673172,1673197,1673202,1673204,1673228,1673282,1673445,1673691-1673692,1673746,1673785,1673803,1674015,1674032,1674170,1674301,1674305,1674308,1674339-1674340,1674406,1674415,1674455-1674456,1674475,1674487,1674522,1674580,1674626-1674627,1674785,1674891,1675771,1675774,1676526,1676535,1676538,1676555,1676564,1676570,1676665,1676667,1676769,1677003,1677191,1677267,1677440,1678147,1678149,1678494,1678571,1678734,1678742,1678745-1678746,1678755,1678839,1678846,1678894,1678950,1678963,1679166,1679169,1679228,1679230,1679240,1679287,1679864,1679866,1679909,1680242,1680264,1680495,1680705,1680819,1681317,1682714,1682854,1683071,1683126,1683135,1683266-1683267,1683290,1683303,1683311,1683378,1683387,1684034,1684077,1684322,1684325,1684344,1684412,1684940,1685034,1685085,1686175,1686239,1686478,1686541,1686543,
 1686554,1686557,1686802,1686888,1686984,1687029,1687304,1687389,1687769,1687776,1687812,1688258,1688273,1688395,1689214,1689216,1689721,1689729,1691712-1691713,1691924,1691928,1692091,1692093,1692098,1692448,1692469-1692470,1692798-1692799,1693135,1693138,1693159,1693886,1694023,1694194,1694481,1694929,1695022,1695600,1695606,1695681,1696222,1696225,1696387,1696695,1697381,1697384,1697387,1697664,1697824,1697835,1697845,1697914,1697967,1698106,1698312,1700130,1700215,1700219-1700220,1700740,1700951,1701064,1701206,1701270,1701298,1701598,1701603,1701611,1701633,1701638,1701646,1701736,1701792,1701797,1701838,1701997,1702198,1702200,1702203,1702218,1702231,1702237-1702239,1702247,1702288,1702299-1702300,1702310,1702397,1702407,1702467,1702472,1702474,1702478,1702533,1702549,1702553,1702565,1702891,1702974,1702991,1703470,1703475-1703477,1703544,1703581,1703675,1703688-1703689,1703740,1704292,1704573,1704821,1704847,1705060,1705062,1705064,1705088,1705328,1705843,1706241,1706323-17063
 24,1706375,1706428,1706437,1706783,1706983,1706999,1708699,1709388-1709389,1709553,1709562,1710104,1710167,1710215,1710290,1710558,1711250,1711346,1711507,1711510,1714314,1714358,1714790,1715224,1715232,1715262,1715793,1716808,1717154,1717869,1717871,1717873-1717875,1717878,1718167,1718267,1718269,1718484,1720015,1720643,1721174-1721175,1722860-1722861,1722879,1722887,1725180,1728308,1728387,1729060,1729519,1730856,1734926,1735179,1735826,1736432,1737122,1738259,1738659,1738828,1739278,1739280,1740252,1740254,1740316,1741071-1741073,1741078,1741096,1741200,1741206,1741401,1745515,1746053,1746277,1746364,1748514,1754190,1757529,1757532,1757539
+/subversion/trunk:1660545-1660547,1660549-1662901,1663003,1663183-1663184,1663253,1663286,1663338,1663347,1663355,1663374,1663450,1663500,1663530,1663671,1663697,1663706,1663738,1663749,1663791,1663991,1664035,1664078,1664080,1664084-1664085,1664187,1664191,1664193,1664200,1664344,1664476,1664480-1664481,1664483,1664489-1664490,1664507,1664520-1664521,1664523,1664526-1664527,1664531-1664532,1664588,1664593-1664594,1664596,1664653,1664664,1664672,1664674,1664684,1664927,1664938-1664940,1664978,1664984,1664997,1665164,1665195,1665213,1665259,1665318,1665437-1665438,1665609,1665611-1665612,1665845,1665850,1665852,1665873,1665886,1665894,1665896,1666096,1666258,1666270,1666272,1666379,1666449,1666690,1666832,1666851,1666965,1667101,1667106-1667107,1667120,1667228,1667233-1667235,1667249-1667250,1667258,1667290,1667301,1667471,1667691-1667693,1667699-1667700,1667715,1667941,1667976,1668320,1668598-1668600,1668602-1668603,1668607-1668608,1668618,1668625,1669743,1669746,1669749,1669945,167
 0139,1670149,1670152,1670329,1670337,1670347,1670353,1671164,1671388,1672295,1672311,1672372,1672404,1672511-1672512,1672578,1672728,1673044,1673062-1673063,1673065,1673153,1673170,1673172,1673197,1673202,1673204,1673228,1673282,1673445,1673691-1673692,1673746,1673785,1673803,1674015,1674032,1674170,1674301,1674305,1674308,1674339-1674340,1674406,1674415,1674455-1674456,1674475,1674487,1674522,1674580,1674626-1674627,1674785,1674891,1675771,1675774,1676526,1676535,1676538,1676555,1676564,1676570,1676665,1676667,1676769,1677003,1677191,1677267,1677440,1678147,1678149,1678494,1678571,1678734,1678742,1678745-1678746,1678755,1678839,1678846,1678894,1678950,1678963,1679166,1679169,1679228,1679230,1679240,1679287,1679864,1679866,1679909,1680242,1680264,1680495,1680705,1680819,1681317,1682714,1682854,1683071,1683126,1683135,1683266-1683267,1683290,1683303,1683311,1683378,1683387,1684034,1684077,1684322,1684325,1684344,1684412,1684940,1685034,1685085,1686175,1686239,1686478,1686541,1686543,
 1686554,1686557,1686802,1686888,1686984,1687029,1687304,1687389,1687769,1687776,1687812,1688258,1688273,1688395,1689214,1689216,1689721,1689729,1691712-1691713,1691924,1691928,1692091,1692093,1692098,1692448,1692469-1692470,1692798-1692799,1693135,1693138,1693159,1693886,1694023,1694194,1694481,1694929,1695022,1695600,1695606,1695681,1696222,1696225,1696387,1696695,1697381,1697384,1697387,1697664,1697824,1697835,1697845,1697914,1697967,1698106,1698312,1700130,1700215,1700219-1700220,1700740,1700951,1701064,1701206,1701270,1701298,1701598,1701603,1701611,1701633,1701638,1701646,1701736,1701792,1701797,1701838,1701997,1702198,1702200,1702203,1702218,1702231,1702237-1702239,1702247,1702288,1702299-1702300,1702310,1702397,1702407,1702467,1702472,1702474,1702478,1702533,1702549,1702553,1702565,1702891,1702974,1702991,1703470,1703475-1703477,1703544,1703581,1703675,1703688-1703689,1703740,1704292,1704573,1704821,1704847,1705060,1705062,1705064,1705088,1705328,1705843,1706241,1706323-17063
 24,1706375,1706428,1706437,1706783,1706983,1706999,1708699,1709388-1709389,1709553,1709562,1710104,1710167,1710215,1710290,1710558,1711250,1711346,1711507,1711510,1714314,1714358,1714790,1715224,1715232,1715262,1715793,1716808,1717154,1717869,1717871,1717873-1717875,1717878,1718167,1718267,1718269,1718484,1720015,1720643,1721174-1721175,1722860-1722861,1722879,1722887,1725180,1728308,1728387,1729060,1729519,1730856,1734926,1735179,1735826,1736432,1737122,1738259,1738659,1738828,1739278,1739280,1740252,1740254,1740316,1741071-1741073,1741078,1741096,1741200,1741206,1741401,1745515,1746053,1746277,1746364,1748514,1754190,1757529,1757532,1757539,1758202,1758204,1758207,1758209,1758224,1758385

Modified: subversion/branches/1.9.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/STATUS?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/STATUS (original)
+++ subversion/branches/1.9.x/STATUS Thu Sep  1 04:00:31 2016
@@ -127,26 +127,6 @@ Veto-blocked changes:
 Approved changes:
 =================
 
- * r1758202, r1758204, r1758207, r1758209, r1758224, r1758385
-   Fix unbounded memory usage when mod_dav_svn is paired with mod_headers
-   or mod_deflate.
-   Justification:
-     Resolves a long-standing memory usage issue that can make Subversion
-     unusable with a seemingly harmless server configuration.  User
-     reported (issue #3084).
-   Branch:
-     ^/subversion/branches/1.9.x-r1758224-group
-   Notes:
-     r1758202 is included to avoid unnecessary conflicts.
-     r1758204, r1758207, r1758209 and r1758385 lay the necessary
-     groundwork for the fix.
-     r1758224 is the fix itself.
-     .
-     The backport branch is required, because of the text conflicts in
-     mod_dav_svn/repos.c and mod_dav_svn/merge.c.
-   Votes:
-     +1: kotkov, ivan, rhuijben
-
  * r1758269
    Fix issue #4652.
    Justification:

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/dav_svn.h?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/dav_svn.h Thu Sep  1 04:00:31 2016
@@ -446,6 +446,40 @@ const char *dav_svn__get_vtxn_stub(reque
 /* For accessing transaction properties (typically "!svn/vtxr") */
 const char *dav_svn__get_vtxn_root_stub(request_rec *r);
 
+
+/*** Output helpers ***/
+
+/* An opaque type which represents an output for a particular request.
+
+   All writes should target a dav_svn__output object by either using
+   the dav_svn__brigade functions or by preparing a bucket brigade and
+   passing it to the output with dav_svn__output_pass_brigade().
+
+   IMPORTANT:  Don't write to an ap_filter_t coming from mod_dav, and
+   use this wrapper and the corresponding private API instead.  Using
+   the ap_filter_t can cause unbounded memory usage with self-removing
+   output filters (e.g., with the filters installed by mod_headers or
+   mod_deflate).
+
+   See https://mail-archives.apache.org/mod_mbox/httpd-dev/201608.mbox/%3C20160822151917.GA22369%40redhat.com%3E
+*/
+typedef struct dav_svn__output dav_svn__output;
+
+/* Create the output wrapper for request R, allocated in POOL. */
+dav_svn__output *
+dav_svn__output_create(request_rec *r,
+                       apr_pool_t *pool);
+
+/* Get a bucket allocator to use for all bucket/brigade creations
+   when writing to OUTPUT. */
+apr_bucket_alloc_t *
+dav_svn__output_get_bucket_alloc(dav_svn__output *output);
+
+/* Pass the bucket brigade BB down to the OUTPUT's filter stack. */
+svn_error_t *
+dav_svn__output_pass_brigade(dav_svn__output *output,
+                             apr_bucket_brigade *bb);
+
 
 /*** activity.c ***/
 
@@ -634,7 +668,7 @@ dav_svn__insert_all_liveprops(request_re
 /* Generate the HTTP response body for a successful MERGE. */
 /* ### more docco */
 dav_error *
-dav_svn__merge_response(ap_filter_t *output,
+dav_svn__merge_response(dav_svn__output *output,
                         const dav_svn_repos *repos,
                         svn_revnum_t new_rev,
                         const char *post_commit_err,
@@ -668,49 +702,49 @@ static const dav_report_elem dav_svn__re
 dav_error *
 dav_svn__update_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output);
+                       dav_svn__output *output);
 dav_error *
 dav_svn__log_report(const dav_resource *resource,
                     const apr_xml_doc *doc,
-                    ap_filter_t *output);
+                    dav_svn__output *output);
 dav_error *
 dav_svn__dated_rev_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 dav_error *
 dav_svn__get_locations_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output);
+                              dav_svn__output *output);
 dav_error *
 dav_svn__get_location_segments_report(const dav_resource *resource,
                                       const apr_xml_doc *doc,
-                                      ap_filter_t *output);
+                                      dav_svn__output *output);
 dav_error *
 dav_svn__file_revs_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 dav_error *
 dav_svn__replay_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output);
+                       dav_svn__output *output);
 dav_error *
 dav_svn__get_mergeinfo_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output);
+                              dav_svn__output *output);
 dav_error *
 dav_svn__get_locks_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 
 dav_error *
 dav_svn__get_deleted_rev_report(const dav_resource *resource,
                                 const apr_xml_doc *doc,
-                                ap_filter_t *output);
+                                dav_svn__output *output);
 
 dav_error *
 dav_svn__get_inherited_props_report(const dav_resource *resource,
                                     const apr_xml_doc *doc,
-                                    ap_filter_t *output);
+                                    dav_svn__output *output);
 
 /*** posts/ ***/
 
@@ -718,11 +752,11 @@ dav_svn__get_inherited_props_report(cons
 dav_error *
 dav_svn__post_create_txn(const dav_resource *resource,
                          svn_skel_t *request_skel,
-                         ap_filter_t *output);
+                         dav_svn__output *output);
 dav_error *
 dav_svn__post_create_txn_with_props(const dav_resource *resource,
                                     svn_skel_t *request_skel,
-                                    ap_filter_t *output);
+                                    dav_svn__output *output);
 
 /*** authz.c ***/
 
@@ -922,23 +956,28 @@ int dav_svn__find_ns(const apr_array_hea
 
 /* Write LEN bytes from DATA to OUTPUT using BB.  */
 svn_error_t *dav_svn__brigade_write(apr_bucket_brigade *bb,
-                                    ap_filter_t *output,
+                                    dav_svn__output *output,
                                     const char *buf,
                                     apr_size_t len);
 
 /* Write NULL-terminated string STR to OUTPUT using BB.  */
 svn_error_t *dav_svn__brigade_puts(apr_bucket_brigade *bb,
-                                   ap_filter_t *output,
+                                   dav_svn__output *output,
                                    const char *str);
 
 
 /* Write data to OUTPUT using BB, using FMT as the output format string.  */
 svn_error_t *dav_svn__brigade_printf(apr_bucket_brigade *bb,
-                                     ap_filter_t *output,
+                                     dav_svn__output *output,
                                      const char *fmt,
                                      ...)
   __attribute__((format(printf, 3, 4)));
 
+/* Write an unspecified number of strings to OUTPUT using BB.  */
+svn_error_t *dav_svn__brigade_putstrs(apr_bucket_brigade *bb,
+                                      dav_svn__output *output,
+                                      ...) SVN_NEEDS_SENTINEL_NULL;
+
 
 
 
@@ -972,11 +1011,10 @@ dav_svn__sanitize_error(svn_error_t *ser
 
 
 /* Return a writable generic stream that will encode its output to base64
-   and send it to the Apache filter OUTPUT using BB.  Allocate the stream in
-   POOL. */
+   and send it to OUTPUT using BB.  Allocate the stream in POOL. */
 svn_stream_t *
 dav_svn__make_base64_output_stream(apr_bucket_brigade *bb,
-                                   ap_filter_t *output,
+                                   dav_svn__output *output,
                                    apr_pool_t *pool);
 
 /* In INFO->r->subprocess_env set "SVN-ACTION" to LINE, "SVN-REPOS" to
@@ -1018,7 +1056,8 @@ dav_svn__operational_log(struct dav_reso
  */
 dav_error *
 dav_svn__final_flush_or_error(request_rec *r, apr_bucket_brigade *bb,
-                              ap_filter_t *output, dav_error *preferred_err,
+                              dav_svn__output *output,
+                              dav_error *preferred_err,
                               apr_pool_t *pool);
 
 /* Log a DAV error response.

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/merge.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/merge.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/merge.c Thu Sep  1 04:00:31 2016
@@ -72,13 +72,12 @@ send_response(const dav_svn_repos *repos
               svn_fs_root_t *root,
               const char *path,
               svn_boolean_t is_dir,
-              ap_filter_t *output,
+              dav_svn__output *output,
               apr_bucket_brigade *bb,
               apr_pool_t *pool)
 {
   const char *href;
   const char *vsn_url;
-  apr_status_t status;
   svn_revnum_t rev_to_use;
 
   href = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_PUBLIC,
@@ -86,7 +85,7 @@ send_response(const dav_svn_repos *repos
   rev_to_use = dav_svn__get_safe_cr(root, path, pool);
   vsn_url = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_VERSION,
                                rev_to_use, path, FALSE /* add_href */, pool);
-  status = ap_fputstrs(output, bb,
+  SVN_ERR(dav_svn__brigade_putstrs(bb, output,
                        "<D:response>" DEBUG_CR
                        "<D:href>",
                        apr_xml_quote_string(pool, href, 1),
@@ -103,9 +102,7 @@ send_response(const dav_svn_repos *repos
                        "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                        "</D:propstat>" DEBUG_CR
                        "</D:response>" DEBUG_CR,
-                       NULL);
-  if (status != APR_SUCCESS)
-    return svn_error_wrap_apr(status, "Can't write response to output");
+                       SVN_VA_NULL));
 
   return SVN_NO_ERROR;
 }
@@ -115,7 +112,7 @@ static svn_error_t *
 do_resources(const dav_svn_repos *repos,
              svn_fs_root_t *root,
              svn_revnum_t revision,
-             ap_filter_t *output,
+             dav_svn__output *output,
              apr_bucket_brigade *bb,
              apr_pool_t *pool)
 {
@@ -209,7 +206,7 @@ do_resources(const dav_svn_repos *repos,
 */
 
 dav_error *
-dav_svn__merge_response(ap_filter_t *output,
+dav_svn__merge_response(dav_svn__output *output,
                         const dav_svn_repos *repos,
                         svn_revnum_t new_rev,
                         const char *post_commit_err,
@@ -225,7 +222,6 @@ dav_svn__merge_response(ap_filter_t *out
   svn_string_t *creationdate, *creator_displayname;
   const char *post_commit_err_elem = NULL,
              *post_commit_header_info = NULL;
-  apr_status_t status;
 
   serr = svn_fs_revision_root(&root, repos->fs, new_rev, pool);
   if (serr != NULL)
@@ -236,7 +232,8 @@ dav_svn__merge_response(ap_filter_t *out
                                   repos->pool);
     }
 
-  bb = apr_brigade_create(pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   /* prep some strings */
 
@@ -286,7 +283,7 @@ dav_svn__merge_response(ap_filter_t *out
     }
 
 
-  status = ap_fputstrs(output, bb,
+  serr = dav_svn__brigade_putstrs(bb, output,
                      DAV_XML_HEADER DEBUG_CR
                      "<D:merge-response xmlns:D=\"DAV:\"",
                      post_commit_header_info,
@@ -305,44 +302,47 @@ dav_svn__merge_response(ap_filter_t *out
                      "<D:resourcetype><D:baseline/></D:resourcetype>" DEBUG_CR,
                      post_commit_err_elem, DEBUG_CR
                      "<D:version-name>", rev, "</D:version-name>" DEBUG_CR,
-                     NULL);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                              "Could not write output");
+                     SVN_VA_NULL);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   if (creationdate)
     {
-      status = ap_fputstrs(output, bb,
+      serr = dav_svn__brigade_putstrs(bb, output,
                          "<D:creationdate>",
                          apr_xml_quote_string(pool, creationdate->data, 1),
                          "</D:creationdate>" DEBUG_CR,
-                         NULL);
-      if (status != APR_SUCCESS)
-        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                                  "Could not write output");
+                         SVN_VA_NULL);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not write output",
+                                    repos->pool);
     }
   if (creator_displayname)
     {
-      status = ap_fputstrs(output, bb,
+      serr = dav_svn__brigade_putstrs(bb, output,
                          "<D:creator-displayname>",
                          apr_xml_quote_string(pool,
                                               creator_displayname->data, 1),
                          "</D:creator-displayname>" DEBUG_CR,
-                         NULL);
-      if (status != APR_SUCCESS)
-        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                                  "Could not write output");
+                         SVN_VA_NULL);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not write output",
+                                    repos->pool);
     }
-  status = ap_fputstrs(output, bb,
+  serr = dav_svn__brigade_putstrs(bb, output,
                      "</D:prop>" DEBUG_CR
                      "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                      "</D:propstat>" DEBUG_CR
                      "</D:response>" DEBUG_CR,
-
-                     NULL);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                              "Could not write output");
+                     SVN_VA_NULL);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   /* ONLY have dir_delta drive the editor if the caller asked us to
      generate a full MERGE response.  svn clients can ask us to
@@ -371,18 +371,20 @@ dav_svn__merge_response(ap_filter_t *out
     }
 
   /* wrap up the merge response */
-  status = ap_fputs(output, bb,
-                  "</D:updated-set>" DEBUG_CR
-                  "</D:merge-response>" DEBUG_CR);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                              "Could not write output");
+  serr = dav_svn__brigade_puts(bb, output,
+                               "</D:updated-set>" DEBUG_CR
+                               "</D:merge-response>" DEBUG_CR);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   /* send whatever is left in the brigade */
-  status = ap_pass_brigade(output, bb);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                              "Could not write output");
+  serr = dav_svn__output_pass_brigade(output, bb);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   return NULL;
 }

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/posts/create_txn.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/posts/create_txn.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/posts/create_txn.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/posts/create_txn.c Thu Sep  1 04:00:31 2016
@@ -34,7 +34,7 @@
 dav_error *
 dav_svn__post_create_txn(const dav_resource *resource,
                          svn_skel_t *request_skel,
-                         ap_filter_t *output)
+                         dav_svn__output *output)
 {
   const char *txn_name;
   const char *vtxn_name;
@@ -75,7 +75,7 @@ dav_svn__post_create_txn(const dav_resou
 dav_error *
 dav_svn__post_create_txn_with_props(const dav_resource *resource,
                                     svn_skel_t *request_skel,
-                                    ap_filter_t *output)
+                                    dav_svn__output *output)
 {
   const char *txn_name;
   const char *vtxn_name;

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/dated-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/dated-rev.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/dated-rev.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/dated-rev.c Thu Sep  1 04:00:31 2016
@@ -50,7 +50,7 @@
 dav_error *
 dav_svn__dated_rev_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output)
+                          dav_svn__output *output)
 {
   apr_xml_elem *child;
   int ns;
@@ -58,7 +58,6 @@ dav_svn__dated_rev_report(const dav_reso
   svn_revnum_t rev;
   apr_bucket_brigade *bb;
   svn_error_t *err;
-  apr_status_t apr_err;
   dav_error *derr = NULL;
 
   /* Find the DAV:creationdate element and get the requested time from it. */
@@ -94,15 +93,16 @@ dav_svn__dated_rev_report(const dav_reso
                                 "Could not access revision times.");
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-  apr_err = ap_fprintf(output, bb,
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
+  err = dav_svn__brigade_printf(bb, output,
                        DAV_XML_HEADER DEBUG_CR
                        "<S:dated-rev-report xmlns:S=\"" SVN_XML_NAMESPACE "\" "
                        "xmlns:D=\"DAV:\">" DEBUG_CR
                        "<D:" SVN_DAV__VERSION_NAME ">%ld</D:"
                        SVN_DAV__VERSION_NAME ">""</S:dated-rev-report>", rev);
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/deleted-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/deleted-rev.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/deleted-rev.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/deleted-rev.c Thu Sep  1 04:00:31 2016
@@ -41,7 +41,7 @@
 dav_error *
 dav_svn__get_deleted_rev_report(const dav_resource *resource,
                                 const apr_xml_doc *doc,
-                                ap_filter_t *output)
+                                dav_svn__output *output)
 {
   apr_xml_elem *child;
   int ns;
@@ -52,7 +52,6 @@ dav_svn__get_deleted_rev_report(const da
   svn_revnum_t deleted_rev;
   apr_bucket_brigade *bb;
   svn_error_t *err;
-  apr_status_t apr_err;
   dav_error *derr = NULL;
 
   /* Sanity check. */
@@ -117,16 +116,17 @@ dav_svn__get_deleted_rev_report(const da
                                 "Could not find revision path was deleted.");
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-  apr_err = ap_fprintf(output, bb,
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
+  err = dav_svn__brigade_printf(bb, output,
                        DAV_XML_HEADER DEBUG_CR
                        "<S:get-deleted-rev-report xmlns:S=\""
                        SVN_XML_NAMESPACE "\" xmlns:D=\"DAV:\">" DEBUG_CR
                        "<D:" SVN_DAV__VERSION_NAME ">%ld</D:"
                        SVN_DAV__VERSION_NAME ">""</S:get-deleted-rev-report>",
                        deleted_rev);
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/file-revs.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/file-revs.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/file-revs.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/file-revs.c Thu Sep  1 04:00:31 2016
@@ -43,7 +43,7 @@ struct file_rev_baton {
   apr_bucket_brigade *bb;
 
   /* where to deliver the output */
-  ap_filter_t *output;
+  dav_svn__output *output;
 
   /* Whether we've written the <S:file-revs-report> header.  Allows for lazy
      writes to support mod_dav-based error handling. */
@@ -234,7 +234,7 @@ file_rev_handler(void *baton,
 dav_error *
 dav_svn__file_revs_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output)
+                          dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -304,7 +304,7 @@ dav_svn__file_revs_report(const dav_reso
                                   "Not all parameters passed");
 
   frb.bb = apr_brigade_create(resource->pool,
-                              output->c->bucket_alloc);
+                              dav_svn__output_get_bucket_alloc(output));
   frb.output = output;
   frb.needs_header = TRUE;
   frb.svndiff_version = resource->info->svndiff_version;

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-location-segments.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-location-segments.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-location-segments.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-location-segments.c Thu Sep  1 04:00:31 2016
@@ -48,7 +48,7 @@
 struct location_segment_baton
 {
   svn_boolean_t sent_opener;
-  ap_filter_t *output;
+  dav_svn__output *output;
   apr_bucket_brigade *bb;
   dav_svn__authz_read_baton arb;
 };
@@ -79,28 +79,26 @@ location_segment_receiver(svn_location_s
                           apr_pool_t *pool)
 {
   struct location_segment_baton *b = baton;
-  apr_status_t apr_err;
 
   SVN_ERR(maybe_send_opener(b));
 
   if (segment->path)
     {
       const char *path_quoted = apr_xml_quote_string(pool, segment->path, 1);
-      apr_err = ap_fprintf(b->output, b->bb,
+
+      SVN_ERR(dav_svn__brigade_printf(b->bb, b->output,
                            "<S:location-segment path=\"%s\" "
                            "range-start=\"%ld\" range-end=\"%ld\"/>" DEBUG_CR,
                            path_quoted,
-                           segment->range_start, segment->range_end);
+                           segment->range_start, segment->range_end));
     }
   else
     {
-      apr_err = ap_fprintf(b->output, b->bb,
+      SVN_ERR(dav_svn__brigade_printf(b->bb, b->output,
                            "<S:location-segment "
                            "range-start=\"%ld\" range-end=\"%ld\"/>" DEBUG_CR,
-                           segment->range_start, segment->range_end);
+                           segment->range_start, segment->range_end));
     }
-  if (apr_err)
-    return svn_error_create(apr_err, 0, NULL);
   return SVN_NO_ERROR;
 }
 
@@ -108,7 +106,7 @@ location_segment_receiver(svn_location_s
 dav_error *
 dav_svn__get_location_segments_report(const dav_resource *resource,
                                       const apr_xml_doc *doc,
-                                      ap_filter_t *output)
+                                      dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -214,7 +212,8 @@ dav_svn__get_location_segments_report(co
   arb.repos = resource->info->repos;
 
   /* Build the bucket brigade we'll use for output. */
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   /* Do what we came here for. */
   location_segment_baton.sent_opener = FALSE;

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locations.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locations.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locations.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locations.c Thu Sep  1 04:00:31 2016
@@ -44,23 +44,20 @@
 #include "../dav_svn.h"
 
 
-static apr_status_t
-send_get_locations_report(ap_filter_t *output,
+static svn_error_t *
+send_get_locations_report(dav_svn__output *output,
                           apr_bucket_brigade *bb,
                           const dav_resource *resource,
                           apr_hash_t *fs_locations)
 {
   apr_hash_index_t *hi;
-  apr_pool_t *pool;
-  apr_status_t apr_err;
+  apr_pool_t *pool = resource->pool;
 
-  pool = resource->pool;
-
-  apr_err = ap_fprintf(output, bb, DAV_XML_HEADER DEBUG_CR
+  SVN_ERR(dav_svn__brigade_printf(
+                       bb, output,
+                       DAV_XML_HEADER DEBUG_CR
                        "<S:get-locations-report xmlns:S=\"" SVN_XML_NAMESPACE
-                       "\" xmlns:D=\"DAV:\">" DEBUG_CR);
-  if (apr_err)
-    return apr_err;
+                       "\" xmlns:D=\"DAV:\">" DEBUG_CR));
 
   for (hi = apr_hash_first(pool, fs_locations); hi; hi = apr_hash_next(hi))
     {
@@ -70,24 +67,25 @@ send_get_locations_report(ap_filter_t *o
 
       apr_hash_this(hi, &key, NULL, &value);
       path_quoted = apr_xml_quote_string(pool, value, 1);
-      apr_err = ap_fprintf(output, bb, "<S:location "
+      SVN_ERR(dav_svn__brigade_printf(
+                           bb, output, "<S:location "
                            "rev=\"%ld\" path=\"%s\"/>" DEBUG_CR,
-                           *(const svn_revnum_t *)key, path_quoted);
-      if (apr_err)
-        return apr_err;
+                           *(const svn_revnum_t *)key, path_quoted));
     }
-  return ap_fprintf(output, bb, "</S:get-locations-report>" DEBUG_CR);
+
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                  "</S:get-locations-report>" DEBUG_CR));
+  return SVN_NO_ERROR;
 }
 
 
 dav_error *
 dav_svn__get_locations_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output)
+                              dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
-  apr_status_t apr_err;
   apr_bucket_brigade *bb;
   dav_svn__authz_read_baton arb;
 
@@ -171,12 +169,13 @@ dav_svn__get_locations_report(const dav_
                                   resource->pool);
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
-  apr_err = send_get_locations_report(output, bb, resource, fs_locations);
+  serr = send_get_locations_report(output, bb, resource, fs_locations);
 
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (serr)
+    derr = dav_svn__convert_err(serr,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locks.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locks.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/get-locks.c Thu Sep  1 04:00:31 2016
@@ -44,25 +44,11 @@
    report in libsvn_ra_neon/get_locks.c.  */
 
 
-#define SVN_APR_ERR(expr)                       \
-  do {                                          \
-    apr_status_t apr_status__temp = (expr);     \
-    if (apr_status__temp)                       \
-      return apr_status__temp;                  \
-  } while (0)
-
-
 /* Transmit LOCKS (a hash of Subversion filesystem locks keyed by
-   path) across OUTPUT using BB.  Use POOL for necessary allocations.
-
-   NOTE:  As written, this function currently returns one of only two
-   status values -- "success", and "we had trouble writing out to the
-   output stream".  If you need to return something more interesting,
-   you'll probably want to generate dav_error's here instead of
-   passing back only apr_status_t's.  */
-static apr_status_t
+   path) across OUTPUT using BB.  Use POOL for necessary allocations. */
+static svn_error_t *
 send_get_lock_response(apr_hash_t *locks,
-                       ap_filter_t *output,
+                       dav_svn__output *output,
                        apr_bucket_brigade *bb,
                        apr_pool_t *pool)
 {
@@ -70,7 +56,7 @@ send_get_lock_response(apr_hash_t *locks
   apr_hash_index_t *hi;
 
   /* start sending report */
-  SVN_APR_ERR(ap_fprintf(output, bb,
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
                          DAV_XML_HEADER DEBUG_CR
                          "<S:get-locks-report xmlns:S=\"" SVN_XML_NAMESPACE
                          "\" xmlns:D=\"DAV:\">" DEBUG_CR));
@@ -86,7 +72,7 @@ send_get_lock_response(apr_hash_t *locks
 
       /* Begin the <S:lock> tag, transmitting the path, token, and
          creation date. */
-      SVN_APR_ERR(ap_fprintf(output, bb,
+      SVN_ERR(dav_svn__brigade_printf(bb, output,
                              "<S:lock>" DEBUG_CR
                              "<S:path>%s</S:path>" DEBUG_CR
                              "<S:token>%s</S:token>" DEBUG_CR
@@ -98,7 +84,7 @@ send_get_lock_response(apr_hash_t *locks
 
       /* Got expiration date?  Tell the client. */
       if (lock->expiration_date)
-        SVN_APR_ERR(ap_fprintf(output, bb,
+        SVN_ERR(dav_svn__brigade_printf(bb, output,
                                "<S:expirationdate>%s</S:expirationdate>"
                                DEBUG_CR,
                                svn_time_to_cstring(lock->expiration_date,
@@ -126,7 +112,7 @@ send_get_lock_response(apr_hash_t *locks
               owner = encoded_owner->data;
               owner_base64 = TRUE;
             }
-          SVN_APR_ERR(ap_fprintf(output, bb,
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
                                  "<S:owner %s>%s</S:owner>" DEBUG_CR,
                                  owner_base64 ? "encoding=\"base64\"" : "",
                                  owner));
@@ -154,34 +140,32 @@ send_get_lock_response(apr_hash_t *locks
               comment = encoded_comment->data;
               comment_base64 = TRUE;
             }
-          SVN_APR_ERR(ap_fprintf(output, bb,
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
                                  "<S:comment %s>%s</S:comment>" DEBUG_CR,
                                  comment_base64 ? "encoding=\"base64\"" : "",
                                  comment));
         }
 
       /* Okay, finish up this lock by closing the <S:lock> tag. */
-      SVN_APR_ERR(ap_fprintf(output, bb, "</S:lock>" DEBUG_CR));
+      SVN_ERR(dav_svn__brigade_printf(bb, output, "</S:lock>" DEBUG_CR));
     }
   svn_pool_destroy(iterpool);
 
   /* Finish the report */
-  SVN_APR_ERR(ap_fprintf(output, bb, "</S:get-locks-report>" DEBUG_CR));
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                  "</S:get-locks-report>" DEBUG_CR));
 
   return APR_SUCCESS;
 }
 
-#undef SVN_APR_ERR
-
 dav_error *
 dav_svn__get_locks_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output)
+                          dav_svn__output *output)
 {
   apr_bucket_brigade *bb;
   svn_error_t *err;
   dav_error *derr = NULL;
-  apr_status_t apr_err;
   apr_hash_t *locks;
   dav_svn__authz_read_baton arb;
   svn_depth_t depth = svn_depth_unknown;
@@ -227,10 +211,12 @@ dav_svn__get_locks_report(const dav_reso
     return dav_svn__convert_err(err, HTTP_INTERNAL_SERVER_ERROR,
                                 err->message, resource->pool);
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
-  if ((apr_err = send_get_lock_response(locks, output, bb, resource->pool)))
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  err = send_get_lock_response(locks, output, bb, resource->pool);
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/inherited-props.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/inherited-props.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/inherited-props.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/inherited-props.c Thu Sep  1 04:00:31 2016
@@ -47,7 +47,7 @@
 dav_error *
 dav_svn__get_inherited_props_report(const dav_resource *resource,
                                     const apr_xml_doc *doc,
-                                    ap_filter_t *output)
+                                    dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -105,7 +105,8 @@ dav_svn__get_inherited_props_report(cons
   arb.repos = resource->info->repos;
 
   /* Build inherited property brigade */
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   serr = svn_fs_revision_root(&root, resource->info->repos->fs,
                               rev, resource->pool);

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/log.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/log.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/log.c Thu Sep  1 04:00:31 2016
@@ -50,7 +50,7 @@ struct log_receiver_baton
   apr_bucket_brigade *bb;
 
   /* where to deliver the output */
-  ap_filter_t *output;
+  dav_svn__output *output;
 
   /* Whether we've written the <S:log-report> header.  Allows for lazy
      writes to support mod_dav-based error handling. */
@@ -297,25 +297,17 @@ log_receiver(void *baton,
   lrb->result_count++;
   if (lrb->result_count == lrb->next_forced_flush)
     {
-      apr_status_t apr_err;
+      apr_bucket *bkt;
 
-      /* This flush is similar to that in dav_svn__final_flush_or_error().
-
-         Compared to using ap_filter_flush(), which we use in other place
+      /* Compared to using ap_filter_flush(), which we use in other place
          this adds a flush frame before flushing the brigade, to make output
          filters perform a flush as well */
 
       /* No brigade empty check. We want output filters to flush anyway */
-      apr_err = ap_fflush(lrb->output, lrb->bb);
-      if (apr_err)
-        return svn_error_create(apr_err, NULL, NULL);
-
-      /* Check for an aborted connection, just like our brigade write
-         helper functions, since the brigade functions don't appear to
-         be return useful errors when the connection is dropped. */
-      if (lrb->output->c->aborted)
-        return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED,
-                                NULL, NULL);
+      bkt = apr_bucket_flush_create(
+                dav_svn__output_get_bucket_alloc(lrb->output));
+      APR_BRIGADE_INSERT_TAIL(lrb->bb, bkt);
+      SVN_ERR(dav_svn__output_pass_brigade(lrb->output, lrb->bb));
 
       if (lrb->result_count < 256)
         lrb->next_forced_flush = lrb->next_forced_flush * 4;
@@ -328,7 +320,7 @@ log_receiver(void *baton,
 dav_error *
 dav_svn__log_report(const dav_resource *resource,
                     const apr_xml_doc *doc,
-                    ap_filter_t *output)
+                    dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -460,7 +452,7 @@ dav_svn__log_report(const dav_resource *
 
   /* Build log receiver baton */
   lrb.bb = apr_brigade_create(resource->pool,  /* not the subpool! */
-                              output->c->bucket_alloc);
+                              dav_svn__output_get_bucket_alloc(output));
   lrb.output = output;
   lrb.needs_header = TRUE;
   lrb.stack_depth = 0;

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/mergeinfo.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/mergeinfo.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/mergeinfo.c Thu Sep  1 04:00:31 2016
@@ -46,7 +46,7 @@
 dav_error *
 dav_svn__get_mergeinfo_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output)
+                              dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -124,7 +124,8 @@ dav_svn__get_mergeinfo_report(const dav_
   arb.repos = resource->info->repos;
 
   /* Build mergeinfo brigade */
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   serr = svn_repos_fs_get_mergeinfo(&catalog, repos->repos, paths, rev,
                                     inherit, include_descendants,

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/replay.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/replay.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/replay.c Thu Sep  1 04:00:31 2016
@@ -44,7 +44,7 @@
 
 typedef struct edit_baton_t {
   apr_bucket_brigade *bb;
-  ap_filter_t *output;
+  dav_svn__output *output;
   svn_boolean_t started;
   svn_boolean_t sending_textdelta;
   int compression_level;
@@ -367,7 +367,7 @@ static void
 make_editor(const svn_delta_editor_t **editor,
             void **edit_baton,
             apr_bucket_brigade *bb,
-            ap_filter_t *output,
+            dav_svn__output *output,
             int compression_level,
             apr_pool_t *pool)
 {
@@ -413,7 +413,7 @@ malformed_element_error(const char *tagn
 dav_error *
 dav_svn__replay_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output)
+                       dav_svn__output *output)
 {
   dav_error *derr = NULL;
   svn_revnum_t low_water_mark = SVN_INVALID_REVNUM;
@@ -530,7 +530,8 @@ dav_svn__replay_report(const dav_resourc
   if (! base_dir)
     base_dir = "";
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   if ((err = svn_fs_revision_root(&root, resource->info->repos->fs, rev,
                                   resource->pool)))

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/reports/update.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/reports/update.c Thu Sep  1 04:00:31 2016
@@ -68,7 +68,7 @@ typedef struct update_ctx_t {
   apr_bucket_brigade *bb;
 
   /* where to deliver the output */
-  ap_filter_t *output;
+  dav_svn__output *output;
 
   /* where do these editor paths *really* point to? */
   apr_hash_t *pathmap;
@@ -954,7 +954,7 @@ validate_input_revision(svn_revnum_t rev
 dav_error *
 dav_svn__update_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output)
+                       dav_svn__output *output)
 {
   svn_delta_editor_t *editor;
   apr_xml_elem *child;
@@ -1202,7 +1202,8 @@ dav_svn__update_report(const dav_resourc
   uc.output = output;
   uc.anchor = src_path;
   uc.target = target;
-  uc.bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  uc.bb = apr_brigade_create(resource->pool,
+                             dav_svn__output_get_bucket_alloc(output));
   uc.pathmap = NULL;
   uc.enable_v2_response = ((resource->info->restype == DAV_SVN_RESTYPE_ME)
                            && (resource->info->repos->v2_protocol));

Modified: subversion/branches/1.9.x/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/mod_dav_svn/repos.c?rev=1758694&r1=1758693&r2=1758694&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/1.9.x/subversion/mod_dav_svn/repos.c Thu Sep  1 04:00:31 2016
@@ -3241,7 +3241,7 @@ set_headers(request_rec *r, const dav_re
 
 
 typedef struct diff_ctx_t {
-  ap_filter_t *output;
+  dav_svn__output *output;
   apr_bucket_brigade *bb;
 } diff_ctx_t;
 
@@ -3250,14 +3250,9 @@ static svn_error_t *  __attribute__((war
 write_to_filter(void *baton, const char *buffer, apr_size_t *len)
 {
   diff_ctx_t *dc = baton;
-  apr_status_t status;
 
   /* take the current data and shove it into the filter */
-  status = apr_brigade_write(dc->bb, ap_filter_flush, dc->output,
-                             buffer, *len);
-  if (status != APR_SUCCESS)
-    return svn_error_create(status, NULL,
-                            "Could not write data to filter");
+  SVN_ERR(dav_svn__brigade_write(dc->bb, dc->output, buffer, *len));
 
   return SVN_NO_ERROR;
 }
@@ -3268,25 +3263,269 @@ close_filter(void *baton)
 {
   diff_ctx_t *dc = baton;
   apr_bucket *bkt;
-  apr_status_t status;
 
   /* done with the file. write an EOS bucket now. */
-  bkt = apr_bucket_eos_create(dc->output->c->bucket_alloc);
+  bkt = apr_bucket_eos_create(dav_svn__output_get_bucket_alloc(dc->output));
   APR_BRIGADE_INSERT_TAIL(dc->bb, bkt);
-  if ((status = ap_pass_brigade(dc->output, dc->bb)) != APR_SUCCESS)
-    return svn_error_create(status, NULL, "Could not write EOS to filter");
+  SVN_ERR(dav_svn__output_pass_brigade(dc->output, dc->bb));
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+emit_collection_head(const dav_resource *resource,
+                     apr_bucket_brigade *bb,
+                     dav_svn__output *output,
+                     svn_boolean_t gen_html,
+                     apr_pool_t *pool)
+{
+  /* XML schema for the directory index if xslt_uri is set:
+
+     <?xml version="1.0"?>
+     <?xml-stylesheet type="text/xsl" href="[info->repos->xslt_uri]"?> */
+  static const char xml_index_dtd[] =
+    "<!DOCTYPE svn [\n"
+    "  <!ELEMENT svn   (index)>\n"
+    "  <!ATTLIST svn   version CDATA #REQUIRED\n"
+    "                  href    CDATA #REQUIRED>\n"
+    "  <!ELEMENT index (updir?, (file | dir)*)>\n"
+    "  <!ATTLIST index name    CDATA #IMPLIED\n"
+    "                  path    CDATA #IMPLIED\n"
+    "                  rev     CDATA #IMPLIED\n"
+    "                  base    CDATA #IMPLIED>\n"
+    "  <!ELEMENT updir EMPTY>\n"
+    "  <!ATTLIST updir href    CDATA #REQUIRED>\n"
+    "  <!ELEMENT file  EMPTY>\n"
+    "  <!ATTLIST file  name    CDATA #REQUIRED\n"
+    "                  href    CDATA #REQUIRED>\n"
+    "  <!ELEMENT dir   EMPTY>\n"
+    "  <!ATTLIST dir   name    CDATA #REQUIRED\n"
+    "                  href    CDATA #REQUIRED>\n"
+    "]>\n";
+
+  if (gen_html)
+    {
+      const char *title;
+      if (resource->info->repos_path == NULL)
+        title = "unknown location";
+      else
+        title = resource->info->repos_path;
+
+      if (resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
+        {
+          if (SVN_IS_VALID_REVNUM(resource->info->root.rev))
+            title = apr_psprintf(pool,
+                                 "Revision %ld: %s",
+                                 resource->info->root.rev, title);
+          if (resource->info->repos->repo_basename)
+            title = apr_psprintf(pool, "%s - %s",
+                                 resource->info->repos->repo_basename,
+                                 title);
+          if (resource->info->repos->repo_name)
+            title = apr_psprintf(pool, "%s: %s",
+                                 resource->info->repos->repo_name,
+                                 title);
+        }
+
+      SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                      "<html><head><title>%s</title></head>\n"
+                                      "<body>\n <h2>%s</h2>\n <ul>\n",
+                                      title, title));
+    }
+  else
+    {
+      const char *name = resource->info->repos->repo_name;
+      const char *href = resource->info->repos_path;
+      const char *base = resource->info->repos->repo_basename;
+
+      SVN_ERR(dav_svn__brigade_puts(bb, output, "<?xml version=\"1.0\"?>\n"));
+      SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                      "<?xml-stylesheet type=\"text/xsl\" "
+                                      "href=\"%s\"?>\n",
+                                      resource->info->repos->xslt_uri));
+      SVN_ERR(dav_svn__brigade_puts(bb, output, xml_index_dtd));
+      SVN_ERR(dav_svn__brigade_puts(bb, output,
+                         "<svn version=\"" SVN_VERSION "\"\n"
+                         "     href=\"http://subversion.apache.org/\">\n"));
+      SVN_ERR(dav_svn__brigade_puts(bb, output, "  <index"));
+
+      if (name)
+        SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                        " name=\"%s\"",
+                                        apr_xml_quote_string(resource->pool,
+                                                             name, 1)));
+      if (SVN_IS_VALID_REVNUM(resource->info->root.rev))
+        SVN_ERR(dav_svn__brigade_printf(bb, output, " rev=\"%ld\"",
+                                        resource->info->root.rev));
+      if (href)
+        SVN_ERR(dav_svn__brigade_printf(bb, output, " path=\"%s\"",
+                                        apr_xml_quote_string(resource->pool,
+                                                             href, 1)));
+      if (base)
+        SVN_ERR(dav_svn__brigade_printf(bb, output, " base=\"%s\"", base));
+
+      SVN_ERR(dav_svn__brigade_puts(bb, output, ">\n"));
+    }
+
+  if ((resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
+      && resource->info->repos_path
+      && ((resource->info->repos_path[1] != '\0')
+          || dav_svn__get_list_parentpath_flag(resource->info->r)))
+    {
+      const char *href;
+      if (resource->info->pegged)
+        {
+          href = apr_psprintf(pool, "../?p=%ld", resource->info->root.rev);
+        }
+      else
+        {
+          href = "../";
+        }
+
+      if (gen_html)
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                          "  <li><a href=\"%s\">..</a></li>\n",
+                                          href));
+        }
+      else
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                          "    <updir href=\"%s\"/>\n",
+                                          href));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+emit_collection_entry(const dav_resource *resource,
+                      apr_bucket_brigade *bb,
+                      dav_svn__output *output,
+                      const svn_fs_dirent_t *entry,
+                      svn_boolean_t gen_html,
+                      apr_pool_t *pool)
+{
+  const char *name = entry->name;
+  const char *href = name;
+  svn_boolean_t is_dir = (entry->kind == svn_node_dir);
+
+  /* append a trailing slash onto the name for directories. we NEED
+     this for the href portion so that the relative reference will
+     descend properly. for the visible portion, it is just nice. */
+  /* ### The xml output doesn't like to see a trailing slash on
+     ### the visible portion, so avoid that. */
+  if (is_dir)
+    href = apr_pstrcat(pool, href, "/", SVN_VA_NULL);
+
+  if (gen_html)
+    name = href;
+
+  /* We quote special characters in both XML and HTML. */
+  name = apr_xml_quote_string(pool, name, !gen_html);
+
+  /* According to httpd-2.0.54/include/httpd.h, ap_os_escape_path()
+     behaves differently on different platforms.  It claims to
+     "convert an OS path to a URL in an OS dependant way".
+     Nevertheless, there appears to be only one implementation
+     of the function in httpd, and the code seems completely
+     platform independent, so we'll assume it's appropriate for
+     mod_dav_svn to use it to quote outbound paths. */
+  href = ap_os_escape_path(pool, href, 0);
+  href = apr_xml_quote_string(pool, href, 1);
+
+  if (gen_html)
+    {
+      /* If our directory was access using the public peg-rev
+         CGI query interface, we'll let its dirents carry that
+         peg-rev, too. */
+      if (resource->info->pegged)
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                     "  <li><a href=\"%s?p=%ld\">%s</a></li>\n",
+                     href, resource->info->root.rev, name));
+        }
+      else
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                     "  <li><a href=\"%s\">%s</a></li>\n",
+                     href, name));
+        }
+    }
+  else
+    {
+      const char *const tag = (is_dir ? "dir" : "file");
+
+      /* This is where we could search for props */
+
+      /* If our directory was access using the public peg-rev
+         CGI query interface, we'll let its dirents carry that
+         peg-rev, too. */
+      if (resource->info->pegged)
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                     "    <%s name=\"%s\" href=\"%s?p=%ld\" />\n",
+                     tag, name, href, resource->info->root.rev));
+        }
+      else
+        {
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
+                     "    <%s name=\"%s\" href=\"%s\" />\n",
+                     tag, name, href));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+emit_collection_tail(const dav_resource *resource,
+                     apr_bucket_brigade *bb,
+                     dav_svn__output *output,
+                     svn_boolean_t gen_html,
+                     apr_pool_t *pool)
+{
+  if (gen_html)
+    {
+      if (strcmp(ap_psignature("FOO", resource->info->r), "") != 0)
+        {
+          /* Apache's signature generation code didn't eat our prefix.
+             ServerSignature must be enabled.  Print our version info.
+
+             WARNING: This is a kludge!! ap_psignature() doesn't promise
+             to return the empty string when ServerSignature is off.  We
+             know it does by code inspection, but this behavior is subject
+             to change. (Perhaps we should try to get the Apache folks to
+             make this promise, though.  Seems harmless/useful enough...)
+          */
+          SVN_ERR(dav_svn__brigade_puts(bb, output,
+                   " </ul>\n <hr noshade><em>Powered by "
+                   "<a href=\"http://subversion.apache.org/\">"
+                   "Apache Subversion"
+                   "</a> version " SVN_VERSION "."
+                   "</em>\n</body></html>"));
+        }
+      else
+        SVN_ERR(dav_svn__brigade_puts(bb, output, " </ul>\n</body></html>"));
+    }
+  else
+    SVN_ERR(dav_svn__brigade_puts(bb, output, "  </index>\n</svn>\n"));
 
   return SVN_NO_ERROR;
 }
 
 
 static dav_error *
-deliver(const dav_resource *resource, ap_filter_t *output)
+deliver(const dav_resource *resource, ap_filter_t *unused)
 {
   svn_error_t *serr;
   apr_bucket_brigade *bb;
   apr_bucket *bkt;
-  apr_status_t status;
+  dav_svn__output *output;
 
   /* Check resource type */
   if (resource->baselined
@@ -3299,39 +3538,17 @@ deliver(const dav_resource *resource, ap
                                 "Cannot GET this type of resource.");
     }
 
+  output = dav_svn__output_create(resource->info->r, resource->pool);
+
   if (resource->collection)
     {
       const int gen_html = !resource->info->repos->xslt_uri;
       apr_hash_t *entries;
-      apr_pool_t *entry_pool;
+      apr_pool_t *iterpool;
       apr_array_header_t *sorted;
       svn_revnum_t dir_rev = SVN_INVALID_REVNUM;
       int i;
 
-      /* XML schema for the directory index if xslt_uri is set:
-
-         <?xml version="1.0"?>
-         <?xml-stylesheet type="text/xsl" href="[info->repos->xslt_uri]"?> */
-      static const char xml_index_dtd[] =
-        "<!DOCTYPE svn [\n"
-        "  <!ELEMENT svn   (index)>\n"
-        "  <!ATTLIST svn   version CDATA #REQUIRED\n"
-        "                  href    CDATA #REQUIRED>\n"
-        "  <!ELEMENT index (updir?, (file | dir)*)>\n"
-        "  <!ATTLIST index name    CDATA #IMPLIED\n"
-        "                  path    CDATA #IMPLIED\n"
-        "                  rev     CDATA #IMPLIED\n"
-        "                  base    CDATA #IMPLIED>\n"
-        "  <!ELEMENT updir EMPTY>\n"
-        "  <!ATTLIST updir href    CDATA #REQUIRED>\n"
-        "  <!ELEMENT file  EMPTY>\n"
-        "  <!ATTLIST file  name    CDATA #REQUIRED\n"
-        "                  href    CDATA #REQUIRED>\n"
-        "  <!ELEMENT dir   EMPTY>\n"
-        "  <!ATTLIST dir   name    CDATA #REQUIRED\n"
-        "                  href    CDATA #REQUIRED>\n"
-        "]>\n";
-
       /* <svn version="1.3.0 (dev-build)"
               href="http://subversion.apache.org">
            <index name="[info->repos->repo_name]"
@@ -3412,99 +3629,21 @@ deliver(const dav_resource *resource, ap
                                         resource->pool);
         }
 
-      bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+      bb = apr_brigade_create(resource->pool,
+                              dav_svn__output_get_bucket_alloc(output));
 
-      if (gen_html)
-        {
-          const char *title;
-          if (resource->info->repos_path == NULL)
-            title = "unknown location";
-          else
-            title = resource->info->repos_path;
-
-          if (resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
-            {
-              if (SVN_IS_VALID_REVNUM(resource->info->root.rev))
-                title = apr_psprintf(resource->pool,
-                                     "Revision %ld: %s",
-                                     resource->info->root.rev, title);
-              if (resource->info->repos->repo_basename)
-                title = apr_psprintf(resource->pool, "%s - %s",
-                                     resource->info->repos->repo_basename,
-                                     title);
-              if (resource->info->repos->repo_name)
-                title = apr_psprintf(resource->pool, "%s: %s",
-                                     resource->info->repos->repo_name,
-                                     title);
-            }
-
-          ap_fprintf(output, bb, "<html><head><title>%s</title></head>\n"
-                     "<body>\n <h2>%s</h2>\n <ul>\n", title, title);
-        }
-      else
-        {
-          const char *name = resource->info->repos->repo_name;
-          const char *href = resource->info->repos_path;
-          const char *base = resource->info->repos->repo_basename;
-
-          ap_fputs(output, bb, "<?xml version=\"1.0\"?>\n");
-          ap_fprintf(output, bb,
-                     "<?xml-stylesheet type=\"text/xsl\" href=\"%s\"?>\n",
-                     resource->info->repos->xslt_uri);
-          ap_fputs(output, bb, xml_index_dtd);
-          ap_fputs(output, bb,
-                   "<svn version=\"" SVN_VERSION "\"\n"
-                   "     href=\"http://subversion.apache.org/\">\n");
-          ap_fputs(output, bb, "  <index");
-          if (name)
-            ap_fprintf(output, bb, " name=\"%s\"",
-                       apr_xml_quote_string(resource->pool, name, 1));
-          if (SVN_IS_VALID_REVNUM(resource->info->root.rev))
-            ap_fprintf(output, bb, " rev=\"%ld\"",
-                       resource->info->root.rev);
-          if (href)
-            ap_fprintf(output, bb, " path=\"%s\"",
-                       apr_xml_quote_string(resource->pool,
-                                            href,
-                                            1));
-          if (base)
-            ap_fprintf(output, bb, " base=\"%s\"", base);
-
-          ap_fputs(output, bb, ">\n");
-        }
-
-      if ((resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
-          && resource->info->repos_path
-          && ((resource->info->repos_path[1] != '\0')
-              || dav_svn__get_list_parentpath_flag(resource->info->r)))
-        {
-          const char *href;
-          if (resource->info->pegged)
-            {
-              href = apr_psprintf(resource->pool, "../?p=%ld",
-                                  resource->info->root.rev);
-            }
-          else
-            {
-              href = "../";
-            }
-
-          if (gen_html)
-            {
-              ap_fprintf(output, bb,
-                         "  <li><a href=\"%s\">..</a></li>\n", href);
-            }
-          else
-            {
-              ap_fprintf(output, bb, "    <updir href=\"%s\"/>\n", href);
-            }
-        }
+      serr = emit_collection_head(resource, bb, output, gen_html,
+                                  resource->pool);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "could not output collection",
+                                    resource->pool);
 
       /* get a sorted list of the entries */
       sorted = svn_sort__hash(entries, svn_sort_compare_items_as_paths,
                               resource->pool);
 
-      entry_pool = svn_pool_create(resource->pool);
+      iterpool = svn_pool_create(resource->pool);
 
       for (i = 0; i < sorted->nelts; ++i)
         {
@@ -3512,11 +3651,9 @@ deliver(const dav_resource *resource, ap
                                                         const svn_sort__item_t);
           const svn_fs_dirent_t *entry = item->value;
           const char *name = item->key;
-          const char *href = name;
-          svn_boolean_t is_dir = (entry->kind == svn_node_dir);
           const char *repos_relpath = NULL;
 
-          svn_pool_clear(entry_pool);
+          svn_pool_clear(iterpool);
 
           /* DIR_REV is set to a valid revision if we're looking at
              the entries of a versioned directory.  Otherwise, we're
@@ -3524,120 +3661,45 @@ deliver(const dav_resource *resource, ap
           if (SVN_IS_VALID_REVNUM(dir_rev))
             {
               repos_relpath = svn_fspath__join(resource->info->repos_path,
-                                               name, entry_pool);
+                                               name, iterpool);
               if (! dav_svn__allow_read(resource->info->r,
                                         resource->info->repos,
                                         repos_relpath,
                                         dir_rev,
-                                        entry_pool))
+                                        iterpool))
                 continue;
             }
           else
             {
                 if (! dav_svn__allow_list_repos(resource->info->r,
-                                                entry->name, entry_pool))
+                                                entry->name, iterpool))
                   continue;
             }
 
-          /* append a trailing slash onto the name for directories. we NEED
-             this for the href portion so that the relative reference will
-             descend properly. for the visible portion, it is just nice. */
-          /* ### The xml output doesn't like to see a trailing slash on
-             ### the visible portion, so avoid that. */
-          if (is_dir)
-            href = apr_pstrcat(entry_pool, href, "/", SVN_VA_NULL);
-
-          if (gen_html)
-            name = href;
-
-          /* We quote special characters in both XML and HTML. */
-          name = apr_xml_quote_string(entry_pool, name, !gen_html);
-
-          /* According to httpd-2.0.54/include/httpd.h, ap_os_escape_path()
-             behaves differently on different platforms.  It claims to
-             "convert an OS path to a URL in an OS dependant way".
-             Nevertheless, there appears to be only one implementation
-             of the function in httpd, and the code seems completely
-             platform independent, so we'll assume it's appropriate for
-             mod_dav_svn to use it to quote outbound paths. */
-          href = ap_os_escape_path(entry_pool, href, 0);
-          href = apr_xml_quote_string(entry_pool, href, 1);
-
-          if (gen_html)
-            {
-              /* If our directory was access using the public peg-rev
-                 CGI query interface, we'll let its dirents carry that
-                 peg-rev, too. */
-              if (resource->info->pegged)
-                {
-                  ap_fprintf(output, bb,
-                             "  <li><a href=\"%s?p=%ld\">%s</a></li>\n",
-                             href, resource->info->root.rev, name);
-                }
-              else
-                {
-                  ap_fprintf(output, bb,
-                             "  <li><a href=\"%s\">%s</a></li>\n",
-                             href, name);
-                }
-            }
-          else
-            {
-              const char *const tag = (is_dir ? "dir" : "file");
-
-              /* This is where we could search for props */
-
-              /* If our directory was access using the public peg-rev
-                 CGI query interface, we'll let its dirents carry that
-                 peg-rev, too. */
-              if (resource->info->pegged)
-                {
-                  ap_fprintf(output, bb,
-                             "    <%s name=\"%s\" href=\"%s?p=%ld\" />\n",
-                             tag, name, href, resource->info->root.rev);
-                }
-              else
-                {
-                  ap_fprintf(output, bb,
-                             "    <%s name=\"%s\" href=\"%s\" />\n",
-                             tag, name, href);
-                }
-            }
+          serr = emit_collection_entry(resource, bb, output, entry, gen_html,
+                                       iterpool);
+          if (serr != NULL)
+            return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                        "could not output collection entry",
+                                        resource->pool);
         }
 
-      svn_pool_destroy(entry_pool);
-
-      if (gen_html)
-        {
-          if (strcmp(ap_psignature("FOO", resource->info->r), "") != 0)
-            {
-              /* Apache's signature generation code didn't eat our prefix.
-                 ServerSignature must be enabled.  Print our version info.
+      svn_pool_destroy(iterpool);
 
-                 WARNING: This is a kludge!! ap_psignature() doesn't promise
-                 to return the empty string when ServerSignature is off.  We
-                 know it does by code inspection, but this behavior is subject
-                 to change. (Perhaps we should try to get the Apache folks to
-                 make this promise, though.  Seems harmless/useful enough...)
-              */
-              ap_fputs(output, bb,
-                       " </ul>\n <hr noshade><em>Powered by "
-                       "<a href=\"http://subversion.apache.org/\">"
-                       "Apache Subversion"
-                       "</a> version " SVN_VERSION "."
-                       "</em>\n</body></html>");
-            }
-          else
-            ap_fputs(output, bb, " </ul>\n</body></html>");
-        }
-      else
-        ap_fputs(output, bb, "  </index>\n</svn>\n");
+      serr = emit_collection_tail(resource, bb, output, gen_html,
+                                  resource->pool);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "could not output collection",
+                                    resource->pool);
 
-      bkt = apr_bucket_eos_create(output->c->bucket_alloc);
+      bkt = apr_bucket_eos_create(dav_svn__output_get_bucket_alloc(output));
       APR_BRIGADE_INSERT_TAIL(bb, bkt);
-      if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS)
-        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                                  "Could not write EOS to filter.");
+      serr = dav_svn__output_pass_brigade(output, bb);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not write EOS to filter.",
+                                    resource->pool);
 
       return NULL;
     }
@@ -3700,7 +3762,8 @@ deliver(const dav_resource *resource, ap
                                         "could not prepare to read a delta",
                                         resource->pool);
 
-          bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+          bb = apr_brigade_create(resource->pool,
+                                  dav_svn__output_get_bucket_alloc(output));
 
           /* create a stream that svndiff data will be written to,
              which will copy it to the network */
@@ -3828,7 +3891,8 @@ deliver(const dav_resource *resource, ap
          ### which will read from the FS stream on demand */
 
       block = apr_palloc(resource->pool, SVN__STREAM_CHUNK_SIZE);
-      bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+      bb = apr_brigade_create(resource->pool,
+                              dav_svn__output_get_bucket_alloc(output));
 
       while (1) {
         apr_size_t bufsize = SVN__STREAM_CHUNK_SIZE;
@@ -3846,29 +3910,32 @@ deliver(const dav_resource *resource, ap
           break;
 
         /* write to the filter ... */
-        bkt = apr_bucket_transient_create(block, bufsize,
-                                          output->c->bucket_alloc);
+        bkt = apr_bucket_transient_create(
+          block, bufsize, dav_svn__output_get_bucket_alloc(output));
         APR_BRIGADE_INSERT_TAIL(bb, bkt);
-        if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) {
-          /* ### what to do with status; and that HTTP code... */
-          apr_brigade_destroy(bb);
-          return dav_svn__new_error(resource->pool,
-                                    HTTP_INTERNAL_SERVER_ERROR, 0,
-                                    "Could not write data to filter.");
-        }
-        apr_brigade_cleanup(bb);
+        serr = dav_svn__output_pass_brigade(output, bb);
+        if (serr != NULL)
+          {
+            apr_brigade_destroy(bb);
+            /* ### that HTTP code... */
+            return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                        "Could not write data to filter.",
+                                        resource->pool);
+          }
       }
 
       /* done with the file. write an EOS bucket now. */
-      bkt = apr_bucket_eos_create(output->c->bucket_alloc);
+      bkt = apr_bucket_eos_create(dav_svn__output_get_bucket_alloc(output));
       APR_BRIGADE_INSERT_TAIL(bb, bkt);
-      if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) {
-        /* ### what to do with status; and that HTTP code... */
-        apr_brigade_destroy(bb);
-        return dav_svn__new_error(resource->pool,
-                                  HTTP_INTERNAL_SERVER_ERROR, 0,
-                                  "Could not write EOS to filter.");
-      }
+      serr = dav_svn__output_pass_brigade(output, bb);
+      if (serr != NULL)
+        {
+          apr_brigade_destroy(bb);
+          /* ### that HTTP code... */
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not write EOS to filter.",
+                                      resource->pool);
+        }
 
       apr_brigade_destroy(bb);
       return NULL;
@@ -4633,7 +4700,7 @@ dav_svn__create_version_resource(dav_res
 static dav_error *
 handle_post_request(request_rec *r,
                     dav_resource *resource,
-                    ap_filter_t *output)
+                    dav_svn__output *output)
 {
   svn_skel_t *request_skel, *post_skel;
   int status;
@@ -4716,7 +4783,9 @@ int dav_svn__method_post(request_rec *r)
   content_type = apr_table_get(r->headers_in, "content-type");
   if (content_type && (strcmp(content_type, SVN_SKEL_MIME_TYPE) == 0))
     {
-      derr = handle_post_request(r, resource, r->output_filters);
+      dav_svn__output *output = dav_svn__output_create(resource->info->r,
+                                                       resource->pool);
+      derr = handle_post_request(r, resource, output);
     }
   else
     {



Mime
View raw message