You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2016/10/03 12:57:47 UTC

svn commit: r1763163 [1/3] - in /httpd/httpd/branches/2.4.x: ./ modules/http2/

Author: icing
Date: Mon Oct  3 12:57:47 2016
New Revision: 1763163

URL: http://svn.apache.org/viewvc?rev=1763163&view=rev
Log:
Merge of 1761479,1761548,1762703,1763158 from trunk

mod_http2: rewrite of how responses and trailers are transferred between
     master and slave connection. Reduction of internal states for tasks
     and streams, stability. Heuristic id generation for slave connections
     to better keep promise of connection ids unique at given point int time.
     Fix for mod_cgid interop in high load situtations. 
     Fix for handling of incoming trailers when no request body is sent.


Added:
    httpd/httpd/branches/2.4.x/modules/http2/h2_headers.c
      - copied unchanged from r1763158, httpd/httpd/trunk/modules/http2/h2_headers.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_headers.h
      - copied unchanged from r1763158, httpd/httpd/trunk/modules/http2/h2_headers.h
Removed:
    httpd/httpd/branches/2.4.x/modules/http2/h2_response.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_response.h
Modified:
    httpd/httpd/branches/2.4.x/   (props changed)
    httpd/httpd/branches/2.4.x/CHANGES
    httpd/httpd/branches/2.4.x/CMakeLists.txt
    httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2
    httpd/httpd/branches/2.4.x/modules/http2/config2.m4
    httpd/httpd/branches/2.4.x/modules/http2/h2.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_h2.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_mplx.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_mplx.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_ngn_shed.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_ngn_shed.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_proxy_util.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_push.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_push.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_request.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_request.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_session.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_session.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_stream.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_stream.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_task.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_task.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_util.c
    httpd/httpd/branches/2.4.x/modules/http2/h2_util.h
    httpd/httpd/branches/2.4.x/modules/http2/h2_version.h
    httpd/httpd/branches/2.4.x/modules/http2/mod_http2.c
    httpd/httpd/branches/2.4.x/modules/http2/mod_http2.dsp

Propchange: httpd/httpd/branches/2.4.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct  3 12:57:47 2016
@@ -2,4 +2,4 @@
 /httpd/httpd/branches/2.4.17-protocols-http2:1701609-1705681
 /httpd/httpd/branches/revert-ap-ldap:1150158-1150173
 /httpd/httpd/branches/wombat-integration:723609-723841
