@@ -1974,6 +1974,192 @@ struct parser_coro_test
19741974 BOOST_TEST (r.success );
19751975 }
19761976
1977+ void
1978+ testSourceForLargeBody ()
1979+ {
1980+ capy::test::fuse f;
1981+ auto r = f.armed ([&](capy::test::fuse&) -> capy::task<>
1982+ {
1983+ std::string const expected (40000 , ' x' );
1984+
1985+ capy::test::read_stream rs (f);
1986+ rs.provide (
1987+ " HTTP/1.1 200 OK\r\n "
1988+ " Content-Length: 40000\r\n "
1989+ " \r\n " );
1990+ rs.provide (expected);
1991+
1992+ response_parser pr (res_cfg_);
1993+ pr.reset ();
1994+ pr.start ();
1995+
1996+ auto source = pr.source_for (rs);
1997+
1998+ std::string body;
1999+ capy::const_buffer arr[16 ];
2000+
2001+ for (;;)
2002+ {
2003+ auto [ec, bufs] = co_await source.pull (arr);
2004+ if (ec == capy::cond::eof)
2005+ break ;
2006+ BOOST_TEST (ec != error::in_place_overflow);
2007+ if (ec)
2008+ co_return ;
2009+ std::size_t n = 0 ;
2010+ for (auto const & buf : bufs)
2011+ {
2012+ body.append (
2013+ static_cast <char const *>(buf.data ()),
2014+ buf.size ());
2015+ n += buf.size ();
2016+ }
2017+ source.consume (n);
2018+ }
2019+
2020+ BOOST_TEST (body == expected);
2021+ BOOST_TEST (pr.is_complete ());
2022+ });
2023+ BOOST_TEST (r.success );
2024+ }
2025+
2026+ void
2027+ testSourceForBodyTooLarge ()
2028+ {
2029+ capy::test::fuse f;
2030+ auto r = f.armed ([&](capy::test::fuse&) -> capy::task<>
2031+ {
2032+ parser_config cfg{false };
2033+ cfg.body_limit = 5 ;
2034+ auto small_cfg = make_parser_config (cfg);
2035+
2036+ capy::test::read_stream rs (f, 1 );
2037+ rs.provide (
2038+ " HTTP/1.1 200 OK\r\n "
2039+ " Content-Length: 100\r\n "
2040+ " \r\n "
2041+ " this body is way over the configured limit" );
2042+
2043+ response_parser pr (small_cfg);
2044+ pr.reset ();
2045+ pr.start ();
2046+
2047+ auto source = pr.source_for (rs);
2048+
2049+ capy::const_buffer arr[16 ];
2050+ auto [ec, bufs] = co_await source.pull (arr);
2051+
2052+ BOOST_TEST (static_cast <bool >(ec));
2053+ BOOST_TEST (ec != capy::cond::eof);
2054+ BOOST_TEST (capy::buffer_size (bufs) == 0 );
2055+ BOOST_TEST (! pr.is_complete ());
2056+ });
2057+ BOOST_TEST (r.success );
2058+ }
2059+
2060+ void
2061+ testRead ()
2062+ {
2063+ capy::test::fuse f;
2064+ auto r = f.armed ([&](capy::test::fuse&) -> capy::task<>
2065+ {
2066+ capy::test::read_stream rs (f, 1 );
2067+ rs.provide (
2068+ " HTTP/1.1 200 OK\r\n "
2069+ " Content-Length: 13\r\n "
2070+ " \r\n "
2071+ " Hello, World!" );
2072+
2073+ response_parser pr (res_cfg_);
2074+ pr.reset ();
2075+ pr.start ();
2076+
2077+ auto [ec] = co_await pr.read (rs);
2078+ if (ec)
2079+ co_return ;
2080+
2081+ BOOST_TEST (pr.is_complete ());
2082+ BOOST_TEST (pr.body () == " Hello, World!" );
2083+ });
2084+ BOOST_TEST (r.success );
2085+ }
2086+
2087+ void
2088+ testReadChunked ()
2089+ {
2090+ capy::test::fuse f;
2091+ auto r = f.armed ([&](capy::test::fuse&) -> capy::task<>
2092+ {
2093+ capy::test::read_stream rs (f, 1 );
2094+ rs.provide (
2095+ " HTTP/1.1 200 OK\r\n "
2096+ " Transfer-Encoding: chunked\r\n "
2097+ " \r\n "
2098+ " 5\r\n Hello\r\n "
2099+ " 7\r\n , World\r\n "
2100+ " 0\r\n\r\n " );
2101+
2102+ response_parser pr (res_cfg_);
2103+ pr.reset ();
2104+ pr.start ();
2105+
2106+ auto [ec] = co_await pr.read (rs);
2107+ if (ec)
2108+ co_return ;
2109+
2110+ BOOST_TEST (pr.is_complete ());
2111+ BOOST_TEST (pr.body () == " Hello, World" );
2112+ });
2113+ BOOST_TEST (r.success );
2114+ }
2115+
2116+ void
2117+ testReadEof ()
2118+ {
2119+ capy::test::fuse f;
2120+ auto r = f.armed ([&](capy::test::fuse&) -> capy::task<>
2121+ {
2122+ capy::test::read_stream rs (f, 1 );
2123+
2124+ response_parser pr (res_cfg_);
2125+ pr.reset ();
2126+ pr.start ();
2127+
2128+ auto [ec] = co_await pr.read (rs);
2129+
2130+ BOOST_TEST (static_cast <bool >(ec));
2131+ BOOST_TEST (! pr.is_complete ());
2132+ });
2133+ BOOST_TEST (r.success );
2134+ }
2135+
2136+ void
2137+ testReadOverflow ()
2138+ {
2139+ capy::test::fuse f;
2140+ auto r = f.armed ([&](capy::test::fuse&) -> capy::task<>
2141+ {
2142+ std::string const big (40000 , ' x' );
2143+
2144+ capy::test::read_stream rs (f);
2145+ rs.provide (
2146+ " HTTP/1.1 200 OK\r\n "
2147+ " Content-Length: 40000\r\n "
2148+ " \r\n " );
2149+ rs.provide (big);
2150+
2151+ response_parser pr (res_cfg_);
2152+ pr.reset ();
2153+ pr.start ();
2154+
2155+ auto [ec] = co_await pr.read (rs);
2156+
2157+ BOOST_TEST (static_cast <bool >(ec));
2158+ BOOST_TEST (! pr.is_complete ());
2159+ });
2160+ BOOST_TEST (r.success );
2161+ }
2162+
19772163 void
19782164 run ()
19792165 {
@@ -1982,6 +2168,12 @@ struct parser_coro_test
19822168 testReadWriteSinkChunked ();
19832169 testSourceFor ();
19842170 testSourceForChunked ();
2171+ testSourceForLargeBody ();
2172+ testSourceForBodyTooLarge ();
2173+ testRead ();
2174+ testReadChunked ();
2175+ testReadEof ();
2176+ testReadOverflow ();
19852177 }
19862178};
19872179
0 commit comments