-/httpd/httpd/trunk:1200475,1200478,1200482,1200491,1200496,1200513,1200550,1200556,1200580,1200605,1200612,1200614,1200639,1200646,1200656,1200667,1200679,1200699,1200702,1200955,1200957,1200961,1200963,1200968,1200975,1200977,1201032,1201042,1201111,1201194,1201198,1201202,1201443,1201450,1201460,1201956,1202236,1202453,1202456,1202886,1203400,1203491,1203632,1203714,1203859,1203980,1204630,1204968,1204990,1205061,1205075,1205379,1205885,1206291,1206472,1206587,1206850,1206940,1206978,1207719,1208753,1208835,1209053,1209085,1209417,1209432,1209461,1209601,1209603,1209618,1209623,1209741,1209754,1209766,1209776,1209797-1209798,1209811-1209812,1209814,1209908,1209910,1209913,1209916-1209917,1209947,1209952,1210067,1210080,1210120,1210124,1210130,1210148,1210219,1210221,1210252,1210284,1210336,1210378,1210725,1210892,1210951,1210954,1211351-1211352,1211364,1211490,1211495,1211528,1211663,1211680,1212872,1212883,1213338,1213380-1213381,1213391,1213399,1213567,1214003,1214005,1214015,12
 15514,1220462,1220467,1220493,1220524,1220570,1220768,1220794,1220826,1220846,1221205,1221292,1222335,1222370,1222473,1222915,1222917,1222921,1222930,1223048,1225060,1225197-1225199,1225223,1225380,1225476,1225478,1225791,1225795-1225796,1226339,1226375,1227910,1228700,1228816,1229024,1229059,1229099,1229116,1229134,1229136,1229930,1230286,1231255,1231257,1231442,1231446,1231508,1231510,1231518,1232575,1232594,1232630,1232838,1234180,1234297,1234479,1234511,1234565,1234574,1234642-1234643,1234876,1234899,1235019,1236122,1236701,1237407,1238545,1238768,1239029-1239030,1239071,1239565,1240315,1240470,1240778,1241069,1241071,1242089,1242798,1242967,1243176,1243246,1243797,1243799,1244211,1245717,1290823,1290835,1291819-1291820,1291834,1291840,1292043,1293405,1293534-1293535,1293658,1293678,1293708,1294306,1294349,1294356,1294358,1294372,1294471,1297560,1299718,1299786,1300766,1301111,1301725,1302444,1302483,1302653,1302665,1302674,1303201,1303435,1303827,1304087,1304874-1304875,1305167
 ,1305586,1306350,1306409,1306426,1306841,1307790,1308327,1308459,1309536,1309567,1311468,1324760,1325218,1325227,1325250,1325265,1325275,1325632,1325724,1326980,1326984,1326991,1327689,1328325-1328326,1328339,1328345,1328950,1330189,1330964,1331110,1331115,1331942,1331977,1332378,1333969,1334343,1335882,1337344,1341906,1341913,1343085,1343087,1343094,1343099,1343109,1343935,1345319,1345329,1346905,1347980,1348036,1348653,1348656,1348660,1349905,1351012-1351020,1351071-1351072,1351074,1351737,1352047,1352534,1352909-1352912,1357685,1358061,1359057,1359881,1359884,1361153,1361298,1361766,1361773,1361778,1361784,1361791-1361792,1361801,1361803,1362020,1362538,1362707,1363035,1363183,1363186,1363312,1363440,1363557,1363589,1363829,1363832,1363836-1363837,1363853,1364133,1364138,1364229,1364601,1364695,1365001,1365020,1365029,1365479,1366319,1366344,1366621,1367778,1367819,1368053,1368058,1368094,1368121,1368131,1368393,1368396,1369419,1369568,1369604,1369618,1369904,1369995,1369999,1370
 001,1370466,1370592,1370615-1370616,1370763,1371387,1371791,1371801,1371878,1371903,1373270,1373447,1373898,1373955,1374157,1374199,1374247,1374874,1374877,1374880,1375006,1375009,1375011,1375013,1375584,1376695,1376700,1378178,1383490,1384408,1384913,1386576,1386578,1386726,1386822,1386880,1386913,1387085,1387088,1387110,1387389,1387444,1387603,1387607,1387633,1387693,1387979,1388029,1388445,1388447,1388648,1388660,1388825,1388899,1389316,1389339,1389481,1389506,1389564,1389566-1389569,1390562,1390564,1391396,1391398,1391771,1392120,1392122,1392150,1392214,1392345-1392347,1392850,1393033,1393058,1393152,1393338,1393564,1394079,1395225,1395253-1395256,1395792,1396440,1397172,1397320,1397636,1397687,1397710,1397716,1398025,1398040,1398066,1398478,1398480-1398481,1398970,1399413,1399687,1399708,1400700,1401448,1402924,1403476,1403483,1403492,1404653,1405407,1405856,1405973,1406068,1406493,1406495,1406616,1406646,1406760,1407004,1407006,1407085,1407088,1407248,1407381,1407459-1407460,1
 407528,1407853,1407965,1408093,1408402,1408958,1408961,1409170,1409437,1409726,1409800,1410681,1410954,1411862,1412278,1413732,1414094,1415008,1415023,1415075,1416121,1416150,1416278,1417197,1417440,1417529,1418524,1418556,1418648,1418655,1418703,1418721,1418752,1418769,1419084,1419719,1419726,1419755,1419781,1419796,1420120,1420124,1420149,1420184,1420644,1420685-1420686,1420975,1421288,1421323,1421851,1421912,1421953,1422135,1422549,1422594,1422712,1422855,1422937,1422943,1422980,1423353,1423933,1425360,1425771-1425772,1425775,1425777,1425874,1426850,1426975,1427546,1428184,1428280,1428916,1429228,1429559,1429561,1429564,1429582,1430575,1430814,1430869,1433001,1433613,1433682,1433861,1433988,1435178,1435811,1436058,1436401,1439083,1439106,1439114,1439404,1439623,1442309,1442320,1442326,1442412,1442759,1442865,1447993,1448171,1448453,1451478,1451484,1451633,1451849,1451905,1451921,1452128,1452195,1452259,1452281,1452551,1452911,1452949,1452954,1453022,1453574,1453604,1453875-145387
 6,1453963,1453981,1454386,1454414-1454415,1454888,1457437,1457450,1457471,1457504,1457520-1457521,1457610,1457995,1458003-1458004,1458020,1458285,1458447,1458456,1462266,1462269,1462643,1463044-1463047,1463052,1463056,1463455,1463736,1463750,1463754,1464675,1464721,1464762,1465115-1465116,1465190,1467765,1468581,1470183,1470679,1470940,1471449,1475878,1476604,1476621,1476642,1476644-1476645,1476652,1476680,1477094,1477530,1478382,1478748,1479117,1479216,1479222,1479411,1479528,1479905,1479966,1480046,1480627,1481197,1481302,1481306,1481396-1481397,1481891,1482041,1482075,1482170,1482555,1482859,1482996,1483005,1483027,1483190,1484343,1484398,1484832,1484910,1484914,1485409,1485668,1486490,1487528,1487530,1488158,1488164,1488296,1488471,1488492,1488644,1490493,1490507,1490550,1490761,1490994,1491155,1491221,1491234,1491458,1491479,1491538,1491564,1491724,1492663,1492710,1492782,1493330,1493921,1493925,1494536,1495501,1496194,1496338,1496429,1496709,1497371,1497588,1498880,1499679,150
 0323,1500345,1500362,1500423,1500437,1500483,1500519,1501294,1501369,1501399,1501913,1502665,1502772,1503680,1503866,1503990-1503991,1504276,1506474,1506714,1509872,1509983,1510084-1510085,1510098,1510588,1510707,1511093,1513492,1513508,1514039,1514064,1514214-1514215,1514255,1514267,1514617,1515050,1515162,1515403,1515411,1515420,1517025,1517045,1517175,1517366,1517386,1517388,1518265,1518269,1519475,1520368,1520445,1520760,1520908,1521909,1523235,1523239,1523281,1523387,1524101,1524158,1524192,1524368,1524388,1524770,1525276,1525280-1525281,1525931,1526168,1526189,1526647,1526666,1527008,1527220,1527291,1527294-1527295,1527509,1527925-1527926,1528143,1528718,1529014,1529277,1529449,1529559,1529988,1529991,1530793,1531340,1531370,1531505,1531672,1531961-1531962,1532746,1532816,1533065,1533224,1534321,1534754,1534890,1534892,1536310,1537535,1538490,1540051-1540052,1541181,1541270,1541368,1542338,1542379,1542533,1542562,1542615,1543020,1543147,1543149,1543174,1544381,1544774,1544784,
 1544812,1544820,1545286,1545292,1545325,1545364,1545408,1545411,1546692-1546693,1546730,1546759-1546760,1546801,1546804-1546805,1546835-1546836,1547845,1550061,1550302,1550307,1551685,1551714,1551802,1552130,1552227,1553204,1553824,1554161,1554168,1554170,1554175-1554176,1554179,1554181,1554184,1554188,1554192,1554195,1554276,1554281,1554300-1554301,1554994-1554995,1555240,1555259,1555266,1555423-1555424,1555463-1555464,1555467,1555555,1555569,1556206,1556428,1556911-1556912,1556914,1556937,1557317,1557617,1558483,1559351,1559828,1560367,1560546,1560679,1560689,1560729,1560977,1560979,1561137,1561262,1561385,1561660,1561923,1562472,1563193,1563379,1563381,1563417-1563418,1563420,1564052,1564437,1564475,1564756,1564760,1565081,1565711,1568404,1569615,1570288,1570598,1571369,1572092,1572198,1572543,1572561,1572611,1572630,1572655,1572663,1572668-1572671,1572896,1572905,1572911,1572967,1573224,1573229,1573626,1574151,1575400,1576233,1576741,1578760,1578762,1580568,1583005,1583007-15830
 08,1583027,1583175,1583191,1584098,1584430,1584434,1584572,1584653,1584658,1584665,1584703,1584878,1584884,1584896,1585054,1585072,1585090,1585435,1585609,1585824,1585918-1585919,1586745,1586827,1587036,1587040,1587053,1587255,1587594,1587607,1587639,1587654,1588054,1588065,1588213,1588330,1588427,1588519,1588527,1588704,1588851,1588853,1588868,1589413,1590437,1590509,1591143,1591320,1591322,1591328,1591390,1591394,1591401,1591472,1591508,1592032,1592037,1592500,1592511,1592514,1592529,1592615,1592632,1593745,1594625,1594643,1594648,1595305,1595321,1595426,1597182,1597349,1597352,1597639,1597642,1598107,1598946,1599535,1601076,1601184-1601185,1601274,1601291,1601624,1601630,1601919,1601995,1602338,1602978,1602989,1603027,1603029,1603122,1603156,1603915,1604382,1604461,1604631,1605207,1605827,1605829,1607960,1608284,1608785,1608999,1609914,1609936,1609938,1610207,1610311,1610353,1610366,1610491,1610652,1610674,1611165,1611169,1611244,1611600,1611871,1611978,1612068,1615026,1615289,16
 17018,1618401,1618541,1619297,1619383,1619444,1619483,1619835,1620324,1620461,1620932,1621367,1621372,1621417,1621453,1621806,1622450,1624234,1624349,1625196,1625952,1626050,1626978,1628104,1628918-1628919,1628924,1628950,1629235,1629239,1629244,1629250,1629372,1629440-1629441,1629485,1629507-1629508,1629519,1629577,1629652,1629916,1631885,1632454,1632740,1632742,1633730-1633731,1633793,1634120,1634237,1634425,1634736,1634836,1635510,1635558,1635644-1635645,1635762,1637112,1638072-1638073,1638879,1639614,1640031,1640036,1640040,1640042,1640331,1641077,1641095,1641376,1642099,1642484,1642499,1642847,1642868,1643034,1643284,1643537,1643825,1644245,1646282,1646724,1647035,1648201,1648394,1648433,1648719,1648840,1649001,1649043,1649632,1649966,1650047,1650061,1650309-1650310,1650320,1651088,1652829,1652929,1652931,1652955,1652982,1652985,1652989,1653941,1653978,1653997,1656225,1656669,1657256,1657261,1657636,1657638,1657685,1657881,1657897,1658760,1658765,1661067,1661258,1661448,1661464
 ,1661486,1662245-1662246,1663017,1663647,1664071,1664133,1664205,1664299,1664709,1665215,1665218,1665625,1665643,1665721,1666297,1666361,1666363,1666468,1666618,1666998,1667385-1667386,1668532,1668535,1668553,1669130,1669289,1669292,1670434,1671364,1671396-1671397,1671918,1672289,1672453,1672466,1672480,1672483,1672564,1672757,1672985,1672989,1673113,1673155,1673368,1673455,1673769,1674056,1674538,1674542,1674606,1674632,1674697,1675103,1675410,1675533,1676085,1676654,1676709,1676842,1677096,1677143-1677146,1677149,1677151,1677153-1677156,1677159,1677339,1677462,1677702,1677830,1677832,1677834-1677835,1678763,1679032,1679181-1679182,1679192,1679428,1679432,1679470,1679620,1679712,1680276,1680895,1680900,1680942,1681037,1681424,1681440,1681685,1681694,1681795,1682482,1682816,1682819,1682907,1682923,1682937,1682979,1682988,1683044,1683047,1683123,1683881,1683884,1684057,1684171,1684900,1685069,1685339,1685345,1685347,1685349-1685350,1685650,1685659,1685779,1686085,1686853,1686856,1687
 539,1687680,1687980,1688274,1688331,1688339-1688341,1688343,1688474-1688475,1688536,1688538,1688660,1689325,1689605,1689694,1689698,1690120,1690137,1690248,1691374,1691582,1691592,1691819,1691908,1692285,1692432,1692486,1692516,1693792,1693918-1693919,1693963,1694903,1694936,1694950-1694951,1695170,1695727,1695874,1695885,1695920,1696105,1696264,1696266,1696279,1696428,1696442,1696565,1696592,1696607,1696755,1696881,1697013,1697015,1697051,1697323,1697339,1697370,1697389,1697446,1697543,1697634,1697855,1698023,1698103,1698107,1698116,1698133,1698330,1700271,1700275,1700317-1700322,1700326,1700328,1700330-1700332,1700334,1700336,1700338,1700418,1700514,1700777,1700851,1700917,1700925,1700968,1701005,1701145,1701178,1701204,1701347,1701436,1701545,1701717,1702643,1702919,1703152,1703417,1703642,1703807,1703813,1703822,1703871,1703902,1703952,1704099,1704241,1704262,1704797,1704799,1704826,1705099,1705134,1705194,1705217,1705257,1705749,1705776,1705823,1705826,1705828,1705833,1705983,1
 706275,1706627,1706635,1706637,1706640,1706918,1706942,1706989,1707002,1707230-1707231,1707497,1707519,1707591,1707626-1707627,1707640,1707831,1707883,1707889,1708107,1709008,1709587,1709596,1709602,1709995,1710095,1710105,1710231,1710380,1710391,1710419,1710572,1710583,1710723,1711479,1711553,1711648,1711728,1711902,1712382,1713040,1713209,1713937,1715023,1715255,1715273,1715567-1715568,1715570-1715572,1715576,1715581-1715585,1715886,1716211,1716388,1716460,1716487,1716660,1716940,1717063,1717086,1717639,1717816,1717934,1717958,1717975,1717985,1718314,1718338,1718400,1718514,1718556,1718569,1718598,1719016,1719018,1719189-1719190,1719252,1719254-1719255,1719257,1719967,1720129,1720996,1721313,1721685,1721899,1722137,1722154,1722177,1722195,1722229,1722320,1722328,1722334,1722350-1722351,1722358,1722377,1722572,1722701,1723122,1723143,1723284,1723295,1723567,1723953,1724847,1724857,1724879,1724992-1724993,1724995,1725018,1725031,1725090,1725120,1725149,1725325,1725328,1725387,172539
 2,1725394-1725395,1725445,1725468,1725485,1725489,1725498-1725499,1725516,1725523,1725545,1725567,1725581,1725602,1725822,1725940,1725967,1726009,1726026,1726038,1726049,1726051-1726052,1726055,1726086,1726167,1726233,1726798,1726881,1726888,1727071,1727111,1727317,1727544,1727573,1727603,1727842,1728326,1729208,1729374,1729376,1729826,1729847,1729929-1729931,1729960,1730297,1730640,1730723,1730865,1731929,1732252,1732353,1732369,1732716,1732954,1732986,1733056,1733064,1733068,1733088-1733089,1733275,1733523,1733537,1733691,1734006,1734125,1734239,1734294,1734412,1734561,1734807,1734817,1734947,1734955,1734989,1735088,1735159,1735337,1735608-1735609,1735611,1735668,1735786,1735931,1735935,1735942,1735952,1736156,1736243,1736250,1736463,1736681,1736686,1737006,1737014,1737020-1737021,1737102,1737114,1737125,1737254,1737256,1737265,1737447,1737449,1737451,1737476,1738217,1738331,1738333,1738563,1739008,1739146,1739151,1739193,1739303,1739312,1739738,1739932,1740075,1740084,1740108,174
 0110,1740155,1740735,1741045,1741065,1741112,1741115,1741268,1741310,1741392,1741414,1741446,1741461,1741557,1741564,1741596,1741621,1741648,1741934,1742005,1742135,1742260,1742359,1742444-1742447,1742460,1742791-1742792,1743335,1743517,1743699,1743788,1743816,1744203-1744204,1744206,1744283,1744415,1744421,1744458-1744459,1744712,1744751,1744767,1744778,1744980,1745034,1745175,1745767,1745835,1746207,1746647,1746988,1747170,1747531,1747550,1747735,1747808,1747810,1747946,1748047,1748155,1748368,1748448,1748531,1748653,1748888,1749151,1749401,1749404,1749505,1749658-1749659,1749676,1749678,1749695,1749924-1749925,1750043,1750218,1750335,1750407,1750420,1750507,1750553,1750567,1750750,1750779,1750854-1750855,1750947,1750955,1750960,1751970,1752087,1752096,1752145,1752347,1752415,1753167,1753224,1753228-1753229,1753257,1753315-1753316,1753498,1753541,1753592,1753594,1753777,1754129,1754391,1754399,1754414,1754534,1755323,1756038,1756611,1756844,1756846,1756852-1756853,1757010-1757011,
 1757524,1757534,1757540,1757662-1757663,1757985,1758003,1758083,1758307-1758311,1758446,1758558,1761434,1761477
+/httpd/httpd/trunk:1200475,1200478,1200482,1200491,1200496,1200513,1200550,1200556,1200580,1200605,1200612,1200614,1200639,1200646,1200656,1200667,1200679,1200699,1200702,1200955,1200957,1200961,1200963,1200968,1200975,1200977,1201032,1201042,1201111,1201194,1201198,1201202,1201443,1201450,1201460,1201956,1202236,1202453,1202456,1202886,1203400,1203491,1203632,1203714,1203859,1203980,1204630,1204968,1204990,1205061,1205075,1205379,1205885,1206291,1206472,1206587,1206850,1206940,1206978,1207719,1208753,1208835,1209053,1209085,1209417,1209432,1209461,1209601,1209603,1209618,1209623,1209741,1209754,1209766,1209776,1209797-1209798,1209811-1209812,1209814,1209908,1209910,1209913,1209916-1209917,1209947,1209952,1210067,1210080,1210120,1210124,1210130,1210148,1210219,1210221,1210252,1210284,1210336,1210378,1210725,1210892,1210951,1210954,1211351-1211352,1211364,1211490,1211495,1211528,1211663,1211680,1212872,1212883,1213338,1213380-1213381,1213391,1213399,1213567,1214003,1214005,1214015,12
 15514,1220462,1220467,1220493,1220524,1220570,1220768,1220794,1220826,1220846,1221205,1221292,1222335,1222370,1222473,1222915,1222917,1222921,1222930,1223048,1225060,1225197-1225199,1225223,1225380,1225476,1225478,1225791,1225795-1225796,1226339,1226375,1227910,1228700,1228816,1229024,1229059,1229099,1229116,1229134,1229136,1229930,1230286,1231255,1231257,1231442,1231446,1231508,1231510,1231518,1232575,1232594,1232630,1232838,1234180,1234297,1234479,1234511,1234565,1234574,1234642-1234643,1234876,1234899,1235019,1236122,1236701,1237407,1238545,1238768,1239029-1239030,1239071,1239565,1240315,1240470,1240778,1241069,1241071,1242089,1242798,1242967,1243176,1243246,1243797,1243799,1244211,1245717,1290823,1290835,1291819-1291820,1291834,1291840,1292043,1293405,1293534-1293535,1293658,1293678,1293708,1294306,1294349,1294356,1294358,1294372,1294471,1297560,1299718,1299786,1300766,1301111,1301725,1302444,1302483,1302653,1302665,1302674,1303201,1303435,1303827,1304087,1304874-1304875,1305167
 ,1305586,1306350,1306409,1306426,1306841,1307790,1308327,1308459,1309536,1309567,1311468,1324760,1325218,1325227,1325250,1325265,1325275,1325632,1325724,1326980,1326984,1326991,1327689,1328325-1328326,1328339,1328345,1328950,1330189,1330964,1331110,1331115,1331942,1331977,1332378,1333969,1334343,1335882,1337344,1341906,1341913,1343085,1343087,1343094,1343099,1343109,1343935,1345319,1345329,1346905,1347980,1348036,1348653,1348656,1348660,1349905,1351012-1351020,1351071-1351072,1351074,1351737,1352047,1352534,1352909-1352912,1357685,1358061,1359057,1359881,1359884,1361153,1361298,1361766,1361773,1361778,1361784,1361791-1361792,1361801,1361803,1362020,1362538,1362707,1363035,1363183,1363186,1363312,1363440,1363557,1363589,1363829,1363832,1363836-1363837,1363853,1364133,1364138,1364229,1364601,1364695,1365001,1365020,1365029,1365479,1366319,1366344,1366621,1367778,1367819,1368053,1368058,1368094,1368121,1368131,1368393,1368396,1369419,1369568,1369604,1369618,1369904,1369995,1369999,1370
 001,1370466,1370592,1370615-1370616,1370763,1371387,1371791,1371801,1371878,1371903,1373270,1373447,1373898,1373955,1374157,1374199,1374247,1374874,1374877,1374880,1375006,1375009,1375011,1375013,1375584,1376695,1376700,1378178,1383490,1384408,1384913,1386576,1386578,1386726,1386822,1386880,1386913,1387085,1387088,1387110,1387389,1387444,1387603,1387607,1387633,1387693,1387979,1388029,1388445,1388447,1388648,1388660,1388825,1388899,1389316,1389339,1389481,1389506,1389564,1389566-1389569,1390562,1390564,1391396,1391398,1391771,1392120,1392122,1392150,1392214,1392345-1392347,1392850,1393033,1393058,1393152,1393338,1393564,1394079,1395225,1395253-1395256,1395792,1396440,1397172,1397320,1397636,1397687,1397710,1397716,1398025,1398040,1398066,1398478,1398480-1398481,1398970,1399413,1399687,1399708,1400700,1401448,1402924,1403476,1403483,1403492,1404653,1405407,1405856,1405973,1406068,1406493,1406495,1406616,1406646,1406760,1407004,1407006,1407085,1407088,1407248,1407381,1407459-1407460,1
 407528,1407853,1407965,1408093,1408402,1408958,1408961,1409170,1409437,1409726,1409800,1410681,1410954,1411862,1412278,1413732,1414094,1415008,1415023,1415075,1416121,1416150,1416278,1417197,1417440,1417529,1418524,1418556,1418648,1418655,1418703,1418721,1418752,1418769,1419084,1419719,1419726,1419755,1419781,1419796,1420120,1420124,1420149,1420184,1420644,1420685-1420686,1420975,1421288,1421323,1421851,1421912,1421953,1422135,1422549,1422594,1422712,1422855,1422937,1422943,1422980,1423353,1423933,1425360,1425771-1425772,1425775,1425777,1425874,1426850,1426975,1427546,1428184,1428280,1428916,1429228,1429559,1429561,1429564,1429582,1430575,1430814,1430869,1433001,1433613,1433682,1433861,1433988,1435178,1435811,1436058,1436401,1439083,1439106,1439114,1439404,1439623,1442309,1442320,1442326,1442412,1442759,1442865,1447993,1448171,1448453,1451478,1451484,1451633,1451849,1451905,1451921,1452128,1452195,1452259,1452281,1452551,1452911,1452949,1452954,1453022,1453574,1453604,1453875-145387
 6,1453963,1453981,1454386,1454414-1454415,1454888,1457437,1457450,1457471,1457504,1457520-1457521,1457610,1457995,1458003-1458004,1458020,1458285,1458447,1458456,1462266,1462269,1462643,1463044-1463047,1463052,1463056,1463455,1463736,1463750,1463754,1464675,1464721,1464762,1465115-1465116,1465190,1467765,1468581,1470183,1470679,1470940,1471449,1475878,1476604,1476621,1476642,1476644-1476645,1476652,1476680,1477094,1477530,1478382,1478748,1479117,1479216,1479222,1479411,1479528,1479905,1479966,1480046,1480627,1481197,1481302,1481306,1481396-1481397,1481891,1482041,1482075,1482170,1482555,1482859,1482996,1483005,1483027,1483190,1484343,1484398,1484832,1484910,1484914,1485409,1485668,1486490,1487528,1487530,1488158,1488164,1488296,1488471,1488492,1488644,1490493,1490507,1490550,1490761,1490994,1491155,1491221,1491234,1491458,1491479,1491538,1491564,1491724,1492663,1492710,1492782,1493330,1493921,1493925,1494536,1495501,1496194,1496338,1496429,1496709,1497371,1497588,1498880,1499679,150
 0323,1500345,1500362,1500423,1500437,1500483,1500519,1501294,1501369,1501399,1501913,1502665,1502772,1503680,1503866,1503990-1503991,1504276,1506474,1506714,1509872,1509983,1510084-1510085,1510098,1510588,1510707,1511093,1513492,1513508,1514039,1514064,1514214-1514215,1514255,1514267,1514617,1515050,1515162,1515403,1515411,1515420,1517025,1517045,1517175,1517366,1517386,1517388,1518265,1518269,1519475,1520368,1520445,1520760,1520908,1521909,1523235,1523239,1523281,1523387,1524101,1524158,1524192,1524368,1524388,1524770,1525276,1525280-1525281,1525931,1526168,1526189,1526647,1526666,1527008,1527220,1527291,1527294-1527295,1527509,1527925-1527926,1528143,1528718,1529014,1529277,1529449,1529559,1529988,1529991,1530793,1531340,1531370,1531505,1531672,1531961-1531962,1532746,1532816,1533065,1533224,1534321,1534754,1534890,1534892,1536310,1537535,1538490,1540051-1540052,1541181,1541270,1541368,1542338,1542379,1542533,1542562,1542615,1543020,1543147,1543149,1543174,1544381,1544774,1544784,
 1544812,1544820,1545286,1545292,1545325,1545364,1545408,1545411,1546692-1546693,1546730,1546759-1546760,1546801,1546804-1546805,1546835-1546836,1547845,1550061,1550302,1550307,1551685,1551714,1551802,1552130,1552227,1553204,1553824,1554161,1554168,1554170,1554175-1554176,1554179,1554181,1554184,1554188,1554192,1554195,1554276,1554281,1554300-1554301,1554994-1554995,1555240,1555259,1555266,1555423-1555424,1555463-1555464,1555467,1555555,1555569,1556206,1556428,1556911-1556912,1556914,1556937,1557317,1557617,1558483,1559351,1559828,1560367,1560546,1560679,1560689,1560729,1560977,1560979,1561137,1561262,1561385,1561660,1561923,1562472,1563193,1563379,1563381,1563417-1563418,1563420,1564052,1564437,1564475,1564756,1564760,1565081,1565711,1568404,1569615,1570288,1570598,1571369,1572092,1572198,1572543,1572561,1572611,1572630,1572655,1572663,1572668-1572671,1572896,1572905,1572911,1572967,1573224,1573229,1573626,1574151,1575400,1576233,1576741,1578760,1578762,1580568,1583005,1583007-15830
 08,1583027,1583175,1583191,1584098,1584430,1584434,1584572,1584653,1584658,1584665,1584703,1584878,1584884,1584896,1585054,1585072,1585090,1585435,1585609,1585824,1585918-1585919,1586745,1586827,1587036,1587040,1587053,1587255,1587594,1587607,1587639,1587654,1588054,1588065,1588213,1588330,1588427,1588519,1588527,1588704,1588851,1588853,1588868,1589413,1590437,1590509,1591143,1591320,1591322,1591328,1591390,1591394,1591401,1591472,1591508,1592032,1592037,1592500,1592511,1592514,1592529,1592615,1592632,1593745,1594625,1594643,1594648,1595305,1595321,1595426,1597182,1597349,1597352,1597639,1597642,1598107,1598946,1599535,1601076,1601184-1601185,1601274,1601291,1601624,1601630,1601919,1601995,1602338,1602978,1602989,1603027,1603029,1603122,1603156,1603915,1604382,1604461,1604631,1605207,1605827,1605829,1607960,1608284,1608785,1608999,1609914,1609936,1609938,1610207,1610311,1610353,1610366,1610491,1610652,1610674,1611165,1611169,1611244,1611600,1611871,1611978,1612068,1615026,1615289,16
 17018,1618401,1618541,1619297,1619383,1619444,1619483,1619835,1620324,1620461,1620932,1621367,1621372,1621417,1621453,1621806,1622450,1624234,1624349,1625196,1625952,1626050,1626978,1628104,1628918-1628919,1628924,1628950,1629235,1629239,1629244,1629250,1629372,1629440-1629441,1629485,1629507-1629508,1629519,1629577,1629652,1629916,1631885,1632454,1632740,1632742,1633730-1633731,1633793,1634120,1634237,1634425,1634736,1634836,1635510,1635558,1635644-1635645,1635762,1637112,1638072-1638073,1638879,1639614,1640031,1640036,1640040,1640042,1640331,1641077,1641095,1641376,1642099,1642484,1642499,1642847,1642868,1643034,1643284,1643537,1643825,1644245,1646282,1646724,1647035,1648201,1648394,1648433,1648719,1648840,1649001,1649043,1649632,1649966,1650047,1650061,1650309-1650310,1650320,1651088,1652829,1652929,1652931,1652955,1652982,1652985,1652989,1653941,1653978,1653997,1656225,1656669,1657256,1657261,1657636,1657638,1657685,1657881,1657897,1658760,1658765,1661067,1661258,1661448,1661464
 ,1661486,1662245-1662246,1663017,1663647,1664071,1664133,1664205,1664299,1664709,1665215,1665218,1665625,1665643,1665721,1666297,1666361,1666363,1666468,1666618,1666998,1667385-1667386,1668532,1668535,1668553,1669130,1669289,1669292,1670434,1671364,1671396-1671397,1671918,1672289,1672453,1672466,1672480,1672483,1672564,1672757,1672985,1672989,1673113,1673155,1673368,1673455,1673769,1674056,1674538,1674542,1674606,1674632,1674697,1675103,1675410,1675533,1676085,1676654,1676709,1676842,1677096,1677143-1677146,1677149,1677151,1677153-1677156,1677159,1677339,1677462,1677702,1677830,1677832,1677834-1677835,1678763,1679032,1679181-1679182,1679192,1679428,1679432,1679470,1679620,1679712,1680276,1680895,1680900,1680942,1681037,1681424,1681440,1681685,1681694,1681795,1682482,1682816,1682819,1682907,1682923,1682937,1682979,1682988,1683044,1683047,1683123,1683881,1683884,1684057,1684171,1684900,1685069,1685339,1685345,1685347,1685349-1685350,1685650,1685659,1685779,1686085,1686853,1686856,1687
 539,1687680,1687980,1688274,1688331,1688339-1688341,1688343,1688474-1688475,1688536,1688538,1688660,1689325,1689605,1689694,1689698,1690120,1690137,1690248,1691374,1691582,1691592,1691819,1691908,1692285,1692432,1692486,1692516,1693792,1693918-1693919,1693963,1694903,1694936,1694950-1694951,1695170,1695727,1695874,1695885,1695920,1696105,1696264,1696266,1696279,1696428,1696442,1696565,1696592,1696607,1696755,1696881,1697013,1697015,1697051,1697323,1697339,1697370,1697389,1697446,1697543,1697634,1697855,1698023,1698103,1698107,1698116,1698133,1698330,1700271,1700275,1700317-1700322,1700326,1700328,1700330-1700332,1700334,1700336,1700338,1700418,1700514,1700777,1700851,1700917,1700925,1700968,1701005,1701145,1701178,1701204,1701347,1701436,1701545,1701717,1702643,1702919,1703152,1703417,1703642,1703807,1703813,1703822,1703871,1703902,1703952,1704099,1704241,1704262,1704797,1704799,1704826,1705099,1705134,1705194,1705217,1705257,1705749,1705776,1705823,1705826,1705828,1705833,1705983,1
 706275,1706627,1706635,1706637,1706640,1706918,1706942,1706989,1707002,1707230-1707231,1707497,1707519,1707591,1707626-1707627,1707640,1707831,1707883,1707889,1708107,1709008,1709587,1709596,1709602,1709995,1710095,1710105,1710231,1710380,1710391,1710419,1710572,1710583,1710723,1711479,1711553,1711648,1711728,1711902,1712382,1713040,1713209,1713937,1715023,1715255,1715273,1715567-1715568,1715570-1715572,1715576,1715581-1715585,1715886,1716211,1716388,1716460,1716487,1716660,1716940,1717063,1717086,1717639,1717816,1717934,1717958,1717975,1717985,1718314,1718338,1718400,1718514,1718556,1718569,1718598,1719016,1719018,1719189-1719190,1719252,1719254-1719255,1719257,1719967,1720129,1720996,1721313,1721685,1721899,1722137,1722154,1722177,1722195,1722229,1722320,1722328,1722334,1722350-1722351,1722358,1722377,1722572,1722701,1723122,1723143,1723284,1723295,1723567,1723953,1724847,1724857,1724879,1724992-1724993,1724995,1725018,1725031,1725090,1725120,1725149,1725325,1725328,1725387,172539
 2,1725394-1725395,1725445,1725468,1725485,1725489,1725498-1725499,1725516,1725523,1725545,1725567,1725581,1725602,1725822,1725940,1725967,1726009,1726026,1726038,1726049,1726051-1726052,1726055,1726086,1726167,1726233,1726798,1726881,1726888,1727071,1727111,1727317,1727544,1727573,1727603,1727842,1728326,1729208,1729374,1729376,1729826,1729847,1729929-1729931,1729960,1730297,1730640,1730723,1730865,1731929,1732252,1732353,1732369,1732716,1732954,1732986,1733056,1733064,1733068,1733088-1733089,1733275,1733523,1733537,1733691,1734006,1734125,1734239,1734294,1734412,1734561,1734807,1734817,1734947,1734955,1734989,1735088,1735159,1735337,1735608-1735609,1735611,1735668,1735786,1735931,1735935,1735942,1735952,1736156,1736243,1736250,1736463,1736681,1736686,1737006,1737014,1737020-1737021,1737102,1737114,1737125,1737254,1737256,1737265,1737447,1737449,1737451,1737476,1738217,1738331,1738333,1738563,1739008,1739146,1739151,1739193,1739303,1739312,1739738,1739932,1740075,1740084,1740108,174
 0110,1740155,1740735,1741045,1741065,1741112,1741115,1741268,1741310,1741392,1741414,1741446,1741461,1741557,1741564,1741596,1741621,1741648,1741934,1742005,1742135,1742260,1742359,1742444-1742447,1742460,1742791-1742792,1743335,1743517,1743699,1743788,1743816,1744203-1744204,1744206,1744283,1744415,1744421,1744458-1744459,1744712,1744751,1744767,1744778,1744980,1745034,1745175,1745767,1745835,1746207,1746647,1746988,1747170,1747531,1747550,1747735,1747808,1747810,1747946,1748047,1748155,1748368,1748448,1748531,1748653,1748888,1749151,1749401,1749404,1749505,1749658-1749659,1749676,1749678,1749695,1749924-1749925,1750043,1750218,1750335,1750407,1750420,1750507,1750553,1750567,1750750,1750779,1750854-1750855,1750947,1750955,1750960,1751970,1752087,1752096,1752145,1752347,1752415,1753167,1753224,1753228-1753229,1753257,1753315-1753316,1753498,1753541,1753592,1753594,1753777,1754129,1754391,1754399,1754414,1754534,1755323,1756038,1756611,1756844,1756846,1756852-1756853,1757010-1757011,
 1757524,1757534,1757540,1757662-1757663,1757985,1758003,1758083,1758307-1758311,1758446,1758558,1761434,1761477,1761479,1761548,1762703,1763158

Modified: httpd/httpd/branches/2.4.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/CHANGES?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.4.x/CHANGES [utf-8] Mon Oct  3 12:57:47 2016
@@ -2,8 +2,16 @@
 
 Changes with Apache 2.4.24
 
+  *) mod_http2: rewrite of how responses and trailers are transferred between
+     master and slave connection. Reduction of internal states for tasks
+     and streams, stability. Heuristic id generation for slave connections
+     to better keep promise of connection ids unique at given point int time.
+     Fix for mod_cgid interop in high load situtations. 
+     Fix for handling of incoming trailers when no request body is sent.
+     [Stefan Eissing]
+  
   *) mod_http2: fix suspended handling for streams. Output could become
-     blocked in rare cases.
+     blocked in rare cases. [Stefan Eissing]
 
   *) mpm_winnt: Prevent a denial of service when the 'data' AcceptFilter is in
      use by replacing it with the 'connect' filter. PR 59970. [Jacob Champion]

Modified: httpd/httpd/branches/2.4.x/CMakeLists.txt
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/CMakeLists.txt?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/CMakeLists.txt (original)
+++ httpd/httpd/branches/2.4.x/CMakeLists.txt Mon Oct  3 12:57:47 2016
@@ -387,7 +387,7 @@ SET(mod_http2_extra_sources
   modules/http2/h2_from_h1.c         modules/http2/h2_h2.c
   modules/http2/h2_bucket_beam.c
   modules/http2/h2_mplx.c            modules/http2/h2_push.c
-  modules/http2/h2_request.c         modules/http2/h2_response.c
+  modules/http2/h2_request.c         modules/http2/h2_headers.c
   modules/http2/h2_session.c         modules/http2/h2_stream.c 
   modules/http2/h2_switch.c          modules/http2/h2_ngn_shed.c 
   modules/http2/h2_task.c            modules/http2/h2_util.c

Modified: httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2 (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/NWGNUmod_http2 Mon Oct  3 12:57:47 2016
@@ -199,7 +199,7 @@ FILES_nlm_objs = \
 	$(OBJDIR)/h2_ngn_shed.o \
 	$(OBJDIR)/h2_push.o \
 	$(OBJDIR)/h2_request.o \
-	$(OBJDIR)/h2_response.o \
+	$(OBJDIR)/h2_headers.o \
 	$(OBJDIR)/h2_session.o \
 	$(OBJDIR)/h2_stream.o \
 	$(OBJDIR)/h2_switch.o \

Modified: httpd/httpd/branches/2.4.x/modules/http2/config2.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/config2.m4?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/config2.m4 (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/config2.m4 Mon Oct  3 12:57:47 2016
@@ -30,11 +30,11 @@ h2_ctx.lo dnl
 h2_filter.lo dnl
 h2_from_h1.lo dnl
 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_response.lo dnl
 h2_session.lo dnl
 h2_stream.lo dnl
 h2_switch.lo dnl

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2.h?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2.h Mon Oct  3 12:57:47 2016
@@ -47,6 +47,9 @@ extern const char *H2_MAGIC_TOKEN;
 #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) 
+
 /* Maximum number of padding bytes in a frame, rfc7540 */
 #define H2_MAX_PADLEN               256
 /* Initial default window size, RFC 7540 ch. 6.5.2 */
@@ -115,39 +118,25 @@ typedef struct h2_session_props {
 typedef struct h2_request h2_request;
 
 struct h2_request {
-    int id;             /* stream id */
-    int initiated_on;   /* initiating stream id (PUSH) or 0 */
-    
     const char *method; /* pseudo header values, see ch. 8.1.2.3 */
     const char *scheme;
     const char *authority;
     const char *path;
     
     apr_table_t *headers;
-    apr_table_t *trailers;
 
     apr_time_t request_time;
-    apr_off_t content_length;
     
-    unsigned int chunked : 1; /* iff requst body needs to be forwarded as chunked */
-    unsigned int eoh     : 1; /* iff end-of-headers has been seen and request is complete */
-    unsigned int body    : 1; /* iff this request has a body */
+    unsigned int chunked : 1;   /* iff requst body needs to be forwarded as chunked */
     unsigned int serialize : 1; /* iff this request is written in HTTP/1.1 serialization */
-    unsigned int push_policy; /* which push policy to use for this request */
 };
 
-typedef struct h2_response h2_response;
+typedef struct h2_headers h2_headers;
 
-struct h2_response {
-    int         stream_id;
-    int         rst_error;
-    int         http_status;
-    apr_off_t   content_length;
+struct h2_headers {
+    int         status;
     apr_table_t *headers;
-    apr_table_t *trailers;
-    struct h2_response *next;
-    
-    const char  *sos_filter;
+    apr_table_t *notes;
 };
 
 typedef apr_status_t h2_io_data_cb(void *ctx, const char *data, apr_off_t len);
@@ -156,7 +145,7 @@ typedef int h2_stream_pri_cmp(int stream
 
 /* Note key to attach connection task id to conn_rec/request_rec instances */
 
-#define H2_TASK_ID_NOTE     "http2-task-id"
-
+#define H2_TASK_ID_NOTE         "http2-task-id"
+#define H2_FILTER_DEBUG_NOTE    "http2-debug"
 
 #endif /* defined(__mod_h2__h2__) */

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.c?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.c Mon Oct  3 12:57:47 2016
@@ -21,6 +21,7 @@
 #include <apr_thread_cond.h>
 
 #include <httpd.h>
+#include <http_protocol.h>
 #include <http_log.h>
 
 #include "h2_private.h"
@@ -170,6 +171,14 @@ const apr_bucket_type_t h2_bucket_type_b
  * h2_blist, a brigade without allocations
  ******************************************************************************/
  
+APR_HOOK_STRUCT(
+            APR_HOOK_LINK(beam_bucket)
+)
+AP_IMPLEMENT_HOOK_RUN_FIRST(apr_bucket *, beam_bucket,
+                            (h2_bucket_beam *beam, apr_bucket_brigade *dest,
+                             const apr_bucket *src),
+                            (beam, dest, src), NULL)
+
 apr_size_t h2_util_bl_print(char *buffer, apr_size_t bmax, 
                             const char *tag, const char *sep, 
                             h2_blist *bl)
@@ -245,9 +254,9 @@ static void report_production(h2_bucket_
     }
 }
 
-static apr_off_t calc_buffered(h2_bucket_beam *beam)
+static apr_size_t calc_buffered(h2_bucket_beam *beam)
 {
-    apr_off_t len = 0;
+    apr_size_t len = 0;
     apr_bucket *b;
     for (b = H2_BLIST_FIRST(&beam->red); 
          b != H2_BLIST_SENTINEL(&beam->red);
@@ -296,7 +305,7 @@ static apr_status_t wait_cond(h2_bucket_
 }
 
 static apr_status_t r_wait_space(h2_bucket_beam *beam, apr_read_type_e block,
-                                 h2_beam_lock *pbl, apr_off_t *premain) 
+                                 h2_beam_lock *pbl, apr_size_t *premain) 
 {
     *premain = calc_space_left(beam);
     while (!beam->aborted && *premain <= 0 
@@ -428,7 +437,7 @@ apr_status_t h2_beam_destroy(h2_bucket_b
 }
 
 apr_status_t h2_beam_create(h2_bucket_beam **pbeam, apr_pool_t *red_pool, 
-                            int id, const char *tag, 
+                            apr_uint32_t id, const char *tag, 
                             apr_size_t max_buf_size)
 {
     h2_bucket_beam *beam;
@@ -518,10 +527,12 @@ void h2_beam_abort(h2_bucket_beam *beam)
     h2_beam_lock bl;
     
     if (enter_yellow(beam, &bl) == APR_SUCCESS) {
-        r_purge_reds(beam);
-        h2_blist_cleanup(&beam->red);
-        beam->aborted = 1;
-        report_consumption(beam, 0);
+        if (!beam->aborted) {
+            beam->aborted = 1;
+            r_purge_reds(beam);
+            h2_blist_cleanup(&beam->red);
+            report_consumption(beam, 0);
+        }
         if (beam->m_cond) {
             apr_thread_cond_broadcast(beam->m_cond);
         }
@@ -585,7 +596,7 @@ static apr_status_t append_bucket(h2_buc
 {
     const char *data;
     apr_size_t len;
-    apr_off_t space_left = 0;
+    apr_size_t space_left = 0;
     apr_status_t status;
     
     if (APR_BUCKET_IS_METADATA(bred)) {
@@ -792,8 +803,10 @@ transfer:
                 else if (APR_BUCKET_IS_FLUSH(bred)) {
                     bgreen = apr_bucket_flush_create(bb->bucket_alloc);
                 }
-                else {
-                    /* put red into hold, no green sent out */
+                else if (AP_BUCKET_IS_ERROR(bred)) {
+                    ap_bucket_error *eb = (ap_bucket_error *)bred;
+                    bgreen = ap_bucket_error_create(eb->status, eb->data,
+                                                    bb->p, bb->bucket_alloc);
                 }
             }
             else if (APR_BUCKET_IS_FILE(bred)) {
@@ -846,6 +859,14 @@ transfer:
                 remain -= bgreen->length;
                 ++transferred;
             }
+            else {
+                bgreen = ap_run_beam_bucket(beam, bb, bred);
+                while (bgreen && bgreen != APR_BRIGADE_SENTINEL(bb)) {
+                    ++transferred;
+                    remain -= bgreen->length;
+                    bgreen = APR_BUCKET_NEXT(bgreen);
+                }
+            }
         }
 
         if (readbytes > 0 && remain < 0) {

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.h?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_bucket_beam.h Mon Oct  3 12:57:47 2016
@@ -170,7 +170,7 @@ typedef int h2_beam_can_beam_callback(vo
 int h2_beam_no_files(void *ctx, h2_bucket_beam *beam, apr_file_t *file);
 
 struct h2_bucket_beam {
-    int id;
+    apr_uint32_t id;
     const char *tag;
     h2_blist red;
     h2_blist hold;
@@ -223,7 +223,7 @@ struct h2_bucket_beam {
  */
 apr_status_t h2_beam_create(h2_bucket_beam **pbeam,
                             apr_pool_t *red_pool, 
-                            int id, const char *tag, 
+                            apr_uint32_t id, const char *tag, 
                             apr_size_t buffer_size);
 
 /**
@@ -373,4 +373,8 @@ int h2_beam_was_received(h2_bucket_beam
 
 apr_size_t h2_beam_get_files_beamed(h2_bucket_beam *beam);
 
+AP_DECLARE_HOOK(apr_bucket *, beam_bucket,
+                (h2_bucket_beam *beam, apr_bucket_brigade *dest,
+                 const apr_bucket *src))
+
 #endif /* h2_bucket_beam_h */

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_conn.c Mon Oct  3 12:57:47 2016
@@ -14,6 +14,7 @@
  */
 
 #include <assert.h>
+#include <apr_strings.h>
 
 #include <ap_mpm.h>
 
@@ -240,12 +241,13 @@ apr_status_t h2_conn_pre_close(struct h2
     return status;
 }
 
-conn_rec *h2_slave_create(conn_rec *master, apr_pool_t *parent,
-                          apr_allocator_t *allocator)
+conn_rec *h2_slave_create(conn_rec *master, apr_uint32_t slave_id, 
+                          apr_pool_t *parent, apr_allocator_t *allocator)
 {
     apr_pool_t *pool;
     conn_rec *c;
     void *cfg;
+    unsigned long l;
     
     AP_DEBUG_ASSERT(master);
     ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, master,
@@ -271,8 +273,29 @@ conn_rec *h2_slave_create(conn_rec *mast
     }
     
     memcpy(c, master, sizeof(conn_rec));
-           
-    /* Replace these */
+        
+    /* 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 
+     * 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. 
+     */
+    l = master->id;
+    if (sizeof(long) >= 8 && l < APR_UINT32_MAX) {
+        c->id = l|(((unsigned long)slave_id) << 32);
+    }
+    else {
+        c->id = l^(~slave_id);
+    }
     c->master                 = master;
     c->pool                   = pool;   
     c->conn_config            = ap_create_conn_config(pool);
@@ -284,7 +307,8 @@ conn_rec *h2_slave_create(conn_rec *mast
     c->data_in_output_filters = 0;
     c->clogging_input_filters = 1;
     c->log                    = NULL;
-    c->log_id                 = NULL;
+    c->log_id                 = apr_psprintf(pool, "%ld-%d", 
+                                             master->id, slave_id);
     /* Simulate that we had already a request on this connection. */
     c->keepalives             = 1;
     /* We cannot install the master connection socket on the slaves, as
@@ -304,6 +328,9 @@ conn_rec *h2_slave_create(conn_rec *mast
         ap_set_module_config(c->conn_config, h2_conn_mpm_module(), cfg);
     }
 
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, 
+                  "h2_task: creating conn, master=%ld, sid=%ld, logid=%s", 
+                  master->id, c->id, c->log_id);
     return c;
 }
 

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_conn.h Mon Oct  3 12:57:47 2016
@@ -66,8 +66,8 @@ typedef enum {
 h2_mpm_type_t h2_conn_mpm_type(void);
 
 
-conn_rec *h2_slave_create(conn_rec *master, apr_pool_t *parent,
-                          apr_allocator_t *allocator);
+conn_rec *h2_slave_create(conn_rec *master, apr_uint32_t slave_id, 
+                          apr_pool_t *parent, apr_allocator_t *allocator);
 void h2_slave_destroy(conn_rec *slave, apr_allocator_t **pallocator);
 
 apr_status_t h2_slave_run_pre_connection(conn_rec *slave, apr_socket_t *csd);

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_conn_io.c Mon Oct  3 12:57:47 2016
@@ -120,8 +120,8 @@ static void h2_conn_io_bb_log(conn_rec *
         line = *buffer? buffer : "(empty)";
     }
     /* Intentional no APLOGNO */
-    ap_log_cerror(APLOG_MARK, level, 0, c, "bb_dump(%ld-%d)-%s: %s", 
-                  c->id, stream_id, tag, line);
+    ap_log_cerror(APLOG_MARK, level, 0, c, "bb_dump(%s)-%s: %s", 
+                  c->log_id, tag, line);
 
 }
 
@@ -132,7 +132,7 @@ apr_status_t h2_conn_io_init(h2_conn_io
     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->pass_threshold = h2_config_geti64(cfg, H2_CONF_STREAM_MAX_MEM) / 2;
+    io->pass_threshold = (apr_size_t)h2_config_geti64(cfg, H2_CONF_STREAM_MAX_MEM) / 2;
     
     if (io->is_tls) {
         /* This is what we start with, 
@@ -269,9 +269,11 @@ static void check_write_size(h2_conn_io
     }
 }
 
-static apr_status_t pass_output(h2_conn_io *io, int flush, int eoc)
+static apr_status_t pass_output(h2_conn_io *io, int flush,
+                                h2_session *session_eoc)
 {
     conn_rec *c = io->c;
+    apr_bucket_brigade *bb = io->output;
     apr_bucket *b;
     apr_off_t bblen;
     apr_status_t status;
@@ -279,28 +281,37 @@ static apr_status_t pass_output(h2_conn_
     append_scratch(io);
     if (flush) {
         b = apr_bucket_flush_create(c->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(io->output, b);
+        APR_BRIGADE_INSERT_TAIL(bb, b);
     }
     
-    if (APR_BRIGADE_EMPTY(io->output)) {
+    if (APR_BRIGADE_EMPTY(bb)) {
         return APR_SUCCESS;
     }
     
     ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, c, "h2_conn_io: pass_output");
     ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, NULL);
-    apr_brigade_length(io->output, 0, &bblen);
+    apr_brigade_length(bb, 0, &bblen);
     
-    h2_conn_io_bb_log(c, 0, APLOG_TRACE2, "master conn pass", io->output);
-    status = ap_pass_brigade(c->output_filters, io->output);
+    h2_conn_io_bb_log(c, 0, APLOG_TRACE2, "master conn pass", bb);
+    status = ap_pass_brigade(c->output_filters, bb);
+    if (status == APR_SUCCESS) {
+        io->bytes_written += (apr_size_t)bblen;
+        io->last_write = apr_time_now();
+    }
+    apr_brigade_cleanup(bb);
 
-    /* careful with access after this, as we might have flushed an EOC bucket
-     * that de-allocated us all. */
-    if (!eoc) {
-        apr_brigade_cleanup(io->output);
+    if (session_eoc) {
+        apr_status_t tmp;
+        b = h2_bucket_eoc_create(c->bucket_alloc, session_eoc);
+        APR_BRIGADE_INSERT_TAIL(bb, b);
+        h2_conn_io_bb_log(c, 0, APLOG_TRACE2, "master conn pass", bb);
+        tmp = ap_pass_brigade(c->output_filters, bb);
         if (status == APR_SUCCESS) {
-            io->bytes_written += (apr_size_t)bblen;
-            io->last_write = apr_time_now();
+            status = tmp;
         }
+        /* careful with access to io after this, we have flushed an EOC bucket
+         * that de-allocated us all. */
+        apr_brigade_cleanup(bb);
     }
     
     if (status != APR_SUCCESS) {
@@ -313,14 +324,12 @@ static apr_status_t pass_output(h2_conn_
 
 apr_status_t h2_conn_io_flush(h2_conn_io *io)
 {
-    return pass_output(io, 1, 0);
+    return pass_output(io, 1, NULL);
 }
 
 apr_status_t h2_conn_io_write_eoc(h2_conn_io *io, h2_session *session)
 {
-    apr_bucket *b = h2_bucket_eoc_create(io->c->bucket_alloc, session);
-    APR_BRIGADE_INSERT_TAIL(io->output, b);
-    return pass_output(io, 1, 1);
+    return pass_output(io, 1, session);
 }
 
 apr_status_t h2_conn_io_write(h2_conn_io *io, const char *data, size_t length)
@@ -413,7 +422,7 @@ apr_status_t h2_conn_io_pass(h2_conn_io
         if (!APR_BRIGADE_EMPTY(io->output)) {
             apr_off_t len = h2_brigade_mem_size(io->output);
             if (len >= io->pass_threshold) {
-                return pass_output(io, 0, 0);
+                return pass_output(io, 0, NULL);
             }
         }
     }

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_filter.c Mon Oct  3 12:57:47 2016
@@ -18,6 +18,7 @@
 #include <apr_strings.h>
 #include <httpd.h>
 #include <http_core.h>
+#include <http_protocol.h>
 #include <http_log.h>
 #include <http_connection.h>
 #include <scoreboard.h>
@@ -32,7 +33,7 @@
 #include "h2_task.h"
 #include "h2_stream.h"
 #include "h2_request.h"
-#include "h2_response.h"
+#include "h2_headers.h"
 #include "h2_stream.h"
 #include "h2_session.h"
 #include "h2_util.h"
@@ -174,30 +175,92 @@ apr_status_t h2_filter_core_input(ap_fil
  * http2 connection status handler + stream out source
  ******************************************************************************/
 
-static const char *H2_SOS_H2_STATUS = "http2-status";
+typedef struct {
+    apr_bucket_refcount refcount;
+    h2_bucket_event_cb *cb;
+    void *ctx;
+} h2_bucket_observer;
+ 
+static apr_status_t bucket_read(apr_bucket *b, const char **str,
+                                apr_size_t *len, apr_read_type_e block)
+{
+    (void)b;
+    (void)block;
+    *str = NULL;
+    *len = 0;
+    return APR_SUCCESS;
+}
 
-int h2_filter_h2_status_handler(request_rec *r)
+static void bucket_destroy(void *data)
 {
-    h2_ctx *ctx = h2_ctx_rget(r);
-    h2_task *task;
-    
-    if (strcmp(r->handler, "http2-status")) {
-        return DECLINED;
-    }
-    if (r->method_number != M_GET) {
-        return DECLINED;
+    h2_bucket_observer *h = data;
+    if (apr_bucket_shared_destroy(h)) {
+        if (h->cb) {
+            h->cb(h->ctx, H2_BUCKET_EV_BEFORE_DESTROY, NULL);
+        }
+        apr_bucket_free(h);
     }
+}
 
-    task = ctx? h2_ctx_get_task(ctx) : NULL;
-    if (task) {
-        /* We need to handle the actual output on the main thread, as
-         * we need to access h2_session information. */
-        apr_table_setn(r->notes, H2_RESP_SOS_NOTE, H2_SOS_H2_STATUS);
-        apr_table_setn(r->headers_out, "Content-Type", "application/json");
-        r->status = 200;
-        return DONE;
+apr_bucket * h2_bucket_observer_make(apr_bucket *b, h2_bucket_event_cb *cb,
+                                 void *ctx)
+{
+    h2_bucket_observer *br;
+
+    br = apr_bucket_alloc(sizeof(*br), b->list);
+    br->cb = cb;
+    br->ctx = ctx;
+
+    b = apr_bucket_shared_make(b, br, 0, 0);
+    b->type = &h2_bucket_type_observer;
+    return b;
+} 
+
+apr_bucket * h2_bucket_observer_create(apr_bucket_alloc_t *list, 
+                                       h2_bucket_event_cb *cb, void *ctx)
+{
+    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
+
+    APR_BUCKET_INIT(b);
+    b->free = apr_bucket_free;
+    b->list = list;
+    b = h2_bucket_observer_make(b, cb, ctx);
+    return b;
+}
+                                       
+apr_status_t h2_bucket_observer_fire(apr_bucket *b, h2_bucket_event event)
+{
+    if (H2_BUCKET_IS_OBSERVER(b)) {
+        h2_bucket_observer *l = (h2_bucket_observer *)b->data; 
+        return l->cb(l->ctx, event, b);
+    }
+    return APR_EINVAL;
+}
+
+const apr_bucket_type_t h2_bucket_type_observer = {
+    "H2LAZY", 5, APR_BUCKET_METADATA,
+    bucket_destroy,
+    bucket_read,
+    apr_bucket_setaside_noop,
+    apr_bucket_split_notimpl,
+    apr_bucket_shared_copy
+};
+
+apr_bucket *h2_bucket_observer_beam(struct h2_bucket_beam *beam,
+                                    apr_bucket_brigade *dest,
+                                    const apr_bucket *src)
+{
+    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, 
+                                                  l->cb, l->ctx);
+        APR_BRIGADE_INSERT_TAIL(dest, b);
+        l->cb = NULL;
+        l->ctx = NULL;
+        h2_bucket_observer_fire(b, H2_BUCKET_EV_BEFORE_MASTER_SEND);
+        return b;
     }
-    return DECLINED;
+    return NULL;
 }
 
 static apr_status_t bbout(apr_bucket_brigade *bb, const char *fmt, ...)
@@ -337,31 +400,28 @@ static void add_stats(apr_bucket_brigade
     bbout(bb, "  }%s\n", last? "" : ",");
 }
 
-static apr_status_t h2_status_stream_filter(h2_stream *stream)
+static apr_status_t h2_status_insert(h2_task *task, apr_bucket *b)
 {
-    h2_session *s = stream->session;
-    conn_rec *c = s->c;
+    h2_mplx *m = task->mplx;
+    h2_stream *stream = h2_mplx_stream_get(m, task->stream_id);
+    h2_session *s;
+    conn_rec *c;
+    
     apr_bucket_brigade *bb;
+    apr_bucket *e;
     int32_t connFlowIn, connFlowOut;
     
-    if (!stream->response) {
-        return APR_EINVAL;
-    }
-    
-    if (!stream->buffer) {
-        stream->buffer = apr_brigade_create(stream->pool, c->bucket_alloc);
+    if (!stream) {
+        /* stream already done */
+        return APR_SUCCESS;
     }
-    bb = stream->buffer;
+    s = stream->session;
+    c = s->c;
     
-    apr_table_unset(stream->response->headers, "Content-Length");
-    stream->response->content_length = -1;
+    bb = apr_brigade_create(stream->pool, c->bucket_alloc);
     
     connFlowIn = nghttp2_session_get_effective_local_window_size(s->ngh2); 
     connFlowOut = nghttp2_session_get_remote_window_size(s->ngh2);
-    apr_table_setn(stream->response->headers, "conn-flow-in", 
-                   apr_itoa(stream->pool, connFlowIn));
-    apr_table_setn(stream->response->headers, "conn-flow-out", 
-                   apr_itoa(stream->pool, connFlowOut));
      
     bbout(bb, "{\n");
     bbout(bb, "  \"version\": \"draft-01\",\n");
@@ -376,15 +436,96 @@ static apr_status_t h2_status_stream_fil
     add_stats(bb, s, stream, 1);
     bbout(bb, "}\n");
     
+    while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
+        APR_BUCKET_REMOVE(e);
+        APR_BUCKET_INSERT_AFTER(b, e);
+        b = e;
+    }
+    apr_brigade_destroy(bb);
+    
     return APR_SUCCESS;
 }
 
-apr_status_t h2_stream_filter(h2_stream *stream)
+static apr_status_t status_event(void *ctx, h2_bucket_event event, 
+                                 apr_bucket *b)
 {
-    const char *fname = stream->response? stream->response->sos_filter : NULL; 
-    if (fname && !strcmp(H2_SOS_H2_STATUS, fname)) {
-        return h2_status_stream_filter(stream);
+    h2_task *task = ctx;
+    
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, task->c->master, 
+                  "status_event(%s): %d", task->id, event);
+    switch (event) {
+        case H2_BUCKET_EV_BEFORE_MASTER_SEND:
+            h2_status_insert(task, b);
+            break;
+        default:
+            break;
     }
     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;
+    apr_bucket *b;
+    apr_status_t status;
+    
+    if (strcmp(r->handler, "http2-status")) {
+        return DECLINED;
+    }
+    if (r->method_number != M_GET && r->method_number != M_POST) {
+        return DECLINED;
+    }
+
+    task = ctx? h2_ctx_get_task(ctx) : NULL;
+    if (task) {
+
+        if ((status = ap_discard_request_body(r)) != OK) {
+            return status;
+        }
+        
+        /* We need to handle the actual output on the main thread, as
+         * we need to access h2_session information. */
+        r->status = 200;
+        r->clength = -1;
+        r->chunked = 1;
+        apr_table_unset(r->headers_out, "Content-Length");
+        ap_set_content_type(r, "application/json");
+        apr_table_setn(r->notes, H2_FILTER_DEBUG_NOTE, "on");
+
+        bb = apr_brigade_create(r->pool, c->bucket_alloc);
+        b = h2_bucket_observer_create(c->bucket_alloc, status_event, task);
+        APR_BRIGADE_INSERT_TAIL(bb, b);
+        b = apr_bucket_eos_create(c->bucket_alloc);
+        APR_BRIGADE_INSERT_TAIL(bb, b);
+
+        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+                      "status_handler(%s): checking for incoming trailers", 
+                      task->id);
+        if (r->trailers_in && !apr_is_empty_table(r->trailers_in)) {
+            ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+                          "status_handler(%s): seeing incoming trailers", 
+                          task->id);
+            apr_table_setn(r->trailers_out, "h2-trailers-in", 
+                           apr_itoa(r->pool, 1));
+        }
+        
+        status = ap_pass_brigade(r->output_filters, bb);
+        if (status == APR_SUCCESS
+            || r->status != HTTP_OK
+            || c->aborted) {
+            return OK;
+        }
+        else {
+            /* no way to know what type of error occurred */
+            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, status, r,
+                          "status_handler(%s): ap_pass_brigade failed", 
+                          task->id);
+            return AP_FILTER_ERROR;
+        }
+    }
+    return DECLINED;
+}
+

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_filter.h Mon Oct  3 12:57:47 2016
@@ -16,6 +16,8 @@
 #ifndef __mod_h2__h2_filter__
 #define __mod_h2__h2_filter__
 
+struct h2_bucket_beam;
+struct h2_headers;
 struct h2_stream;
 struct h2_session;
 
@@ -43,9 +45,33 @@ apr_status_t h2_filter_core_input(ap_fil
                                   apr_read_type_e block,
                                   apr_off_t readbytes);
 
-#define H2_RESP_SOS_NOTE     "h2-sos-filter"
+/******* observer bucket ******************************************************/
+
+typedef enum {
+    H2_BUCKET_EV_BEFORE_DESTROY,
+    H2_BUCKET_EV_BEFORE_MASTER_SEND
+} h2_bucket_event;
+
+extern const apr_bucket_type_t h2_bucket_type_observer;
+
+typedef apr_status_t h2_bucket_event_cb(void *ctx, h2_bucket_event event, apr_bucket *b);
+
+#define H2_BUCKET_IS_OBSERVER(e)     (e->type == &h2_bucket_type_observer)
+
+apr_bucket * h2_bucket_observer_make(apr_bucket *b, h2_bucket_event_cb *cb, 
+                                     void *ctx); 
+
+apr_bucket * h2_bucket_observer_create(apr_bucket_alloc_t *list, 
+                                       h2_bucket_event_cb *cb, void *ctx); 
+                                       
+apr_status_t h2_bucket_observer_fire(apr_bucket *b, h2_bucket_event event);
+
+apr_bucket *h2_bucket_observer_beam(struct h2_bucket_beam *beam,
+                                    apr_bucket_brigade *dest,
+                                    const apr_bucket *src);
+
+/******* /.well-known/h2/state handler ****************************************/
 
-apr_status_t h2_stream_filter(struct h2_stream *stream);
 int h2_filter_h2_status_handler(request_rec *r);
 
 #endif /* __mod_h2__h2_filter__ */

Modified: httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c?rev=1763163&r1=1763162&r2=1763163&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c (original)
+++ httpd/httpd/branches/2.4.x/modules/http2/h2_from_h1.c Mon Oct  3 12:57:47 2016
@@ -28,190 +28,12 @@
 #include <util_time.h>
 
 #include "h2_private.h"
-#include "h2_response.h"
+#include "h2_headers.h"
 #include "h2_from_h1.h"
 #include "h2_task.h"
 #include "h2_util.h"
 
 
-static void set_state(h2_from_h1 *from_h1, h2_from_h1_state_t state);
-
-h2_from_h1 *h2_from_h1_create(int stream_id, apr_pool_t *pool)
-{
-    h2_from_h1 *from_h1 = apr_pcalloc(pool, sizeof(h2_from_h1));
-    if (from_h1) {
-        from_h1->stream_id = stream_id;
-        from_h1->pool = pool;
-        from_h1->state = H2_RESP_ST_STATUS_LINE;
-        from_h1->hlines = apr_array_make(pool, 10, sizeof(char *));
-    }
-    return from_h1;
-}
-
-static void set_state(h2_from_h1 *from_h1, h2_from_h1_state_t state)
-{
-    if (from_h1->state != state) {
-        from_h1->state = state;
-    }
-}
-
-h2_response *h2_from_h1_get_response(h2_from_h1 *from_h1)
-{
-    return from_h1->response;
-}
-
-static apr_status_t make_h2_headers(h2_from_h1 *from_h1, request_rec *r)
-{
-    from_h1->response = h2_response_create(from_h1->stream_id, 0,
-                                           from_h1->http_status, 
-                                           from_h1->hlines,
-                                           r->notes,
-                                           from_h1->pool);
-    from_h1->content_length = from_h1->response->content_length;
-    from_h1->chunked = r->chunked;
-    
-    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, r->connection, APLOGNO(03197)
-                  "h2_from_h1(%d): converted headers, content-length: %d"
-                  ", chunked=%d",
-                  from_h1->stream_id, (int)from_h1->content_length, 
-                  (int)from_h1->chunked);
-    
-    set_state(from_h1, ((from_h1->chunked || from_h1->content_length > 0)?
-                        H2_RESP_ST_BODY : H2_RESP_ST_DONE));
-    /* We are ready to be sent to the client */
-    return APR_SUCCESS;
-}
-
-static apr_status_t parse_header(h2_from_h1 *from_h1, ap_filter_t* f, 
-                                 char *line) {
-    (void)f;
-    
-    if (line[0] == ' ' || line[0] == '\t') {
-        char **plast;
-        /* continuation line from the header before this */
-        while (line[0] == ' ' || line[0] == '\t') {
-            ++line;
-        }
-        
-        plast = apr_array_pop(from_h1->hlines);
-        if (plast == NULL) {
-            /* not well formed */
-            return APR_EINVAL;
-        }
-        APR_ARRAY_PUSH(from_h1->hlines, const char*) = apr_psprintf(from_h1->pool, "%s %s", *plast, line);
-    }
-    else {
-        /* new header line */
-        APR_ARRAY_PUSH(from_h1->hlines, const char*) = apr_pstrdup(from_h1->pool, line);
-    }
-    return APR_SUCCESS;
-}
-
-static apr_status_t get_line(h2_from_h1 *from_h1, apr_bucket_brigade *bb,
-                             ap_filter_t* f, char *line, apr_size_t len)
-{
-    apr_status_t status;
-    if (!from_h1->bb) {
-        from_h1->bb = apr_brigade_create(from_h1->pool, f->c->bucket_alloc);
-    }
-    else {
-        apr_brigade_cleanup(from_h1->bb);                
-    }
-    status = apr_brigade_split_line(from_h1->bb, bb, 
-                                                 APR_BLOCK_READ, 
-                                                 HUGE_STRING_LEN);
-    if (status == APR_SUCCESS) {
-        --len;
-        status = apr_brigade_flatten(from_h1->bb, line, &len);
-        if (status == APR_SUCCESS) {
-            /* we assume a non-0 containing line and remove
-             * trailing crlf. */
-            line[len] = '\0';
-            if (len >= 2 && !strcmp(H2_CRLF, line + len - 2)) {
-                len -= 2;
-                line[len] = '\0';
-            }
-            
-            apr_brigade_cleanup(from_h1->bb);
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
-                          "h2_from_h1(%d): read line: %s",
-                          from_h1->stream_id, line);
-        }
-    }
-    return status;
-}
-
-apr_status_t h2_from_h1_read_response(h2_from_h1 *from_h1, ap_filter_t* f,
-                                      apr_bucket_brigade* bb)
-{
-    apr_status_t status = APR_SUCCESS;
-    char line[HUGE_STRING_LEN];
-    
-    if ((from_h1->state == H2_RESP_ST_BODY) 
-        || (from_h1->state == H2_RESP_ST_DONE)) {
-        if (from_h1->chunked) {
-            /* The httpd core HTTP_HEADER filter has or will install the 
-             * "CHUNK" output transcode filter, which appears further down 
-             * the filter chain. We do not want it for HTTP/2.
-             * Once we successfully deinstalled it, this filter has no
-             * further function and we remove it.
-             */
-            status = ap_remove_output_filter_byhandle(f->r->output_filters, 
-                                                      "CHUNK");
-            if (status == APR_SUCCESS) {
-                ap_remove_output_filter(f);
-            }
-        }
-        
-        return ap_pass_brigade(f->next, bb);
-    }
-    
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
-                  "h2_from_h1(%d): read_response", from_h1->stream_id);
-    
-    while (!APR_BRIGADE_EMPTY(bb) && status == APR_SUCCESS) {
-        
-        switch (from_h1->state) {
-                
-            case H2_RESP_ST_STATUS_LINE:
-            case H2_RESP_ST_HEADERS:
-                status = get_line(from_h1, bb, f, line, sizeof(line));
-                if (status != APR_SUCCESS) {
-                    return status;
-                }
-                if (from_h1->state == H2_RESP_ST_STATUS_LINE) {
-                    /* instead of parsing, just take it directly */
-                    from_h1->http_status = f->r->status;
-                    from_h1->state = H2_RESP_ST_HEADERS;
-                }
-                else if (line[0] == '\0') {
-                    /* end of headers, create the h2_response and
-                     * pass the rest of the brigade down the filter
-                     * chain.
-                     */
-                    status = make_h2_headers(from_h1, f->r);
-                    if (from_h1->bb) {
-                        apr_brigade_destroy(from_h1->bb);
-                        from_h1->bb = NULL;
-                    }
-                    if (!APR_BRIGADE_EMPTY(bb)) {
-                        return ap_pass_brigade(f->next, bb);
-                    }
-                }
-                else {
-                    status = parse_header(from_h1, f, line);
-                }
-                break;
-                
-            default:
-                return ap_pass_brigade(f->next, bb);
-        }
-        
-    }
-    
-    return status;
-}
-
 /* This routine is called by apr_table_do and merges all instances of
  * the passed field values into a single array that will be further
  * processed by some later routine.  Originally intended to help split
@@ -345,7 +167,7 @@ static int copy_header(void *ctx, const
     return 1;
 }
 
-static h2_response *create_response(h2_from_h1 *from_h1, request_rec *r)
+static h2_headers *create_response(h2_task *task, request_rec *r)
 {
     const char *clheader;
     const char *ctype;
@@ -471,115 +293,316 @@ static h2_response *create_response(h2_f
                      (void *) headers, r->headers_out, NULL);
     }
     
-    return h2_response_rcreate(from_h1->stream_id, r, r->status, 
-                               headers, r->pool);
+    return h2_headers_rcreate(r, r->status, headers, r->pool);
 }
 
-apr_status_t h2_response_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
+apr_status_t h2_headers_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
 {
     h2_task *task = f->ctx;
-    h2_from_h1 *from_h1 = task->output.from_h1;
     request_rec *r = f->r;
-    apr_bucket *b;
+    apr_bucket *b, *bresp, *body_bucket = NULL, *next;
     ap_bucket_error *eb = NULL;
+    h2_headers *response = NULL;
 
-    AP_DEBUG_ASSERT(from_h1 != NULL);
-    
     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
-                  "h2_from_h1(%d): output_filter called", from_h1->stream_id);
+                  "h2_task(%s): output_filter called", task->id);
     
-    if (r->header_only && from_h1->response) {
-        /* throw away any data after we have compiled the response */
-        apr_brigade_cleanup(bb);
-        return OK;
-    }
-    
-    for (b = APR_BRIGADE_FIRST(bb);
-         b != APR_BRIGADE_SENTINEL(bb);
-         b = APR_BUCKET_NEXT(b))
-    {
-        if (AP_BUCKET_IS_ERROR(b) && !eb) {
-            eb = b->data;
-            continue;
-        }
-        /*
-         * If we see an EOC bucket it is a signal that we should get out
-         * of the way doing nothing.
-         */
-        if (AP_BUCKET_IS_EOC(b)) {
-            ap_remove_output_filter(f);
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, f->c,
-                          "h2_from_h1(%d): eoc bucket passed", 
-                          from_h1->stream_id);
-            return ap_pass_brigade(f->next, bb);
+    if (!task->output.sent_response) {
+        /* check, if we need to send the response now. Until we actually
+         * see a DATA bucket or some EOS/EOR, we do not do so. */
+        for (b = APR_BRIGADE_FIRST(bb);
+             b != APR_BRIGADE_SENTINEL(bb);
+             b = APR_BUCKET_NEXT(b))
+        {
+            if (AP_BUCKET_IS_ERROR(b) && !eb) {
+                eb = b->data;
+            }
+            else if (AP_BUCKET_IS_EOC(b)) {
+                /* If we see an EOC bucket it is a signal that we should get out
+                 * of the way doing nothing.
+                 */
+                ap_remove_output_filter(f);
+                ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, f->c,
+                              "h2_task(%s): eoc bucket passed", task->id);
+                return ap_pass_brigade(f->next, bb);
+            }
+            else if (!H2_BUCKET_IS_HEADERS(b) && !APR_BUCKET_IS_FLUSH(b)) { 
+                body_bucket = b;
+                break;
+            }
+        }
+        
+        if (eb) {
+            int st = eb->status;
+            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03047)
+                          "h2_task(%s): err bucket status=%d", task->id, st);
+            /* throw everything away and replace it with the error response
+             * generated by ap_die() */
+            apr_brigade_cleanup(bb);
+            ap_die(st, r);
+            return AP_FILTER_ERROR;
+        }
+        
+        if (body_bucket) {
+            /* time to insert the response bucket before the body */
+            response = create_response(task, r);
+            if (response == NULL) {
+                ap_log_cerror(APLOG_MARK, APLOG_NOTICE, 0, f->c, APLOGNO(03048)
+                              "h2_task(%s): unable to create response", task->id);
+                return APR_ENOMEM;
+            }
+            
+            bresp = h2_bucket_headers_create(f->c->bucket_alloc, response);
+            APR_BUCKET_INSERT_BEFORE(body_bucket, bresp);
+            /*APR_BRIGADE_INSERT_HEAD(bb, bresp);*/
+            task->output.sent_response = 1;
+            r->sent_bodyct = 1;
         }
-    }
-    
-    if (eb) {
-        int st = eb->status;
-        apr_brigade_cleanup(bb);
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03047)
-                      "h2_from_h1(%d): err bucket status=%d", 
-                      from_h1->stream_id, st);
-        ap_die(st, r);
-        return AP_FILTER_ERROR;
-    }
-    
-    from_h1->response = create_response(from_h1, r);
-    if (from_h1->response == NULL) {
-        ap_log_cerror(APLOG_MARK, APLOG_NOTICE, 0, f->c, APLOGNO(03048)
-                      "h2_from_h1(%d): unable to create response", 
-                      from_h1->stream_id);
-        return APR_ENOMEM;
     }
     
     if (r->header_only) {
         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
-                      "h2_from_h1(%d): header_only, cleanup output brigade", 
-                      from_h1->stream_id);
-        apr_brigade_cleanup(bb);
-        return OK;
+                      "h2_task(%s): header_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);
+            b = next;
+        }
     }
-    
-    r->sent_bodyct = 1;         /* Whatever follows is real body stuff... */
-    
-    ap_remove_output_filter(f);
-    if (APLOGctrace1(f->c)) {
-        apr_off_t len = 0;
-        apr_brigade_length(bb, 0, &len);
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
-                      "h2_from_h1(%d): removed header filter, passing brigade "
-                      "len=%ld", from_h1->stream_id, (long)len);
+    else if (task->output.sent_response) {
+        /* lets get out of the way, our task is done */
+        ap_remove_output_filter(f);
     }
     return ap_pass_brigade(f->next, bb);
 }
 
-apr_status_t h2_response_trailers_filter(ap_filter_t *f, apr_bucket_brigade *bb)
+static void make_chunk(h2_task *task, apr_bucket_brigade *bb, 
+                       apr_bucket *first, apr_uint64_t chunk_len, 
+                       apr_bucket *tail)
+{
+    /* Surround the buckets [first, tail[ with new buckets carrying the
+     * HTTP/1.1 chunked encoding format. If tail is NULL, the chunk extends
+     * to the end of the brigade. */
+    char buffer[128];
+    apr_bucket *c;
+    int len;
+    
+    len = apr_snprintf(buffer, H2_ALEN(buffer), 
+                       "%"APR_UINT64_T_HEX_FMT"\r\n", chunk_len);
+    c = apr_bucket_heap_create(buffer, len, NULL, bb->bucket_alloc);
+    APR_BUCKET_INSERT_BEFORE(first, c);
+    c = apr_bucket_heap_create("\r\n", 2, NULL, bb->bucket_alloc);
+    if (tail) {
+        APR_BUCKET_INSERT_BEFORE(tail, c);
+    }
+    else {
+        APR_BRIGADE_INSERT_TAIL(bb, c);
+    }
+}
+
+static int ser_header(void *ctx, const char *name, const char *value) 
+{
+    apr_bucket_brigade *bb = ctx;
+    apr_brigade_printf(bb, NULL, NULL, "%s: %s\r\n", name, value);
+    return 1;
+}
+
+apr_status_t h2_filter_request_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 = f->ctx;
-    h2_from_h1 *from_h1 = task->output.from_h1;
     request_rec *r = f->r;
-    apr_bucket *b;
+    apr_status_t status = APR_SUCCESS;
+    apr_bucket *b, *next, *first_data = NULL;
+    apr_off_t bblen = 0;
+
+    if (!task->input.chunked) {
+        status = ap_get_brigade(f->next, bb, mode, block, readbytes);
+        /* pipe data through, just take care of trailers */
+        for (b = APR_BRIGADE_FIRST(bb); 
+             b != APR_BRIGADE_SENTINEL(bb); b = next) {
+            next = APR_BUCKET_NEXT(b);
+            if (H2_BUCKET_IS_HEADERS(b)) {
+                h2_headers *headers = h2_bucket_headers_get(b);
+                ap_assert(headers);
+                ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+                              "h2_task(%s): receiving trailers", task->id);
+                r->trailers_in = apr_table_clone(r->pool, headers->headers);
+                APR_BUCKET_REMOVE(b);
+                apr_bucket_destroy(b);
+                ap_remove_input_filter(f);
+                break;
+            }
+        }
+        return status;
+    }
+
+    /* Things are more complicated. The standard HTTP input filter, which
+     * does a lot what we do not want to duplicate, also cares about chunked
+     * transfer encoding and trailers.
+     * We need to simulate chunked encoding for it to be happy.
+     */
+    
+    if (!task->input.bbchunk) {
+        task->input.bbchunk = apr_brigade_create(r->pool, f->c->bucket_alloc);
+    }
+    if (APR_BRIGADE_EMPTY(task->input.bbchunk)) {
+        /* get more data from the lower layer filters. Always do this
+         * in larger pieces, since we handle the read modes ourself.
+         */
+        status = ap_get_brigade(f->next, task->input.bbchunk, 
+                                AP_MODE_READBYTES, block, 32*1024);
+        if (status == APR_EOF) {
+            if (!task->input.eos) {
+                status = apr_brigade_puts(bb, NULL, NULL, "0\r\n\r\n");
+                task->input.eos = 1;
+                return APR_SUCCESS;
+            }
+            ap_remove_input_filter(f);
+            return status;
+            
+        }
+        else if (status != APR_SUCCESS) {
+            return status;
+        }
+
+        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+                      "h2_task(%s): trailers_in inspecting brigade", task->id);
+        for (b = APR_BRIGADE_FIRST(task->input.bbchunk); 
+             b != APR_BRIGADE_SENTINEL(task->input.bbchunk) && !task->input.eos; 
+             b = next) {
+            next = APR_BUCKET_NEXT(b);
+            if (APR_BUCKET_IS_METADATA(b)) {
+                if (first_data) {
+                    make_chunk(task, task->input.bbchunk, first_data, bblen, b);
+                    first_data = NULL;
+                    bblen = 0;
+                }
+                
+                if (H2_BUCKET_IS_HEADERS(b)) {
+                    apr_bucket_brigade *tmp;
+                    h2_headers *headers = h2_bucket_headers_get(b);
+                    
+                    ap_assert(headers);
+                    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+                                  "h2_task(%s): receiving trailers", task->id);
+                    tmp = apr_brigade_split_ex(task->input.bbchunk, b, NULL);
+                    if (!apr_is_empty_table(headers->headers)) {
+                        status = apr_brigade_puts(task->input.bbchunk, NULL, NULL, "0\r\n");
+                        apr_table_do(ser_header, task->input.bbchunk, headers->headers, NULL);
+                        status = apr_brigade_puts(task->input.bbchunk, NULL, NULL, "\r\n");
+                    }
+                    else {
+                        status = apr_brigade_puts(task->input.bbchunk, NULL, NULL, "0\r\n\r\n");
+                    }
+                    APR_BRIGADE_CONCAT(task->input.bbchunk, tmp);
+                    apr_brigade_destroy(tmp);
+                    r->trailers_in = apr_table_clone(r->pool, headers->headers);
+                    APR_BUCKET_REMOVE(b);
+                    apr_bucket_destroy(b);
+                    task->input.eos = 1;
+                }
+                else if (APR_BUCKET_IS_EOS(b)) {
+                    apr_bucket_brigade *tmp = apr_brigade_split_ex(task->input.bbchunk, b, NULL);
+                    status = apr_brigade_puts(task->input.bbchunk, NULL, NULL, "0\r\n\r\n");
+                    APR_BRIGADE_CONCAT(task->input.bbchunk, tmp);
+                    apr_brigade_destroy(tmp);
+                    task->input.eos = 1;
+                }
+                break;
+            }
+            else if (b->length == 0) {
+                APR_BUCKET_REMOVE(b);
+                apr_bucket_destroy(b);
+            } 
+            else {
+                if (!first_data) {
+                    first_data = b;
+                }
+                bblen += b->length;
+            }    
+        }
+        
+        if (first_data) {
+            make_chunk(task, task->input.bbchunk, first_data, bblen, NULL);
+        }            
+    }
+    
+    if (mode == AP_MODE_EXHAUSTIVE) {
+        /* return all we have */
+        APR_BRIGADE_CONCAT(bb, task->input.bbchunk);
+    }
+    else if (mode == AP_MODE_READBYTES) {
+        status = h2_brigade_concat_length(bb, task->input.bbchunk, readbytes);
+    }
+    else if (mode == AP_MODE_SPECULATIVE) {
+        status = h2_brigade_copy_length(bb, task->input.bbchunk, readbytes);
+    }
+    else if (mode == AP_MODE_GETLINE) {
+        /* we are reading a single LF line, e.g. the HTTP headers. 
+         * this has the nasty side effect to split the bucket, even
+         * though it ends with CRLF and creates a 0 length bucket */
+        status = apr_brigade_split_line(bb, task->input.bbchunk, block, 
+                                        HUGE_STRING_LEN);
+        if (APLOGctrace1(f->c)) {
+            char buffer[1024];
+            apr_size_t len = sizeof(buffer)-1;
+            apr_brigade_flatten(bb, buffer, &len);
+            buffer[len] = 0;
+            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
+                          "h2_task(%s): getline: %s",
+                          task->id, buffer);
+        }
+    }
+    else {
+        /* Hmm, well. There is mode AP_MODE_EATCRLF, but we chose not
+         * to support it. Seems to work. */
+        ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOTIMPL, f->c,
+                      APLOGNO(02942) 
+                      "h2_task, unsupported READ mode %d", mode);
+        status = APR_ENOTIMPL;
+    }
+    
+    h2_util_bb_log(f->c, task->stream_id, APLOG_TRACE2, "forwarding input", bb);
+    return status;
+}
+
+apr_status_t h2_filter_trailers_out(ap_filter_t *f, apr_bucket_brigade *bb)
+{
+    h2_task *task = f->ctx;
+    request_rec *r = f->r;
+    apr_bucket *b, *e;
  
-    if (from_h1 && from_h1->response) {
-        /* Detect the EOR bucket and forward any trailers that may have
-         * been set to our h2_response.
+    if (task && r) {
+        /* Detect the EOS/EOR bucket and forward any trailers that may have
+         * been set to our h2_headers.
          */
         for (b = APR_BRIGADE_FIRST(bb);
              b != APR_BRIGADE_SENTINEL(bb);
              b = APR_BUCKET_NEXT(b))
         {
-            if (AP_BUCKET_IS_EOR(b)) {
-                /* FIXME: need a better test case than this.
-                apr_table_setn(r->trailers_out, "X", "1"); */
-                if (r->trailers_out && !apr_is_empty_table(r->trailers_out)) {
-                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03049)
-                                  "h2_from_h1(%d): trailers filter, saving trailers",
-                                  from_h1->stream_id);
-                    h2_response_set_trailers(from_h1->response,
-                                             apr_table_clone(from_h1->pool, 
-                                                             r->trailers_out));
-                }
+            if ((APR_BUCKET_IS_EOS(b) || AP_BUCKET_IS_EOR(b))
+                && r->trailers_out && !apr_is_empty_table(r->trailers_out)) {
+                h2_headers *headers;
+                apr_table_t *trailers;
+                
+                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03049)
+                              "h2_task(%s): sending trailers", task->id);
+                trailers = apr_table_clone(r->pool, r->trailers_out);
+                headers = h2_headers_rcreate(r, HTTP_OK, trailers, r->pool);
+                e = h2_bucket_headers_create(bb->bucket_alloc, headers);
+                APR_BUCKET_INSERT_BEFORE(b, e);
+                apr_table_clear(r->trailers_out);
+                ap_remove_output_filter(f);
                 break;
             }
         }